[SCM] calf/master: More de-inlinization and refactoring.
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:01 UTC 2013
The following commit has been merged in the master branch:
commit 75c235ae66f0784f0ccbd70c84ff04775222f9d3
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Mon Apr 5 14:24:22 2010 +0100
More de-inlinization and refactoring.
This reduces dependencies, which should reduce build times a little bit in
some scenarios (like finetuning of details in DSP code).
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 6bce138..51e1695 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -85,40 +85,8 @@ public:
is_active = false;
}
void set_sample_rate(uint32_t sr);
- void params_changed() {
- float dry = *params[par_dryamount];
- float wet = *params[par_amount];
- float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
- float min_delay = *params[par_delay] / 1000.0;
- float mod_depth = *params[par_depth] / 1000.0;
- float fb = *params[par_fb];
- left.set_dry(dry); right.set_dry(dry);
- left.set_wet(wet); right.set_wet(wet);
- left.set_rate(rate); right.set_rate(rate);
- left.set_min_delay(min_delay); right.set_min_delay(min_delay);
- left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
- left.set_fb(fb); right.set_fb(fb);
- float r_phase = *params[par_stereo] * (1.f / 360.f);
- clear_reset = false;
- if (*params[par_reset] >= 0.5) {
- clear_reset = true;
- left.reset_phase(0.f);
- right.reset_phase(r_phase);
- } else {
- if (fabs(r_phase - last_r_phase) > 0.0001f) {
- right.phase = left.phase;
- right.inc_phase(r_phase);
- last_r_phase = r_phase;
- }
- }
- }
- void params_reset()
- {
- if (clear_reset) {
- *params[par_reset] = 0.f;
- clear_reset = false;
- }
- }
+ void params_changed();
+ void params_reset();
void activate();
void deactivate();
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
@@ -145,42 +113,8 @@ public:
phaser_audio_module() {
is_active = false;
}
- void params_changed() {
- float dry = *params[par_dryamount];
- float wet = *params[par_amount];
- float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
- float base_frq = *params[par_freq];
- float mod_depth = *params[par_depth];
- float fb = *params[par_fb];
- int stages = (int)*params[par_stages];
- left.set_dry(dry); right.set_dry(dry);
- left.set_wet(wet); right.set_wet(wet);
- left.set_rate(rate); right.set_rate(rate);
- left.set_base_frq(base_frq); right.set_base_frq(base_frq);
- left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
- left.set_fb(fb); right.set_fb(fb);
- left.set_stages(stages); right.set_stages(stages);
- float r_phase = *params[par_stereo] * (1.f / 360.f);
- clear_reset = false;
- if (*params[par_reset] >= 0.5) {
- clear_reset = true;
- left.reset_phase(0.f);
- right.reset_phase(r_phase);
- } else {
- if (fabs(r_phase - last_r_phase) > 0.0001f) {
- right.phase = left.phase;
- right.inc_phase(r_phase);
- last_r_phase = r_phase;
- }
- }
- }
- void params_reset()
- {
- if (clear_reset) {
- *params[par_reset] = 0.f;
- clear_reset = false;
- }
- }
+ void params_changed();
+ void params_reset();
void activate();
void set_sample_rate(uint32_t sr);
void deactivate();
@@ -209,57 +143,8 @@ public:
float *outs[out_count];
float *params[param_count];
- void params_changed() {
- //reverb.set_time(0.5*pow(8.0f, *params[par_decay]));
- //reverb.set_cutoff(2000*pow(10.0f, *params[par_hfdamp]));
- reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
- reverb.set_time(*params[par_decay]);
- reverb.set_cutoff(*params[par_hfdamp]);
- amount.set_inertia(*params[par_amount]);
- dryamount.set_inertia(*params[par_dry]);
- left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
- left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
- right_lo.copy_coeffs(left_lo);
- right_hi.copy_coeffs(left_hi);
- predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1);
- }
- uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
- numsamples += offset;
- clip -= std::min(clip, numsamples);
- for (uint32_t i = offset; i < numsamples; i++) {
- float dry = dryamount.get();
- float wet = amount.get();
- stereo_sample<float> s(ins[0][i], ins[1][i]);
- stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
-
- float rl = s2.left, rr = s2.right;
- rl = left_lo.process(left_hi.process(rl));
- rr = right_lo.process(right_hi.process(rr));
- reverb.process(rl, rr);
- outs[0][i] = dry*s.left + wet*rl;
- outs[1][i] = dry*s.right + wet*rr;
- meter_wet = std::max(fabs(wet*rl), fabs(wet*rr));
- meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i]));
- if(outs[0][i] > 1.f or outs[1][i] > 1.f) {
- clip = srate >> 3;
- }
- }
- reverb.extra_sanitize();
- left_lo.sanitize();
- left_hi.sanitize();
- right_lo.sanitize();
- right_hi.sanitize();
- if(params[par_meter_wet] != NULL) {
- *params[par_meter_wet] = meter_wet;
- }
- if(params[par_meter_out] != NULL) {
- *params[par_meter_out] = meter_out;
- }
- if(params[par_clip] != NULL) {
- *params[par_clip] = clip;
- }
- return outputs_mask;
- }
+ void params_changed();
+ uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
void activate();
void set_sample_rate(uint32_t sr);
void deactivate();
@@ -285,124 +170,14 @@ public:
uint32_t srate;
- vintage_delay_audio_module()
- {
- old_medium = -1;
- for (int i = 0; i < MAX_DELAY; i++) {
- buffers[0][i] = 0.f;
- buffers[1][i] = 0.f;
- }
- }
+ vintage_delay_audio_module();
- void params_changed()
- {
- float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
- deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
- deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
- amt_left.set_inertia(*params[par_amount]); amt_right.set_inertia(*params[par_amount]);
- float fb = *params[par_feedback];
- dry = *params[par_dryamount];
- mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
- medium = dsp::fastf2i_drm(*params[par_medium]);
- if (mixmode == 0)
- {
- fb_left.set_inertia(fb);
- fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
- } else {
- fb_left.set_inertia(fb);
- fb_right.set_inertia(fb);
- }
- if (medium != old_medium)
- calc_filters();
- }
- void activate() {
- bufptr = 0;
- age = 0;
- }
- void deactivate() {
- }
- void set_sample_rate(uint32_t sr) {
- srate = sr;
- old_medium = -1;
- amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
- fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
- }
- void calc_filters()
- {
- // parameters are heavily influenced by gordonjcp and his tape delay unit
- // although, don't blame him if it sounds bad - I've messed with them too :)
- biquad_left[0].set_lp_rbj(6000, 0.707, srate);
- biquad_left[1].set_bp_rbj(4500, 0.250, srate);
- biquad_right[0].copy_coeffs(biquad_left[0]);
- biquad_right[1].copy_coeffs(biquad_left[1]);
- }
- uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
- uint32_t ostate = 3; // XXXKF optimize!
- uint32_t end = offset + numsamples;
- int v = mixmode ? 1 : 0;
- int orig_bufptr = bufptr;
- for(uint32_t i = offset; i < end; i++)
- {
- float out_left, out_right, del_left, del_right;
- // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
-
- if (deltime_l >= age) {
- del_left = ins[0][i];
- out_left = dry * del_left;
- amt_left.step();
- fb_left.step();
- }
- else
- {
- float in_left = buffers[v][(bufptr - deltime_l) & ADDR_MASK];
- dsp::sanitize(in_left);
- out_left = dry * ins[0][i] + in_left * amt_left.get();
- del_left = ins[0][i] + in_left * fb_left.get();
- }
- if (deltime_r >= age) {
- del_right = ins[1][i];
- out_right = dry * del_right;
- amt_right.step();
- fb_right.step();
- }
- else
- {
- float in_right = buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK];
- dsp::sanitize(in_right);
- out_right = dry * ins[1][i] + in_right * amt_right.get();
- del_right = ins[1][i] + in_right * fb_right.get();
- }
-
- age++;
- outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
- bufptr = (bufptr + 1) & (MAX_DELAY - 1);
- }
- if (age >= MAX_DELAY)
- age = MAX_DELAY;
- if (medium > 0) {
- bufptr = orig_bufptr;
- if (medium == 2)
- {
- for(uint32_t i = offset; i < end; i++)
- {
- buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
- buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
- bufptr = (bufptr + 1) & (MAX_DELAY - 1);
- }
- biquad_left[0].sanitize();biquad_right[0].sanitize();
- } else {
- for(uint32_t i = offset; i < end; i++)
- {
- buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
- buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
- bufptr = (bufptr + 1) & (MAX_DELAY - 1);
- }
- }
- biquad_left[1].sanitize();biquad_right[1].sanitize();
-
- }
- return ostate;
- }
+ void params_changed();
+ void activate();
+ void deactivate();
+ void set_sample_rate(uint32_t sr);
+ void calc_filters();
+ uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
};
class rotary_speaker_audio_module: public audio_module<rotary_speaker_metadata>
@@ -441,133 +216,16 @@ public:
void activate();
void deactivate();
- void params_changed() {
- set_vibrato();
- }
- void set_vibrato()
- {
- vibrato_mode = fastf2i_drm(*params[par_speed]);
- // manual vibrato - do not recalculate speeds as they're not used anyway
- if (vibrato_mode == 5)
- return;
- if (!vibrato_mode)
- dspeed = -1;
- else {
- float speed = vibrato_mode - 1;
- if (vibrato_mode == 3)
- speed = hold_value;
- if (vibrato_mode == 4)
- speed = mwhl_value;
- dspeed = (speed < 0.5f) ? 0 : 1;
- }
- update_speed();
- }
+ void params_changed();
+ void set_vibrato();
/// Convert RPM speed to delta-phase
- inline uint32_t rpm2dphase(float rpm)
- {
- return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2;
- }
+ uint32_t rpm2dphase(float rpm);
/// Set delta-phase variables based on current calculated (and interpolated) RPM speed
- void update_speed()
- {
- float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h));
- float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l));
- dphase_h = rpm2dphase(speed_h);
- dphase_l = rpm2dphase(speed_l);
- }
- void update_speed_manual(float delta)
- {
- float ts = *params[par_treblespeed];
- float bs = *params[par_bassspeed];
- incr_towards(maspeed_h, ts, delta * 200, delta * 200);
- incr_towards(maspeed_l, bs, delta * 200, delta * 200);
- dphase_h = rpm2dphase(maspeed_h);
- dphase_l = rpm2dphase(maspeed_l);
- }
- /// map a ramp [int] to a sinusoid-like function [0, 65536]
- static inline int pseudo_sine_scl(int counter)
- {
- // premature optimization is a root of all evil; it can be done with integers only - but later :)
- double v = counter * (1.0 / (65536.0 * 32768.0));
- return (int) (32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849));
- }
+ void update_speed();
+ void update_speed_manual(float delta);
/// Increase or decrease aspeed towards raspeed, with required negative and positive rate
- inline bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc)
- {
- if (aspeed < raspeed) {
- aspeed = std::min(raspeed, aspeed + delta_acc);
- return true;
- }
- else if (aspeed > raspeed)
- {
- aspeed = std::max(raspeed, aspeed - delta_decc);
- return true;
- }
- return false;
- }
- uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
- {
- int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
- int md = (int)(100 * (*params[par_moddepth]));
- float mix = 0.5 * (1.0 - *params[par_micdistance]);
- float mix2 = *params[par_reflection];
- float mix3 = mix2 * mix2;
- for (unsigned int i = 0; i < nsamples; i++) {
- float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
- float in_mono = 0.5f * (in_l + in_r);
-
- int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000);
- int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000);
- // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
- meter_l = xl;
- meter_h = xh;
- // float out_hi_l = in_mono - delay.get_interp_1616(shift + md * xh) + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) - delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
- // float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - delay.get_interp_1616(shift + pdelta + md * xh) + delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
- float out_hi_l = in_mono + delay.get_interp_1616(shift + md * xh) - mix2 * delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) + mix3 * delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
- float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - mix2 * delay.get_interp_1616(shift + pdelta + md * xh) + mix3 * delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
-
- float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
- float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
-
- out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
- out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
- out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
- out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
-
- float out_l = out_hi_l + out_lo_l;
- float out_r = out_hi_r + out_lo_r;
-
- float mic_l = out_l + mix * (out_r - out_l);
- float mic_r = out_r + mix * (out_l - out_r);
-
- outs[0][i + offset] = mic_l * 0.5f;
- outs[1][i + offset] = mic_r * 0.5f;
- delay.put(in_mono);
- phase_l += dphase_l;
- phase_h += dphase_h;
- }
- crossover1l.sanitize();
- crossover1r.sanitize();
- crossover2l.sanitize();
- crossover2r.sanitize();
- float delta = nsamples * 1.0 / srate;
- if (vibrato_mode == 5)
- update_speed_manual(delta);
- else
- {
- bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14);
- bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5);
- if (u1 || u2)
- set_vibrato();
- }
- if(params[par_meter_l] != NULL) {
- *params[par_meter_l] = (float)meter_l / 65536.0;
- }
- if(params[par_meter_h] != NULL) {
- *params[par_meter_h] = (float)meter_h / 65536.0;
- }
- return outputs_mask;
- }
+ bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc);
+ uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask);
virtual void control_change(int ctl, int val);
};
@@ -728,47 +386,9 @@ public:
bool is_active;
public:
- multichorus_audio_module()
- {
- is_active = false;
- last_r_phase = -1;
- }
-
- void params_changed()
- {
- // delicious copy-pasta from flanger module - it'd be better to keep it common or something
- float dry = *params[par_dryamount];
- float wet = *params[par_amount];
- float rate = *params[par_rate];
- float min_delay = *params[par_delay] / 1000.0;
- float mod_depth = *params[par_depth] / 1000.0;
- float overlap = *params[par_overlap];
- left.set_dry(dry); right.set_dry(dry);
- left.set_wet(wet); right.set_wet(wet);
- left.set_rate(rate); right.set_rate(rate);
- left.set_min_delay(min_delay); right.set_min_delay(min_delay);
- left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
- int voices = (int)*params[par_voices];
- left.lfo.set_voices(voices); right.lfo.set_voices(voices);
- left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap);
- float vphase = *params[par_vphase] * (1.f / 360.f);
- left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
- float r_phase = *params[par_stereo] * (1.f / 360.f);
- if (fabs(r_phase - last_r_phase) > 0.0001f) {
- right.lfo.phase = left.lfo.phase;
- right.lfo.phase += chorus_phase(r_phase * 4096);
- last_r_phase = r_phase;
- }
- left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate);
- left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate);
- right.post.f1.copy_coeffs(left.post.f1);
- right.post.f2.copy_coeffs(left.post.f2);
- }
- uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
- left.process(outs[0] + offset, ins[0] + offset, numsamples);
- right.process(outs[1] + offset, ins[1] + offset, numsamples);
- return outputs_mask; // XXXKF allow some delay after input going blank
- }
+ multichorus_audio_module();
+ void params_changed();
+ uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
void activate();
void deactivate();
void set_sample_rate(uint32_t sr);
@@ -778,7 +398,9 @@ public:
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
};
-class gain_reduction_audio_module {
+/// Not a true _audio_module style class, just pretends to be one!
+class gain_reduction_audio_module
+{
private:
float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop;
float compressedKneeStop, adjKneeStart, thres;
@@ -793,22 +415,23 @@ public:
gain_reduction_audio_module();
void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu);
void update_curve();
- void process(float &left, float &right, float det_left = NULL, float det_right = NULL);
+ void process(float &left, float &right, const float *det_left = NULL, const float *det_right = NULL);
void activate();
void deactivate();
int id;
void set_sample_rate(uint32_t sr);
float get_output_level();
float get_comp_level();
- virtual bool get_graph(int subindex, float *data, int points, cairo_iface *context) const;
- virtual bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const;
- virtual bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
- virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
+ bool get_graph(int subindex, float *data, int points, cairo_iface *context) const;
+ bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const;
+ bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
+ int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const;
};
/// Compressor by Thor
class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
private:
+ typedef compressor_audio_module AM;
uint32_t clip_in, clip_out;
float meter_in, meter_out;
gain_reduction_audio_module compressor;
@@ -835,6 +458,7 @@ public:
/// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters)
class sidechaincompressor_audio_module: public audio_module<sidechaincompressor_metadata>, public frequency_response_line_graph {
private:
+ typedef sidechaincompressor_audio_module AM;
enum CalfScModes {
WIDEBAND,
DEESSER_WIDE,
@@ -868,38 +492,8 @@ public:
void activate();
void deactivate();
void params_changed();
- inline cfloat h_z(const cfloat &z) const {
- switch (sc_mode) {
- default:
- case WIDEBAND:
- return false;
- break;
- case DEESSER_WIDE:
- case DERUMBLER_WIDE:
- case WEIGHTED_1:
- case WEIGHTED_2:
- case WEIGHTED_3:
- case BANDPASS_2:
- return f1L.h_z(z) * f2L.h_z(z);
- break;
- case DEESSER_SPLIT:
- return f2L.h_z(z);
- break;
- case DERUMBLER_SPLIT:
- case BANDPASS_1:
- return f1L.h_z(z);
- break;
- }
-
- }
- float freq_gain(int index, double freq, uint32_t sr) const
- {
- typedef std::complex<double> cfloat;
- freq *= 2.0 * M_PI / sr;
- cfloat z = 1.0 / exp(cfloat(0.0, freq));
-
- return std::abs(h_z(z));
- }
+ cfloat h_z(const cfloat &z) const;
+ float freq_gain(int index, double freq, uint32_t sr) const;
void set_sample_rate(uint32_t sr);
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
@@ -1050,6 +644,7 @@ public:
/// Pulsator by Markus Schmidt
class pulsator_audio_module: public audio_module<pulsator_metadata>, public frequency_response_line_graph {
private:
+ typedef pulsator_audio_module AM;
uint32_t clip_inL, clip_inR, clip_outL, clip_outR;
float meter_inL, meter_inR, meter_outL, meter_outR;
float offset_old;
@@ -1093,101 +688,20 @@ class filterclavier_audio_module:
int last_velocity;
public:
- filterclavier_audio_module()
- :
- min_gain(1.0),
- max_gain(32.0),
- last_note(-1),
- last_velocity(-1) {}
-
- void params_changed()
- {
- inertia_filter_module::inertia_cutoff.set_inertia(
- note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
-
- float min_resonance = param_props[par_max_resonance].min;
- inertia_filter_module::inertia_resonance.set_inertia(
- (float(last_velocity) / 127.0)
- // 0.001: see below
- * (*params[par_max_resonance] - min_resonance + 0.001)
- + min_resonance);
-
- adjust_gain_according_to_filter_mode(last_velocity);
-
- inertia_filter_module::calculate_filter();
- }
-
- void activate()
- {
- inertia_filter_module::activate();
- }
-
- void set_sample_rate(uint32_t sr)
- {
- inertia_filter_module::set_sample_rate(sr);
- }
-
-
- void deactivate()
- {
- inertia_filter_module::deactivate();
- }
+ filterclavier_audio_module();
+ void params_changed();
+ void activate();
+ void set_sample_rate(uint32_t sr);
+ void deactivate();
/// MIDI control
- virtual void note_on(int note, int vel)
- {
- last_note = note;
- last_velocity = vel;
- inertia_filter_module::inertia_cutoff.set_inertia(
- note_to_hz(note + *params[par_transpose], *params[par_detune]));
-
- float min_resonance = param_props[par_max_resonance].min;
- inertia_filter_module::inertia_resonance.set_inertia(
- (float(vel) / 127.0)
- // 0.001: if the difference is equal to zero (which happens
- // when the max_resonance knom is at minimum position
- // then the filter gain doesnt seem to snap to zero on most note offs
- * (*params[par_max_resonance] - min_resonance + 0.001)
- + min_resonance);
-
- adjust_gain_according_to_filter_mode(vel);
-
- inertia_filter_module::calculate_filter();
- }
+ virtual void note_on(int note, int vel);
+ virtual void note_off(int note, int vel);
- virtual void note_off(int note, int vel)
- {
- if (note == last_note) {
- inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
- inertia_filter_module::inertia_gain.set_inertia(min_gain);
- inertia_filter_module::calculate_filter();
- last_velocity = 0;
- }
- }
-
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
private:
- void adjust_gain_according_to_filter_mode(int velocity) {
- int mode = dsp::fastf2i_drm(*params[par_mode]);
-
- // for bandpasses: boost gain for velocities > 0
- if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
- // gain for velocity 0: 1.0
- // gain for velocity 127: 32.0
- float mode_max_gain = max_gain;
- // max_gain is right for mode_6db_bp
- if (mode == mode_12db_bp)
- mode_max_gain /= 6.0;
- if (mode == mode_18db_bp)
- mode_max_gain /= 10.5;
-
- inertia_filter_module::inertia_gain.set_now(
- (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
- } else {
- inertia_filter_module::inertia_gain.set_now(min_gain);
- }
- }
+ void adjust_gain_according_to_filter_mode(int velocity);
};
extern std::string get_builtin_modules_rdf();
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index 69b98ed..0e6543b 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -87,6 +87,43 @@ float flanger_audio_module::freq_gain(int subindex, float freq, float srate) con
return (subindex ? right : left).freq_gain(freq, srate);
}
+void flanger_audio_module::params_changed()
+{
+ float dry = *params[par_dryamount];
+ float wet = *params[par_amount];
+ float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
+ float min_delay = *params[par_delay] / 1000.0;
+ float mod_depth = *params[par_depth] / 1000.0;
+ float fb = *params[par_fb];
+ left.set_dry(dry); right.set_dry(dry);
+ left.set_wet(wet); right.set_wet(wet);
+ left.set_rate(rate); right.set_rate(rate);
+ left.set_min_delay(min_delay); right.set_min_delay(min_delay);
+ left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
+ left.set_fb(fb); right.set_fb(fb);
+ float r_phase = *params[par_stereo] * (1.f / 360.f);
+ clear_reset = false;
+ if (*params[par_reset] >= 0.5) {
+ clear_reset = true;
+ left.reset_phase(0.f);
+ right.reset_phase(r_phase);
+ } else {
+ if (fabs(r_phase - last_r_phase) > 0.0001f) {
+ right.phase = left.phase;
+ right.inc_phase(r_phase);
+ last_r_phase = r_phase;
+ }
+ }
+}
+
+void flanger_audio_module::params_reset()
+{
+ if (clear_reset) {
+ *params[par_reset] = 0.f;
+ clear_reset = false;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////
void phaser_audio_module::set_sample_rate(uint32_t sr)
@@ -133,6 +170,45 @@ bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool
return get_freq_gridline(subindex, pos, vertical, legend, context);
}
+void phaser_audio_module::params_changed()
+{
+ float dry = *params[par_dryamount];
+ float wet = *params[par_amount];
+ float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
+ float base_frq = *params[par_freq];
+ float mod_depth = *params[par_depth];
+ float fb = *params[par_fb];
+ int stages = (int)*params[par_stages];
+ left.set_dry(dry); right.set_dry(dry);
+ left.set_wet(wet); right.set_wet(wet);
+ left.set_rate(rate); right.set_rate(rate);
+ left.set_base_frq(base_frq); right.set_base_frq(base_frq);
+ left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
+ left.set_fb(fb); right.set_fb(fb);
+ left.set_stages(stages); right.set_stages(stages);
+ float r_phase = *params[par_stereo] * (1.f / 360.f);
+ clear_reset = false;
+ if (*params[par_reset] >= 0.5) {
+ clear_reset = true;
+ left.reset_phase(0.f);
+ right.reset_phase(r_phase);
+ } else {
+ if (fabs(r_phase - last_r_phase) > 0.0001f) {
+ right.phase = left.phase;
+ right.inc_phase(r_phase);
+ last_r_phase = r_phase;
+ }
+ }
+}
+
+void phaser_audio_module::params_reset()
+{
+ if (clear_reset) {
+ *params[par_reset] = 0.f;
+ clear_reset = false;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////
void reverb_audio_module::activate()
@@ -151,6 +227,189 @@ void reverb_audio_module::set_sample_rate(uint32_t sr)
amount.set_sample_rate(sr);
}
+void reverb_audio_module::params_changed()
+{
+ reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
+ reverb.set_time(*params[par_decay]);
+ reverb.set_cutoff(*params[par_hfdamp]);
+ amount.set_inertia(*params[par_amount]);
+ dryamount.set_inertia(*params[par_dry]);
+ left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
+ left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
+ right_lo.copy_coeffs(left_lo);
+ right_hi.copy_coeffs(left_hi);
+ predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1);
+}
+
+uint32_t reverb_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+ numsamples += offset;
+ clip -= std::min(clip, numsamples);
+ for (uint32_t i = offset; i < numsamples; i++) {
+ float dry = dryamount.get();
+ float wet = amount.get();
+ stereo_sample<float> s(ins[0][i], ins[1][i]);
+ stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
+
+ float rl = s2.left, rr = s2.right;
+ rl = left_lo.process(left_hi.process(rl));
+ rr = right_lo.process(right_hi.process(rr));
+ reverb.process(rl, rr);
+ outs[0][i] = dry*s.left + wet*rl;
+ outs[1][i] = dry*s.right + wet*rr;
+ meter_wet = std::max(fabs(wet*rl), fabs(wet*rr));
+ meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i]));
+ if(outs[0][i] > 1.f or outs[1][i] > 1.f) {
+ clip = srate >> 3;
+ }
+ }
+ reverb.extra_sanitize();
+ left_lo.sanitize();
+ left_hi.sanitize();
+ right_lo.sanitize();
+ right_hi.sanitize();
+ if(params[par_meter_wet] != NULL) {
+ *params[par_meter_wet] = meter_wet;
+ }
+ if(params[par_meter_out] != NULL) {
+ *params[par_meter_out] = meter_out;
+ }
+ if(params[par_clip] != NULL) {
+ *params[par_clip] = clip;
+ }
+ return outputs_mask;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+vintage_delay_audio_module::vintage_delay_audio_module()
+{
+ old_medium = -1;
+ for (int i = 0; i < MAX_DELAY; i++) {
+ buffers[0][i] = 0.f;
+ buffers[1][i] = 0.f;
+ }
+}
+
+void vintage_delay_audio_module::params_changed()
+{
+ float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
+ deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
+ deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
+ amt_left.set_inertia(*params[par_amount]); amt_right.set_inertia(*params[par_amount]);
+ float fb = *params[par_feedback];
+ dry = *params[par_dryamount];
+ mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
+ medium = dsp::fastf2i_drm(*params[par_medium]);
+ if (mixmode == 0)
+ {
+ fb_left.set_inertia(fb);
+ fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
+ } else {
+ fb_left.set_inertia(fb);
+ fb_right.set_inertia(fb);
+ }
+ if (medium != old_medium)
+ calc_filters();
+}
+
+void vintage_delay_audio_module::activate()
+{
+ bufptr = 0;
+ age = 0;
+}
+
+void vintage_delay_audio_module::deactivate()
+{
+}
+
+void vintage_delay_audio_module::set_sample_rate(uint32_t sr)
+{
+ srate = sr;
+ old_medium = -1;
+ amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
+ fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
+}
+
+void vintage_delay_audio_module::calc_filters()
+{
+ // parameters are heavily influenced by gordonjcp and his tape delay unit
+ // although, don't blame him if it sounds bad - I've messed with them too :)
+ biquad_left[0].set_lp_rbj(6000, 0.707, srate);
+ biquad_left[1].set_bp_rbj(4500, 0.250, srate);
+ biquad_right[0].copy_coeffs(biquad_left[0]);
+ biquad_right[1].copy_coeffs(biquad_left[1]);
+}
+
+uint32_t vintage_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+ uint32_t ostate = 3; // XXXKF optimize!
+ uint32_t end = offset + numsamples;
+ int v = mixmode ? 1 : 0;
+ int orig_bufptr = bufptr;
+ for(uint32_t i = offset; i < end; i++)
+ {
+ float out_left, out_right, del_left, del_right;
+ // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
+
+ if (deltime_l >= age) {
+ del_left = ins[0][i];
+ out_left = dry * del_left;
+ amt_left.step();
+ fb_left.step();
+ }
+ else
+ {
+ float in_left = buffers[v][(bufptr - deltime_l) & ADDR_MASK];
+ dsp::sanitize(in_left);
+ out_left = dry * ins[0][i] + in_left * amt_left.get();
+ del_left = ins[0][i] + in_left * fb_left.get();
+ }
+ if (deltime_r >= age) {
+ del_right = ins[1][i];
+ out_right = dry * del_right;
+ amt_right.step();
+ fb_right.step();
+ }
+ else
+ {
+ float in_right = buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK];
+ dsp::sanitize(in_right);
+ out_right = dry * ins[1][i] + in_right * amt_right.get();
+ del_right = ins[1][i] + in_right * fb_right.get();
+ }
+
+ age++;
+ outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
+ bufptr = (bufptr + 1) & (MAX_DELAY - 1);
+ }
+ if (age >= MAX_DELAY)
+ age = MAX_DELAY;
+ if (medium > 0) {
+ bufptr = orig_bufptr;
+ if (medium == 2)
+ {
+ for(uint32_t i = offset; i < end; i++)
+ {
+ buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
+ buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
+ bufptr = (bufptr + 1) & (MAX_DELAY - 1);
+ }
+ biquad_left[0].sanitize();biquad_right[0].sanitize();
+ } else {
+ for(uint32_t i = offset; i < end; i++)
+ {
+ buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
+ buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
+ bufptr = (bufptr + 1) & (MAX_DELAY - 1);
+ }
+ }
+ biquad_left[1].sanitize();biquad_right[1].sanitize();
+
+ }
+ return ostate;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////
bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
@@ -188,6 +447,100 @@ int filter_audio_module::get_changed_offsets(int index, int generation, int &sub
///////////////////////////////////////////////////////////////////////////////////////////////
+filterclavier_audio_module::filterclavier_audio_module()
+: min_gain(1.0)
+, max_gain(32.0)
+, last_note(-1)
+, last_velocity(-1)
+{
+}
+
+void filterclavier_audio_module::params_changed()
+{
+ inertia_filter_module::inertia_cutoff.set_inertia(
+ note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
+
+ float min_resonance = param_props[par_max_resonance].min;
+ inertia_filter_module::inertia_resonance.set_inertia(
+ (float(last_velocity) / 127.0)
+ // 0.001: see below
+ * (*params[par_max_resonance] - min_resonance + 0.001)
+ + min_resonance);
+
+ adjust_gain_according_to_filter_mode(last_velocity);
+
+ inertia_filter_module::calculate_filter();
+}
+
+void filterclavier_audio_module::activate()
+{
+ inertia_filter_module::activate();
+}
+
+void filterclavier_audio_module::set_sample_rate(uint32_t sr)
+{
+ inertia_filter_module::set_sample_rate(sr);
+}
+
+void filterclavier_audio_module::deactivate()
+{
+ inertia_filter_module::deactivate();
+}
+
+
+void filterclavier_audio_module::note_on(int note, int vel)
+{
+ last_note = note;
+ last_velocity = vel;
+ inertia_filter_module::inertia_cutoff.set_inertia(
+ note_to_hz(note + *params[par_transpose], *params[par_detune]));
+
+ float min_resonance = param_props[par_max_resonance].min;
+ inertia_filter_module::inertia_resonance.set_inertia(
+ (float(vel) / 127.0)
+ // 0.001: if the difference is equal to zero (which happens
+ // when the max_resonance knom is at minimum position
+ // then the filter gain doesnt seem to snap to zero on most note offs
+ * (*params[par_max_resonance] - min_resonance + 0.001)
+ + min_resonance);
+
+ adjust_gain_according_to_filter_mode(vel);
+
+ inertia_filter_module::calculate_filter();
+}
+
+void filterclavier_audio_module::note_off(int note, int vel)
+{
+ if (note == last_note) {
+ inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
+ inertia_filter_module::inertia_gain.set_inertia(min_gain);
+ inertia_filter_module::calculate_filter();
+ last_velocity = 0;
+ }
+}
+
+void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity)
+{
+ int mode = dsp::fastf2i_drm(*params[par_mode]);
+
+ // for bandpasses: boost gain for velocities > 0
+ if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
+ // gain for velocity 0: 1.0
+ // gain for velocity 127: 32.0
+ float mode_max_gain = max_gain;
+ // max_gain is right for mode_6db_bp
+ if (mode == mode_12db_bp)
+ mode_max_gain /= 6.0;
+ if (mode == mode_18db_bp)
+ mode_max_gain /= 10.5;
+
+ inertia_filter_module::inertia_gain.set_now(
+ (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
+ } else {
+ inertia_filter_module::inertia_gain.set_now(min_gain);
+ }
+}
+
bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
{
if (!is_active || index != par_mode) {
@@ -200,6 +553,7 @@ bool filterclavier_audio_module::get_graph(int index, int subindex, float *data,
return false;
}
+
///////////////////////////////////////////////////////////////////////////////////////////////
rotary_speaker_audio_module::rotary_speaker_audio_module()
@@ -252,8 +606,151 @@ void rotary_speaker_audio_module::control_change(int ctl, int val)
}
}
+void rotary_speaker_audio_module::params_changed()
+{
+ set_vibrato();
+}
+
+void rotary_speaker_audio_module::set_vibrato()
+{
+ vibrato_mode = fastf2i_drm(*params[par_speed]);
+ // manual vibrato - do not recalculate speeds as they're not used anyway
+ if (vibrato_mode == 5)
+ return;
+ if (!vibrato_mode)
+ dspeed = -1;
+ else {
+ float speed = vibrato_mode - 1;
+ if (vibrato_mode == 3)
+ speed = hold_value;
+ if (vibrato_mode == 4)
+ speed = mwhl_value;
+ dspeed = (speed < 0.5f) ? 0 : 1;
+ }
+ update_speed();
+}
+
+/// Convert RPM speed to delta-phase
+uint32_t rotary_speaker_audio_module::rpm2dphase(float rpm)
+{
+ return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2;
+}
+
+/// Set delta-phase variables based on current calculated (and interpolated) RPM speed
+void rotary_speaker_audio_module::update_speed()
+{
+ float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h));
+ float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l));
+ dphase_h = rpm2dphase(speed_h);
+ dphase_l = rpm2dphase(speed_l);
+}
+
+void rotary_speaker_audio_module::update_speed_manual(float delta)
+{
+ float ts = *params[par_treblespeed];
+ float bs = *params[par_bassspeed];
+ incr_towards(maspeed_h, ts, delta * 200, delta * 200);
+ incr_towards(maspeed_l, bs, delta * 200, delta * 200);
+ dphase_h = rpm2dphase(maspeed_h);
+ dphase_l = rpm2dphase(maspeed_l);
+}
+
+/// map a ramp [int] to a sinusoid-like function [0, 65536]
+static inline int pseudo_sine_scl(int counter)
+{
+ // premature optimization is a root of all evil; it can be done with integers only - but later :)
+ double v = counter * (1.0 / (65536.0 * 32768.0));
+ return (int) (32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849));
+}
+
+/// Increase or decrease aspeed towards raspeed, with required negative and positive rate
+inline bool rotary_speaker_audio_module::incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc)
+{
+ if (aspeed < raspeed) {
+ aspeed = std::min(raspeed, aspeed + delta_acc);
+ return true;
+ }
+ else if (aspeed > raspeed)
+ {
+ aspeed = std::max(raspeed, aspeed - delta_decc);
+ return true;
+ }
+ return false;
+}
+
+uint32_t rotary_speaker_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+ int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
+ int md = (int)(100 * (*params[par_moddepth]));
+ float mix = 0.5 * (1.0 - *params[par_micdistance]);
+ float mix2 = *params[par_reflection];
+ float mix3 = mix2 * mix2;
+ for (unsigned int i = 0; i < nsamples; i++) {
+ float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
+ float in_mono = 0.5f * (in_l + in_r);
+
+ int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000);
+ int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000);
+ // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
+ meter_l = xl;
+ meter_h = xh;
+ // float out_hi_l = in_mono - delay.get_interp_1616(shift + md * xh) + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) - delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
+ // float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - delay.get_interp_1616(shift + pdelta + md * xh) + delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
+ float out_hi_l = in_mono + delay.get_interp_1616(shift + md * xh) - mix2 * delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) + mix3 * delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
+ float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - mix2 * delay.get_interp_1616(shift + pdelta + md * xh) + mix3 * delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
+
+ float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
+ float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
+
+ out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
+ out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
+ out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
+ out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
+
+ float out_l = out_hi_l + out_lo_l;
+ float out_r = out_hi_r + out_lo_r;
+
+ float mic_l = out_l + mix * (out_r - out_l);
+ float mic_r = out_r + mix * (out_l - out_r);
+
+ outs[0][i + offset] = mic_l * 0.5f;
+ outs[1][i + offset] = mic_r * 0.5f;
+ delay.put(in_mono);
+ phase_l += dphase_l;
+ phase_h += dphase_h;
+ }
+ crossover1l.sanitize();
+ crossover1r.sanitize();
+ crossover2l.sanitize();
+ crossover2r.sanitize();
+ float delta = nsamples * 1.0 / srate;
+ if (vibrato_mode == 5)
+ update_speed_manual(delta);
+ else
+ {
+ bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14);
+ bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5);
+ if (u1 || u2)
+ set_vibrato();
+ }
+ if(params[par_meter_l] != NULL) {
+ *params[par_meter_l] = (float)meter_l / 65536.0;
+ }
+ if(params[par_meter_h] != NULL) {
+ *params[par_meter_h] = (float)meter_h / 65536.0;
+ }
+ return outputs_mask;
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////
+multichorus_audio_module::multichorus_audio_module()
+{
+ is_active = false;
+ last_r_phase = -1;
+}
+
void multichorus_audio_module::activate()
{
is_active = true;
@@ -347,6 +844,46 @@ float multichorus_audio_module::freq_gain(int subindex, float freq, float srate)
return (subindex ? right : left).freq_gain(freq, srate);
}
+void multichorus_audio_module::params_changed()
+{
+ // delicious copy-pasta from flanger module - it'd be better to keep it common or something
+ float dry = *params[par_dryamount];
+ float wet = *params[par_amount];
+ float rate = *params[par_rate];
+ float min_delay = *params[par_delay] / 1000.0;
+ float mod_depth = *params[par_depth] / 1000.0;
+ float overlap = *params[par_overlap];
+ left.set_dry(dry); right.set_dry(dry);
+ left.set_wet(wet); right.set_wet(wet);
+ left.set_rate(rate); right.set_rate(rate);
+ left.set_min_delay(min_delay); right.set_min_delay(min_delay);
+ left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
+ int voices = (int)*params[par_voices];
+ left.lfo.set_voices(voices); right.lfo.set_voices(voices);
+ left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap);
+ float vphase = *params[par_vphase] * (1.f / 360.f);
+ left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
+ float r_phase = *params[par_stereo] * (1.f / 360.f);
+ if (fabs(r_phase - last_r_phase) > 0.0001f) {
+ right.lfo.phase = left.lfo.phase;
+ right.lfo.phase += chorus_phase(r_phase * 4096);
+ last_r_phase = r_phase;
+ }
+ left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate);
+ left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate);
+ right.post.f1.copy_coeffs(left.post.f1);
+ right.post.f2.copy_coeffs(left.post.f2);
+}
+
+uint32_t multichorus_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+ left.process(outs[0] + offset, ins[0] + offset, numsamples);
+ right.process(outs[1] + offset, ins[1] + offset, numsamples);
+ return outputs_mask; // XXXKF allow some delay after input going blank
+}
+
+
+
/// Multibandcompressor by Markus Schmidt
///
/// This module splits the signal in four different bands
@@ -746,10 +1283,8 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples,
float leftAC = inL;
float rightAC = inR;
- float leftSC = inL;
- float rightSC = inR;
- compressor.process(leftAC, rightAC, leftSC, rightSC);
+ compressor.process(leftAC, rightAC);
outL = leftAC;
outR = rightAC;
@@ -774,18 +1309,10 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples,
} // cycle trough samples
}
// draw meters
- if(params[param_clip_in] != NULL) {
- *params[param_clip_in] = clip_in;
- }
- if(params[param_clip_out] != NULL) {
- *params[param_clip_out] = clip_out;
- }
- if(params[param_meter_in] != NULL) {
- *params[param_meter_in] = meter_in;
- }
- if(params[param_meter_out] != NULL) {
- *params[param_meter_out] = meter_out;
- }
+ SET_IF_CONNECTED(clip_in)
+ SET_IF_CONNECTED(clip_out)
+ SET_IF_CONNECTED(meter_in)
+ SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_compression] != NULL) {
@@ -858,6 +1385,40 @@ void sidechaincompressor_audio_module::deactivate()
compressor.deactivate();
}
+sidechaincompressor_audio_module::cfloat sidechaincompressor_audio_module::h_z(const cfloat &z) const
+{
+ switch (sc_mode) {
+ default:
+ case WIDEBAND:
+ return false;
+ break;
+ case DEESSER_WIDE:
+ case DERUMBLER_WIDE:
+ case WEIGHTED_1:
+ case WEIGHTED_2:
+ case WEIGHTED_3:
+ case BANDPASS_2:
+ return f1L.h_z(z) * f2L.h_z(z);
+ break;
+ case DEESSER_SPLIT:
+ return f2L.h_z(z);
+ break;
+ case DERUMBLER_SPLIT:
+ case BANDPASS_1:
+ return f1L.h_z(z);
+ break;
+ }
+}
+
+float sidechaincompressor_audio_module::freq_gain(int index, double freq, uint32_t sr) const
+{
+ typedef std::complex<double> cfloat;
+ freq *= 2.0 * M_PI / sr;
+ cfloat z = 1.0 / exp(cfloat(0.0, freq));
+
+ return std::abs(h_z(z));
+}
+
void sidechaincompressor_audio_module::params_changed()
{
// set the params of all filters
@@ -1014,7 +1575,7 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
switch ((int)*params[param_sc_mode]) {
default:
case WIDEBAND:
- compressor.process(leftAC, rightAC, leftSC, rightSC);
+ compressor.process(leftAC, rightAC);
break;
case DEESSER_WIDE:
case DERUMBLER_WIDE:
@@ -1026,14 +1587,14 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
rightSC = f2R.process(f1R.process(rightSC));
leftMC = leftSC;
rightMC = rightSC;
- compressor.process(leftAC, rightAC, leftSC, rightSC);
+ compressor.process(leftAC, rightAC, &leftSC, &rightSC);
break;
case DEESSER_SPLIT:
leftSC = f2L.process(leftSC);
rightSC = f2R.process(rightSC);
leftMC = leftSC;
rightMC = rightSC;
- compressor.process(leftSC, rightSC, leftSC, rightSC);
+ compressor.process(leftSC, rightSC, &leftSC, &rightSC);
leftAC = f1L.process(leftAC);
rightAC = f1R.process(rightAC);
leftAC += leftSC;
@@ -1044,7 +1605,7 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
rightSC = f1R.process(rightSC);
leftMC = leftSC;
rightMC = rightSC;
- compressor.process(leftSC, rightSC, leftSC, rightSC);
+ compressor.process(leftSC, rightSC);
leftAC = f2L.process(leftAC);
rightAC = f2R.process(rightAC);
leftAC += leftSC;
@@ -1055,7 +1616,7 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
rightSC = f1R.process(rightSC);
leftMC = leftSC;
rightMC = rightSC;
- compressor.process(leftAC, rightAC, leftSC, rightSC);
+ compressor.process(leftAC, rightAC, &leftSC, &rightSC);
break;
}
@@ -1092,18 +1653,10 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num
}
// draw meters
- if(params[param_clip_in] != NULL) {
- *params[param_clip_in] = clip_in;
- }
- if(params[param_clip_out] != NULL) {
- *params[param_clip_out] = clip_out;
- }
- if(params[param_meter_in] != NULL) {
- *params[param_meter_in] = meter_in;
- }
- if(params[param_meter_out] != NULL) {
- *params[param_meter_out] = meter_out;
- }
+ SET_IF_CONNECTED(clip_in)
+ SET_IF_CONNECTED(clip_out)
+ SET_IF_CONNECTED(meter_in)
+ SET_IF_CONNECTED(meter_out)
// draw strip meter
if(bypass > 0.5f) {
if(params[param_compression] != NULL) {
@@ -1293,14 +1846,14 @@ uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uin
switch ((int)*params[param_mode]) {
default:
case WIDE:
- compressor.process(leftAC, rightAC, leftSC, rightSC);
+ compressor.process(leftAC, rightAC, &leftSC, &rightSC);
break;
case SPLIT:
hpL.sanitize();
hpR.sanitize();
leftRC = hpL.process(leftRC);
rightRC = hpR.process(rightRC);
- compressor.process(leftRC, rightRC, leftSC, rightSC);
+ compressor.process(leftRC, rightRC, &leftSC, &rightSC);
leftAC = lpL.process(leftAC);
rightAC = lpR.process(rightAC);
leftAC += leftRC;
@@ -1461,13 +2014,13 @@ void gain_reduction_audio_module::update_curve()
compressedKneeStop = (kneeStop - thres) / ratio + thres;
}
-void gain_reduction_audio_module::process(float &left, float &right, float det_left, float det_right)
+void gain_reduction_audio_module::process(float &left, float &right, const float *det_left, const float *det_right)
{
if(!det_left) {
- det_left = left;
+ det_left = &left;
}
if(!det_right) {
- det_right = right;
+ det_right = &right;
}
float gain = 1.f;
if(bypass < 0.5f) {
@@ -1479,7 +2032,7 @@ void gain_reduction_audio_module::process(float &left, float &right, float det_l
float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f));
update_curve();
- float absample = average ? (fabs(det_left) + fabs(det_right)) * 0.5f : std::max(fabs(det_left), fabs(det_right));
+ float absample = average ? (fabs(*det_left) + fabs(*det_right)) * 0.5f : std::max(fabs(*det_left), fabs(*det_right));
if(rms) absample *= absample;
linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff);
@@ -1903,8 +2456,6 @@ uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offs
return outputs_mask;
}
-#undef SET_IF_CONNECTED
-
template<class BaseClass, bool has_lphp>
bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
{
@@ -2267,31 +2818,14 @@ uint32_t pulsator_audio_module::process(uint32_t offset, uint32_t numsamples, ui
} // cycle trough samples
}
// draw meters
- if(params[param_clip_inL] != NULL) {
- *params[param_clip_inL] = clip_inL;
- }
- if(params[param_clip_inR] != NULL) {
- *params[param_clip_inR] = clip_inR;
- }
- if(params[param_clip_outL] != NULL) {
- *params[param_clip_outL] = clip_outL;
- }
- if(params[param_clip_outR] != NULL) {
- *params[param_clip_outR] = clip_outR;
- }
-
- if(params[param_meter_inL] != NULL) {
- *params[param_meter_inL] = meter_inL;
- }
- if(params[param_meter_inR] != NULL) {
- *params[param_meter_inR] = meter_inR;
- }
- if(params[param_meter_outL] != NULL) {
- *params[param_meter_outL] = meter_outL;
- }
- if(params[param_meter_outR] != NULL) {
- *params[param_meter_outR] = meter_outR;
- }
+ SET_IF_CONNECTED(clip_inL)
+ SET_IF_CONNECTED(clip_inR)
+ SET_IF_CONNECTED(clip_outL)
+ SET_IF_CONNECTED(clip_outR)
+ SET_IF_CONNECTED(meter_inL)
+ SET_IF_CONNECTED(meter_inR)
+ SET_IF_CONNECTED(meter_outL)
+ SET_IF_CONNECTED(meter_outR)
// whatever has to be returned x)
return outputs_mask;
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list