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