98 lines
2.1 KiB
C
98 lines
2.1 KiB
C
// --------------------------------------------------------------
|
|
// --------------------------------------------------------------
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
|
|
#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*jsy_pi*phase);
|
|
pObj->y[1] = sin(2*jsy_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*jsy_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];
|
|
}
|
|
|