00001 #ifndef SYN_GENERATOR_H
00002 #define SYN_GENERATOR_H
00003
00004 #include <syn/Util/Math.h>
00005
00027 namespace syn
00028 {
00032 class TriangleOsc
00033 {
00034 public:
00035 TriangleOsc() : mFreq( 80.0f ), mSamplingRateHz( 44100.0f ), dp( 1 )
00036 {
00037 this->reset();
00038 }
00039
00042 inline float generate()
00043 {
00044 const float float_max = 1.0f;
00045 const float float_min = -1.0f;
00046
00047 p += dp;
00048 if (p > float_max)
00049 {
00050 p = float_max;
00051 dp = -dp;
00052 }
00053 else if (p < float_min)
00054 {
00055 p = float_min;
00056 dp = -dp;
00057 }
00058
00059 return p;
00060 }
00061
00066 inline unsigned int samplesPerOsc()
00067 {
00068
00069
00070
00071 return (unsigned int)(mSamplingRateHz / mFreq);
00072 }
00073
00076 inline void setFreq( float freqHz )
00077 {
00078 if (freqHz != mFreq)
00079 {
00080 mFreq = freqHz;
00081 on_change_of_freq_or_samprate();
00082 }
00083 }
00084
00088 inline void setSampRate( float samplingRateHz )
00089 {
00090 if (samplingRateHz != mSamplingRateHz)
00091 {
00092 mSamplingRateHz = samplingRateHz;
00093 on_change_of_freq_or_samprate();
00094 }
00095 }
00096
00099 inline void reset()
00100 {
00101 p = 0.0f;
00102 dp = 1.0f;
00103 on_change_of_freq_or_samprate();
00104 }
00105
00106 private:
00108 inline void on_change_of_freq_or_samprate()
00109 {
00110
00111
00112
00113 float delta = 2.00495f * mFreq / mSamplingRateHz;
00114
00115
00116
00117 const float float_range = 2.0f;
00118 if (dp > 0.0f)
00119 dp = delta * float_range;
00120 else
00121 dp = -delta * float_range;
00122 }
00123
00124
00125 float mFreq, mSamplingRateHz;
00126 float p, dp;
00127 };
00128
00129
00132 class SineOsc
00133 {
00134 public:
00135 SineOsc() : mFreq( 80.0f ), mSamplingRateHz( 44100.0f )
00136 {
00137 this->reset();
00138 }
00139
00142 inline float generate()
00143 {
00144 const float float_range = 2.0f;
00145 s[0] = s[0] - a * s[1];
00146 s[1] = s[1] + a * s[0];
00147 return s[0] * float_range;
00148 }
00149
00154 inline unsigned int samplesPerOsc()
00155 {
00156
00157
00158
00159 return (unsigned int)(mSamplingRateHz / mFreq);
00160 }
00161
00164 inline void setFreq( float freqHz )
00165 {
00166 if (freqHz != mFreq)
00167 {
00168 mFreq = freqHz;
00169 on_change_of_freq_or_samprate();
00170 }
00171 }
00172
00176 inline void setSampRate( float samplingRateHz )
00177 {
00178 if (samplingRateHz != mSamplingRateHz)
00179 {
00180 mSamplingRateHz = samplingRateHz;
00181 on_change_of_freq_or_samprate();
00182 }
00183 }
00184
00187 inline void reset()
00188 {
00189 s[0] = 0.5f;
00190 s[1] = 0.0f;
00191 on_change_of_freq_or_samprate();
00192 }
00193
00194 private:
00196 inline void on_change_of_freq_or_samprate()
00197 {
00198 const float float_range = 2.0f;
00199 a = float_range * Math::sin( Math::PI * mFreq / mSamplingRateHz );
00200 }
00201
00202
00203 float mFreq, mSamplingRateHz;
00204 float s[2], a;
00205 };
00206
00210 class SquareOsc
00211 {
00212 public:
00213 SquareOsc() : mFreq( 80.0f ), mSamplingRateHz( 44100.0f )
00214 {
00215 this->reset();
00216 }
00217
00220 inline float generate()
00221 {
00222 (*((unsigned long *)&one)) &= 0x7FFFFFFF;
00223 (*((unsigned long *)&one)) |= (intOver & 0x80000000);
00224 intOver += intIncr;
00225 return float( long( intOver ) ) / float( long( 0x7FFFFFFF ) );
00226 }
00227
00232 inline unsigned int samplesPerOsc()
00233 {
00234
00235
00236
00237 return (unsigned int)( mSamplingRateHz / mFreq );
00238 }
00239
00242 inline void setFreq( float freqHz )
00243 {
00244 if (freqHz != mFreq)
00245 {
00246 mFreq = freqHz;
00247 on_change_of_freq_or_samprate();
00248 }
00249 }
00250
00254 inline void setSampRate( float samplingRateHz )
00255 {
00256 if (samplingRateHz != mSamplingRateHz)
00257 {
00258 mSamplingRateHz = samplingRateHz;
00259 on_change_of_freq_or_samprate();
00260 }
00261 }
00262
00265 inline void reset()
00266 {
00267 one = 1.0f;
00268 on_change_of_freq_or_samprate();
00269 }
00270
00271 private:
00273 inline void on_change_of_freq_or_samprate()
00274 {
00275 intOver = 0L;
00276 intIncr = ((unsigned long)0xffffffff) / (unsigned long)(mSamplingRateHz / mFreq);
00277 }
00278
00279
00280 float mFreq, mSamplingRateHz;
00281 unsigned long intOver, intIncr;
00282 float one;
00283 };
00284
00285
00286
00289 class WhiteNoiseOsc
00290 {
00291 public:
00292 WhiteNoiseOsc() : mSamplingRateHz( 44100.0f )
00293 {
00294 this->reset();
00295
00296 long pmax = 0x7fffffff;
00297 mScalar = 1.0f / pmax;
00298 }
00299
00302 inline float generate()
00303 {
00304
00305
00306 return (mScalar * (float)(long)(mRand = (mRand * 196314165) + 907633515));
00307 }
00308
00311 inline void reset()
00312 {
00313 mRandSeed = 22222;
00314 mRand = mRandSeed;
00315 }
00316
00322 inline unsigned int samplesPerOsc()
00323 {
00324
00325 return (unsigned int)( mSamplingRateHz );
00326 }
00327
00331 inline void setFreq( float freqHz ) {}
00332
00337 inline void setSampRate( float samplingRateHz )
00338 {
00339 mSamplingRateHz = samplingRateHz;
00340 }
00341
00342 private:
00343 enum
00344 {
00345 mRandomRows = 16,
00346 mRandomBits = 24
00347 };
00348
00349 unsigned long mRandSeed, mRand;
00350 float mSamplingRateHz;
00351 float mScalar;
00352 };
00353
00356 class PinkNoiseOsc
00357 {
00358 public:
00359 PinkNoiseOsc() : mSamplingRateHz( 44100.0f ),
00360 mRandomBits( 24 ),
00361 mRandomShift( sizeof( long ) * 8 - mRandomBits )
00362 {
00363 this->reset();
00364 }
00365
00368 inline float generate()
00369 {
00370 long newRandom;
00371
00372
00373 mIndex = (mIndex + 1) & mIndexMask;
00374
00375
00376 if( mIndex != 0 )
00377 {
00378
00379
00380 int numZeros = 0;
00381 int n = mIndex;
00382 while ((n & 1) == 0)
00383 {
00384 n = n >> 1;
00385 ++numZeros;
00386 }
00387
00388
00389
00390
00391
00392 mRunningSum -= mRows[numZeros];
00393 newRandom = ((long)this->generateWhiteNoise()) >> mRandomShift;
00394 mRunningSum += newRandom;
00395 mRows[numZeros] = newRandom;
00396 }
00397
00398
00399 newRandom = ((long)this->generateWhiteNoise()) >> mRandomShift;
00400
00401
00402 return mScalar * (float)(mRunningSum + newRandom);
00403 }
00404
00407 inline void reset()
00408 {
00409 this->initializeWhiteNoise();
00410 this->initializePinkNoise();
00411 }
00412
00418 inline unsigned int samplesPerOsc()
00419 {
00420
00421 return (unsigned int)( mSamplingRateHz );
00422 }
00423
00427 inline void setFreq( float freqHz ) {}
00428
00433 inline void setSampRate( float samplingRateHz )
00434 {
00435 mSamplingRateHz = samplingRateHz;
00436 }
00437
00438 private:
00439 inline void initializeWhiteNoise()
00440 {
00441 mRandSeed = 22222;
00442 mRand = mRandSeed;
00443 }
00444 inline unsigned long generateWhiteNoise()
00445 {
00446
00447
00448 return mRand = (mRand * 196314165) + 907633515;
00449 }
00450
00451
00452 void initializePinkNoise()
00453 {
00454 int i;
00455 mIndex = 0;
00456 mIndexMask = (1 << mRandomRows) - 1;
00457
00458
00459 long pmax = (mRandomRows + 1) * (1 << (mRandomBits - 1));
00460 mScalar = 1.0f / pmax;
00461
00462
00463 for( i = 0; i < mRandomRows; ++i )
00464 {
00465 mRows[i] = 0;
00466 }
00467 mRunningSum = 0;
00468 }
00469
00470
00471 enum
00472 {
00473 mRandomRows = 16
00474 };
00475 float mSamplingRateHz;
00476 const int mRandomBits;
00477 const int mRandomShift;
00478 unsigned long mRandSeed, mRand;
00479 long mRows[mRandomRows];
00480 long mRunningSum;
00481 int mIndex;
00482 int mIndexMask;
00483 float mScalar;
00484 };
00485
00491 class AdsrEnvOsc
00492 {
00493 public:
00494 AdsrEnvOsc() : mSamplingRateHz( 44100.0f ),
00495 mAttackTime( 0.01f ),
00496 mDecayTime( 0.03f ),
00497 mSustainLevel( 0.5f ),
00498 mReleaseTime( 0.04f )
00499 {
00500 this->reset();
00501 }
00502
00503 inline float lerp( const float lerpVal, const float from, const float to )
00504 {
00505 return from + (to - from) * lerpVal;
00506 }
00507
00511 inline float generate()
00512 {
00513
00514 if (mDurationTime != -1)
00515 {
00516 ++mTotalTimeSamps;
00517 if (mTotalTimeSamps > mDurationSamps)
00518 {
00519 this->release();
00520 }
00521 }
00522
00523 float count = mCount;
00524 switch (mState)
00525 {
00526 case 0:
00527 if (mCount++ >= mAttackSamps)
00528 {
00529 mState = 1;
00530 mCount = 0;
00531 }
00532 return lerp( count / mAttackSamps, 0.0f, 1.0f );
00533 break;
00534 case 1:
00535 if (mCount++ >= mDecaySamps)
00536 {
00537 mState = 2;
00538 mCount = 0;
00539 }
00540 return lerp( count / mDecaySamps, 1.0f, mSustainLevel );
00541 break;
00542 case 2:
00543 if (mReleased)
00544 {
00545 mState = 3;
00546 mReleased = false;
00547 }
00548 return mSustainLevel;
00549 break;
00550 case 3:
00551 if (mCount++ >= mReleaseSamps)
00552 {
00553 mState = 4;
00554 mCount = 0;
00555 }
00556 return lerp( count / mReleaseSamps, mSustainLevel, 0.0f );
00557 break;
00558 default:
00559 case 4:
00560 return 0.0f;
00561 break;
00562 }
00563 }
00564
00571 void trigger( float duration = -1 )
00572 {
00573 mState = 0;
00574 mDurationTime = duration;
00575 mDurationSamps = mDurationTime * mSamplingRateHz;
00576 mTotalTimeSamps = 0;
00577 }
00578
00579 void release()
00580 {
00581 mReleased = true;
00582 }
00583
00591 void setAttackTime( float t )
00592 {
00593 mAttackTime = t;
00594
00595 mAttackSamps = mAttackTime * mSamplingRateHz;
00596 }
00597 float getAttackTime() { return mAttackTime; }
00598
00606 void setDecayTime( float t )
00607 {
00608 mDecayTime = t;
00609
00610 mDecaySamps = mDecayTime * mSamplingRateHz;
00611 }
00612 float getDecayTime() { return mDecayTime; }
00613
00622 void setSustainLevel( float sustain )
00623 {
00624 mSustainLevel = sustain;
00625 }
00626 float getSustainLevel() { return mSustainLevel; }
00627
00635 void setReleaseTime( float t )
00636 {
00637 mReleaseTime = t;
00638 mReleaseSamps = mReleaseTime * mSamplingRateHz;
00639 }
00640
00641 float getReleaseTime() { return mReleaseTime; }
00642
00647 inline unsigned int samplesPerOsc()
00648 {
00649
00650
00651
00652
00653
00654 return (unsigned int)( mAttackSamps + mDecaySamps + mDecaySamps + mReleaseSamps );
00655 }
00656
00658 inline void setFreq( float freqHz ) {}
00659
00663 inline void setSampRate( float samplingRateHz )
00664 {
00665 if (samplingRateHz != mSamplingRateHz)
00666 {
00667 mSamplingRateHz = samplingRateHz;
00668 on_change_of_samprate();
00669 }
00670 }
00671
00674 inline void reset()
00675 {
00676 mState = 4;
00677 mCount = 0.0f;
00678 mReleased = false;
00679 on_change_of_samprate();
00680 }
00681
00682 private:
00684 inline void on_change_of_samprate()
00685 {
00686 this->setAttackTime( mAttackTime );
00687 this->setDecayTime( mDecayTime );
00688 this->setSustainLevel( mSustainLevel );
00689 this->setReleaseTime( mReleaseTime );
00690 mDurationSamps = mDurationTime * mSamplingRateHz;
00691 }
00692
00693
00694 float mSamplingRateHz;
00695 float mAttackTime, mDecayTime, mSustainLevel, mReleaseTime;
00696 float mCount;
00697 float mAttackSamps, mDecaySamps, mReleaseSamps;
00698 unsigned int mState;
00699 bool mTriggered;
00700 bool mReleased;
00701 float mDurationSamps, mDurationTime, mTotalTimeSamps;
00702 };
00703 }
00704
00705 #endif