1 #include "VocoderEffect.h"
2 #include <algorithm>
3 
4 // Hz from http://www.sequencer.de/pix/moog/moog_vocoder_rack.jpg
5 // const float vocoder_freq_moog[n_vocoder_bands] = {50, 158, 200, 252, 317, 400, 504, 635, 800,
6 // 1008, 1270, 1600, 2016, 2504, 3200, 4032, 5080}; const float vocoder_freq[n_vocoder_bands] =
7 // {100, 175, 230, 290, 360, 450, 580, 700, 900, 1100, 1400, 1800, 2300, 2800, 3600, 4700};
8 
9 // const float vocoder_freq[n_vocoder_bands] = {100, 175, 230, 290, 360, 450, 580, 700, 900, 1100,
10 // 1400, 1800, 2300, 3000, 4500, 8000}; const float vocoder_freq[n_vocoder_bands] = {158, 200, 252,
11 // 317, 400, 504, 635, 800, 1008, 1270, 1600, 2016, 2504, 3200, 4032, 5080};
12 
13 // const float vocoder_freq_vsm201[n_vocoder_bands] = {190, 290, 400, 510, 630, 760, 910, 1080,
14 // 1270, 1480, 1700, 2000, 2300, 2700, 3100, 3700, 4400, 5200, 6600, 8000}; const float
15 // vocoder_freq_vsm201[n_vocoder_bands] = {170, 240, 340, 440, 560, 680, 820, 970, 1150, 1370, 1605,
16 // 1850, 2150, 2500, 2900, 3400, 4050, 4850, 5850, 7500};
17 
18 const float vocoder_freq_vsm201[n_vocoder_bands] = {180,  219,  266,  324,  394,  480,  584,
19                                                     711,  865,  1053, 1281, 1559, 1898, 2309,
20                                                     2810, 3420, 4162, 5064, 6163, 7500};
21 
22 //------------------------------------------------------------------------------------------------
23 
VocoderEffect(SurgeStorage * storage,FxStorage * fxdata,pdata * pd)24 VocoderEffect::VocoderEffect(SurgeStorage *storage, FxStorage *fxdata, pdata *pd)
25     : Effect(storage, fxdata, pd), mBI(0)
26 {
27     /*mVoicedDetect.storage = storage;
28     mUnvoicedDetect.storage = storage;
29     mVoicedLevel = 0.f;
30     mUnvoicedLevel = 0.f;*/
31 
32     active_bands = n_vocoder_bands;
33     mGain.set_blocksize(BLOCK_SIZE);
34     mGainR.set_blocksize(BLOCK_SIZE);
35     for (int i = 0; i < voc_vector_size; i++)
36     {
37         mEnvF[i] = vZero;
38         mEnvFR[i] = vZero;
39     }
40 }
41 
42 //------------------------------------------------------------------------------------------------
43 
~VocoderEffect()44 VocoderEffect::~VocoderEffect() {}
45 
46 //------------------------------------------------------------------------------------------------
47 
init()48 void VocoderEffect::init() { setvars(true); }
49 
50 //------------------------------------------------------------------------------------------------
51 
setvars(bool init)52 void VocoderEffect::setvars(bool init)
53 {
54     modulator_mode = *f[voc_mod_input];
55     wet = *f[voc_mix];
56     float Freq[4], FreqM[4];
57 
58     const float Q = 20.f * (1.f + 0.5f * *f[voc_q]);
59     const float Spread = 0.4f / Q;
60 
61     active_bands = *pdata_ival[voc_num_bands];
62     active_bands = active_bands - (active_bands % 4); // FIXME - adjust the UI to be chunks of 4
63 
64     // We need to clamp these in reasonable ranges
65     float flo = limit_range(*f[voc_minfreq], -36.f, 36.f);
66     float fhi = limit_range(*f[voc_maxfreq], 0.f, 60.f);
67 
68     if (flo > fhi)
69     {
70         auto t = fhi;
71         fhi = flo;
72         flo = t;
73     }
74     float df = (fhi - flo) / (active_bands - 1);
75 
76     float hzlo = 440.f * pow(2.f, flo / 12.f);
77     float dhz = pow(2.f, df / 12.f);
78 
79     float fb = hzlo;
80 
81     float mb = fb;
82     float mdhz = dhz;
83     bool sepMod = false;
84 
85     float mC = *f[voc_mod_center];
86     float mX = *f[voc_mod_range];
87 
88     if (mC != 0 || mX != 0)
89     {
90         sepMod = true;
91         auto fDist = fhi - flo;
92         auto fDistHalf = fDist / 2.f;
93         auto mMid =
94             fDistHalf + flo +
95             0.3 * mC * fDistHalf; // that 0.3 is a tuning choice about how far we can move center
96         auto mLo = mMid - fDistHalf * (1 + 0.7 * mX); // as is that 0.7
97         auto dM = fDistHalf * 2 * (1.0 + 0.7 * mX) / (active_bands - 1);
98 
99         auto mHi = mLo + dM * (active_bands - 1);
100 
101         if (mHi > 60)
102             dM = (60 - mLo) / (active_bands - 1);
103 
104         mHi = mLo + dM * (active_bands - 1);
105 
106         mb = 440.0 * pow(2.f, mLo / 12.f);
107         mdhz = pow(2.f, dM / 12.f);
108     }
109 
110     for (int i = 0; i < active_bands && i < n_vocoder_bands; i++)
111     {
112         Freq[i & 3] = fb * samplerate_inv;
113         FreqM[i & 3] = mb * samplerate_inv;
114 
115         if ((i & 3) == 3)
116         {
117             int j = i >> 2;
118             mCarrierL[j].SetCoeff(Freq, Q, Spread);
119             mCarrierR[j].CopyCoeff(mCarrierL[j]);
120             if (sepMod)
121             {
122                 mModulator[j].SetCoeff(FreqM, Q, Spread);
123                 if (modulator_mode == vim_stereo)
124                 {
125                     mModulatorR[j].SetCoeff(FreqM, Q, Spread);
126                 }
127                 else
128                 {
129                     mModulatorR[j].CopyCoeff(mModulator[j]);
130                 }
131             }
132             else
133             {
134                 mModulator[j].CopyCoeff(mCarrierL[j]);
135                 mModulatorR[j].CopyCoeff(mCarrierR[j]);
136             }
137         }
138         fb *= dhz;
139         mb *= mdhz;
140     }
141 
142     /*mVoicedDetect.coeff_LP(BiquadFilter::calc_omega_from_Hz(1000.f), 0.707);
143     mUnvoicedDetect.coeff_HP(BiquadFilter::calc_omega_from_Hz(5000.f), 0.707);
144 
145     if (init)
146     {
147        mVoicedDetect.coeff_instantize();
148        mUnvoicedDetect.coeff_instantize();
149     }*/
150 }
151 
152 //------------------------------------------------------------------------------------------------
153 
process(float * dataL,float * dataR)154 void VocoderEffect::process(float *dataL, float *dataR)
155 {
156     mBI = (mBI + 1) & 0x3f;
157 
158     if (mBI == 0)
159     {
160         setvars(false);
161     }
162     modulator_mode = fxdata->p[voc_mod_input].val.i;
163     wet = *f[voc_mix];
164     float EnvFRate = 0.001f * powf(2.f, 4.f * *f[voc_envfollow]);
165 
166     // the left channel variables are used for mono when stereo is disabled
167     float modulator_in alignas(16)[BLOCK_SIZE];
168     float modulator_inR alignas(16)[BLOCK_SIZE];
169 
170     if (modulator_mode == vim_mono)
171     {
172         add_block(storage->audio_in_nonOS[0], storage->audio_in_nonOS[1], modulator_in,
173                   BLOCK_SIZE_QUAD);
174     }
175     else
176     {
177         copy_block(storage->audio_in_nonOS[0], modulator_in, BLOCK_SIZE_QUAD);
178         copy_block(storage->audio_in_nonOS[1], modulator_inR, BLOCK_SIZE_QUAD);
179     }
180 
181     float Gain = *f[voc_input_gain] + 24.f;
182     mGain.set_target_smoothed(db_to_linear(Gain));
183     mGain.multiply_block(modulator_in, BLOCK_SIZE_QUAD);
184 
185     mGainR.set_target_smoothed(db_to_linear(Gain));
186     mGainR.multiply_block(modulator_inR, BLOCK_SIZE_QUAD);
187 
188     vFloat Rate = vLoad1(EnvFRate);
189     vFloat Ratem1 = vLoad1(1.f - EnvFRate);
190 
191     float Gate = db_to_linear(*f[voc_input_gate] + Gain);
192     vFloat GateLevel = vLoad1(Gate * Gate);
193 
194     const vFloat MaxLevel = vLoad1(6.f);
195 
196     // Voiced / Unvoiced detection
197     /*   mVoicedDetect.process_block_to(modulator_in, modulator_tbuf);
198        float a = min(4.f, get_squaremax(modulator_tbuf,BLOCK_SIZE_QUAD));
199        mVoicedLevel = mVoicedLevel * (1.f - EnvFRate) + a * EnvFRate;
200 
201        mUnvoicedDetect.process_block_to(modulator_in, modulator_tbuf);
202        a = min(4.f, get_squaremax(modulator_tbuf, BLOCK_SIZE_QUAD));
203        mUnvoicedLevel = mUnvoicedLevel * (1.f - EnvFRate) + a * EnvFRate;
204 
205        float Ratio = db_to_linear(*f[voc_unvoiced_threshold]);
206 
207        if (mUnvoicedLevel > (mVoicedLevel * Ratio))
208          // mix carrier with noise
209          for(int i = 0; i < BLOCK_SIZE; i++)
210          {
211             float rand11 = storage->rand_pm1();
212             dataL[i] = rand11;
213             rand11 = storage->rand_pm1();
214             dataR[i] = rand11;
215          }*/
216 
217     if (modulator_mode == vim_mono || modulator_mode == vim_left || modulator_mode == vim_right)
218     {
219         float *input;
220 
221         if (modulator_mode == vim_mono || modulator_mode == vim_left)
222         {
223             input = modulator_in;
224         }
225         else
226         {
227             input = modulator_inR;
228         }
229 
230         for (int k = 0; k < BLOCK_SIZE; k++)
231         {
232             vFloat In = vLoad1(input[k]);
233 
234             vFloat Left = vLoad1(dataL[k]);
235             vFloat Right = vLoad1(dataR[k]);
236 
237             vFloat LeftSum = vZero;
238             vFloat RightSum = vZero;
239 
240             for (int j = 0; (j < (active_bands >> 2)) && (j < voc_vector_size); j++)
241             {
242                 vFloat Mod = mModulator[j].CalcBPF(In);
243                 Mod = vMin(vMul(Mod, Mod), MaxLevel);
244                 Mod = vAnd(Mod, vCmpGE(Mod, GateLevel));
245                 mEnvF[j] = vMAdd(mEnvF[j], Ratem1, vMul(Rate, Mod));
246                 Mod = vSqrtFast(mEnvF[j]);
247 
248                 LeftSum = vAdd(LeftSum, mCarrierL[j].CalcBPF(vMul(Left, Mod)));
249                 RightSum = vAdd(RightSum, mCarrierR[j].CalcBPF(vMul(Right, Mod)));
250             }
251 
252             float inMul = 1.0 - wet;
253             dataL[k] = dataL[k] * inMul + wet * vSum(LeftSum) * 4.f;
254             dataR[k] = dataR[k] * inMul + wet * vSum(RightSum) * 4.f;
255         }
256     }
257     else if (modulator_mode == vim_stereo)
258     {
259         for (int k = 0; k < BLOCK_SIZE; k++)
260         {
261             vFloat InL = vLoad1(modulator_in[k]);
262             vFloat InR = vLoad1(modulator_inR[k]);
263             vFloat Left = vLoad1(dataL[k]);
264             vFloat Right = vLoad1(dataR[k]);
265 
266             vFloat LeftSum = vZero;
267             vFloat RightSum = vZero;
268 
269             for (int j = 0; j < (active_bands >> 2) && j < (n_vocoder_bands >> 2); j++)
270             {
271                 vFloat ModL = mModulator[j].CalcBPF(InL);
272                 vFloat ModR = mModulatorR[j].CalcBPF(InR);
273                 ModL = vMin(vMul(ModL, ModL), MaxLevel);
274                 ModR = vMin(vMul(ModR, ModR), MaxLevel);
275 
276                 ModL = vAnd(ModL, vCmpGE(ModL, GateLevel));
277                 ModR = vAnd(ModR, vCmpGE(ModR, GateLevel));
278 
279                 mEnvF[j] = vMAdd(mEnvF[j], Ratem1, vMul(Rate, ModL));
280                 mEnvFR[j] = vMAdd(mEnvFR[j], Ratem1, vMul(Rate, ModR));
281                 ModL = vSqrtFast(mEnvF[j]);
282                 ModR = vSqrtFast(mEnvFR[j]);
283                 LeftSum = vAdd(LeftSum, mCarrierL[j].CalcBPF(vMul(Left, ModL)));
284                 RightSum = vAdd(RightSum, mCarrierR[j].CalcBPF(vMul(Right, ModR)));
285             }
286 
287             float inMul = 1.0 - wet;
288             dataL[k] = dataL[k] * inMul + wet * vSum(LeftSum) * 4.f;
289             dataR[k] = dataR[k] * inMul + wet * vSum(RightSum) * 4.f;
290         }
291     }
292 }
293 
294 //------------------------------------------------------------------------------------------------
295 
suspend()296 void VocoderEffect::suspend() { init(); }
297 
298 //------------------------------------------------------------------------------------------------
299 
init_default_values()300 void VocoderEffect::init_default_values()
301 {
302     fxdata->p[voc_input_gain].val.f = 0.f;
303     fxdata->p[voc_input_gate].val.f = -96.f;
304     fxdata->p[voc_envfollow].val.f = 0.f;
305     fxdata->p[voc_q].val.f = 0.f;
306 
307     fxdata->p[voc_num_bands].val.i = n_vocoder_bands;
308 
309     fxdata->p[voc_minfreq].val.f = 12.f * log(vocoder_freq_vsm201[0] / 440.f) / log(2.f);
310     fxdata->p[voc_maxfreq].val.f =
311         12.f * log(vocoder_freq_vsm201[n_vocoder_bands - 1] / 440.f) / log(2.f);
312 
313     fxdata->p[voc_mod_range].val.f = 0.f;
314     fxdata->p[voc_mod_center].val.f = 0.f;
315 
316     fxdata->p[voc_mod_input].val.i = 0;
317     fxdata->p[voc_mix].val.f = 1.f;
318 }
319 
320 //------------------------------------------------------------------------------------------------
321 
group_label(int id)322 const char *VocoderEffect::group_label(int id)
323 {
324     switch (id)
325     {
326     case 0:
327         return "Input";
328     case 1:
329         return "Filter Bank";
330     case 2:
331         return "Carrier";
332     case 3:
333         return "Modulator";
334     case 4:
335         return "Output";
336     }
337     return 0;
338 }
339 
340 //------------------------------------------------------------------------------------------------
341 
group_label_ypos(int id)342 int VocoderEffect::group_label_ypos(int id)
343 {
344     switch (id)
345     {
346     case 0:
347         return 1;
348     case 1:
349         return 7;
350     case 2:
351         return 13;
352     case 3:
353         return 21;
354     case 4:
355         return 29;
356     }
357     return 0;
358 }
359 
360 //------------------------------------------------------------------------------------------------
361 
init_ctrltypes()362 void VocoderEffect::init_ctrltypes()
363 {
364     Effect::init_ctrltypes();
365 
366     fxdata->p[voc_input_gain].set_name("Gain");
367     fxdata->p[voc_input_gain].set_type(ct_decibel);
368     fxdata->p[voc_input_gain].posy_offset = 1;
369 
370     fxdata->p[voc_input_gate].set_name("Gate");
371     fxdata->p[voc_input_gate].set_type(ct_decibel_attenuation_large);
372     fxdata->p[voc_input_gate].posy_offset = 1;
373 
374     fxdata->p[voc_envfollow].set_name("Env Follow");
375     fxdata->p[voc_envfollow].set_type(ct_percent);
376     fxdata->p[voc_envfollow].posy_offset = 3;
377 
378     /*fxdata->p[voc_unvoiced_threshold].set_name("Unvoiced Thresh");
379     fxdata->p[voc_unvoiced_threshold].set_type(ct_decibel);
380     fxdata->p[voc_unvoiced_threshold].posy_offset = 3;*/
381 
382     fxdata->p[voc_q].set_name("Q");
383     fxdata->p[voc_q].set_type(ct_percent_bipolar);
384     fxdata->p[voc_q].posy_offset = 3;
385 
386     fxdata->p[voc_num_bands].set_name("Bands");
387     fxdata->p[voc_num_bands].set_type(ct_vocoder_bandcount);
388     fxdata->p[voc_num_bands].posy_offset = 3;
389 
390     fxdata->p[voc_minfreq].set_name("Min Frequency");
391     fxdata->p[voc_minfreq].set_type(ct_freq_vocoder_low);
392     fxdata->p[voc_minfreq].posy_offset = 3;
393 
394     fxdata->p[voc_maxfreq].set_name("Max Frequency");
395     fxdata->p[voc_maxfreq].set_type(ct_freq_vocoder_high);
396     fxdata->p[voc_maxfreq].posy_offset = 3;
397 
398     fxdata->p[voc_mod_input].set_name("Input");
399     fxdata->p[voc_mod_input].set_type(ct_vocoder_modulator_mode);
400     fxdata->p[voc_mod_input].posy_offset = 5;
401 
402     fxdata->p[voc_mod_range].set_name("Range");
403     fxdata->p[voc_mod_range].set_type(ct_percent_bipolar);
404     fxdata->p[voc_mod_range].posy_offset = 5;
405 
406     fxdata->p[voc_mod_center].set_name("Center");
407     fxdata->p[voc_mod_center].set_type(ct_percent_bipolar);
408     fxdata->p[voc_mod_center].posy_offset = 5;
409 
410     fxdata->p[voc_mix].set_name("Mix");
411     fxdata->p[voc_mix].set_type(ct_percent);
412     fxdata->p[voc_mix].posy_offset = 7;
413 }
414 
handleStreamingMismatches(int streamingRevision,int currentSynthStreamingRevision)415 void VocoderEffect::handleStreamingMismatches(int streamingRevision,
416                                               int currentSynthStreamingRevision)
417 {
418     if (streamingRevision <= 10)
419     {
420         fxdata->p[voc_num_bands].val.i = n_vocoder_bands;
421 
422         fxdata->p[voc_minfreq].val.f = 12.f * log(vocoder_freq_vsm201[0] / 440.f) / log(2.f);
423         fxdata->p[voc_maxfreq].val.f =
424             12.f * log(vocoder_freq_vsm201[n_vocoder_bands - 1] / 440.f) / log(2.f);
425 
426         fxdata->p[voc_mod_range].val.f = 0.f;
427         fxdata->p[voc_mod_center].val.f = 0.f;
428 
429         fxdata->p[voc_mod_input].val.i = 0;
430         fxdata->p[voc_mix].val.f = 1.f;
431     }
432 }
433 //------------------------------------------------------------------------------------------------
434