2 #ifndef __IPLUGPOLYSYNTHDSP__
3 #define __IPLUGPOLYSYNTHDSP__
5 const double ENV_VALUE_LOW
= 0.000001; // -120dB
6 const double ENV_VALUE_HIGH
= 0.999;
7 const double MIN_ENV_TIME_MS
= 0.5;
8 const double MAX_ENV_TIME_MS
= 60000.;
10 inline double midi2CPS(double pitch
)
12 return 440. * pow(2., (pitch
- 69.) / 12.);
15 inline double fastClip(double x
, double low
, double high
)
17 double x1
= fabs(x
-low
);
18 double x2
= fabs(x
-high
);
24 inline double wrap(double x
, double low
= 0., double high
= 1.)
26 while (x
>= high
) x
-= high
;
27 while (x
< low
) x
+= high
- low
;
32 inline double lerp(double phase
, const double* buffer
, unsigned long int mask
)
34 const int intPart
= (int) phase
;
35 const double fracPart
= phase
-intPart
;
37 const double a
= buffer
[intPart
& mask
];
38 const double b
= buffer
[(intPart
+1) & mask
];
40 return a
+ (b
- a
) * fracPart
;
43 inline double calcIncrFromTimeLinear(double timeMS
, double sr
)
45 if (timeMS
<= 0.) return 0.;
46 else return (1./sr
) / (timeMS
/1000.);
51 double mPhase
; // float phase (goes between 0. and 1.)
52 double mPhaseIncr
; // freq * mPhaseStep
65 const double* mLUT
; // pointer to waveform lookup table, const because the oscilator doesn't change the table data
66 unsigned long int mLUTSize
; // wavetable size
67 unsigned long int mLUTSizeM
; // wavetable Mask (size -1)
68 double mLUTSizeF
; // float version
72 CWTOsc(const double* LUT
, unsigned long int LUTSize
)
79 void setLUT(const double* LUT
, unsigned long int LUTSize
)
82 mLUTSizeM
= LUTSize
-1;
83 mLUTSizeF
= (double) LUTSize
;
87 inline double process(CWTOscState
* pState
)
89 pState
->mPhase
= wrap(pState
->mPhase
, 0., 1.);
90 const double output
= lerp(pState
->mPhase
* mLUTSizeF
, mLUT
, mLUTSizeM
);
91 pState
->mPhase
+= pState
->mPhaseIncr
;
107 struct CADSREnvLState
109 double mEnvValue
; // current value of the envelope
110 int mStage
; // idle, attack, decay, sustain, release
111 double mLevel
; // envelope depth
113 double mReleaseLevel
;
129 double mAttackIncr
, mDecayIncr
, mReleaseIncr
;
130 double mSustainLevel
, mReleaseLevel
;
140 mSampleRate
= 44100.;
142 setStageTime(kStageAttack
, 1.);
143 setStageTime(kStageDecay
, 100.);
144 setStageTime(kStageRelease
, 20.);
147 void setStageTime(int stage
, double timeMS
)
149 const double incr
= calcIncrFromTimeLinear(fastClip(timeMS
, MIN_ENV_TIME_MS
, MAX_ENV_TIME_MS
), mSampleRate
);
168 void setSustainLevel(double sustainLevel
)
170 mSustainLevel
= sustainLevel
;
173 virtual void setSampleRate(double sr
)
178 inline double process(CADSREnvLState
* pS
)
185 result
= pS
->mEnvValue
;
188 pS
->mEnvValue
+= mAttackIncr
;
189 if (pS
->mEnvValue
> ENV_VALUE_HIGH
|| mAttackIncr
== 0.)
191 pS
->mStage
= kStageDecay
;
194 result
= pS
->mEnvValue
;
197 pS
->mEnvValue
-= mDecayIncr
;
198 result
= (pS
->mEnvValue
* (1.-mSustainLevel
)) + mSustainLevel
;
199 if (pS
->mEnvValue
< ENV_VALUE_LOW
)
201 pS
->mStage
= kStageSustain
;
203 result
= mSustainLevel
;
207 result
= mSustainLevel
;
210 pS
->mEnvValue
-= mReleaseIncr
;
211 if(pS
->mEnvValue
< ENV_VALUE_LOW
|| mReleaseIncr
== 0.)
216 result
= pS
->mEnvValue
* pS
->mReleaseLevel
;
219 result
= pS
->mEnvValue
;
225 return result
* pS
->mLevel
;
230 // http://www.musicdsp.org/archive.php?classid=3#257
235 // CParamSmooth() { a = 0.99; b = 1. - a; z = 0.; };
236 // ~CParamSmooth() {};
237 // inline double Process(double in) { z = (in * b) + (z * a); return z; }
244 CWTOscState mOsc_ctx
;
245 CADSREnvLState mEnv_ctx
;
257 if (mEnv_ctx
.mStage
== kIdle
)
265 #endif //__IPLUGPOLYSYNTHDSP__