1 /* Calf DSP Library
2 * Reusable audio effect classes - implementation.
3 *
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
20 */
21
22 #include <calf/audio_fx.h>
23 #include <calf/giface.h>
24 #include <limits.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <math.h>
28
29 using namespace calf_plugins;
30 using namespace dsp;
31
simple_phaser(int _max_stages,float * x1vals,float * y1vals)32 simple_phaser::simple_phaser(int _max_stages, float *x1vals, float *y1vals)
33 {
34 max_stages = _max_stages;
35 x1 = x1vals;
36 y1 = y1vals;
37
38 set_base_frq(1000);
39 set_mod_depth(1000);
40 set_fb(0);
41 state = 0;
42 cnt = 0;
43 stages = 0;
44 set_stages(_max_stages);
45 }
46
set_stages(int _stages)47 void simple_phaser::set_stages(int _stages)
48 {
49 if (_stages > stages)
50 {
51 assert(_stages <= max_stages);
52 if (_stages > max_stages)
53 _stages = max_stages;
54 for (int i = stages; i < _stages; i++)
55 {
56 x1[i] = x1[stages-1];
57 y1[i] = y1[stages-1];
58 }
59 }
60 stages = _stages;
61 }
62
reset()63 void simple_phaser::reset()
64 {
65 cnt = 0;
66 state = 0;
67 phase.set(0);
68 for (int i = 0; i < max_stages; i++)
69 x1[i] = y1[i] = 0;
70 control_step();
71 }
72
control_step()73 void simple_phaser::control_step()
74 {
75 cnt = 0;
76 int v = phase.get() + 0x40000000;
77 int sign = v >> 31;
78 v ^= sign;
79 // triangle wave, range from 0 to INT_MAX
80 double vf = (double)((v >> 16) * (1.0 / 16384.0) - 1);
81
82 float freq = base_frq * pow(2.0, vf * mod_depth / 1200.0);
83 freq = dsp::clip<float>(freq, 10.0, 0.49 * sample_rate);
84 stage1.set_ap_w(freq * (M_PI / 2.0) * odsr);
85 if (lfo_active)
86 phase += dphase * 32;
87 for (int i = 0; i < stages; i++)
88 {
89 dsp::sanitize(x1[i]);
90 dsp::sanitize(y1[i]);
91 }
92 dsp::sanitize(state);
93 }
94
process(float * buf_out,float * buf_in,int nsamples,bool active,float level_in,float level_out)95 void simple_phaser::process(float *buf_out, float *buf_in, int nsamples, bool active, float level_in, float level_out)
96 {
97 for (int i=0; i<nsamples; i++) {
98 cnt++;
99 if (cnt == 32)
100 control_step();
101 float in = *buf_in++ * level_in;
102 float fd = in + state * fb;
103 for (int j = 0; j < stages; j++)
104 fd = stage1.process_ap(fd, x1[j], y1[j]);
105 state = fd;
106
107 float sdry = in * gs_dry.get();
108 float swet = fd * gs_wet.get();
109 *buf_out++ = (sdry + (active ? swet : 0)) * level_out;
110 }
111 }
112
freq_gain(float freq,float sr) const113 float simple_phaser::freq_gain(float freq, float sr) const
114 {
115 typedef std::complex<double> cfloat;
116 freq *= 2.0 * M_PI / sr;
117 cfloat z = 1.0 / exp(cfloat(0.0, freq)); // z^-1
118
119 cfloat p = cfloat(1.0);
120 cfloat stg = stage1.h_z(z);
121
122 for (int i = 0; i < stages; i++)
123 p = p * stg;
124
125 p = p / (cfloat(1.0) - cfloat(fb) * p);
126 return std::abs(cfloat(gs_dry.get_last()) + cfloat(gs_wet.get_last()) * p);
127 }
128
129 ///////////////////////////////////////////////////////////////////////////////////
130
calculate_filter(float freq,float q,int mode,float gain)131 void biquad_filter_module::calculate_filter(float freq, float q, int mode, float gain)
132 {
133 if (mode <= mode_36db_lp) {
134 order = mode + 1;
135 left[0].set_lp_rbj(freq, pow(q, 1.0 / order), srate, gain);
136 } else if ( mode_12db_hp <= mode && mode <= mode_36db_hp ) {
137 order = mode - mode_12db_hp + 1;
138 left[0].set_hp_rbj(freq, pow(q, 1.0 / order), srate, gain);
139 } else if ( mode_6db_bp <= mode && mode <= mode_18db_bp ) {
140 order = mode - mode_6db_bp + 1;
141 left[0].set_bp_rbj(freq, pow(q, 1.0 / order), srate, gain);
142 } else if ( mode_6db_br <= mode && mode <= mode_18db_br) {
143 order = mode - mode_6db_br + 1;
144 left[0].set_br_rbj(freq, order * 0.1 * q, srate, gain);
145 } else { // mode_allpass
146 order = 3;
147 left[0].set_allpass(freq, 1, srate);
148 }
149
150 right[0].copy_coeffs(left[0]);
151 for (int i = 1; i < order; i++) {
152 left[i].copy_coeffs(left[0]);
153 right[i].copy_coeffs(left[0]);
154 }
155 }
156
filter_activate()157 void biquad_filter_module::filter_activate()
158 {
159 for (int i=0; i < order; i++) {
160 left[i].reset();
161 right[i].reset();
162 }
163 }
164
sanitize()165 void biquad_filter_module::sanitize()
166 {
167 for (int i=0; i < order; i++) {
168 left[i].sanitize();
169 right[i].sanitize();
170 }
171 }
172
process_channel(uint16_t channel_no,const float * in,float * out,uint32_t numsamples,int inmask,float lvl_in,float lvl_out)173 int biquad_filter_module::process_channel(uint16_t channel_no, const float *in, float *out, uint32_t numsamples, int inmask, float lvl_in, float lvl_out) {
174 dsp::biquad_d1 *filter;
175 switch (channel_no) {
176 case 0:
177 filter = left;
178 break;
179
180 case 1:
181 filter = right;
182 break;
183
184 default:
185 assert(false);
186 return 0;
187 }
188
189 if (inmask) {
190 switch(order) {
191 case 1:
192 for (uint32_t i = 0; i < numsamples; i++) {
193 out[i] = filter[0].process(in[i] * lvl_in);
194 out[i] *= lvl_out;
195 }
196 break;
197 case 2:
198 for (uint32_t i = 0; i < numsamples; i++) {
199 out[i] = filter[1].process(filter[0].process(in[i] * lvl_in));
200 out[i] *= lvl_out;
201 }
202 break;
203 case 3:
204 for (uint32_t i = 0; i < numsamples; i++) {
205 out[i] = filter[2].process(filter[1].process(filter[0].process(in[i] * lvl_in)));
206 out[i] *= lvl_out;
207 }
208 break;
209 }
210 } else {
211 if (filter[order - 1].empty())
212 return 0;
213 switch(order) {
214 case 1:
215 for (uint32_t i = 0; i < numsamples; i++) {
216 out[i] = filter[0].process_zeroin();
217 out[i] *= lvl_out;
218 }
219 break;
220 case 2:
221 if (filter[0].empty())
222 for (uint32_t i = 0; i < numsamples; i++) {
223 out[i] = filter[1].process_zeroin();
224 out[i] *= lvl_out;
225 }
226 else
227 for (uint32_t i = 0; i < numsamples; i++) {
228 out[i] = filter[1].process(filter[0].process_zeroin());
229 out[i] *= lvl_out;
230 }
231 break;
232 case 3:
233 if (filter[1].empty())
234 for (uint32_t i = 0; i < numsamples; i++) {
235 out[i] = filter[2].process_zeroin();
236 out[i] *= lvl_out;
237 }
238 else
239 for (uint32_t i = 0; i < numsamples; i++) {
240 out[i] = filter[2].process(filter[1].process(filter[0].process_zeroin()));
241 out[i] *= lvl_out;
242 }
243 break;
244 }
245 }
246 for (int i = 0; i < order; i++)
247 filter[i].sanitize();
248 return filter[order - 1].empty() ? 0 : inmask;
249 }
250
freq_gain(int subindex,float freq,float srate) const251 float biquad_filter_module::freq_gain(int subindex, float freq, float srate) const
252 {
253 float level = 1.0;
254 for (int j = 0; j < order; j++)
255 level *= left[j].freq_gain(freq, srate);
256 return level;
257 }
258
259 /////////////////////////////////////////////////////////////////////////////////////////////////////////
260
update_times()261 void reverb::update_times()
262 {
263 switch(type)
264 {
265 case 0:
266 tl[0] = 397 << 16, tr[0] = 383 << 16;
267 tl[1] = 457 << 16, tr[1] = 429 << 16;
268 tl[2] = 549 << 16, tr[2] = 631 << 16;
269 tl[3] = 649 << 16, tr[3] = 756 << 16;
270 tl[4] = 773 << 16, tr[4] = 803 << 16;
271 tl[5] = 877 << 16, tr[5] = 901 << 16;
272 break;
273 case 1:
274 tl[0] = 697 << 16, tr[0] = 783 << 16;
275 tl[1] = 957 << 16, tr[1] = 929 << 16;
276 tl[2] = 649 << 16, tr[2] = 531 << 16;
277 tl[3] = 1049 << 16, tr[3] = 1177 << 16;
278 tl[4] = 473 << 16, tr[4] = 501 << 16;
279 tl[5] = 587 << 16, tr[5] = 681 << 16;
280 break;
281 case 2:
282 default:
283 tl[0] = 697 << 16, tr[0] = 783 << 16;
284 tl[1] = 957 << 16, tr[1] = 929 << 16;
285 tl[2] = 649 << 16, tr[2] = 531 << 16;
286 tl[3] = 1249 << 16, tr[3] = 1377 << 16;
287 tl[4] = 1573 << 16, tr[4] = 1671 << 16;
288 tl[5] = 1877 << 16, tr[5] = 1781 << 16;
289 break;
290 case 3:
291 tl[0] = 1097 << 16, tr[0] = 1087 << 16;
292 tl[1] = 1057 << 16, tr[1] = 1031 << 16;
293 tl[2] = 1049 << 16, tr[2] = 1039 << 16;
294 tl[3] = 1083 << 16, tr[3] = 1055 << 16;
295 tl[4] = 1075 << 16, tr[4] = 1099 << 16;
296 tl[5] = 1003 << 16, tr[5] = 1073 << 16;
297 break;
298 case 4:
299 tl[0] = 197 << 16, tr[0] = 133 << 16;
300 tl[1] = 357 << 16, tr[1] = 229 << 16;
301 tl[2] = 549 << 16, tr[2] = 431 << 16;
302 tl[3] = 949 << 16, tr[3] = 1277 << 16;
303 tl[4] = 1173 << 16, tr[4] = 1671 << 16;
304 tl[5] = 1477 << 16, tr[5] = 1881 << 16;
305 break;
306 case 5:
307 tl[0] = 197 << 16, tr[0] = 133 << 16;
308 tl[1] = 257 << 16, tr[1] = 179 << 16;
309 tl[2] = 549 << 16, tr[2] = 431 << 16;
310 tl[3] = 619 << 16, tr[3] = 497 << 16;
311 tl[4] = 1173 << 16, tr[4] = 1371 << 16;
312 tl[5] = 1577 << 16, tr[5] = 1881 << 16;
313 break;
314 }
315
316 float fDec=1000 + 2400.f * diffusion;
317 for (int i = 0 ; i < 6; i++) {
318 ldec[i]=exp(-float(tl[i] >> 16) / fDec),
319 rdec[i]=exp(-float(tr[i] >> 16) / fDec);
320 }
321 }
322
reset()323 void reverb::reset()
324 {
325 apL1.reset();apR1.reset();
326 apL2.reset();apR2.reset();
327 apL3.reset();apR3.reset();
328 apL4.reset();apR4.reset();
329 apL5.reset();apR5.reset();
330 apL6.reset();apR6.reset();
331 lp_left.reset();lp_right.reset();
332 old_left = 0; old_right = 0;
333 }
334
process(float & left,float & right)335 void reverb::process(float &left, float &right)
336 {
337 unsigned int ipart = phase.ipart();
338
339 // the interpolated LFO might be an overkill here
340 int lfo = phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]) >> 2;
341 phase += dphase;
342
343 left += old_right;
344 left = apL1.process_allpass_comb_lerp16(left, tl[0] - 45*lfo, ldec[0]);
345 left = apL2.process_allpass_comb_lerp16(left, tl[1] + 47*lfo, ldec[1]);
346 float out_left = left;
347 left = apL3.process_allpass_comb_lerp16(left, tl[2] + 54*lfo, ldec[2]);
348 left = apL4.process_allpass_comb_lerp16(left, tl[3] - 69*lfo, ldec[3]);
349 left = apL5.process_allpass_comb_lerp16(left, tl[4] + 69*lfo, ldec[4]);
350 left = apL6.process_allpass_comb_lerp16(left, tl[5] - 46*lfo, ldec[5]);
351 old_left = lp_left.process(left * fb);
352 sanitize(old_left);
353
354 right += old_left;
355 right = apR1.process_allpass_comb_lerp16(right, tr[0] - 45*lfo, rdec[0]);
356 right = apR2.process_allpass_comb_lerp16(right, tr[1] + 47*lfo, rdec[1]);
357 float out_right = right;
358 right = apR3.process_allpass_comb_lerp16(right, tr[2] + 54*lfo, rdec[2]);
359 right = apR4.process_allpass_comb_lerp16(right, tr[3] - 69*lfo, rdec[3]);
360 right = apR5.process_allpass_comb_lerp16(right, tr[4] + 69*lfo, rdec[4]);
361 right = apR6.process_allpass_comb_lerp16(right, tr[5] - 46*lfo, rdec[5]);
362 old_right = lp_right.process(right * fb);
363 sanitize(old_right);
364
365 left = out_left, right = out_right;
366 }
367
368 /// Distortion Module by Tom Szilagyi
369 ///
370 /// This module provides a blendable saturation stage
371 ///////////////////////////////////////////////////////////////////////////////////////////////
372
tap_distortion()373 tap_distortion::tap_distortion()
374 {
375 is_active = false;
376 srate = 0;
377 meter = 0.f;
378 rdrive = rbdr = kpa = kpb = kna = knb = ap = an = imr = kc = srct = sq = pwrq = prev_med = prev_out = 0.f;
379 drive_old = blend_old = -1.f;
380 over = 1;
381 }
382
activate()383 void tap_distortion::activate()
384 {
385 is_active = true;
386 set_params(0.f, 0.f);
387 }
deactivate()388 void tap_distortion::deactivate()
389 {
390 is_active = false;
391 }
392
set_params(float blend,float drive)393 void tap_distortion::set_params(float blend, float drive)
394 {
395 // set distortion coeffs
396 if ((drive_old != drive) || (blend_old != blend)) {
397 rdrive = 12.0f / drive;
398 rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f;
399 kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f;
400 kpb = (2.0f - kpa) / 2.0f;
401 ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f;
402 kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive);
403
404 srct = (0.1f * srate) / (0.1f * srate + 1.0f);
405 sq = kc*kc + 1.0f;
406 knb = -1.0f * rbdr / D(sq);
407 kna = 2.0f * kc * rbdr / D(sq);
408 an = rbdr*rbdr / sq;
409 imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f);
410 pwrq = 2.0f / (imr + 1.0f);
411
412 drive_old = drive;
413 blend_old = blend;
414 }
415 }
416
set_sample_rate(uint32_t sr)417 void tap_distortion::set_sample_rate(uint32_t sr)
418 {
419 srate = sr;
420 over = srate * 2 > 96000 ? 1 : 2;
421 resampler.set_params(srate, over, 2);
422 }
423
process(float in)424 float tap_distortion::process(float in)
425 {
426 double *samples = resampler.upsample((double)in);
427 meter = 0.f;
428 for (int o = 0; o < over; o++) {
429 float proc = samples[o];
430 float med;
431 if (proc >= 0.0f) {
432 med = (D(ap + proc * (kpa - proc)) + kpb) * pwrq;
433 } else {
434 med = (D(an - proc * (kna + proc)) + knb) * pwrq * -1.0f;
435 }
436 proc = srct * (med - prev_med + prev_out);
437 prev_med = M(med);
438 prev_out = M(proc);
439 samples[o] = proc;
440 meter = std::max(meter, proc);
441 }
442 float out = (float)resampler.downsample(samples);
443 return out;
444 }
445
get_distortion_level()446 float tap_distortion::get_distortion_level()
447 {
448 return meter;
449 }
450
451 ////////////////////////////////////////////////////////////////////////////////
452
simple_lfo()453 simple_lfo::simple_lfo()
454 {
455 is_active = false;
456 phase = 0.f;
457 pwidth = 1.f;
458 }
459
activate()460 void simple_lfo::activate()
461 {
462 is_active = true;
463 phase = 0.f;
464 }
465
deactivate()466 void simple_lfo::deactivate()
467 {
468 is_active = false;
469 }
470
get_value()471 float simple_lfo::get_value()
472 {
473 return get_value_from_phase(phase);
474 }
475
get_value_from_phase(float ph) const476 float simple_lfo::get_value_from_phase(float ph) const
477 {
478 float val = 0.f;
479 float phs = std::min(100.f, ph / std::min(1.99f, std::max(0.01f, pwidth)) + offset);
480 if (phs > 1)
481 phs = fmod(phs, 1.f);
482 switch (mode) {
483 default:
484 case 0:
485 // sine
486 val = sin((phs * 360.f) * M_PI / 180);
487 break;
488 case 1:
489 // triangle
490 if(phs > 0.75)
491 val = (phs - 0.75) * 4 - 1;
492 else if(phs > 0.5)
493 val = (phs - 0.5) * 4 * -1;
494 else if(phs > 0.25)
495 val = 1 - (phs - 0.25) * 4;
496 else
497 val = phs * 4;
498 break;
499 case 2:
500 // square
501 val = (phs < 0.5) ? -1 : +1;
502 break;
503 case 3:
504 // saw up
505 val = phs * 2.f - 1;
506 break;
507 case 4:
508 // saw down
509 val = 1 - phs * 2.f;
510 break;
511 }
512 return val * amount;
513 }
514
advance(uint32_t count)515 void simple_lfo::advance(uint32_t count)
516 {
517 //this function walks from 0.f to 1.f and starts all over again
518 set_phase(phase + count * freq * (1.0 / srate));
519 }
520
set_phase(float ph)521 void simple_lfo::set_phase(float ph)
522 {
523 //set the phase from outsinde
524 phase = fabs(ph);
525 if (phase >= 1.0)
526 phase = fmod(phase, 1.f);
527 }
528
set_params(float f,int m,float o,uint32_t sr,float a,float p)529 void simple_lfo::set_params(float f, int m, float o, uint32_t sr, float a, float p)
530 {
531 // freq: a value in Hz
532 // mode: sine=0, triangle=1, square=2, saw_up=3, saw_down=4
533 // offset: value between 0.f and 1.f to offset the lfo in time
534 freq = f;
535 mode = m;
536 offset = o;
537 srate = sr;
538 amount = a;
539 pwidth = p;
540 }
set_freq(float f)541 void simple_lfo::set_freq(float f)
542 {
543 freq = f;
544 }
set_mode(int m)545 void simple_lfo::set_mode(int m)
546 {
547 mode = m;
548 }
set_offset(float o)549 void simple_lfo::set_offset(float o)
550 {
551 offset = o;
552 }
set_amount(float a)553 void simple_lfo::set_amount(float a)
554 {
555 amount = a;
556 }
set_pwidth(float p)557 void simple_lfo::set_pwidth(float p)
558 {
559 pwidth = p;
560 }
get_graph(float * data,int points,cairo_iface * context,int * mode) const561 bool simple_lfo::get_graph(float *data, int points, cairo_iface *context, int *mode) const
562 {
563 if (!is_active)
564 return false;
565 for (int i = 0; i < points; i++) {
566 float ph = (float)i / (float)points;
567 data[i] = get_value_from_phase(ph);
568 }
569 return true;
570 }
571
get_dot(float & x,float & y,int & size,cairo_iface * context) const572 bool simple_lfo::get_dot(float &x, float &y, int &size, cairo_iface *context) const
573 {
574 if (!is_active)
575 return false;
576 float phs = phase + offset;
577 if (phs >= 1.0)
578 phs = fmod(phs, 1.f);
579 x = phase;
580 y = get_value_from_phase(phase);
581 return true;
582 }
583
584
585 /// Lookahead Limiter by Christian Holschuh and Markus Schmidt
586
lookahead_limiter()587 lookahead_limiter::lookahead_limiter() {
588 is_active = false;
589 channels = 2;
590 id = 0;
591 buffer_size = 0;
592 overall_buffer_size = 0;
593 att = 1.f;
594 att_max = 1.0;
595 pos = 0;
596 delta = 0.f;
597 _delta = 0.f;
598 peak = 0.f;
599 over_s = 0;
600 over_c = 1.f;
601 attack = 0.005;
602 use_multi = false;
603 weight = 1.f;
604 _sanitize = false;
605 auto_release = false;
606 asc_active = false;
607 nextiter = 0;
608 nextlen = 0;
609 asc = 0.f;
610 asc_c = 0;
611 asc_pos = -1;
612 asc_changed = false;
613 asc_coeff = 1.f;
614 buffer = NULL;
615 nextpos = NULL;
616 nextdelta = NULL;
617 }
~lookahead_limiter()618 lookahead_limiter::~lookahead_limiter()
619 {
620 free(buffer);
621 free(nextpos);
622 free(nextdelta);
623 }
624
activate()625 void lookahead_limiter::activate()
626 {
627 is_active = true;
628 pos = 0;
629
630 }
631
set_multi(bool set)632 void lookahead_limiter::set_multi(bool set) { use_multi = set; }
633
deactivate()634 void lookahead_limiter::deactivate()
635 {
636 is_active = false;
637 }
638
get_attenuation()639 float lookahead_limiter::get_attenuation()
640 {
641 float a = att_max;
642 att_max = 1.0;
643 return a;
644 }
645
set_sample_rate(uint32_t sr)646 void lookahead_limiter::set_sample_rate(uint32_t sr)
647 {
648 srate = sr;
649
650 free(buffer);
651 free(nextpos);
652 free(nextdelta);
653
654 // rebuild buffer
655 overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size attack rate multiplied by 2 channels
656 buffer = (float*) calloc(overall_buffer_size, sizeof(float));
657 pos = 0;
658
659 nextdelta = (float*) calloc(overall_buffer_size, sizeof(float));
660 nextpos = (int*) malloc(overall_buffer_size * sizeof(int));
661 memset(nextpos, -1, overall_buffer_size * sizeof(int));
662
663 reset();
664 }
665
set_params(float l,float a,float r,float w,bool ar,float arc,bool d)666 void lookahead_limiter::set_params(float l, float a, float r, float w, bool ar, float arc, bool d)
667 {
668 limit = l;
669 attack = a / 1000.f;
670 release = r / 1000.f;
671 auto_release = ar;
672 asc_coeff = arc;
673 debug = d;
674 weight = w;
675 }
676
reset()677 void lookahead_limiter::reset() {
678 int bs = (int)(srate * attack * channels);
679 buffer_size = bs - bs % channels; // buffer size attack rate
680 _sanitize = true;
681 pos = 0;
682 nextpos[0] = -1;
683 nextlen = 0;
684 nextiter = 0;
685 delta = 0.f;
686 att = 1.f;
687 reset_asc();
688 }
689
reset_asc()690 void lookahead_limiter::reset_asc() {
691 asc = 0.f;
692 asc_c = 0;
693 asc_pos = pos;
694 asc_changed = true;
695 }
696
get_rdelta(float peak,float _limit,float _att,bool _asc)697 float lookahead_limiter::get_rdelta(float peak, float _limit, float _att, bool _asc) {
698
699 // calc the att for average input to walk to if we use asc (att of average signal)
700 float _a_att = (limit * weight) / (asc_coeff * asc) * (float)asc_c;
701
702 // calc a release delta from this attenuation
703 float _rdelta = (1.0 - _att) / (srate * release);
704 if(_asc && auto_release && asc_c > 0 && _a_att > _att) {
705 // check if releasing to average level of peaks is steeper than
706 // releasing to 1.f
707 float _delta = std::max((_a_att - _att) / (srate * release), _rdelta / 10);
708 if(_delta < _rdelta) {
709 asc_active = true;
710 _asc_used = true;
711 _rdelta = _delta;
712 }
713 }
714 return _rdelta;
715 }
716
process(float & left,float & right,float * multi_buffer)717 void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
718 {
719 // PROTIP: harming paying customers enough to make them develop a competing
720 // product may be considered an example of a less than sound business practice.
721
722 // fill lookahead buffer
723 if(_sanitize) {
724 // if we're sanitizing (zeroing) the buffer on attack time change,
725 // don't write the samples to the buffer
726 buffer[pos] = 0.f;
727 buffer[pos + 1] = 0.f;
728 } else {
729 buffer[pos] = left;
730 buffer[pos + 1] = right;
731 }
732
733 // are we using multiband? get the multiband coefficient or use 1.f
734 float multi_coeff = (use_multi) ? multi_buffer[pos] : 1.f;
735
736 // calc the real limit including weight and multi coeff
737 float _limit = limit * multi_coeff * weight;
738
739 // input peak - impact higher in left or right channel?
740 peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
741
742 // add an eventually appearing peak to the asc fake buffer if asc active
743 if(auto_release && peak > _limit) {
744 asc += peak;
745 asc_c ++;
746 }
747
748 if(peak > _limit || multi_coeff < 1.0) {
749 float _multi_coeff = 1.f;
750 float _peak;
751
752 // calc the attenuation needed to reduce incoming peak
753 float _att = std::min(_limit / peak, 1.f);
754 // calc release without any asc to keep all relevant peaks
755 float _rdelta = get_rdelta(peak, _limit, _att, false);
756
757 // calc the delta for walking to incoming peak attenuation
758 float _delta = (_limit / peak - att) / buffer_size * channels;
759
760 if(_delta < delta) {
761 // is the delta more important than the actual one?
762 // if so, we can forget about all stored deltas (because they can't
763 // be more important - we already checked that earlier) and use this
764 // delta now. and we have to create a release delta in nextpos buffer
765 nextpos[0] = pos;
766 nextpos[1] = -1;
767 nextdelta[0] = _rdelta;
768 nextlen = 1;
769 nextiter = 0;
770 delta = _delta;
771 } else {
772 // we have a peak on input its delta is less important than the
773 // actual delta. But what about the stored deltas we're following?
774 bool _found = false;
775 int i = 0;
776 for(i = nextiter; i < nextiter + nextlen; i++) {
777 // walk through our nextpos buffer
778 int j = i % buffer_size;
779 // calculate a delta for the next stored peak
780 // are we using multiband? then get the multi_coeff for the
781 // stored position
782 _multi_coeff = (use_multi) ? multi_buffer[nextpos[j]] : 1.f;
783 // is the left or the right channel on this position more
784 // important?
785 _peak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ? fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]);
786 // calc a delta to use to reach our incoming peak from the
787 // stored position
788 _delta = (_limit / peak - (limit * _multi_coeff * weight) / _peak) / (((buffer_size - nextpos[j] + pos) % buffer_size) / channels);
789 if(_delta < nextdelta[j]) {
790 // if the buffered delta is more important than the delta
791 // used to reach our peak from the stored position, store
792 // the new delta at that position and stop the loop
793 nextdelta[j] = _delta;
794 _found = true;
795 break;
796 }
797 }
798 if(_found) {
799 // there was something more important in the next-buffer.
800 // throw away any position and delta after the important
801 // position and add a new release delta
802 nextlen = i - nextiter + 1;
803 nextpos[(nextiter + nextlen) % buffer_size] = pos;
804 nextdelta[(nextiter + nextlen) % buffer_size] = _rdelta;
805 // set the next following position value to -1 (cleaning up the
806 // nextpos buffer)
807 nextpos[(nextiter + nextlen + 1) % buffer_size] = -1;
808 // and raise the length of our nextpos buffer for keeping the
809 // release value
810 nextlen ++;
811 }
812 }
813 }
814
815 // switch left and right pointers in buffer to output position
816 left = buffer[(pos + channels) % buffer_size];
817 right = buffer[(pos + channels + 1) % buffer_size];
818
819 // if a peak leaves the buffer, remove it from asc fake buffer
820 // but only if we're not sanitizing asc buffer
821 float _peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
822 float _multi_coeff = (use_multi) ? multi_buffer[(pos + channels) % buffer_size] : 1.f;
823 if(pos == asc_pos && !asc_changed) {
824 asc_pos = -1;
825 }
826 if(auto_release && asc_pos == -1 && _peak > (limit * weight * _multi_coeff)) {
827 asc -= _peak;
828 asc_c --;
829 }
830
831 // change the attenuation level
832 att += delta;
833
834 // ...and calculate outpout from it
835 left *= att;
836 right *= att;
837
838 if((pos + channels) % buffer_size == nextpos[nextiter]) {
839 // if we reach a buffered position, change the actual delta and erase
840 // this (the first) element from nextpos and nextdelta buffer
841 if(auto_release) {
842 // set delta to asc influenced release delta
843 delta = get_rdelta(_peak, (limit * weight * _multi_coeff), att);
844 if(nextlen > 1) {
845 // if there are more positions to walk to, calc delta to next
846 // position in buffer and compare it to release delta (keep
847 // changes between peaks below asc steepness)
848 int _nextpos = nextpos[(nextiter + 1) % buffer_size];
849 float __peak = fabs(buffer[_nextpos]) > fabs(buffer[_nextpos + 1]) ? fabs(buffer[_nextpos]) : fabs(buffer[_nextpos + 1]);
850 float __multi_coeff = (use_multi) ? multi_buffer[_nextpos] : 1.f;
851 float __delta = ((limit * __multi_coeff * weight) / __peak - att) / (((buffer_size + _nextpos - ((pos + channels) % buffer_size)) % buffer_size) / channels);
852 if(__delta < delta) {
853 delta = __delta;
854 }
855 }
856 } else {
857 // if no asc set delta from nextdelta buffer and fix the attenuation
858 delta = nextdelta[nextiter];
859 att = (limit * weight * _multi_coeff) / _peak;
860 }
861 // remove first element from circular nextpos buffer
862 nextlen -= 1;
863 nextpos[nextiter] = -1;
864 nextiter = (nextiter + 1) % buffer_size;
865 }
866
867 if (att > 1.0f) {
868 // release time seems over, reset attenuation and delta
869 att = 1.0f;
870 delta = 0.0f;
871 nextiter = 0;
872 nextlen = 0;
873 nextpos[0] = -1;
874 }
875
876 // main limiting party is over, let's cleanup the puke
877
878 if(_sanitize) {
879 // we're sanitizing? then send 0.f as output
880 left = 0.f;
881 right = 0.f;
882 }
883
884 // security personnel pawing your values
885 if(att <= 0.f) {
886 // if this happens we're doomed!!
887 // may happen on manually lowering attack
888 att = 0.0000000000001;
889 delta = (1.0f - att) / (srate * release);
890 }
891
892 if(att != 1.f && 1 - att < 0.0000000000001) {
893 // denormalize att
894 att = 1.f;
895 }
896
897 if(delta != 0.f && fabs(delta) < 0.00000000000001) {
898 // denormalize delta
899 delta = 0.f;
900 }
901
902 // post treatment (denormal, limit)
903 denormal(&left);
904 denormal(&right);
905
906 // store max attenuation for meter output
907 att_max = (att < att_max) ? att : att_max;
908
909 // step forward in our sample ring buffer
910 pos = (pos + channels) % buffer_size;
911
912 // sanitizing is always done after a full cycle through the lookahead buffer
913 if(_sanitize && pos == 0) _sanitize = false;
914
915 asc_changed = false;
916 }
917
get_asc()918 bool lookahead_limiter::get_asc() {
919 if(!asc_active) return false;
920 asc_active = false;
921 return true;
922 }
923
924
925 ////////////////////////////////////////////////////////////////////////////////
926
transients()927 transients::transients() {
928 envelope = 0.f;
929 attack = 0.f;
930 release = 0.f;
931 attack_coef = 0.f;
932 release_coef = 0.f;
933 att_time = 0.f;
934 att_level = 0.f;
935 rel_time = 0.f;
936 rel_level = 0.f;
937 sust_thres = 1.f;
938 maxdelta = 0.f;
939 new_return = 1.f;
940 old_return = 1.f;
941 lookahead = 0;
942 lookpos = 0;
943 channels = 1;
944 sustain_ended = false;
945 srand(1);
946 }
~transients()947 transients::~transients()
948 {
949 free(lookbuf);
950 }
set_channels(int ch)951 void transients::set_channels(int ch) {
952 channels = ch;
953 lookbuf = (float*) calloc(looksize * channels, sizeof(float));
954 lookpos = 0;
955 }
set_sample_rate(uint32_t sr)956 void transients::set_sample_rate(uint32_t sr) {
957 srate = sr;
958 attack_coef = exp(log(0.01) / (0.001 * srate));
959 release_coef = exp(log(0.01) / (0.2f * srate));
960 // due to new calculation in attack, we sometimes get harsh
961 // gain reduction/boost.
962 // to prevent "clicks" a maxdelta is set, which allows the signal
963 // to raise/fall ~6dB/ms.
964 maxdelta = pow(4, 1.f / (0.001 * srate));
965 calc_relfac();
966 }
set_params(float att_t,float att_l,float rel_t,float rel_l,float sust_th,int look)967 void transients::set_params(float att_t, float att_l, float rel_t, float rel_l, float sust_th, int look) {
968 lookahead = look;
969 sust_thres = sust_th;
970 att_time = att_t;
971 rel_time = rel_t;
972 att_level = att_l > 0 ? 0.25f * pow(att_l * 8, 2)
973 : -0.25f * pow(att_l * 4, 2);
974 rel_level = rel_l > 0 ? 0.5f * pow(rel_l * 8, 2)
975 : -0.25f * pow(rel_l * 4, 2);
976 calc_relfac();
977 }
calc_relfac()978 void transients::calc_relfac()
979 {
980 relfac = pow(0.5f, 1.f / (0.001 * rel_time * srate));
981 }
process(float * in,float s)982 void transients::process(float *in, float s) {
983 s = fabs(s) + 1e-10f * ((float)rand() / (float)RAND_MAX);
984 // fill lookahead buffer
985 for (int i = 0; i < channels; i++) {
986 lookbuf[lookpos + i] = in[i];
987 }
988
989 // envelope follower
990 // this is the real envelope follower curve. It raises as
991 // fast as the signal is raising and falls much slower
992 // depending on the sample rate and the ffactor
993 // (the falling factor)
994 if(s > envelope)
995 envelope = attack_coef * (envelope - s) + s;
996 else
997 envelope = release_coef * (envelope - s) + s;
998
999 // attack follower
1000 // this is a curve which follows the envelope slowly.
1001 // It never can rise above the envelope. It reaches 70.7%
1002 // of the envelope in a certain amount of time set by the user
1003
1004 double attdelta = (envelope - attack)
1005 * 0.707
1006 / (srate * att_time * 0.001);
1007 if (sustain_ended == true && envelope / attack - 1 > 0.2f)
1008 sustain_ended = false;
1009 attack += attdelta;
1010
1011 // never raise above envelope
1012 attack = std::min(envelope, attack);
1013
1014 // release follower
1015 // this is a curve which is always above the envelope. It
1016 // starts to fall when the envelope falls beneath the
1017 // sustain threshold
1018
1019 if ((envelope / release) - sust_thres < 0 && sustain_ended == false)
1020 sustain_ended = true;
1021 double reldelta = sustain_ended ? relfac : 1;
1022
1023 // release delta can never raise above 0
1024 release *= reldelta;
1025
1026 // never fall below envelope
1027 release = std::max(envelope, release);
1028
1029 // difference between attack and envelope
1030 double attdiff = attack > 0 ? log(envelope / attack) : 0;
1031
1032 // difference between release and envelope
1033 double reldiff = envelope > 0 ? log(release / envelope) : 0;
1034
1035 // amplification factor from attack and release curve
1036 double ampfactor = attdiff * att_level + reldiff * rel_level;
1037 old_return = new_return;
1038 new_return = 1 + (ampfactor < 0 ? std::max(-1 + 1e-15, exp(ampfactor) - 1) : ampfactor);
1039 if (new_return / old_return > maxdelta)
1040 new_return = old_return * maxdelta;
1041 else if (new_return / old_return < 1 / maxdelta)
1042 new_return = old_return / maxdelta;
1043
1044 int pos = (lookpos + looksize * channels - lookahead * channels) % (looksize * channels);
1045
1046 for (int i = 0; i < channels; i++)
1047 in[i] = lookbuf[pos + i] * new_return;
1048
1049 // advance lookpos
1050 lookpos = (lookpos + channels) % (looksize * channels);
1051 }
1052
1053
1054 //////////////////////////////////////////////////////////////////
1055
crossover()1056 crossover::crossover() {
1057 bands = -1;
1058 mode = -1;
1059 redraw_graph = 1;
1060 }
set_sample_rate(uint32_t sr)1061 void crossover::set_sample_rate(uint32_t sr) {
1062 srate = sr;
1063 }
init(int c,int b,uint32_t sr)1064 void crossover::init(int c, int b, uint32_t sr) {
1065 channels = std::min(8, c);
1066 bands = std::min(8, b);
1067 srate = sr;
1068 for(int b = 0; b < bands; b ++) {
1069 // reset frequency settings
1070 freq[b] = 1.0;
1071 active[b] = true;
1072 level[b] = 1.0;
1073 for (int c = 0; c < channels; c ++) {
1074 // reset outputs
1075 out[c][b] = 0.f;
1076 }
1077 }
1078 }
set_filter(int b,float f,bool force)1079 float crossover::set_filter(int b, float f, bool force) {
1080 // keep between neighbour bands
1081 if (b)
1082 f = std::max((float)freq[b-1] * 1.1f, f);
1083 if (b < bands - 2)
1084 f = std::min((float)freq[b+1] * 0.9f, f);
1085 // restrict to 10-20k
1086 f = std::max(10.f, std::min(20000.f, f));
1087 // nothing changed? return
1088 if (freq[b] == f && !force)
1089 return freq[b];
1090 freq[b] = f;
1091 float q;
1092 switch (mode) {
1093 case 0:
1094 default:
1095 q = 0.5;
1096 break;
1097 case 1:
1098 q = 0.7071068123730965;
1099 break;
1100 case 2:
1101 q = 0.54;
1102 break;
1103 }
1104 for (int c = 0; c < channels; c ++) {
1105 if (!c) {
1106 lp[c][b][0].set_lp_rbj(freq[b], q, (float)srate);
1107 hp[c][b][0].set_hp_rbj(freq[b], q, (float)srate);
1108 } else {
1109 lp[c][b][0].copy_coeffs(lp[c-1][b][0]);
1110 hp[c][b][0].copy_coeffs(hp[c-1][b][0]);
1111 }
1112 if (mode > 1) {
1113 if (!c) {
1114 lp[c][b][1].set_lp_rbj(freq[b], 1.34, (float)srate);
1115 hp[c][b][1].set_hp_rbj(freq[b], 1.34, (float)srate);
1116 } else {
1117 lp[c][b][1].copy_coeffs(lp[c-1][b][1]);
1118 hp[c][b][1].copy_coeffs(hp[c-1][b][1]);
1119 }
1120 lp[c][b][2].copy_coeffs(lp[c][b][0]);
1121 hp[c][b][2].copy_coeffs(hp[c][b][0]);
1122 lp[c][b][3].copy_coeffs(lp[c][b][1]);
1123 hp[c][b][3].copy_coeffs(hp[c][b][1]);
1124 } else {
1125 lp[c][b][1].copy_coeffs(lp[c][b][0]);
1126 hp[c][b][1].copy_coeffs(hp[c][b][0]);
1127 }
1128 }
1129 redraw_graph = std::min(2, redraw_graph + 1);
1130 return freq[b];
1131 }
set_mode(int m)1132 void crossover::set_mode(int m) {
1133 if(mode == m)
1134 return;
1135 mode = m;
1136 for(int i = 0; i < bands - 1; i ++) {
1137 set_filter(i, freq[i], true);
1138 }
1139 redraw_graph = std::min(2, redraw_graph + 1);
1140 }
set_active(int b,bool a)1141 void crossover::set_active(int b, bool a) {
1142 if (active[b] == a)
1143 return;
1144 active[b] = a;
1145 redraw_graph = std::min(2, redraw_graph + 1);
1146 }
set_level(int b,float l)1147 void crossover::set_level(int b, float l) {
1148 if (level[b] == l)
1149 return;
1150 level[b] = l;
1151 redraw_graph = std::min(2, redraw_graph + 1);
1152 }
process(float * data)1153 void crossover::process(float *data) {
1154 for (int c = 0; c < channels; c++) {
1155 for(int b = 0; b < bands; b ++) {
1156 out[c][b] = data[c];
1157 for (int f = 0; f < get_filter_count(); f++){
1158 if(b + 1 < bands) {
1159 out[c][b] = lp[c][b][f].process(out[c][b]);
1160 lp[c][b][f].sanitize();
1161 }
1162 if(b - 1 >= 0) {
1163 out[c][b] = hp[c][b - 1][f].process(out[c][b]);
1164 hp[c][b - 1][f].sanitize();
1165 }
1166 }
1167 out[c][b] *= level[b];
1168 }
1169 }
1170 }
get_value(int c,int b)1171 float crossover::get_value(int c, int b) {
1172 return out[c][b];
1173 }
get_graph(int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const1174 bool crossover::get_graph(int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1175 {
1176 if (subindex >= bands) {
1177 redraw_graph = std::max(0, redraw_graph - 1);
1178 return false;
1179 }
1180 float ret;
1181 double freq;
1182 for (int i = 0; i < points; i++) {
1183 ret = 1.f;
1184 freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
1185 for(int f = 0; f < get_filter_count(); f ++) {
1186 if(subindex < bands -1)
1187 ret *= lp[0][subindex][f].freq_gain(freq, (float)srate);
1188 if(subindex > 0)
1189 ret *= hp[0][subindex - 1][f].freq_gain(freq, (float)srate);
1190 }
1191 ret *= level[subindex];
1192 context->set_source_rgba(0.15, 0.2, 0.0, !active[subindex] ? 0.3 : 0.8);
1193 data[i] = dB_grid(ret);
1194 }
1195 return true;
1196 }
get_layers(int index,int generation,unsigned int & layers) const1197 bool crossover::get_layers(int index, int generation, unsigned int &layers) const
1198 {
1199 layers = 0 | (redraw_graph || !generation ? LG_CACHE_GRAPH : 0) | (!generation ? LG_CACHE_GRID : 0);
1200 return redraw_graph || !generation;
1201 }
1202
get_filter_count() const1203 int crossover::get_filter_count() const
1204 {
1205 switch (mode) {
1206 case 0:
1207 default:
1208 return 1;
1209 case 1:
1210 return 2;
1211 case 2:
1212 return 4;
1213 }
1214 }
1215
1216 //////////////////////////////////////////////////////////////////
1217
bitreduction()1218 bitreduction::bitreduction()
1219 {
1220 coeff = 1;
1221 morph = 0;
1222 mode = 0;
1223 dc = 0;
1224 sqr = 0;
1225 aa = 0;
1226 aa1 = 0;
1227 redraw_graph = true;
1228 bypass = true;
1229 }
set_sample_rate(uint32_t sr)1230 void bitreduction::set_sample_rate(uint32_t sr)
1231 {
1232 srate = sr;
1233 }
set_params(float b,float mo,bool bp,uint32_t md,float d,float a)1234 void bitreduction::set_params(float b, float mo, bool bp, uint32_t md, float d, float a)
1235 {
1236 morph = 1 - mo;
1237 bypass = bp;
1238 dc = d;
1239 aa = a;
1240 mode = md;
1241 coeff = powf(2.0f, b) - 1;
1242 sqr = sqrt(coeff / 2);
1243 aa1 = (1.f - aa) / 2.f;
1244 redraw_graph = true;
1245 }
add_dc(float s,float dc) const1246 float bitreduction::add_dc(float s, float dc) const
1247 {
1248 return s > 0 ? s *= dc : s /= dc;
1249 }
remove_dc(float s,float dc) const1250 float bitreduction::remove_dc(float s, float dc) const
1251 {
1252 return s > 0 ? s /= dc : s *= dc;
1253 }
waveshape(float in) const1254 float bitreduction::waveshape(float in) const
1255 {
1256 double y;
1257 double k;
1258
1259 // add dc
1260 in = add_dc(in, dc);
1261
1262 // main rounding calculation depending on mode
1263
1264 // the idea for anti-aliasing:
1265 // you need a function f which brings you to the scale, where you want to round
1266 // and the function f_b (with f(f_b)=id) which brings you back to your original scale.
1267 //
1268 // then you can use the logic below in the following way:
1269 // y = f(in) and k = roundf(y)
1270 // if (y > k + aa1)
1271 // k = f_b(k) + ( f_b(k+1) - f_b(k) ) *0.5 * (sin(x - PI/2) + 1)
1272 // if (y < k + aa1)
1273 // k = f_b(k) - ( f_b(k+1) - f_b(k) ) *0.5 * (sin(x - PI/2) + 1)
1274 //
1275 // whereas x = (fabs(f(in) - k) - aa1) * PI / aa
1276 // for both cases.
1277
1278 switch (mode) {
1279 case 0:
1280 default:
1281 // linear
1282 y = (in) * coeff;
1283 k = roundf(y);
1284 if (k - aa1 <= y && y <= k + aa1) {
1285 k /= coeff;
1286 } else if (y > k + aa1) {
1287 k = k / coeff + ((k + 1) / coeff - k / coeff) * 0.5 * (sin(M_PI * (fabs(y - k) - aa1) / aa - M_PI_2) + 1);
1288 } else {
1289 k = k / coeff - (k / coeff - (k - 1) / coeff) * 0.5 * (sin(M_PI * (fabs(y - k) - aa1) / aa - M_PI_2) + 1);
1290 }
1291 break;
1292 case 1:
1293 // logarithmic
1294 y = sqr * log(fabs(in)) + sqr * sqr;
1295 k = roundf(y);
1296 if(!in) {
1297 k = 0;
1298 } else if (k - aa1 <= y && y <= k + aa1) {
1299 k = in / fabs(in) * exp(k / sqr - sqr);
1300 } else if (y > k + aa1) {
1301 k = in / fabs(in) * (exp(k / sqr - sqr) + (exp((k + 1) / sqr - sqr) - exp(k / sqr - sqr)) * 0.5 * (sin((fabs(y - k) - aa1) / aa * M_PI - M_PI_2) + 1));
1302 } else {
1303 k = in / fabs(in) * (exp(k / sqr - sqr) - (exp(k / sqr - sqr) - exp((k - 1) / sqr - sqr)) * 0.5 * (sin((fabs(y - k) - aa1) / aa * M_PI - M_PI_2) + 1));
1304 }
1305 break;
1306 }
1307
1308 // morph between dry and wet signal
1309 k += (in - k) * morph;
1310
1311 // remove dc
1312 k = remove_dc(k, dc);
1313
1314 return k;
1315 }
process(float in)1316 float bitreduction::process(float in)
1317 {
1318 return waveshape(in);
1319 }
1320
get_layers(int index,int generation,unsigned int & layers) const1321 bool bitreduction::get_layers(int index, int generation, unsigned int &layers) const
1322 {
1323 layers = redraw_graph || !generation ? LG_CACHE_GRAPH | LG_CACHE_GRID : 0;
1324 return redraw_graph || !generation;
1325 }
get_graph(int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const1326 bool bitreduction::get_graph(int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1327 {
1328 if (subindex >= 2) {
1329 redraw_graph = false;
1330 return false;
1331 }
1332 for (int i = 0; i < points; i++) {
1333 data[i] = sin(((float)i / (float)points * 360.) * M_PI / 180.);
1334 if (subindex && !bypass)
1335 data[i] = waveshape(data[i]);
1336 else {
1337 context->set_line_width(1);
1338 context->set_source_rgba(0.15, 0.2, 0.0, 0.15);
1339 }
1340 }
1341 return true;
1342 }
get_gridline(int subindex,int phase,float & pos,bool & vertical,std::string & legend,cairo_iface * context) const1343 bool bitreduction::get_gridline(int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
1344 {
1345 if (phase || subindex)
1346 return false;
1347 pos = 0;
1348 vertical = false;
1349 return true;
1350 }
1351
1352 //////////////////////////////////////////////////////////////////
1353
resampleN()1354 resampleN::resampleN()
1355 {
1356 factor = 2;
1357 srate = 0;
1358 filters = 2;
1359 }
~resampleN()1360 resampleN::~resampleN()
1361 {
1362 }
set_params(uint32_t sr,int fctr=2,int fltrs=2)1363 void resampleN::set_params(uint32_t sr, int fctr = 2, int fltrs = 2)
1364 {
1365 srate = std::max(2u, sr);
1366 factor = std::min(16, std::max(1, fctr));
1367 filters = std::min(4, std::max(1, fltrs));
1368 // set all filters
1369 filter[0][0].set_lp_rbj(std::max(25000., (double)srate / 2), 0.8, (float)srate * factor);
1370 for (int i = 1; i < filters; i++) {
1371 filter[0][i].copy_coeffs(filter[0][0]);
1372 filter[1][i].copy_coeffs(filter[0][0]);
1373 }
1374 }
upsample(double sample)1375 double *resampleN::upsample(double sample)
1376 {
1377 tmp[0] = sample;
1378 if (factor > 1) {
1379 for (int f = 0; f < filters; f++)
1380 tmp[0] = filter[0][f].process(sample);
1381 for (int i = 1; i < factor; i++) {
1382 tmp[i] = 0;
1383 for (int f = 0; f < filters; f++)
1384 tmp[i] = filter[0][f].process(sample);
1385 }
1386 }
1387 return tmp;
1388 }
downsample(double * sample)1389 double resampleN::downsample(double *sample)
1390 {
1391 if (factor > 1) {
1392 for(int i = 0; i < factor; i++) {
1393 for (int f = 0; f < filters; f++) {
1394 sample[i] = filter[1][f].process(sample[i]);
1395 }
1396 }
1397 }
1398 return sample[0];
1399 }
1400
1401 //////////////////////////////////////////////////////////////////
1402
samplereduction()1403 samplereduction::samplereduction()
1404 {
1405 target = 0;
1406 real = 0;
1407 samples = 0;
1408 last = 0;
1409 amount = 0;
1410 round = 0;
1411 }
set_params(float am)1412 void samplereduction::set_params(float am)
1413 {
1414 amount = am;
1415 round = roundf(amount);
1416 //samples = round;
1417 }
process(double in)1418 double samplereduction::process(double in)
1419 {
1420 samples ++;
1421 if (samples >= round) {
1422 target += amount;
1423 real += round;
1424 if (target + amount >= real + 1) {
1425 last = in;
1426 target = 0;
1427 real = 0;
1428 }
1429 samples = 0;
1430 }
1431 return last;
1432 }
1433