From 4c6f9859bddcb28601c0fa1a6badcf8b1cb4d4f2 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Tue, 11 Aug 2020 16:36:00 +0000 Subject: [PATCH] - wired all LFO types to Sync_phase_update - refactored waveform names git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@721 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- Source/synth/lfo.c | 228 ++++++++++++++++++++++++++++----------------- Source/synth/lfo.h | 13 +-- 2 files changed, 152 insertions(+), 89 deletions(-) diff --git a/Source/synth/lfo.c b/Source/synth/lfo.c index 2c3a25f..a2cb80b 100644 --- a/Source/synth/lfo.c +++ b/Source/synth/lfo.c @@ -96,6 +96,8 @@ void Sync_init(sync_t *pObj) pObj->klead = 1.0; pObj->klag = 0.04/200; pObj->phase_update = 0; + pObj->freq_update = 0; + } void Sync_set_callback(sync_t *pObj, void *pFuncObj, SyncOnProcess funcSyncOnProcess, SyncOnGetPhase funcSyncOnGetPhase, SyncOnFreqUpdate funcSyncOnFreqUpdate) @@ -112,9 +114,8 @@ void Sync_phase_update(sync_t *pObj, synth_float_t phase_ref) pObj->phase_update = 1; } -int Sync_process(sync_t *pObj) +void Sync_process(sync_t *pObj) { - int do_lfo_update = 0; synth_float_t perr = 0; if (pObj->funcSyncOnProcess) { @@ -123,7 +124,6 @@ int Sync_process(sync_t *pObj) if (pObj->phase_update) { pObj->phase_update = 0; - do_lfo_update = 1; if (pObj->funcSyncOnGetPhase) { synth_float_t phase = (*pObj->funcSyncOnGetPhase)(pObj->pFuncObj); @@ -131,37 +131,143 @@ int Sync_process(sync_t *pObj) SynthDebug("phase_ref=%f, phase_lo=%f, perr=%f\n", pObj->phase_ref, pObj->phase, perr); } } - synth_float_t omega = -(pObj->klag*pObj->accu + pObj->klead*perr); - if (omega != pObj->omega) + if (perr != 0 || pObj->freq_update) { + synth_float_t omega = -(pObj->klag*pObj->accu + pObj->klead*perr); if (pObj->funcSyncOnFreqUpdate) { (*pObj->funcSyncOnFreqUpdate)(pObj->pFuncObj, omega); } } pObj->accu += perr; - - return do_lfo_update; + pObj->freq_update = perr != 0; } void syncOnProcess(void *pFuncObj) { lfo_t *pObj = (lfo_t*)pFuncObj; - pObj->sync.phase = Sync_mod(pObj->sync.phase + pObj->sync.omega, 1.0); + + switch((int)pObj->param[LFO_PARAM2_WAVEFORM]) + { + case LFO_WAVEFORM_SAW: + case LFO_WAVEFORM_SAW_REV: + pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0); + break; + + case LFO_WAVEFORM_SH_UNI: + pObj->x += pObj->dx; + if (pObj->x >= 1.f) + { + pObj->x -= 1.f; + pObj->sh_sample = Noise_Uniform(&pObj->noise, 1, 0.5); + } + break; + + case LFO_WAVEFORM_SH_GAUSS: + pObj->x += pObj->dx; + if (pObj->x >= 1.f) + { + pObj->x -= 1.f; + do + { + pObj->sh_sample = Noise_Gaussian(&pObj->noise, sqrt(1.f/36), 0.5); + + } while ((pObj->sh_sample < 0) || (pObj->sh_sample > 1.f)); + } + break; + + case LFO_WAVEFORM_SQUARE: + case LFO_WAVEFORM_SQUARE_REV: + pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0); + pObj->sqr = (int)(pObj->x < 0.5); + break; + + case LFO_WAVEFORM_SINE: + case LFO_WAVEFORM_SINE_REV: + case LFO_WAVEFORM_COSINE: + case LFO_WAVEFORM_COSINE_REV: + pObj->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; + pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; + break; + + case LFO_WAVEFORM_TRIANGLE: + case LFO_WAVEFORM_TRIANGLE_REV: + pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0); + if (pObj->x < 0.5) + pObj->tri = 2*pObj->x; + else + pObj->tri = 2*(1-pObj->x); + break; + + default: + pObj->sync.phase = Sync_mod(pObj->sync.phase + pObj->sync.omega, 1.0); + break; + } } synth_float_t syncOnGetPhase(void *pFuncObj) { + synth_float_t result = 0; lfo_t *pObj = (lfo_t*)pFuncObj; - SynthDebug("syncOnGetPhase()\n"); - return pObj->sync.phase; + switch((int)pObj->param[LFO_PARAM2_WAVEFORM]) + { + case LFO_WAVEFORM_SAW: + case LFO_WAVEFORM_SAW_REV: + case LFO_WAVEFORM_SH_UNI: + case LFO_WAVEFORM_SH_GAUSS: + case LFO_WAVEFORM_SQUARE: + case LFO_WAVEFORM_SQUARE_REV: + case LFO_WAVEFORM_TRIANGLE: + case LFO_WAVEFORM_TRIANGLE_REV: + result = Sync_mod(pObj->x, 1.0); + break; + + case LFO_WAVEFORM_SINE: + case LFO_WAVEFORM_SINE_REV: + case LFO_WAVEFORM_COSINE: + case LFO_WAVEFORM_COSINE_REV: + result = 0.5 + 0.5*atan2(pObj->y[0], -pObj->y[1])/M_PI; + break; + + default: + result = pObj->sync.phase; + break; + } + + return result; + } void syncOnFreqUpdate(void *pFuncObj, synth_float_t omega) { lfo_t *pObj = (lfo_t*)pFuncObj; - pObj->sync.omega = omega; + + switch((int)pObj->param[LFO_PARAM2_WAVEFORM]) + { + case LFO_WAVEFORM_SAW: + case LFO_WAVEFORM_SAW_REV: + case LFO_WAVEFORM_SH_UNI: + case LFO_WAVEFORM_SH_GAUSS: + case LFO_WAVEFORM_SQUARE: + case LFO_WAVEFORM_SQUARE_REV: + case LFO_WAVEFORM_TRIANGLE: + case LFO_WAVEFORM_TRIANGLE_REV: + pObj->dx = omega; + break; + + case LFO_WAVEFORM_SINE: + case LFO_WAVEFORM_SINE_REV: + case LFO_WAVEFORM_COSINE: + case LFO_WAVEFORM_COSINE_REV: + pObj->b = 2.0 * sin(omega*pi); + break; + + default: + pObj->sync.omega = omega; + break; + } + SynthDebug("syncOnFreqUpdate(): BPM=%f\n", omega*pObj->fs*60); } @@ -327,11 +433,7 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) // Create phase for (i=i0; i< len; i++) { - if (Sync_process(&pObj->sync)) - { -// LFO_set_omega(pObj, pObj->sync.omega); - } - pObj->x = pObj->sync.phase; + Sync_process(&pObj->sync); in = pObj->x + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; @@ -342,8 +444,6 @@ 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 = Sync_mod(pObj->x + pObj->dx, 1.0); - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -352,11 +452,13 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) } } - if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_ONE_MINUS_SAW) + if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_SAW_REV) { // Create phase for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (1-pObj->x) + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -366,8 +468,6 @@ 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 = Sync_mod(pObj->x + pObj->dx, 1.0); - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -381,11 +481,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) // Create phase for S/H for (i=i0; i< len; i++) { - if (pObj->x >= 1.f) - { - pObj->x -= 1.f; - pObj->sh_sample = Noise_Uniform(&pObj->noise, 1, 0.5); - } + Sync_process(&pObj->sync); + in = pObj->sh_sample + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -395,8 +492,6 @@ 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->freq_update_req) { pObj->freq_update_req = 0; @@ -410,15 +505,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) // Create phase for S/H for (i=i0; i< len; i++) { - if (pObj->x >= 1.f) - { - pObj->x -= 1.f; - do - { - pObj->sh_sample = Noise_Gaussian(&pObj->noise, sqrt(1.f/36), 0.5); - - } while ((pObj->sh_sample < 0) || (pObj->sh_sample > 1.f)); - } + Sync_process(&pObj->sync); + in = pObj->sh_sample + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -428,8 +516,6 @@ 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->freq_update_req) { pObj->freq_update_req = 0; @@ -443,6 +529,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) { for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = pObj->y[1]+pObj->a + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -452,9 +540,6 @@ 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->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; - pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -463,10 +548,12 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) } } - if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_ONE_MINUS_SINE) + if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_SINE_REV) { for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (1-(pObj->y[1]+pObj->a)) + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -476,9 +563,6 @@ 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->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; - pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -491,6 +575,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) { for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = pObj->y[0]+pObj->a + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -500,9 +586,6 @@ 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->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; - pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -511,10 +594,12 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) } } - if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_ONE_MINUS_COSINE) + if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_COSINE_REV) { for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (1-(pObj->y[0]+pObj->a)) + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -524,9 +609,6 @@ 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->y[0] = pObj->y[0] - pObj->b*pObj->y[1]; - pObj->y[1] = pObj->y[1] + pObj->b*pObj->y[0]; - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -540,6 +622,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) // Create phase for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (synth_float_t)pObj->sqr + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -549,13 +633,6 @@ 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 += 2*pObj->dx; - if (pObj->x >= 1.f) - { - pObj->x -= 1.f; - pObj->sqr = !pObj->sqr; - } - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -564,11 +641,13 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) } } - if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_ONE_MINUS_SQUARE) + if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_SQUARE_REV) { // Create phase for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (1-((synth_float_t)pObj->sqr)) + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -578,13 +657,6 @@ 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 += 2*pObj->dx; - if (pObj->x >= 1.f) - { - pObj->x -= 1.f; - pObj->sqr = !pObj->sqr; - } - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -598,6 +670,8 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) // Create phase for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (synth_float_t)pObj->tri + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -607,13 +681,6 @@ 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); - if (pObj->x < 0.5) - pObj->tri = 2*pObj->x; - else - pObj->tri = 2*(1-pObj->x); - - pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0); - if (pObj->freq_update_req) { pObj->freq_update_req = 0; @@ -622,11 +689,13 @@ synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len) } } - if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_ONE_MINUS_TRIANGLE) + if (pObj->param[LFO_PARAM2_WAVEFORM] == LFO_WAVEFORM_TRIANGLE_REV) { // Create phase for (i=i0; i< len; i++) { + Sync_process(&pObj->sync); + in = (1-((synth_float_t)pObj->tri)) + pObj->offset; pObj->out = pObj->smooth_a*pObj->out + pObj->smooth_b*in; out = pObj->out; @@ -636,13 +705,6 @@ 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); - if (pObj->x < 0.5) - pObj->tri = 2*pObj->x; - else - pObj->tri = 2*(1-pObj->x); - - pObj->x = Sync_mod(pObj->x + pObj->dx, 1.0); - if (pObj->freq_update_req) { pObj->freq_update_req = 0; diff --git a/Source/synth/lfo.h b/Source/synth/lfo.h index 32ab42c..2b70c14 100644 --- a/Source/synth/lfo.h +++ b/Source/synth/lfo.h @@ -21,11 +21,11 @@ enum LFO_WAVEFORM_TRIANGLE, LFO_WAVEFORM_SH_UNI, LFO_WAVEFORM_SH_GAUSS, - LFO_WAVEFORM_ONE_MINUS_SINE, - LFO_WAVEFORM_ONE_MINUS_COSINE, - LFO_WAVEFORM_ONE_MINUS_SAW, - LFO_WAVEFORM_ONE_MINUS_SQUARE, - LFO_WAVEFORM_ONE_MINUS_TRIANGLE, + LFO_WAVEFORM_SINE_REV, + LFO_WAVEFORM_COSINE_REV, + LFO_WAVEFORM_SAW_REV, + LFO_WAVEFORM_SQUARE_REV, + LFO_WAVEFORM_TRIANGLE_REV, LFO_NUM_WAVEFORMS }; @@ -59,6 +59,7 @@ typedef struct _ssync_t synth_float_t accu; int phase_update; + int freq_update; } sync_t; @@ -73,7 +74,7 @@ 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); +void Sync_process(sync_t *pObj); #if defined(__cplusplus) }