- abstracted Sync with callbacks
git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@719 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
+66
-33
@@ -14,10 +14,7 @@
|
||||
// --------------------------------------------------------------
|
||||
void LFO_set_omega(lfo_t *pObj, synth_float_t omega)
|
||||
{
|
||||
if (omega < 0.0 || omega > 1.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
omega = fmin(0.5, fmax(-0.5, omega));
|
||||
pObj->b = 2.0 * sin(omega*pi);
|
||||
pObj->dx = omega;
|
||||
}
|
||||
@@ -77,8 +74,21 @@ synth_float_t Sync_mod(synth_float_t x, synth_float_t y)
|
||||
return result;
|
||||
}
|
||||
|
||||
synth_float_t phase_det(synth_float_t lo, synth_float_t ref)
|
||||
{
|
||||
lo = Sync_mod(lo - 0.5, 1.0);
|
||||
synth_float_t perr = Sync_mod(lo - ref, 1.0) - (synth_float_t)0.5;
|
||||
|
||||
return perr;
|
||||
}
|
||||
|
||||
void Sync_init(sync_t *pObj)
|
||||
{
|
||||
pObj->pFuncObj = NULL;
|
||||
pObj->funcSyncOnProcess = NULL;
|
||||
pObj->funcSyncOnGetPhase = NULL;
|
||||
pObj->funcSyncOnFreqUpdate = NULL;
|
||||
|
||||
pObj->phase = 0;
|
||||
pObj->phase_ref = 0;
|
||||
pObj->omega = 0.0;
|
||||
@@ -88,6 +98,14 @@ void Sync_init(sync_t *pObj)
|
||||
pObj->phase_update = 0;
|
||||
}
|
||||
|
||||
void Sync_set_callback(sync_t *pObj, void *pFuncObj, SyncOnProcess funcSyncOnProcess, SyncOnGetPhase funcSyncOnGetPhase, SyncOnFreqUpdate funcSyncOnFreqUpdate)
|
||||
{
|
||||
pObj->pFuncObj = pFuncObj;
|
||||
pObj->funcSyncOnProcess = funcSyncOnProcess;
|
||||
pObj->funcSyncOnGetPhase = funcSyncOnGetPhase;
|
||||
pObj->funcSyncOnFreqUpdate = funcSyncOnFreqUpdate;
|
||||
}
|
||||
|
||||
void Sync_phase_update(sync_t *pObj, synth_float_t phase_ref)
|
||||
{
|
||||
pObj->phase_ref = phase_ref;
|
||||
@@ -98,21 +116,52 @@ int Sync_process(sync_t *pObj)
|
||||
{
|
||||
int do_lfo_update = 0;
|
||||
synth_float_t perr = 0;
|
||||
if (pObj->funcSyncOnProcess)
|
||||
{
|
||||
(*pObj->funcSyncOnProcess)(pObj->pFuncObj);
|
||||
}
|
||||
if (pObj->phase_update)
|
||||
{
|
||||
do_lfo_update = 1;
|
||||
pObj->phase_update = 0;
|
||||
synth_float_t phase_lo = Sync_mod(pObj->phase - 0.5, 1.0);
|
||||
perr = (synth_float_t)Sync_mod(phase_lo - pObj->phase_ref, 1.0) - (synth_float_t)0.5;
|
||||
SynthDebug("phase_ref=%f, phase_lo=%f, perr=%f\n", pObj->phase_ref, pObj->phase, perr);
|
||||
do_lfo_update = 1;
|
||||
if (pObj->funcSyncOnGetPhase)
|
||||
{
|
||||
synth_float_t phase = (*pObj->funcSyncOnGetPhase)(pObj->pFuncObj);
|
||||
perr = phase_det(phase, pObj->phase_ref);
|
||||
SynthDebug("phase_ref=%f, phase_lo=%f, perr=%f\n", pObj->phase_ref, pObj->phase, perr);
|
||||
}
|
||||
if (pObj->funcSyncOnFreqUpdate)
|
||||
{
|
||||
(*pObj->funcSyncOnFreqUpdate)(pObj->pFuncObj, pObj->omega);
|
||||
}
|
||||
}
|
||||
pObj->phase = Sync_mod(pObj->phase + pObj->omega, 1.0);
|
||||
pObj->omega = -(pObj->klag*pObj->accu + pObj->klead*perr);
|
||||
pObj->accu += perr;
|
||||
|
||||
pObj->omega = -(pObj->klag*pObj->accu + pObj->klead*perr);
|
||||
|
||||
return do_lfo_update;
|
||||
}
|
||||
|
||||
void syncOnProcess(void *pFuncObj)
|
||||
{
|
||||
lfo_t *pObj = (lfo_t*)pFuncObj;
|
||||
pObj->sync.phase = Sync_mod(pObj->sync.phase + pObj->sync.omega, 1.0);
|
||||
}
|
||||
|
||||
synth_float_t syncOnGetPhase(void *pFuncObj)
|
||||
{
|
||||
lfo_t *pObj = (lfo_t*)pFuncObj;
|
||||
SynthDebug("syncOnGetPhase()\n");
|
||||
|
||||
return pObj->sync.phase;
|
||||
}
|
||||
|
||||
void syncOnFreqUpdate(void *pFuncObj, synth_float_t omega)
|
||||
{
|
||||
lfo_t *pObj = (lfo_t*)pFuncObj;
|
||||
SynthDebug("syncOnFreqUpdate(): BPM=%f\n", omega*pObj->fs*60);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Exported functions
|
||||
// --------------------------------------------------------------
|
||||
@@ -143,6 +192,7 @@ void LFO_Init(lfo_t *pObj, synth_float_t fs)
|
||||
Noise_Init(&pObj->noise, 1+(UINT32)clock() * (UINT32)clock());
|
||||
|
||||
Sync_init(&pObj->sync);
|
||||
Sync_set_callback(&pObj->sync, pObj, syncOnProcess, syncOnGetPhase, syncOnFreqUpdate);
|
||||
}
|
||||
|
||||
void LFO_Free(lfo_t *pObj)
|
||||
@@ -276,10 +326,9 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len)
|
||||
if (Sync_process(&pObj->sync))
|
||||
{
|
||||
LFO_set_omega(pObj, pObj->sync.omega);
|
||||
SynthDebug("BPM=%f\n", pObj->sync.omega*pObj->fs*60);
|
||||
}
|
||||
pObj->x = pObj->sync.phase;
|
||||
|
||||
|
||||
in = pObj->x + pObj->offset;
|
||||
pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in;
|
||||
out = pObj->out;
|
||||
@@ -289,11 +338,7 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len)
|
||||
*(pOut++) = out*pObj->attack_y;
|
||||
pObj->attack_y += pObj->attack_a*(1-pObj->attack_y);
|
||||
|
||||
pObj->x += pObj->dx;
|
||||
if (pObj->x >= 1.f)
|
||||
{
|
||||
pObj->x -= 1.f;
|
||||
}
|
||||
pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0);
|
||||
|
||||
if (pObj->freq_update_req)
|
||||
{
|
||||
@@ -317,11 +362,7 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len)
|
||||
*(pOut++) = out*pObj->attack_y;
|
||||
pObj->attack_y += pObj->attack_a*(1-pObj->attack_y);
|
||||
|
||||
pObj->x += pObj->dx;
|
||||
if (pObj->x >= 1.f)
|
||||
{
|
||||
pObj->x -= 1.f;
|
||||
}
|
||||
pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0);
|
||||
|
||||
if (pObj->freq_update_req)
|
||||
{
|
||||
@@ -567,11 +608,7 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len)
|
||||
else
|
||||
pObj->tri = 2*(1-pObj->x);
|
||||
|
||||
pObj->x += pObj->dx;
|
||||
if (pObj->x >= 1.f)
|
||||
{
|
||||
pObj->x -= 1.f;
|
||||
}
|
||||
pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0);
|
||||
|
||||
if (pObj->freq_update_req)
|
||||
{
|
||||
@@ -600,11 +637,7 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len)
|
||||
else
|
||||
pObj->tri = 2*(1-pObj->x);
|
||||
|
||||
pObj->x += pObj->dx;
|
||||
if (pObj->x >= 1.f)
|
||||
{
|
||||
pObj->x -= 1.f;
|
||||
}
|
||||
pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0);
|
||||
|
||||
if (pObj->freq_update_req)
|
||||
{
|
||||
|
||||
@@ -40,8 +40,16 @@ enum
|
||||
LFO_NUM_PARAMS
|
||||
};
|
||||
|
||||
typedef void (*SyncOnProcess)(void *pFuncObj);
|
||||
typedef void (*SyncOnFreqUpdate)(void *pFuncObj, synth_float_t omega);
|
||||
typedef synth_float_t (*SyncOnGetPhase)(void *pFuncObj);
|
||||
typedef struct _ssync_t
|
||||
{
|
||||
void *pFuncObj;
|
||||
SyncOnProcess funcSyncOnProcess;
|
||||
SyncOnGetPhase funcSyncOnGetPhase;
|
||||
SyncOnFreqUpdate funcSyncOnFreqUpdate;
|
||||
|
||||
synth_float_t phase;
|
||||
synth_float_t phase_ref;
|
||||
synth_float_t omega;
|
||||
@@ -62,6 +70,8 @@ extern "C" {
|
||||
// Exported functions
|
||||
// --------------------------------------------------------------
|
||||
void Sync_init(sync_t *pObj);
|
||||
void Sync_set_callback(sync_t *pObj, void *pFuncObj, SyncOnProcess funcSyncOnProcess, SyncOnGetPhase funcSyncOnGetPhase, SyncOnFreqUpdate funcSyncOnFreqUpdate);
|
||||
|
||||
void Sync_phase_update(sync_t *pObj, synth_float_t phase_ref);
|
||||
int Sync_process(sync_t *pObj);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user