Skip to content

Commit

Permalink
An expanded vocder implementation (#1007)
Browse files Browse the repository at this point in the history
These changes address issue #864

1. Add the appropriate parameters to do band control to the effect
   and make sure they display properly and save properly in the fxp
2. Make the bands tunable and coutnable (although bands must be %4)
   and respond properly to hi and low band frequency.
3. Implement tuning to reset the frequency bands; also
   implement separate tuning through the center and expand
   for the modulator bands.
4. Bind vocoderbands to multiple of 4.
  • Loading branch information
baconpaul authored Aug 9, 2019
1 parent 3f230be commit 6de6bd5
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 7 deletions.
15 changes: 15 additions & 0 deletions src/common/Parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,12 @@ void Parameter::set_type(int ctrltype)
valtype = vt_int;
val_default.i = 0;
break;
case ct_vocoder_bandcount:
val_min.i = 4;
val_max.i = 20;
valtype = vt_int;
val_default.i = 20;
break;
case ct_countedset_percent:
val_min.f = 0;
val_max.f = 1;
Expand Down Expand Up @@ -630,6 +636,11 @@ void Parameter::bound_value(bool force_integer)
val.f = 1.0 * intcount / count;
}

if( ctrltype == ct_vocoder_bandcount )
{
val.i = val.i - val.i % 4;
}

switch (valtype)
{
case vt_float:
Expand Down Expand Up @@ -985,6 +996,10 @@ void Parameter::get_display(char* txt, bool external, float ef)
// FIXME - do better than this of course
sprintf(txt, "%d", i);
break;
case ct_vocoder_bandcount:
// FIXME - do better than this of course
sprintf(txt, "%d bands", i);
break;
case ct_oscroute:
switch (i)
{
Expand Down
1 change: 1 addition & 0 deletions src/common/Parameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum ctrltypes
ct_character,
ct_sineoscmode,
ct_countedset_percent, // what % through a counted set are you
ct_vocoder_bandcount,
num_ctrltypes,
};

Expand Down
3 changes: 3 additions & 0 deletions src/common/dsp/effect/Effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ Effect::Effect(SurgeStorage* storage, FxStorage* fxdata, pdata* pd)
this->pd = pd;
ringout = 10000000;
for (int i = 0; i < n_fx_params; i++)
{
f[i] = &pd[fxdata->p[i].id].f;
pdata_ival[i] = &pd[fxdata->p[i].id].i;
}
}

bool Effect::process_ringout(float* dataL, float* dataR, bool indata_present)
Expand Down
1 change: 1 addition & 0 deletions src/common/dsp/effect/Effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class alignas(16) Effect
pdata* pd;
int ringout;
float* f[n_fx_params];
int* pdata_ival[n_fx_params]; // f is not a great choice for a member name, but 'i' woudl be worse!
};

Effect* spawn_effect(int id, SurgeStorage* storage, FxStorage* fxdata, pdata* pd);
97 changes: 91 additions & 6 deletions src/common/dsp/effect/VocoderEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ VocoderEffect::VocoderEffect(SurgeStorage* storage, FxStorage* fxdata, pdata* pd
mVoicedLevel = 0.f;
mUnvoicedLevel = 0.f;*/

active_bands = n_vocoder_bands;
mGain.set_blocksize(BLOCK_SIZE);

for (int i = 0; i < NVocoderVec; i++)
Expand All @@ -56,22 +57,70 @@ void VocoderEffect::init()

void VocoderEffect::setvars(bool init)
{
float Freq[4];
float Freq[4], FreqM[4];

const float Q = 20.f * (1.f + 0.5f * *f[KQuality]);
const float Spread = 0.4f / Q;

for (int i = 0; i < n_vocoder_bands; i++)
{
Freq[i & 3] = vocoder_freq_vsm201[i] * samplerate_inv;
active_bands = *pdata_ival[kNumBands];
active_bands = active_bands - ( active_bands % 4 ); // FIXME - adjust the UI to be chunks of 4
#if 0
std::cout << "ACtivet bands is " << active_bands << std::endl;

std::cout << "Freq Low is " << *f[kFreqLo] << " " << 440.f * pow(2.f, *f[kFreqLo]/12.f) << std::endl;
std::cout << "Freq High is " << *f[kFreqHi] << std::endl;
#endif
float flo = *f[kFreqLo];
float fhi = *f[kFreqHi];
float df = (fhi-flo)/(active_bands-1);

float hzlo = 440.f * pow(2.f, flo / 12.f );
float dhz = pow(2.f, df / 12.f );

float fb = hzlo;

float mb = fb;
float mdhz = dhz;
bool sepMod = false;

float mC = *f[kModCenter];
float mX = *f[kModExpand];

if( mC != 0 || mX != 0 )
{
sepMod = true;
auto fDist = fhi - flo;
auto fDistHalf = fDist / 2.f;
auto mMid = fDistHalf + flo + 0.3 * mC * fDistHalf; // that 0.3 is a tuning choice about how far we can move center
auto mLo = mMid - fDistHalf * ( 1 + 0.7 * mX ); // as is that 0.7
auto dM = fDistHalf * 2 * ( 1.0 + 0.7 * mX ) / (active_bands - 1);

mb = 440.0 * pow(2.f, mLo / 12.f );
mdhz = pow( 2.f, dM / 12.f );
}

for (int i = 0; i < active_bands && i < n_vocoder_bands; i++)
{
//std::cout << "vsm201[" << i << "]=" << vocoder_freq_vsm201[i] << " fb=" << fb << std::endl;
Freq[i & 3] = fb * samplerate_inv;
FreqM[i & 3] = mb * samplerate_inv;

if ((i & 3) == 3)
{
int j = i >> 2;
mCarrierL[j].SetCoeff(Freq, Q, Spread);
mCarrierR[j].CopyCoeff(mCarrierL[j]);
mModulator[j].CopyCoeff(mCarrierL[j]);
if( sepMod )
{
mModulator[j].SetCoeff(FreqM, Q, Spread);
}
else
{
mModulator[j].CopyCoeff(mCarrierL[j]);
}
}
fb *= dhz;
mb *= mdhz;
}

/* mVoicedDetect.coeff_LP(biquadunit::calc_omega_from_Hz(1000.f), 0.707);
Expand Down Expand Up @@ -147,7 +196,7 @@ void VocoderEffect::process(float* dataL, float* dataR)
vFloat LeftSum = vZero;
vFloat RightSum = vZero;

for (int j = 0; j < (NVocoderVec); j++)
for (int j = 0; j < (active_bands >> 2) && j < ( n_vocoder_bands >> 2 ) /*(NVocoderVec)*/; j++)
{
vFloat Mod = mModulator[j].CalcBPF(In);
Mod = vMin(vMul(Mod, Mod), MaxLevel);
Expand Down Expand Up @@ -180,6 +229,17 @@ void VocoderEffect::init_default_values()
fxdata->p[KGateLevel].val.f = -96.f;
fxdata->p[KRate].val.f = 0.f;
fxdata->p[KQuality].val.f = 0.f;

fxdata->p[kNumBands].val.i = n_vocoder_bands;

// freq = 440 * 2^(v/12)
// log(freq/440)/log(2) = v/12
// 12 * log(freq/440) / log(2) = v;
fxdata->p[kFreqLo].val.f = 12.f * log(vocoder_freq_vsm201[0]/440.f)/log(2.f);
fxdata->p[kFreqHi].val.f = 12.f * log(vocoder_freq_vsm201[n_vocoder_bands-1]/440.f)/log(2.f);

fxdata->p[kModExpand].val.f = 0.f;
fxdata->p[kModCenter].val.f = 0.f;
}

//------------------------------------------------------------------------------------------------
Expand All @@ -192,6 +252,8 @@ const char* VocoderEffect::group_label(int id)
return "Levels";
case 1:
return "Filterbank";
case 2:
return "Bands";
}
return 0;
}
Expand All @@ -206,6 +268,8 @@ int VocoderEffect::group_label_ypos(int id)
return 1;
case 1:
return 7;
case 2:
return 13;
}
return 0;
}
Expand Down Expand Up @@ -235,6 +299,27 @@ void VocoderEffect::init_ctrltypes()
fxdata->p[KQuality].set_name("Q");
fxdata->p[KQuality].set_type(ct_percent_bidirectional);
fxdata->p[KQuality].posy_offset = 3;

fxdata->p[kNumBands].set_name("# Bands");
fxdata->p[kNumBands].set_type(ct_vocoder_bandcount);
fxdata->p[kNumBands].posy_offset = 3;

fxdata->p[kFreqLo].set_name("Low band");
fxdata->p[kFreqLo].set_type(ct_freq_audible);
fxdata->p[kFreqLo].posy_offset = 3;

fxdata->p[kFreqHi].set_name("High band");
fxdata->p[kFreqHi].set_type(ct_freq_audible);
fxdata->p[kFreqHi].posy_offset = 3;

fxdata->p[kModExpand].set_name("Mod XPand");
fxdata->p[kModExpand].set_type(ct_percent_bidirectional);
fxdata->p[kModExpand].posy_offset = 3;

fxdata->p[kModCenter].set_name("Mod Center");
fxdata->p[kModCenter].set_type(ct_percent_bidirectional);
fxdata->p[kModCenter].posy_offset = 3;

}

//------------------------------------------------------------------------------------------------
9 changes: 8 additions & 1 deletion src/common/dsp/effect/effect_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ class VocoderEffect : public Effect
// KUnvoicedThreshold,
KQuality,
KShift,

kNumBands,
kFreqLo,
kFreqHi,
kModExpand,
kModCenter,
};

VocoderEffect(SurgeStorage* storage, FxStorage* fxdata, pdata* pd);
Expand Down Expand Up @@ -307,7 +313,8 @@ class VocoderEffect : public Effect
lipol_ps mGain alignas(16);

int mBI; // block increment (to keep track of events not occurring every n blocks)

int active_bands;

/*
float mVoicedLevel;
float mUnvoicedLevel;
Expand Down

0 comments on commit 6de6bd5

Please sign in to comment.