oscillator.hpp (9819B)
1 #pragma once 2 3 #include <stdlib.h> 4 #include <stdint.h> 5 #include <math.h> 6 #include <vector> 7 8 #include "base.hpp" 9 #include "math.hpp" 10 #include "table.hpp" 11 12 namespace bogaudio { 13 namespace dsp { 14 15 struct Oscillator { 16 float _sampleRate; 17 float _frequency; 18 19 Oscillator( 20 float sampleRate = 1000.0f, 21 float frequency = 100.0f 22 ) 23 : _sampleRate(sampleRate > 1.0 ? sampleRate : 1.0) 24 , _frequency(frequency) 25 { 26 } 27 virtual ~Oscillator() {} 28 29 void setSampleRate(float sampleRate) { 30 if (_sampleRate != sampleRate && sampleRate >= 1.0) { 31 _sampleRate = sampleRate; 32 _sampleRateChanged(); 33 } 34 } 35 36 virtual void _sampleRateChanged() {} 37 38 void setFrequency(float frequency) { 39 if (_frequency != frequency) { 40 _frequency = frequency; 41 _frequencyChanged(); 42 } 43 } 44 45 virtual void _frequencyChanged() {} 46 }; 47 48 struct OscillatorGenerator : Oscillator, Generator { 49 OscillatorGenerator( 50 float sampleRate = 1000.0f, 51 float frequency = 100.0f 52 ) 53 : Oscillator(sampleRate, frequency) 54 { 55 } 56 }; 57 58 struct Phasor : OscillatorGenerator { 59 typedef uint64_t phase_t; 60 typedef int64_t phase_delta_t; 61 static constexpr phase_t cyclePhase = UINT32_MAX; 62 static constexpr float twoPI = 2.0f * M_PI; 63 static constexpr float maxSampleWidth = 0.25f; 64 65 phase_delta_t _delta; 66 phase_t _phase = 0; 67 float _sampleWidth = 0.0f; 68 phase_t _samplePhase = 0; 69 70 Phasor( 71 float sampleRate = 1000.0f, 72 float frequency = 100.0f, 73 float initialPhase = 0.0f 74 ) 75 : OscillatorGenerator(sampleRate, frequency) 76 { 77 setPhase(initialPhase); 78 _update(); 79 } 80 81 void _sampleRateChanged() override { 82 _update(); 83 } 84 85 void _frequencyChanged() override { 86 _update(); 87 } 88 89 void setSampleWidth(float sw); 90 virtual void resetPhase(); 91 void setPhase(float radians); 92 void syncPhase(const Phasor& phasor); 93 float nextFromPhasor(const Phasor& phasor, phase_delta_t offset = 0); 94 virtual float nextForPhase(phase_t phase); 95 virtual void _update(); 96 inline void advancePhase() { _phase += _delta; } 97 inline void advancePhase(int n) { assert(n > 0); _phase += n * _delta; } 98 float _next() override final; 99 100 inline static phase_delta_t radiansToPhase(float radians) { return (radians / twoPI) * cyclePhase; } 101 inline static float phaseToRadians(phase_t phase) { return (phase / (float)cyclePhase) * twoPI; } 102 }; 103 104 struct TablePhasor : Phasor { 105 enum Interpolation { 106 INTERPOLATION_DEFAULT, 107 INTERPOLATION_ON, 108 INTERPOLATION_OFF 109 }; 110 111 const Table& _table; 112 int _tableLength; 113 Interpolation _interpolation; 114 115 TablePhasor( 116 const Table& table, 117 double sampleRate = 1000.0f, 118 double frequency = 100.0f, 119 Interpolation interpolation = INTERPOLATION_DEFAULT 120 ) 121 : Phasor(sampleRate, frequency) 122 , _table(table) 123 , _tableLength(table.length()) 124 , _interpolation(interpolation) 125 { 126 } 127 128 void setInterpolation(Interpolation interpolation); 129 130 float nextForPhase(phase_t phase) override; 131 }; 132 133 struct SineOscillator : OscillatorGenerator { 134 double _k1, _k2; 135 double _x; 136 double _y; 137 138 SineOscillator( 139 double sampleRate = 1000.0f, 140 double frequency = 100.0f, 141 double initialPhase = 0.0 142 ) 143 : OscillatorGenerator(sampleRate, frequency) 144 { 145 setPhase(initialPhase); 146 update(); 147 } 148 149 void _sampleRateChanged() override { 150 update(); 151 } 152 153 void _frequencyChanged() override { 154 update(); 155 } 156 157 void setPhase(double phase); 158 void update(); 159 float _next() override; 160 }; 161 162 struct SineTableOscillator : TablePhasor { 163 SineTableOscillator( 164 float sampleRate = 1000.0f, 165 float frequency = 100.0f, 166 Interpolation interpolation = INTERPOLATION_ON 167 ) 168 : TablePhasor(StaticSineTable::table(), sampleRate, frequency, interpolation) 169 { 170 } 171 }; 172 173 struct SawOscillator : Phasor { 174 SawOscillator( 175 float sampleRate = 1000.0f, 176 float frequency = 100.0f 177 ) 178 : Phasor(sampleRate, frequency) 179 { 180 } 181 182 float nextForPhase(phase_t phase) override; 183 }; 184 185 struct SaturatingSawOscillator : SawOscillator { 186 float _saturation; 187 float _saturationNormalization; 188 FastTanhf _tanhf; 189 190 SaturatingSawOscillator( 191 float sampleRate = 1000.0f, 192 float frequency = 100.0f 193 ) 194 : SawOscillator(sampleRate, frequency) 195 , _saturation(0.0f) 196 , _saturationNormalization(1.0f) 197 { 198 } 199 200 void setSaturation(float saturation); 201 float nextForPhase(phase_t phase) override; 202 }; 203 204 struct BandLimitedSawOscillator : SaturatingSawOscillator { 205 int _quality; 206 const Table& _table; 207 phase_t _qd = 0; 208 float _halfTableLen; 209 210 BandLimitedSawOscillator( 211 float sampleRate = 1000.0f, 212 float frequency = 100.0f, 213 int quality = 5, 214 const Table& table = StaticBlepTable::table() 215 ) 216 : SaturatingSawOscillator(sampleRate, frequency) 217 , _quality(quality) 218 , _table(table) 219 , _halfTableLen(_table.length() / 2) 220 { 221 setQuality(quality); 222 } 223 224 void setQuality(int quality); 225 void _update() override; 226 float nextForPhase(phase_t phase) override; 227 }; 228 229 struct SquareOscillator : Phasor { 230 static constexpr float minPulseWidth = 0.03f; 231 static constexpr float maxPulseWidth = 1.0f - minPulseWidth; 232 static constexpr float defaultPulseWidth = 0.5f; 233 float _pulseWidthInput = -1.0f; 234 phase_t _lastCycle = -1; 235 phase_t _pulseWidth = cyclePhase * defaultPulseWidth, _nextPulseWidth = cyclePhase * defaultPulseWidth; 236 bool positive = true; 237 238 SquareOscillator( 239 float sampleRate = 1000.0f, 240 float frequency = 100.0f 241 ) 242 : Phasor(sampleRate, frequency) 243 { 244 } 245 246 void setPulseWidth(float pw); 247 float nextForPhase(phase_t phase) override; 248 }; 249 250 struct BandLimitedSquareOscillator : BandLimitedSawOscillator { 251 const float minPulseWidth = 0.03f; 252 const float maxPulseWidth = 1.0f - minPulseWidth; 253 float _pulseWidthInput = -1.0f; 254 bool _dcCorrection = false; 255 phase_t _lastCycle = -1; 256 phase_delta_t _pulseWidth = 0, _nextPulseWidth = 0; 257 float _offset = 0.0f, _nextOffset = 0.0f; 258 float _dcOffset = 0.0f, _nextDcOffset = 0.0f; 259 260 BandLimitedSquareOscillator( 261 float sampleRate = 1000.0f, 262 float frequency = 100.0f, 263 int quality = 5, 264 const Table& table = StaticBlepTable::table() 265 ) 266 : BandLimitedSawOscillator(sampleRate, frequency, quality, table) 267 { 268 setPulseWidth(0.5f); 269 } 270 271 void setPulseWidth(float pw, bool dcCorrection = true); 272 float nextForPhase(phase_t phase) override; 273 }; 274 275 struct TriangleOscillator : Phasor { 276 const phase_t quarterCyclePhase = cyclePhase * 0.25f; 277 const phase_t threeQuartersCyclePhase = cyclePhase * 0.75f; 278 279 TriangleOscillator( 280 float sampleRate = 1000.0f, 281 float frequency = 100.0f 282 ) 283 : Phasor(sampleRate, frequency) 284 { 285 } 286 287 float nextForPhase(phase_t phase) override; 288 }; 289 290 struct SteppedRandomOscillator : Phasor { 291 const phase_t _n; 292 const phase_t _k; 293 float* _t = NULL; 294 phase_t _seed; 295 296 SteppedRandomOscillator( 297 float sampleRate = 1000.0f, 298 float frequency = 100.0f, 299 phase_t seed = 0 300 ); 301 ~SteppedRandomOscillator(); 302 303 void resetPhase() override; 304 float nextForPhase(phase_t phase) override; 305 }; 306 307 struct SineBankOscillator : Oscillator { 308 struct Partial { 309 float frequency; 310 float frequencyRatio; 311 float amplitude; 312 float amplitudeTarget; 313 float amplitudeStepDelta; 314 int amplitudeSteps; 315 SineTableOscillator sine; 316 317 Partial() 318 : frequency(0.0) 319 , frequencyRatio(0.0) 320 , amplitude(0.0) 321 , amplitudeTarget(0.0) 322 , amplitudeStepDelta(0.0) 323 , amplitudeSteps(0) 324 , sine(0.0, 0.0) 325 {} 326 }; 327 328 const float _maxPartialFrequencySRRatio = 0.48; 329 float _maxPartialFrequency = 0.0; 330 const int _amplitudeEnvelopeMS = 10; 331 int _amplitudeEnvelopeSamples = 0; 332 std::vector<Partial> _partials; 333 334 SineBankOscillator( 335 float sampleRate = 1000.0f, 336 float frequency = 100.0f, 337 int partialCount = 20 338 ) 339 : Oscillator(sampleRate, frequency) 340 , _partials(partialCount) 341 { 342 _sampleRateChanged(); 343 _frequencyChanged(); 344 } 345 346 int partialCount() { 347 return _partials.size(); 348 } 349 350 // one-based indexes. 351 void setPartial(int i, float frequencyRatio, float amplitude); 352 bool setPartialFrequencyRatio(int i, float frequencyRatio); 353 void setPartialAmplitude(int i, float amplitude, bool envelope = false); 354 355 void syncToPhase(float phase); 356 void syncTo(const SineBankOscillator& other); 357 358 void _sampleRateChanged() override; 359 void _frequencyChanged() override; 360 float next(Phasor::phase_t phaseOffset = 0.0f); 361 }; 362 363 struct ChirpOscillator : OscillatorGenerator { 364 static constexpr float minFrequency = 1.0f; 365 static constexpr float minTimeSeconds = 0.01f; 366 367 SineTableOscillator _oscillator; 368 float _f1 = -1.0f; 369 float _f2 = -1.0f; 370 float _Time = -1.0f; 371 bool _linear = false; 372 373 float _sampleTime = 0.0f; 374 float _time = 0.0f; 375 bool _complete = false; 376 double _k = 0.0; 377 378 ChirpOscillator( 379 float sampleRate = 1000.0f, 380 float frequency1 = 100.0f, 381 float frequency2 = 300.0f, 382 float time = 1.0f, 383 bool linear = true 384 ) 385 : _oscillator(sampleRate) 386 { 387 setParams(frequency1, frequency2, time, linear); 388 } 389 390 inline bool isCycleComplete() { return _complete; } 391 inline bool isCycleNearlyComplete(float seconds) { return _time > _Time - seconds; } 392 void setParams(float frequency1, float frequency2, float time, bool linear); 393 void _sampleRateChanged() override; 394 float _next() override; 395 void reset(); 396 }; 397 398 struct PureChirpOscillator : OscillatorGenerator { 399 static constexpr float minFrequency = 1.0f; 400 static constexpr float minTimeSeconds = 0.01f; 401 402 float _f1 = -1.0f; 403 float _f2 = -1.0f; 404 double _Time = -1.0; 405 bool _linear = false; 406 407 double _sampleTime = 0.0f; 408 double _time = 0.0f; 409 bool _complete = false; 410 double _c = 0.0; 411 double _k = 0.0; 412 double _invlogk = 0.0; 413 414 PureChirpOscillator( 415 float sampleRate = 1000.0f, 416 float frequency1 = 100.0f, 417 float frequency2 = 300.0f, 418 float time = 1.0f, 419 bool linear = true 420 ) 421 { 422 setParams(frequency1, frequency2, time, linear); 423 } 424 425 inline bool isCycleComplete() { return _complete; } 426 inline bool isCycleNearlyComplete(float seconds) { return _time > _Time - seconds; } 427 void setParams(float frequency1, float frequency2, double time, bool linear); 428 void _sampleRateChanged() override; 429 void update(); 430 float _next() override; 431 void reset(); 432 }; 433 434 } // namespace dsp 435 } // namespace bogaudio