// -------------------------------------------------------------- // -------------------------------------------------------------- #include #include #include #include #include "synth_defs.h" #include "sine.h" // -------------------------------------------------------------- // internal funcs // -------------------------------------------------------------- // -------------------------------------------------------------- // Exported functions // -------------------------------------------------------------- void Sine_Init(sine_gen_t *pObj, synth_float_t fs) { Sine_SetFS(pObj, fs); Sine_Prepare(pObj); } void Sine_Free(sine_gen_t *pObj) { } void Sine_SetFS(sine_gen_t *pObj, synth_float_t fs) { pObj->fs = SINE_OVERSAMPLING*fs; pObj->pitch = -1; } void Sine_Reset(sine_gen_t *pObj, synth_float_t phase) { pObj->y[0] = cos(2*pi*phase); pObj->y[1] = sin(2*pi*phase); pObj->fscale = 1; } void Sine_Start(sine_gen_t *pObj) { pObj->pitch = -1; pObj->CV_fm = -1; } void Sine_Prepare(sine_gen_t *pObj) { Sine_Reset(pObj, (synth_float_t)rand()/RAND_MAX); } void Sine_Update(sine_gen_t *pObj) { synth_float_t freq; freq = pObj->fscale * pObj->pitch; pObj->b = 2.0 * sin(freq*pi / pObj->fs); } synth_float_t Sine_Process_Scalar(sine_gen_t *pObj, synth_float_t pitch, synth_float_t CV_fm) { int i; synth_float_t a, phi; // ToDo: amplitude drift correction // y[0]^2 + y[1]^2 = a; if (pObj->CV_fm != CV_fm) { pObj->CV_fm = CV_fm; pObj->fscale = (synth_float_t)pow((synth_float_t)2, CV_fm); Sine_Update(pObj); } if (pObj->pitch != pitch) { pObj->pitch = pitch; Sine_Update(pObj); } for (i=0; i < SINE_OVERSAMPLING; i++) { pObj->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; } a = pObj->y[0]*pObj->y[0] + pObj->y[1]*pObj->y[1]; if (fabs(a - 1) > 0.5) { phi = atan2(pObj->y[0], pObj->y[1]); pObj->y[0] = sin(phi); pObj->y[1] = cos(phi); } return -pObj->y[0]; }