2 * Reusable audio effect classes.
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
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.
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.
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
21 #ifndef CALF_AUDIOFX_H
22 #define CALF_AUDIOFX_H
26 #include "fixed_point.h"
32 namespace calf_plugins
{
38 }; to keep editor happy
42 * Audio effect base class. Not really useful until it gets more developed.
47 virtual void setup(int sample_rate
)=0;
48 virtual ~audio_effect() {}
51 class modulation_effect
: public audio_effect
55 float rate
, wet
, dry
, odsr
;
56 gain_smoothing gs_wet
, gs_dry
;
58 fixed_point
<unsigned int, 20> phase
, dphase
;
59 float get_rate() const {
62 void set_rate(float rate
) {
64 dphase
= rate
/sample_rate
*4096;
66 float get_wet() const {
69 void set_wet(float wet
) {
71 gs_wet
.set_inertia(wet
);
73 float get_dry() const {
76 void set_dry(float dry
) {
78 gs_dry
.set_inertia(dry
);
80 void reset_phase(float req_phase
)
82 phase
= req_phase
* 4096.0;
84 void inc_phase(float req_phase
)
86 phase
+= fixed_point
<unsigned int, 20>(req_phase
* 4096.0);
88 void setup(int sample_rate
)
90 this->sample_rate
= sample_rate
;
91 this->odsr
= 1.0 / sample_rate
;
98 * A monophonic phaser. If you want stereo, combine two :)
99 * Also, gave up on using template args for signal type.
101 class simple_phaser
: public modulation_effect
104 float base_frq
, mod_depth
, fb
;
106 int cnt
, stages
, max_stages
;
107 dsp::onepole
<float, float> stage1
;
110 simple_phaser(int _max_stages
, float *x1vals
, float *y1vals
);
112 float get_base_frq() const {
115 void set_base_frq(float _base_frq
) {
116 base_frq
= _base_frq
;
118 int get_stages() const {
121 void set_stages(int _stages
);
123 float get_mod_depth() const {
126 void set_mod_depth(float _mod_depth
) {
127 mod_depth
= _mod_depth
;
130 float get_fb() const {
133 void set_fb(float fb
) {
137 virtual void setup(int sample_rate
) {
138 modulation_effect::setup(sample_rate
);
143 void process(float *buf_out
, float *buf_in
, int nsamples
);
144 float freq_gain(float freq
, float sr
) const;
148 * Base class for chorus and flanger. Wouldn't be needed if it wasn't
149 * for odd behaviour of GCC when deriving templates from template
150 * base classes (not seeing fields from base classes!).
152 class chorus_base
: public modulation_effect
155 int min_delay_samples
, mod_depth_samples
;
156 float min_delay
, mod_depth
;
157 sine_table
<int, 4096, 65536> sine
;
159 float get_min_delay() const {
162 void set_min_delay(float min_delay
) {
163 this->min_delay
= min_delay
;
164 this->min_delay_samples
= (int)(min_delay
* 65536.0 * sample_rate
);
166 float get_mod_depth() const {
169 void set_mod_depth(float mod_depth
) {
170 this->mod_depth
= mod_depth
;
171 // 128 because it's then multiplied by (hopefully) a value of 32768..-32767
172 this->mod_depth_samples
= (int)(mod_depth
* 32.0 * sample_rate
);
177 * Single-tap chorus without feedback.
178 * Perhaps MaxDelay should be a bit longer!
180 template<class T
, int MaxDelay
=512>
181 class simple_chorus
: public chorus_base
184 simple_delay
<MaxDelay
,T
> delay
;
197 virtual void setup(int sample_rate
) {
198 modulation_effect::setup(sample_rate
);
200 set_min_delay(get_min_delay());
201 set_mod_depth(get_mod_depth());
203 template<class OutIter
, class InIter
>
204 void process(OutIter buf_out
, InIter buf_in
, int nsamples
) {
205 int mds
= min_delay_samples
+ mod_depth_samples
* 1024 + 2*65536;
206 int mdepth
= mod_depth_samples
;
207 for (int i
=0; i
<nsamples
; i
++) {
209 unsigned int ipart
= phase
.ipart();
211 float in
= *buf_in
++;
212 int lfo
= phase
.lerp_by_fract_int
<int, 14, int>(sine
.data
[ipart
], sine
.data
[ipart
+1]);
213 int v
= mds
+ (mdepth
* lfo
>> 6);
214 // if (!(i & 7)) printf("%d\n", v);
217 T fd
; // signal from delay's output
218 delay
.get_interp(fd
, ifv
, (v
& 0xFFFF)*(1.0/65536.0));
219 T sdry
= in
* gs_dry
.get();
220 T swet
= fd
* gs_wet
.get();
221 *buf_out
++ = sdry
+ swet
;
227 * Single-tap flanger (chorus plus feedback).
229 template<class T
, int MaxDelay
=1024>
230 class simple_flanger
: public chorus_base
233 simple_delay
<MaxDelay
,T
> delay
;
235 int last_delay_pos
, last_actual_delay_pos
;
236 int ramp_pos
, ramp_delay_pos
;
242 last_delay_pos
= last_actual_delay_pos
= ramp_delay_pos
= 0;
245 virtual void setup(int sample_rate
) {
246 this->sample_rate
= sample_rate
;
247 this->odsr
= 1.0 / sample_rate
;
250 set_rate(get_rate());
251 set_min_delay(get_min_delay());
253 float get_fb() const {
256 void set_fb(float fb
) {
259 template<class OutIter
, class InIter
>
260 void process(OutIter buf_out
, InIter buf_in
, int nsamples
) {
263 int mds
= this->min_delay_samples
+ this->mod_depth_samples
* 1024 + 2 * 65536;
264 int mdepth
= this->mod_depth_samples
;
266 unsigned int ipart
= this->phase
.ipart();
267 int lfo
= phase
.lerp_by_fract_int
<int, 14, int>(this->sine
.data
[ipart
], this->sine
.data
[ipart
+1]);
268 delay_pos
= mds
+ (mdepth
* lfo
>> 6);
270 if (delay_pos
!= last_delay_pos
|| ramp_pos
< 1024)
272 if (delay_pos
!= last_delay_pos
) {
273 // we need to ramp from what the delay tap length actually was,
274 // not from old (ramp_delay_pos) or desired (delay_pos) tap length
275 ramp_delay_pos
= last_actual_delay_pos
;
280 for (int i
=0; i
<nsamples
; i
++) {
281 float in
= *buf_in
++;
282 T fd
; // signal from delay's output
283 dp
= (((int64_t)ramp_delay_pos
) * (1024 - ramp_pos
) + ((int64_t)delay_pos
) * ramp_pos
) >> 10;
285 if (ramp_pos
> 1024) ramp_pos
= 1024;
286 this->delay
.get_interp(fd
, dp
>> 16, (dp
& 0xFFFF)*(1.0/65536.0));
288 T sdry
= in
* this->dry
;
289 T swet
= fd
* this->wet
;
290 *buf_out
++ = sdry
+ swet
;
291 this->delay
.put(in
+fb
*fd
);
293 this->phase
+= this->dphase
;
294 ipart
= this->phase
.ipart();
295 lfo
= phase
.lerp_by_fract_int
<int, 14, int>(this->sine
.data
[ipart
], this->sine
.data
[ipart
+1]);
296 delay_pos
= mds
+ (mdepth
* lfo
>> 6);
298 last_actual_delay_pos
= dp
;
301 for (int i
=0; i
<nsamples
; i
++) {
302 float in
= *buf_in
++;
303 T fd
; // signal from delay's output
304 this->delay
.get_interp(fd
, delay_pos
>> 16, (delay_pos
& 0xFFFF)*(1.0/65536.0));
306 T sdry
= in
* this->gs_dry
.get();
307 T swet
= fd
* this->gs_wet
.get();
308 *buf_out
++ = sdry
+ swet
;
309 this->delay
.put(in
+fb
*fd
);
311 this->phase
+= this->dphase
;
312 ipart
= this->phase
.ipart();
313 lfo
= phase
.lerp_by_fract_int
<int, 14, int>(this->sine
.data
[ipart
], this->sine
.data
[ipart
+1]);
314 delay_pos
= mds
+ (mdepth
* lfo
>> 6);
316 last_actual_delay_pos
= delay_pos
;
318 last_delay_pos
= delay_pos
;
320 float freq_gain(float freq
, float sr
) const
322 typedef std::complex<double> cfloat
;
323 freq
*= 2.0 * M_PI
/ sr
;
324 cfloat z
= 1.0 / exp(cfloat(0.0, freq
)); // z^-1
326 float ldp
= last_delay_pos
/ 65536.0;
327 float fldp
= floor(ldp
);
328 cfloat zn
= std::pow(z
, fldp
); // z^-N
329 cfloat zn1
= zn
* z
; // z^-(N+1)
330 // simulate a lerped comb filter - H(z) = 1 / (1 + fb * (lerp(z^-N, z^-(N+1), fracpos))), N = int(pos), fracpos = pos - int(pos)
331 cfloat delayed
= zn
+ (zn1
- zn
) * cfloat(ldp
- fldp
);
332 cfloat h
= cfloat(delayed
) / (cfloat(1.0) - cfloat(fb
) * delayed
);
333 // mix with dry signal
334 float v
= std::abs(cfloat(gs_dry
.get_last()) + cfloat(gs_wet
.get_last()) * h
);
340 * A classic allpass loop reverb with modulated allpass filter.
341 * Just started implementing it, so there is no control over many
344 class reverb
: public audio_effect
346 simple_delay
<2048, float> apL1
, apL2
, apL3
, apL4
, apL5
, apL6
;
347 simple_delay
<2048, float> apR1
, apR2
, apR3
, apR4
, apR5
, apR6
;
348 fixed_point
<unsigned int, 25> phase
, dphase
;
349 sine_table
<int, 128, 10000> sine
;
350 onepole
<float> lp_left
, lp_right
;
351 float old_left
, old_right
;
353 float time
, fb
, cutoff
, diffusion
;
355 float ldec
[6], rdec
[6];
368 virtual void setup(int sample_rate
) {
377 float get_time() const {
380 void set_time(float time
) {
382 // fb = pow(1.0f/4096.0f, (float)(1700/(time*sr)));
383 fb
= 1.0 - 0.3 / (time
* sr
/ 44100.0);
385 float get_type() const {
388 void set_type(int type
) {
392 float get_diffusion() const {
395 void set_diffusion(float diffusion
) {
396 this->diffusion
= diffusion
;
399 void set_type_and_diffusion(int type
, float diffusion
) {
401 this->diffusion
= diffusion
;
408 void set_fb(float fb
)
412 float get_cutoff() const {
415 void set_cutoff(float cutoff
) {
416 this->cutoff
= cutoff
;
417 lp_left
.set_lp(cutoff
,sr
);
418 lp_right
.set_lp(cutoff
,sr
);
421 void process(float &left
, float &right
);
422 void extra_sanitize()
429 class filter_module_iface
432 virtual void calculate_filter(float freq
, float q
, int mode
, float gain
= 1.0) = 0;
433 virtual void filter_activate() = 0;
434 virtual void sanitize() = 0;
435 virtual int process_channel(uint16_t channel_no
, const float *in
, float *out
, uint32_t numsamples
, int inmask
) = 0;
436 virtual float freq_gain(int subindex
, float freq
, float srate
) const = 0;
438 virtual ~filter_module_iface() {}
442 class biquad_filter_module
: public filter_module_iface
445 dsp::biquad_d1 left
[3], right
[3];
451 enum { mode_12db_lp
= 0, mode_24db_lp
= 1, mode_36db_lp
= 2,
452 mode_12db_hp
= 3, mode_24db_hp
= 4, mode_36db_hp
= 5,
453 mode_6db_bp
= 6, mode_12db_bp
= 7, mode_18db_bp
= 8,
454 mode_6db_br
= 9, mode_12db_br
= 10, mode_18db_br
= 11,
459 biquad_filter_module()
461 /// Calculate filter coefficients based on parameters - cutoff/center frequency, q, filter type, output gain
462 void calculate_filter(float freq
, float q
, int mode
, float gain
= 1.0);
463 /// Reset filter state
464 void filter_activate();
467 /// Process a single channel (float buffer) of data
468 int process_channel(uint16_t channel_no
, const float *in
, float *out
, uint32_t numsamples
, int inmask
);
469 /// Determine gain (|H(z)|) for a given frequency
470 float freq_gain(int subindex
, float freq
, float srate
) const;
476 dsp::onepole
<float> lowcut
, highcut
;
477 float low_gain
, high_gain
;
486 inline float process(float v
)
488 v
= dsp::lerp(lowcut
.process_hp(v
), v
, low_gain
);
489 v
= dsp::lerp(highcut
.process_lp(v
), v
, high_gain
);
493 inline void copy_coeffs(const two_band_eq
&src
)
495 lowcut
.copy_coeffs(src
.lowcut
);
496 highcut
.copy_coeffs(src
.highcut
);
497 low_gain
= src
.low_gain
;
498 high_gain
= src
.high_gain
;
507 void set(float _low_freq
, float _low_gain
, float _high_freq
, float _high_gain
, float sr
)
509 lowcut
.set_hp(_low_freq
, sr
);
510 highcut
.set_lp(_high_freq
, sr
);
511 low_gain
= _low_gain
;
512 high_gain
= _high_gain
;
516 /// LFO module by Markus
517 /// This module provides simple LFO's (sine=0, triangle=1, square=2, saw_up=3, saw_down=4)
518 /// get_value() returns a value between -1 and 1
521 float phase
, freq
, offset
, amount
;
527 void set_params(float f
, int m
, float o
, uint32_t sr
, float amount
= 1.f
);
528 void set_freq(float f
);
529 void set_mode(int m
);
530 void set_amount(float a
);
531 void set_offset(float o
);
533 void advance(uint32_t count
);
534 void set_phase(float ph
);
537 float get_value_from_phase(float ph
, float off
) const;
538 bool get_graph(float *data
, int points
, calf_plugins::cairo_iface
*context
, int *mode
) const;
539 bool get_dot(float &x
, float &y
, int &size
, calf_plugins::cairo_iface
*context
) const;
543 /// Lookahead Limiter by Markus Schmidt and Christian Holschuh
544 class lookahead_limiter
{
547 float limit
, attack
, release
, weight
;
549 float att
; // a coefficient the output is multiplied with
550 float att_max
; // a memory for the highest attenuation - used for display
551 int pos
; // where we are actually in our sample buffer
553 int overall_buffer_size
;
578 static inline void denormal(volatile float *f
) {
582 inline float get_rdelta(float peak
, float _limit
, float _att
, bool _asc
= true);
587 ~lookahead_limiter();
588 void set_multi(bool set
);
589 void process(float &left
, float &right
, float *multi_buffer
);
590 void set_sample_rate(uint32_t sr
);
591 void set_params(float l
, float a
, float r
, float weight
= 1.f
, bool ar
= false, float arc
= 1.f
, bool d
= false);
592 float get_attenuation();
599 float attack_coef
, release_coef
;
601 float envelope
, attack
, release
;
603 float old_return
, new_return
, maxdelta
, relfac
;
604 float att_time
, att_level
, rel_time
, rel_level
, sust_thres
, mix
;
605 static const int looksize
= 101;
606 int lookahead
, lookpos
;
613 void process(float *in
);
614 void waveshape(float *in
);
615 void set_channels(int ch
);
616 void set_sample_rate(uint32_t sr
);
617 void set_params(float att_t
, float att_l
, float rel_t
, float rel_l
, float sust_th
, int look
, float mix
);
625 int channels
, bands
, mode
;
626 float freq
[8], active
[8], level
[8], out
[8][8];
627 dsp::biquad_d2 lp
[8][8][4], hp
[8][8][4];
628 mutable int redraw_graph
;
631 void process(float *data
);
632 float get_value(int c
, int b
);
633 void set_sample_rate(uint32_t sr
);
634 float set_filter(int b
, float f
, bool force
= false);
635 void set_level(int b
, float l
);
636 void set_active(int b
, bool a
);
637 void set_mode(int m
);
638 int get_filter_count() const;
639 void init(int c
, int b
, uint32_t sr
);
640 virtual bool get_graph(int subindex
, int phase
, float *data
, int points
, calf_plugins::cairo_iface
*context
, int *mode
) const;
641 bool get_layers(int index
, int generation
, unsigned int &layers
) const;
648 float morph
, coeff
, dc
, sqr
, aa
, aa1
;
650 uint32_t mode
, srate
;
651 mutable bool redraw_graph
;
653 void set_sample_rate(uint32_t sr
);
654 float add_dc(float s
, float dc
) const;
655 float remove_dc(float s
, float dc
) const;
656 void set_params(float b
, float m
, bool bp
, uint32_t mode
, float dc
, float aa
);
657 float waveshape(float in
) const;
658 float process(float in
);
659 virtual bool get_graph(int subindex
, int phase
, float *data
, int points
, calf_plugins::cairo_iface
*context
, int *mode
) const;
660 bool get_layers(int index
, int generation
, unsigned int &layers
) const;
661 bool get_gridline(int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, calf_plugins::cairo_iface
*context
) const;
668 uint32_t srate
; // sample rate; source for upsampling, target for downsampling
669 int factor
; // number of added/removed samples, max 16
670 int filters
; // how many lowpasses should be used, max 4
672 dsp::biquad_d2 filter
[2][4];
675 void set_params(uint32_t sr
, int factor
, int filters
);
676 double *upsample(double sample
);
677 double downsample(double *sample
);
680 class samplereduction
684 float target
, real
, amount
;
685 uint samples
, round
, cnt
;
688 void set_params(float am
);
689 double process(double in
);
693 /// Tom Szilagyi's distortion code, used with permission
694 /// KF: I'm not 100% sure how this is supposed to work, but it does.
695 /// I'm planning to rewrite it using more modular approach when I have more time.
696 class tap_distortion
{
698 float blend_old
, drive_old
;
700 float rdrive
, rbdr
, kpa
, kpb
, kna
, knb
, ap
, an
, imr
, kc
, srct
, sq
, pwrq
;
702 float prev_med
, prev_out
;
710 void set_params(float blend
, float drive
);
711 void set_sample_rate(uint32_t sr
);
712 float process(float in
);
713 float get_distortion_level();
714 static inline float M(float x
)
716 return (fabs(x
) > 0.00000001f
) ? x
: 0.0f
;
719 static inline float D(float x
)
722 return (x
> 0.00000001f
) ? sqrtf(x
) : 0.0f
;
727 { to keep editor happy