diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index 4a23300ca..56305bcb9 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -69,6 +69,7 @@ enum parameter_flags PF_CTL_BUTTON = 0x0600, ///< push button PF_CTL_METER = 0x0700, ///< volume meter PF_CTL_LED = 0x0800, ///< light emitting diode + PF_CTL_LABEL = 0x0900, ///< label PF_CTLOPTIONS = 0x00F000, ///< bit mask for control (widget) options PF_CTLO_HORIZ = 0x001000, ///< horizontal version of the control (unused) diff --git a/plugins/ladspa_effect/calf/calf/metadata.h b/plugins/ladspa_effect/calf/calf/metadata.h index fd89b6040..c959e1940 100644 --- a/plugins/ladspa_effect/calf/calf/metadata.h +++ b/plugins/ladspa_effect/calf/calf/metadata.h @@ -63,7 +63,7 @@ struct filterclavier_metadata: public plugin_metadata struct reverb_metadata: public plugin_metadata { - enum { par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count }; + enum { par_clip, par_meter_wet, par_meter_out, par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count }; enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb") }; @@ -78,7 +78,7 @@ struct vintage_delay_metadata: public plugin_metadata struct rotary_speaker_metadata: public plugin_metadata { public: - enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, param_count }; + enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, par_meter_l, par_meter_h, param_count }; enum { in_count = 2, out_count = 2, support_midi = true, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker") }; @@ -126,16 +126,27 @@ struct monosynth_metadata: public plugin_metadata }; PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth") }; - + /// Thor's compressor - metadata struct compressor_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, // param_freq, param_bw, + enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, param_input,// param_freq, param_bw, param_count }; PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor") }; +/// Markus's sidechain compressor - metadata +struct sidechaincompressor_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, + param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, + param_sc_listen, param_f1_active, param_f2_active, param_count }; + PLUGIN_NAME_ID_LABEL("sidechaincompressor", "sidechaincompressor", "Sidechain Compressor") +}; + /// Markus's multibandcompressor - metadata struct multibandcompressor_metadata: public plugin_metadata { @@ -157,6 +168,71 @@ struct multibandcompressor_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_detected, param_compression, param_detected_led, param_clip_out, + param_detection, param_mode, + param_threshold, param_ratio, param_laxity, param_makeup, + param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_f2_q, + param_sc_listen, param_count }; + PLUGIN_NAME_ID_LABEL("deesser", "deesser", "Deesser") +}; + +/// Markus's 5-band EQ - metadata +struct equalizer5band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_in, + param_meter_out, param_clip_in, param_clip_out, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer5band", "equalizer5band", "Equalizer 5 Band") +}; +/// Markus's 8-band EQ - metadata +struct equalizer8band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, + param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + param_hp_active, param_hp_freq, param_hp_mode, + param_lp_active, param_lp_freq, param_lp_mode, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_p4_active, param_p4_level, param_p4_freq, param_p4_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer8band", "equalizer8band", "Equalizer 8 Band") +}; +/// Markus's 12-band EQ - metadata +struct equalizer12band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, + param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + param_hp_active, param_hp_freq, param_hp_mode, + param_lp_active, param_lp_freq, param_lp_mode, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_p4_active, param_p4_level, param_p4_freq, param_p4_q, + param_p5_active, param_p5_level, param_p5_freq, param_p5_q, + param_p6_active, param_p6_level, param_p6_freq, param_p6_q, + param_p7_active, param_p7_level, param_p7_freq, param_p7_q, + param_p8_active, param_p8_level, param_p8_freq, param_p8_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer12band", "equalizer12band", "Equalizer 12 Band") +}; + /// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was /// a bad design decision and should be sorted out some day) XXXKF @todo struct organ_enums diff --git a/plugins/ladspa_effect/calf/calf/modulelist.h b/plugins/ladspa_effect/calf/calf/modulelist.h index ca990654b..83c123cad 100644 --- a/plugins/ladspa_effect/calf/calf/modulelist.h +++ b/plugins/ladspa_effect/calf/calf/modulelist.h @@ -10,7 +10,12 @@ PER_MODULE_ITEM(phaser, false, "phaser") PER_MODULE_ITEM(multichorus, false, "multichorus") PER_MODULE_ITEM(compressor, false, "compressor") + PER_MODULE_ITEM(sidechaincompressor, false, "sidechaincompressor") PER_MODULE_ITEM(multibandcompressor, false, "multibandcompressor") + PER_MODULE_ITEM(deesser, false, "deesser") + PER_MODULE_ITEM(equalizer5band, false, "equalizer5band") + PER_MODULE_ITEM(equalizer8band, false, "equalizer8band") + PER_MODULE_ITEM(equalizer12band, false, "equalizer12band") #ifdef ENABLE_EXPERIMENTAL PER_MODULE_ITEM(fluidsynth, true, "fluidsynth") PER_MODULE_ITEM(wavetable, true, "wavetable") diff --git a/plugins/ladspa_effect/calf/calf/modules.h b/plugins/ladspa_effect/calf/calf/modules.h index d1545eb87..19075725d 100644 --- a/plugins/ladspa_effect/calf/calf/modules.h +++ b/plugins/ladspa_effect/calf/calf/modules.h @@ -203,6 +203,8 @@ public: uint32_t srate; gain_smoothing amount, dryamount; int predelay_amt; + float meter_wet, meter_out; + uint32_t clip; float *ins[in_count]; float *outs[out_count]; float *params[param_count]; @@ -223,7 +225,7 @@ public: } 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(); @@ -236,12 +238,26 @@ public: 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 activate(); @@ -416,7 +432,9 @@ public: float maspeed_l; /// Current rotation speed for treble rotor - manual mode float maspeed_h; - + + int meter_l, meter_h; + rotary_speaker_audio_module(); void set_sample_rate(uint32_t sr); void setup(); @@ -501,7 +519,8 @@ public: 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); @@ -541,6 +560,12 @@ public: 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; } virtual void control_change(int ctl, int val); @@ -901,8 +926,8 @@ class gain_reduction_audio_module { private: float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; float compressedKneeStop, adjKneeStart, thres; - float attack, release, threshold, ratio, knee, makeup, detection, bypass, mute, meter_out, meter_comp; - float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection; + float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; + float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; int last_generation; uint32_t srate; bool is_active; @@ -910,8 +935,8 @@ private: inline float output_gain(float linSlope, bool rms); public: gain_reduction_audio_module(); - void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float byp, float mu); - void process(float &left, float &right); + void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu); + void process(float &left, float &right, float det_left = NULL, float det_right = NULL); void activate(); void deactivate(); int id; @@ -924,6 +949,81 @@ public: virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); }; +/// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) +class sidechaincompressor_audio_module: public audio_module, public frequency_response_line_graph { +private: + enum CalfScModes { + WIDEBAND, + DEESSER_WIDE, + DEESSER_SPLIT, + DERUMBLER_WIDE, + DERUMBLER_SPLIT, + WEIGHTED_1, + WEIGHTED_2, + WEIGHTED_3, + BANDPASS_1, + BANDPASS_2 + }; + float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; + float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; + CalfScModes sc_mode, sc_mode_old, sc_mode_old1; + float f1_active, f2_active; + uint32_t clip_in, clip_out; + float meter_in, meter_out; + gain_reduction_audio_module compressor; + biquad_d2 f1L, f1R, f2L, f2R; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + sidechaincompressor_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + inline cfloat h_z(const cfloat &z) { + 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) + { + typedef std::complex cfloat; + freq *= 2.0 * M_PI / sr; + cfloat z = 1.0 / exp(cfloat(0.0, freq)); + + return std::abs(h_z(z)); + } + 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); + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + /// Multibandcompressor by Markus Schmidt class multibandcompressor_audio_module: public audio_module, public line_graph_iface { private: @@ -952,6 +1052,264 @@ public: virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); }; +/// Deesser by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) +class deesser_audio_module: public audio_module, public frequency_response_line_graph { +private: + enum CalfDeessModes { + WIDE, + SPLIT + }; + float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old; + float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1; + uint32_t detected_led; + float detected, clip_out; + uint32_t clip_led; + gain_reduction_audio_module compressor; + biquad_d2 hpL, hpR, lpL, lpR, pL, pR; +public: + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + deesser_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr); + } + 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); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 12 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer12band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float hp_mode_old, hp_freq_old; + float lp_mode_old, lp_freq_old; + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[8], p_freq_old[8], p_q_old[8]; + float hp_mode_old1, hp_freq_old1, hp_active_old1; + float lp_mode_old1, lp_freq_old1, lp_active_old1; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[8], p_freq_old1[8], p_q_old1[8], p_active_old1[8]; + enum CalfEqModes { + MODE12DB, + MODE24DB, + MODE36DB + }; + CalfEqModes eq_mode, eq_mode_old1[2]; + uint32_t clip_inL, clip_outL, clip_inR, clip_outR; + float meter_inL, meter_outL, meter_inR, meter_outR; + biquad_d2 hpL[3], hpR[3], lpL[3], lpR[3]; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[8], pR[8]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer12band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + ret *= hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + ret *= lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + } + } + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1; + ret *= (*params[param_p5_active] > 0.f) ? pL[4].freq_gain(freq, sr) : 1; + ret *= (*params[param_p6_active] > 0.f) ? pL[5].freq_gain(freq, sr) : 1; + ret *= (*params[param_p7_active] > 0.f) ? pL[6].freq_gain(freq, sr) : 1; + ret *= (*params[param_p8_active] > 0.f) ? pL[7].freq_gain(freq, sr) : 1; + return ret; + } + 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); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 8 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer8band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float hp_mode_old, hp_freq_old; + float lp_mode_old, lp_freq_old; + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[4], p_freq_old[4], p_q_old[4]; + float hp_mode_old1, hp_freq_old1, hp_active_old1; + float lp_mode_old1, lp_freq_old1, lp_active_old1; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[4], p_freq_old1[4], p_q_old1[4], p_active_old1[4]; + enum CalfEqModes { + MODE12DB, + MODE24DB, + MODE36DB + }; + CalfEqModes eq_mode, eq_mode_old1[2]; + uint32_t clip_inL, clip_outL, clip_inR, clip_outR; + float meter_inL, meter_outL, meter_inR, meter_outR; + biquad_d2 hpL[3], hpR[3], lpL[3], lpR[3]; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[4], pR[4]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer8band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + ret *= hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + ret *= lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + } + } + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1; + return ret; + } + 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); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 5 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer5band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float hp_mode_old, hp_freq_old; + float lp_mode_old, lp_freq_old; + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[3], p_freq_old[3], p_q_old[3]; + float hp_mode_old1, hp_freq_old1, hp_active_old1; + float lp_mode_old1, lp_freq_old1, lp_active_old1; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[3], p_freq_old1[3], p_q_old1[3], p_active_old1[3]; + uint32_t clip_in, clip_out; + float meter_in, meter_out; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[3], pR[3]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer5band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + return ret; + } + 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); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + /// Filterclavier --- MIDI controlled filter by Hans Baier class filterclavier_audio_module: public audio_module, diff --git a/plugins/ladspa_effect/calf/src/modules.cpp b/plugins/ladspa_effect/calf/src/modules.cpp index 5dc413e6d..225e38712 100644 --- a/plugins/ladspa_effect/calf/src/modules.cpp +++ b/plugins/ladspa_effect/calf/src/modules.cpp @@ -37,9 +37,9 @@ const char *calf_plugins::calf_copyright_info = "(C) 2001-2008 Krzysztof Foltman CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(flanger) = { - { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Minimum delay" }, - { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Modulation depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" }, + { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, + { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Mod depth" }, + { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, { 0.90, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, { 0, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, @@ -55,8 +55,8 @@ CALF_PORT_NAMES(phaser) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(phaser) = { { 1000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "base_freq", "Center Freq" }, - { 4000, 0, 10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Modulation depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" }, + { 4000, 0, 10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Mod depth" }, + { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, { 0.25, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, { 6, 1, 12, 12, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "stages", "# Stages" }, { 180, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, @@ -74,6 +74,9 @@ CALF_PORT_NAMES(reverb) = {"In L", "In R", "Out L", "Out R"}; const char *reverb_room_sizes[] = { "Small", "Medium", "Large", "Tunnel-like", "Large/smooth", "Experimental" }; CALF_PORT_PROPS(reverb) = { + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_wet", "Wet amount" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, { 1.5, 0.4, 15.0, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "decay_time", "Decay time" }, { 5000, 2000,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hf_damp", "High Frq Damp" }, { 2, 0, 5, 0, PF_ENUM | PF_CTL_COMBO , reverb_room_sizes, "room_size", "Room size", }, @@ -151,7 +154,7 @@ const char *vintage_delay_fbmodes[] = { }; CALF_PORT_PROPS(vintage_delay) = { - { 120, 30, 300,2701, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" }, + { 120, 30, 300, 1, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" }, { 4, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "subdiv", "Subdivide"}, { 3, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_l", "Time L"}, { 5, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_r", "Time R"}, @@ -171,14 +174,16 @@ CALF_PORT_NAMES(rotary_speaker) = {"In L", "In R", "Out L", "Out R"}; const char *rotary_speaker_speed_names[] = { "Off", "Chorale", "Tremolo", "HoldPedal", "ModWheel", "Manual" }; CALF_PORT_PROPS(rotary_speaker) = { - { 2, 0, 5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" }, + { 5, 0, 5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "spacing", "Tap Spacing" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "shift", "Tap Offset" }, { 0.10, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mod_depth", "Mod Depth" }, - { 390, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "treble_speed", "Treble Motor" }, - { 410, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "bass_speed", "Bass Motor" }, + { 36, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "treble_speed", "Treble Motor" }, + { 30, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "bass_speed", "Bass Motor" }, { 0.7, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mic_distance", "Mic Distance" }, { 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" }, }; CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulationPlugin" }; @@ -188,8 +193,8 @@ CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speak CALF_PORT_NAMES(multichorus) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(multichorus) = { - { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Minimum delay" }, - { 6, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC| PF_PROP_GRAPH, NULL, "mod_depth", "Modulation depth" }, + { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, + { 6, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC| PF_PROP_GRAPH, NULL, "mod_depth", "Mod depth" }, { 0.5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ| PF_PROP_GRAPH, NULL, "mod_rate", "Modulation rate" }, { 180, 0, 360, 91, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, { 4, 1, 8, 8, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "voices", "Voices"}, @@ -224,8 +229,9 @@ CALF_PORT_PROPS(compressor) = { { 0, 0, 4, 0, PF_ENUM | PF_CTL_COMBO, compressor_weighting_names, "aweighting", "Weighting" }, { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Compression" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "peak", "Peak Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "input", "Input" }, // { 2000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "deess_freq", "Frequency" }, // { 0.707, 0.707, 32, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "deess_res", "Q" }, }; @@ -234,6 +240,53 @@ CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor //////////////////////////////////////////////////////////////////////////// +CALF_PORT_NAMES(sidechaincompressor) = {"In L", "In R", "Out L", "Out R"}; + +const char *sidechaincompressor_detection_names[] = { "RMS", "Peak" }; +const char *sidechaincompressor_stereo_link_names[] = { "Average", "Maximum" }; +const char *sidechaincompressor_mode_names[] = {"Wideband (F1:off / F2:off)", + "Deesser wide (F1:Bell / F2:HP)", + "Deesser split (F1:off / F2:HP)", + "Derumbler wide (F1:LP / F2:Bell)", + "Derumbler split (F1:LP / F2:off)", + "Weighted #1 (F1:Shelf / F2:Shelf)", + "Weighted #2 (F1:Shelf / F2:Bell)", + "Weighted #3 (F1:Bell / F2:Shelf)", + "Bandpass #1 (F1:BP / F2:off)", + "Bandpass #2 (F1:HP / F2:LP)"}; +const char *sidechaincompressor_filter_choices[] = { "12dB", "24dB", "36dB"}; + + +CALF_PORT_PROPS(sidechaincompressor) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, + { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, + { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, + { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, + { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_detection_names, "detection", "Detection" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_stereo_link_names, "stereo_link", "Stereo Link" }, + { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, + { 0, 0, 9, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_mode_names, "sc_mode", "Sidechain Mode" }, + { 250, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Freq" }, + { 4500, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Freq" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Level" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "active" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "active" }, +}; + +CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8502, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + CALF_PORT_NAMES(multibandcompressor) = {"In L", "In R", "Out L", "Out R"}; const char *multibandcompressor_detection_names[] = { "RMS", "Peak" }; @@ -246,10 +299,10 @@ CALF_PORT_PROPS(multibandcompressor) = { { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, { 100, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" }, { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" }, @@ -320,6 +373,197 @@ CALF_PLUGIN_INFO(multibandcompressor) = { 0x8502, "Multibandcompressor", "Calf M //////////////////////////////////////////////////////////////////////////// +CALF_PORT_NAMES(deesser) = {"In L", "In R", "Out L", "Out R"}; + +const char *deesser_detection_names[] = { "RMS", "Peak" }; +const char *deesser_mode_names[] = { "Wide", "Split" }; + + +CALF_PORT_PROPS(deesser) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected", "Detected" }, + { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected_led", "Active" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "Out" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_detection_names, "detection", "Detection" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_mode_names, "mode", "Mode" }, + { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, + { 15, 1, 100, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "laxity", "Laxity" }, + { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup" }, + + { 6000, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Split" }, + { 4500, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Peak" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Gain" }, + { 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, + { 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, +}; + +CALF_PLUGIN_INFO(deesser) = { 0x8502, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer5band) = {"In L", "In R", "Out L", "Out R"}; + +CALF_PORT_PROPS(equalizer5band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, +}; + +CALF_PLUGIN_INFO(equalizer5band) = { 0x8501, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +////////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer8band) = {"In L", "In R", "Out L", "Out R"}; +const char *rolloff_mode_names[] = {"12dB", "24dB", "36dB"}; + +CALF_PORT_PROPS(equalizer8band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "active" }, + { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "active" }, + { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p4_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p4_level", "Level 4" }, + { 5000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p4_freq", "Freq 4" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p4_q", "Q 4" }, +}; + +CALF_PLUGIN_INFO(equalizer8band) = { 0x8501, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer12band) = {"In L", "In R", "Out L", "Out R"}; + +CALF_PORT_PROPS(equalizer12band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "active" }, + { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "active" }, + { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 60, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 120, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p4_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p4_level", "Level 4" }, + { 500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p4_freq", "Freq 4" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p4_q", "Q 4" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p5_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p5_level", "Level 5" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p5_freq", "Freq 5" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p5_q", "Q 5" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p6_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p6_level", "Level 6" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p6_freq", "Freq 6" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p6_q", "Q 6" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p7_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p7_level", "Level 7" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p7_freq", "Freq 7" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p7_q", "Q 7" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p8_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p8_level", "Level 8" }, + { 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p8_freq", "Freq 8" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p8_q", "Q 8" }, +}; + +CALF_PLUGIN_INFO(equalizer12band) = { 0x8501, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// CALF_PORT_NAMES(monosynth) = { @@ -363,11 +607,11 @@ CALF_PORT_PROPS(monosynth) = { { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2res", "Env->Res" }, { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2amp", "Env->Amp" }, - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_a", "Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_d", "Decay" }, + { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_a", "Attack" }, + { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_d", "Decay" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_f", "Fade" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_r", "Release" }, + { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_f", "Fade" }, + { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_r", "Release" }, { 0, 0, 2, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "key_follow", "Key Follow" }, { 0, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, monosynth_legato_names, "legato", "Legato Mode" }, @@ -608,8 +852,8 @@ CALF_PORT_PROPS(fluidsynth) = { { 0.5, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_PROP_OUTPUT_GAIN, NULL, "master", "Volume" }, { 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_soundfont, "soundfont", "Soundfont" }, { 2, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, fluidsynth_interpolation_names, "interpolation", "Interpolation" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Enable Reverb" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Enable Chorus" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Reverb" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Chorus" }, }; //////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ladspa_effect/calf/src/modules_dsp.cpp b/plugins/ladspa_effect/calf/src/modules_dsp.cpp index 3ef471b0b..452844ea1 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -574,14 +574,12 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, numsamples += offset; float compression = 1.f; - - peak -= peak * 5.f * numsamples / srate; - + peak = 0.f; clip -= std::min(clip, numsamples); while(offset < numsamples) { - float left = ins[0][offset]; - float right = ins[1][offset]; + float left = ins[0][offset] * *params[param_input]; + float right = ins[1][offset] * *params[param_input]; if(aweighting == 1) { left = awL.process(left); @@ -606,8 +604,8 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, compression = gain; gain *= makeup; - float outL = ins[0][offset] * gain; - float outR = ins[1][offset] * gain; + float outL = ins[0][offset] * gain * *params[param_input]; + float outR = ins[1][offset] * gain * *params[param_input]; outs[0][offset] = outL; outs[1][offset] = outR; @@ -615,12 +613,10 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, ++offset; float maxLR = std::max(fabs(outL), fabs(outR)); - - if(maxLR > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */ - - if(maxLR > peak) { + if(maxLR > peak) peak = maxLR; - } + + if(peak > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */ } detected = linSlope; @@ -691,27 +687,27 @@ void multibandcompressor_audio_module::params_changed() // set the params of all filters if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0]) { lpL0.set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); - lpR0.set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); + lpR0.copy_coeffs(lpL0); hpL0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); - hpR0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); + hpR0.copy_coeffs(hpL0); freq_old[0] = *params[param_freq0]; sep_old[0] = *params[param_sep2]; q_old[0] = *params[param_q2]; } if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1]) { lpL1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); - lpR1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); + lpR1.copy_coeffs(lpL1); hpL1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); - hpR1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); + hpR1.copy_coeffs(hpL1); freq_old[1] = *params[param_freq1]; sep_old[1] = *params[param_sep2]; q_old[1] = *params[param_q2]; } if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2]) { lpL2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); - lpR2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); + lpR2.copy_coeffs(lpL2); hpL2.set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); - hpR2.set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); + hpR2.copy_coeffs(hpL2); freq_old[2] = *params[param_freq2]; sep_old[2] = *params[param_sep2]; q_old[2] = *params[param_q2]; @@ -720,16 +716,16 @@ void multibandcompressor_audio_module::params_changed() for (int j = 0; j < strips; j ++) { switch (j) { case 0: - strip[j].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], *params[param_bypass0], *params[param_mute0]); + strip[j].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], *params[param_mute0]); break; case 1: - strip[j].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], *params[param_bypass1], *params[param_mute1]); + strip[j].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], *params[param_mute1]); break; case 2: - strip[j].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], *params[param_bypass2], *params[param_mute2]); + strip[j].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], *params[param_mute2]); break; case 3: - strip[j].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], *params[param_bypass3], *params[param_mute3]); + strip[j].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], *params[param_mute3]); break; } } @@ -778,11 +774,10 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num clip_inR -= std::min(clip_inR, numsamples); clip_outL -= std::min(clip_outL, numsamples); clip_outR -= std::min(clip_outR, numsamples); - meter_inL -= meter_inL * 2.5 * numsamples / srate; - meter_inR -= meter_inR * 2.5 * numsamples / srate; - meter_outL -= meter_outL * 2.5 * numsamples / srate; - meter_outR -= meter_outR * 2.5 * numsamples / srate; - + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; while(offset < numsamples) { // cycle through samples float inL = ins[0][offset]; @@ -873,7 +868,7 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num if(outR > 1.f) { clip_outR = srate >> 3; } - // rise up in / out meters + // set up in / out meters if(inL > meter_inL) { meter_inL = inL; } @@ -1054,6 +1049,597 @@ int multibandcompressor_audio_module::get_changed_offsets(int index, int generat } return 0; } + +/// Sidecain Compressor by Markus Schmidt +/// +/// This module splits the signal in a sidechain- and a process signal. +/// The sidechain is processed through Krzystofs filters and compresses +/// the process signal via Thor's compression routine afterwards. +/////////////////////////////////////////////////////////////////////////////////////////////// + +sidechaincompressor_audio_module::sidechaincompressor_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; +} + +void sidechaincompressor_audio_module::activate() +{ + is_active = true; + // set all filters and strips + compressor.activate(); + params_changed(); + meter_in = 0.f; + meter_out = 0.f; + clip_in = 0.f; + clip_out = 0.f; +} +void sidechaincompressor_audio_module::deactivate() +{ + is_active = false; + compressor.deactivate(); +} + +void sidechaincompressor_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old + or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old + or *params[param_sc_mode] != sc_mode) { + float q = 0.707; + switch ((int)*params[param_sc_mode]) { + default: + case WIDEBAND: + f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.f; + f2_active = 0.f; + break; + case DEESSER_WIDE: + f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 1.f; + break; + case DEESSER_SPLIT: + f1L.set_lp_rbj((float)*params[param_f2_freq] * (1 + 0.17), q, (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.f; + f2_active = 1.f; + break; + case DERUMBLER_WIDE: + f1L.set_lp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.5f; + break; + case DERUMBLER_SPLIT: + f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.f; + break; + case WEIGHTED_1: + f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case WEIGHTED_2: + f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case WEIGHTED_3: + f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case BANDPASS_1: + f1L.set_bp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.f; + break; + case BANDPASS_2: + f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 1.f; + break; + } + f1_freq_old = *params[param_f1_freq]; + f1_level_old = *params[param_f1_level]; + f2_freq_old = *params[param_f2_freq]; + f2_level_old = *params[param_f2_level]; + sc_mode = (CalfScModes)*params[param_sc_mode]; + } + // light LED's + if(params[param_f1_active] != NULL) { + *params[param_f1_active] = f1_active; + } + if(params[param_f2_active] != NULL) { + *params[param_f2_active] = f2_active; + } + // and set the compressor module + compressor.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f); +} + +void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; + compressor.set_sample_rate(srate); +} + +uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; + } else { + // process + + clip_in -= std::min(clip_in, numsamples); + clip_out -= std::min(clip_out, numsamples); + + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + + float leftAC = inL; + float rightAC = inR; + float leftSC = inL; + float rightSC = inR; + float leftMC = inL; + float rightMC = inR; + + switch ((int)*params[param_sc_mode]) { + default: + case WIDEBAND: + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + case DEESSER_WIDE: + case DERUMBLER_WIDE: + case WEIGHTED_1: + case WEIGHTED_2: + case WEIGHTED_3: + case BANDPASS_2: + leftSC = f2L.process(f1L.process(leftSC)); + rightSC = f2R.process(f1R.process(rightSC)); + leftMC = leftSC; + rightMC = 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); + leftAC = f1L.process(leftAC); + rightAC = f1R.process(rightAC); + leftAC += leftSC; + rightAC += rightSC; + break; + case DERUMBLER_SPLIT: + leftSC = f1L.process(leftSC); + rightSC = f1R.process(rightSC); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftSC, rightSC, leftSC, rightSC); + leftAC = f2L.process(leftAC); + rightAC = f2R.process(rightAC); + leftAC += leftSC; + rightAC += rightSC; + break; + case BANDPASS_1: + leftSC = f1L.process(leftSC); + rightSC = f1R.process(rightSC); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + } + + if(*params[param_sc_listen] > 0.f) { + outL = leftMC; + outR = rightMC; + } else { + outL = leftAC; + outR = rightAC; + } + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(std::max(fabs(inL), fabs(inR)) > 1.f) { + clip_in = srate >> 3; + } + if(std::max(fabs(outL), fabs(outR)) > 1.f) { + clip_out = srate >> 3; + } + // rise up out meter + meter_in = std::max(fabs(inL), fabs(inR));; + meter_out = std::max(fabs(outL), fabs(outR));; + + // next sample + ++offset; + } // cycle trough samples + f1L.sanitize(); + f1R.sanitize(); + f2L.sanitize(); + f2R.sanitize(); + + } + // 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; + } + // draw strip meter + if(bypass > 0.5f) { + if(params[param_compression] != NULL) { + *params[param_compression] = 1.0f; + } + } else { + if(params[param_compression] != NULL) { + *params[param_compression] = compressor.get_comp_level(); + } + } + // whatever has to be returned x) + return outputs_mask; +} +bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_f1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } else if(index == param_compression) { + return compressor.get_graph(subindex, data, points, context); + } + return false; +} + +bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_compression) { + return compressor.get_dot(subindex, x, y, size, context); + } + return false; +} + +bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_compression) { + return compressor.get_gridline(subindex, pos, vertical, legend, context); + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +// return false; +} + +int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) + return false; + if(index == param_compression) { + return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); + } else { + // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) + if (*params[param_f1_freq] != f1_freq_old1 + or *params[param_f2_freq] != f2_freq_old1 + or *params[param_f1_level] != f1_level_old1 + or *params[param_f2_level] != f2_level_old1 + or *params[param_sc_mode] !=sc_mode_old1) + { + f1_freq_old1 = *params[param_f1_freq]; + f2_freq_old1 = *params[param_f2_freq]; + f1_level_old1 = *params[param_f1_level]; + f2_level_old1 = *params[param_f2_level]; + sc_mode_old1 = (CalfScModes)*params[param_sc_mode]; + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Deesser by Markus Schmidt +/// +/// This module splits the signal in a sidechain- and a process signal. +/// The sidechain is processed through Krzystofs filters and compresses +/// the process signal via Thor's compression routine afterwards. +/////////////////////////////////////////////////////////////////////////////////////////////// + +deesser_audio_module::deesser_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; +} + +void deesser_audio_module::activate() +{ + is_active = true; + // set all filters and strips + compressor.activate(); + params_changed(); + detected = 0.f; + detected_led = 0.f; + clip_out = 0.f; +} +void deesser_audio_module::deactivate() +{ + is_active = false; + compressor.deactivate(); +} + +void deesser_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old + or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old + or *params[param_f2_q] != f2_q_old) { + float q = 0.707; + + hpL.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate, *params[param_f1_level]); + hpR.copy_coeffs(hpL); + lpL.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate); + lpR.copy_coeffs(lpL); + pL.set_peakeq_rbj((float)*params[param_f2_freq], *params[param_f2_q], *params[param_f2_level], (float)srate); + pR.copy_coeffs(pL); + f1_freq_old = *params[param_f1_freq]; + f1_level_old = *params[param_f1_level]; + f2_freq_old = *params[param_f2_freq]; + f2_level_old = *params[param_f2_level]; + f2_q_old = *params[param_f2_q]; + } + // and set the compressor module + compressor.set_params((float)*params[param_laxity], (float)*params[param_laxity] * 1.33, *params[param_threshold], *params[param_ratio], 2.8, *params[param_makeup], *params[param_detection], 0.f, *params[param_bypass], 0.f); +} + +void deesser_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; + compressor.set_sample_rate(srate); +} + +uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_out = 0.f; + detected = 0.f; + detected_led = 0.f; + } else { + // process + + detected_led -= std::min(detected_led, numsamples); + clip_led -= std::min(clip_led, numsamples); + + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + + + float leftAC = inL; + float rightAC = inR; + float leftSC = inL; + float rightSC = inR; + float leftRC = inL; + float rightRC = inR; + float leftMC = inL; + float rightMC = inR; + + leftSC = pL.process(hpL.process(leftSC)); + rightSC = pR.process(hpR.process(rightSC)); + leftMC = leftSC; + rightMC = rightSC; + + switch ((int)*params[param_mode]) { + default: + case WIDE: + 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); + leftAC = lpL.process(leftAC); + rightAC = lpR.process(rightAC); + leftAC += leftRC; + rightAC += rightRC; + break; + } + + if(*params[param_sc_listen] > 0.f) { + outL = leftMC; + outR = rightMC; + } else { + outL = leftAC; + outR = rightAC; + } + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + if(std::max(fabs(leftSC), fabs(rightSC)) > 0.1) { + detected_led = srate >> 3; + } + if(std::max(fabs(leftAC), fabs(rightAC)) > 1.f) { + clip_led = srate >> 3; + } + if(clip_led > 0) { + clip_out = 1.f; + } else { + clip_out = std::max(fabs(outL), fabs(outR)); + } + detected = std::max(fabs(leftMC), fabs(rightMC)); + + // next sample + ++offset; + } // cycle trough samples + hpL.sanitize(); + hpR.sanitize(); + lpL.sanitize(); + lpR.sanitize(); + pL.sanitize(); + pR.sanitize(); + } + // draw meters + if(params[param_detected_led] != NULL) { + *params[param_detected_led] = detected_led; + } + if(params[param_clip_out] != NULL) { + *params[param_clip_out] = clip_out; + } + if(params[param_detected] != NULL) { + *params[param_detected] = detected; + } + // draw strip meter + if(bypass > 0.5f) { + if(params[param_compression] != NULL) { + *params[param_compression] = 1.0f; + } + } else { + if(params[param_compression] != NULL) { + *params[param_compression] = compressor.get_comp_level(); + } + } + // whatever has to be returned x) + return outputs_mask; +} +bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_f1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + return get_freq_gridline(subindex, pos, vertical, legend, context); + +// return false; +} + +int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) + if (*params[param_f1_freq] != f1_freq_old1 + or *params[param_f2_freq] != f2_freq_old1 + or *params[param_f1_level] != f1_level_old1 + or *params[param_f2_level] != f2_level_old1 + or *params[param_f2_q] !=f2_q_old1) + { + f1_freq_old1 = *params[param_f1_freq]; + f2_freq_old1 = *params[param_f2_freq]; + f1_level_old1 = *params[param_f1_level]; + f2_level_old1 = *params[param_f2_level]; + f2_q_old1 = *params[param_f2_q]; + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + /// Gain reduction module implemented by Markus Schmidt /// Nearly all functions of this module are originally written /// by Thor, while some features have been stripped (mainly stereo linking @@ -1085,14 +1671,20 @@ void gain_reduction_audio_module::deactivate() is_active = false; } -void gain_reduction_audio_module::process(float &left, float &right) +void gain_reduction_audio_module::process(float &left, float &right, float det_left, float det_right) { - float compression = 1.f; - meter_out -= meter_out * 5.f * 1 / srate; + if(!det_left) { + det_left = left; + } + if(!det_right) { + det_right = right; + } + float gain = 1.f; if(bypass < 0.5f) { // this routine is mainly copied from thor's compressor module // greatest sounding compressor I've heard! bool rms = detection == 0; + bool average = stereo_link == 0; float linThreshold = threshold; float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); @@ -1105,32 +1697,21 @@ void gain_reduction_audio_module::process(float &left, float &right) kneeStop = log(linKneeStop); compressedKneeStop = (kneeStop - thres) / ratio + thres; - float absample = (fabs(left) + fabs(right)) * 0.5f; + 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); - float gain = 1.f; - if(linSlope > 0.f) { gain = output_gain(linSlope, rms); } - compression = gain; - gain *= makeup; - - left *= gain; - right *= gain; - + left *= gain * makeup; + right *= gain * makeup; + meter_out = std::max(fabs(left), fabs(right));; + meter_comp = gain; detected = rms ? sqrt(linSlope) : linSlope; } - - float maxLR = std::max(fabs(left), fabs(right)); - - if(maxLR > meter_out) { - meter_out = maxLR; - } - meter_comp = compression; } float gain_reduction_audio_module::output_level(float slope) { @@ -1167,7 +1748,7 @@ void gain_reduction_audio_module::set_sample_rate(uint32_t sr) { srate = sr; } -void gain_reduction_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float byp, float mu) +void gain_reduction_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu) { // set all params attack = att; @@ -1177,6 +1758,7 @@ void gain_reduction_audio_module::set_params(float att, float rel, float thr, fl knee = kn; makeup = mak; detection = det; + stereo_link = stl; bypass = byp; mute = mu; if(mute > 0.f) { @@ -1278,3 +1860,1092 @@ int gain_reduction_audio_module::get_changed_offsets(int generation, int &subind subindex_graph = 2; return last_generation; } + +/// Equalizer 12 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer12band_audio_module::equalizer12band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; +} + +void equalizer12band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer12band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer12band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_hp_freq] != hp_freq_old) { + hpL[0].set_hp_rbj(*params[param_hp_freq], 0.707, (float)srate, 1.0); + hpL[1].copy_coeffs(hpL[0]); + hpL[2].copy_coeffs(hpL[0]); + hpR[0].copy_coeffs(hpL[0]); + hpR[1].copy_coeffs(hpL[0]); + hpR[2].copy_coeffs(hpL[0]); + hp_freq_old = *params[param_hp_freq]; + } + if(*params[param_lp_freq] != lp_freq_old) { + lpL[0].set_lp_rbj(*params[param_lp_freq], 0.707, (float)srate, 1.0); + lpL[1].copy_coeffs(lpL[0]); + lpL[2].copy_coeffs(lpL[0]); + lpR[0].copy_coeffs(lpL[0]); + lpR[1].copy_coeffs(lpL[0]); + lpR[2].copy_coeffs(lpL[0]); + lp_freq_old = *params[param_lp_freq]; + } + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } + if(*params[param_p4_freq] != p_freq_old[3] or *params[param_p4_level] != p_level_old[3] or *params[param_p4_q] != p_q_old[3]) { + pL[3].set_peakeq_rbj((float)*params[param_p4_freq], *params[param_p4_q], *params[param_p4_level], (float)srate); + pR[3].copy_coeffs(pL[3]); + p_freq_old[3] = *params[param_p4_freq]; + p_level_old[3] = *params[param_p4_level]; + p_q_old[3] = *params[param_p4_q]; + } + if(*params[param_p5_freq] != p_freq_old[4] or *params[param_p5_level] != p_level_old[4] or *params[param_p5_q] != p_q_old[4]) { + pL[4].set_peakeq_rbj((float)*params[param_p5_freq], *params[param_p5_q], *params[param_p5_level], (float)srate); + pR[4].copy_coeffs(pL[4]); + p_freq_old[4] = *params[param_p5_freq]; + p_level_old[4] = *params[param_p5_level]; + p_q_old[4] = *params[param_p5_q]; + } + if(*params[param_p6_freq] != p_freq_old[5] or *params[param_p6_level] != p_level_old[5] or *params[param_p6_q] != p_q_old[5]) { + pL[5].set_peakeq_rbj((float)*params[param_p6_freq], *params[param_p6_q], *params[param_p6_level], (float)srate); + pR[5].copy_coeffs(pL[5]); + p_freq_old[5] = *params[param_p6_freq]; + p_level_old[5] = *params[param_p6_level]; + p_q_old[5] = *params[param_p6_q]; + } + if(*params[param_p7_freq] != p_freq_old[6] or *params[param_p7_level] != p_level_old[6] or *params[param_p7_q] != p_q_old[6]) { + pL[6].set_peakeq_rbj((float)*params[param_p7_freq], *params[param_p7_q], *params[param_p7_level], (float)srate); + pR[6].copy_coeffs(pL[6]); + p_freq_old[6] = *params[param_p7_freq]; + p_level_old[6] = *params[param_p7_level]; + p_q_old[6] = *params[param_p7_q]; + } + if(*params[param_p8_freq] != p_freq_old[7] or *params[param_p8_level] != p_level_old[7] or *params[param_p8_q] != p_q_old[7]) { + pL[7].set_peakeq_rbj((float)*params[param_p8_freq], *params[param_p8_q], *params[param_p8_level], (float)srate); + pR[7].copy_coeffs(pL[7]); + p_freq_old[7] = *params[param_p8_freq]; + p_level_old[7] = *params[param_p8_level]; + p_q_old[7] = *params[param_p8_q]; + } +} + +void equalizer12band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + } else { + + clip_inL -= std::min(clip_inL, numsamples); + clip_inR -= std::min(clip_inR, numsamples); + clip_outL -= std::min(clip_outL, numsamples); + clip_outR -= std::min(clip_outR, numsamples); + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + procL = hpL[0].process(procL); + procR = hpR[0].process(procR); + break; + case MODE24DB: + procL = hpL[1].process(hpL[0].process(procL)); + procR = hpR[1].process(hpR[0].process(procR)); + break; + case MODE36DB: + procL = hpL[2].process(hpL[1].process(hpL[0].process(procL))); + procR = hpR[2].process(hpR[1].process(hpR[0].process(procR))); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + procL = lpL[0].process(procL); + procR = lpR[0].process(procR); + break; + case MODE24DB: + procL = lpL[1].process(lpL[0].process(procL)); + procR = lpR[1].process(lpR[0].process(procR)); + break; + case MODE36DB: + procL = lpL[2].process(lpL[1].process(lpL[0].process(procL))); + procR = lpR[2].process(lpR[1].process(lpR[0].process(procR))); + break; + } + } + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + if(*params[param_p4_active] > 0.f) { + procL = pL[3].process(procL); + procR = pR[3].process(procR); + } + if(*params[param_p5_active] > 0.f) { + procL = pL[4].process(procL); + procR = pR[4].process(procR); + } + if(*params[param_p6_active] > 0.f) { + procL = pL[5].process(procL); + procR = pR[5].process(procR); + } + if(*params[param_p7_active] > 0.f) { + procL = pL[6].process(procL); + procR = pR[6].process(procR); + } + if(*params[param_p8_active] > 0.f) { + procL = pL[7].process(procL); + procR = pR[7].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(inL > 1.f) { + clip_inL = srate >> 3; + } + if(inR > 1.f) { + clip_inR = srate >> 3; + } + if(outL > 1.f) { + clip_outL = srate >> 3; + } + if(outR > 1.f) { + clip_outR = srate >> 3; + } + // set up in / out meters + if(inL > meter_inL) { + meter_inL = inL; + } + if(inR > meter_inR) { + meter_inR = inR; + } + if(outL > meter_outL) { + meter_outL = outL; + } + if(outR > meter_outR) { + meter_outR = outR; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + for(int i = 0; i < 3; ++i) { + hpL[i].sanitize(); + hpR[i].sanitize(); + lpL[i].sanitize(); + lpR[i].sanitize(); + } + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 8; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // 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; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer12band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer12band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer12band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_hp_freq] != hp_freq_old1 + or *params[param_hp_mode] != hp_mode_old1 + or *params[param_lp_freq] != lp_freq_old1 + or *params[param_lp_mode] != lp_mode_old1 + + or *params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2] + + or *params[param_p4_freq] != p_freq_old1[3] + or *params[param_p4_level] != p_level_old1[3] + or *params[param_p4_q] != p_q_old1[3] + + or *params[param_p5_freq] != p_freq_old1[4] + or *params[param_p5_level] != p_level_old1[4] + or *params[param_p5_q] != p_q_old1[4] + + or *params[param_p6_freq] != p_freq_old1[5] + or *params[param_p6_level] != p_level_old1[5] + or *params[param_p6_q] != p_q_old1[5] + + or *params[param_p7_freq] != p_freq_old1[6] + or *params[param_p7_level] != p_level_old1[6] + or *params[param_p7_q] != p_q_old1[6] + + or *params[param_p8_freq] != p_freq_old1[7] + or *params[param_p8_level] != p_level_old1[7] + or *params[param_p8_q] != p_q_old1[7]) + { + + hp_freq_old1 = *params[param_hp_freq]; + hp_mode_old1 = *params[param_hp_mode]; + lp_freq_old1 = *params[param_lp_freq]; + lp_mode_old1 = *params[param_lp_mode]; + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + p_freq_old1[3] = *params[param_p4_freq]; + p_level_old1[3] = *params[param_p4_level]; + p_q_old1[3] = *params[param_p4_q]; + + p_freq_old1[4] = *params[param_p5_freq]; + p_level_old1[4] = *params[param_p5_level]; + p_q_old1[4] = *params[param_p5_q]; + + p_freq_old1[5] = *params[param_p6_freq]; + p_level_old1[5] = *params[param_p6_level]; + p_q_old1[5] = *params[param_p6_q]; + + p_freq_old1[6] = *params[param_p7_freq]; + p_level_old1[6] = *params[param_p7_level]; + p_q_old1[6] = *params[param_p7_q]; + + p_freq_old1[7] = *params[param_p8_freq]; + p_level_old1[7] = *params[param_p8_level]; + p_q_old1[7] = *params[param_p8_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Equalizer 8 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer8band_audio_module::equalizer8band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; +} + +void equalizer8band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer8band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer8band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_hp_freq] != hp_freq_old) { + hpL[0].set_hp_rbj(*params[param_hp_freq], 0.707, (float)srate, 1.0); + hpL[1].copy_coeffs(hpL[0]); + hpL[2].copy_coeffs(hpL[0]); + hpR[0].copy_coeffs(hpL[0]); + hpR[1].copy_coeffs(hpL[0]); + hpR[2].copy_coeffs(hpL[0]); + hp_freq_old = *params[param_hp_freq]; + } + if(*params[param_lp_freq] != lp_freq_old) { + lpL[0].set_lp_rbj(*params[param_lp_freq], 0.707, (float)srate, 1.0); + lpL[1].copy_coeffs(lpL[0]); + lpL[2].copy_coeffs(lpL[0]); + lpR[0].copy_coeffs(lpL[0]); + lpR[1].copy_coeffs(lpL[0]); + lpR[2].copy_coeffs(lpL[0]); + lp_freq_old = *params[param_lp_freq]; + } + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } + if(*params[param_p4_freq] != p_freq_old[3] or *params[param_p4_level] != p_level_old[3] or *params[param_p4_q] != p_q_old[3]) { + pL[3].set_peakeq_rbj((float)*params[param_p4_freq], *params[param_p4_q], *params[param_p4_level], (float)srate); + pR[3].copy_coeffs(pL[3]); + p_freq_old[3] = *params[param_p4_freq]; + p_level_old[3] = *params[param_p4_level]; + p_q_old[3] = *params[param_p4_q]; + } +} + +void equalizer8band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + } else { + + clip_inL -= std::min(clip_inL, numsamples); + clip_inR -= std::min(clip_inR, numsamples); + clip_outL -= std::min(clip_outL, numsamples); + clip_outR -= std::min(clip_outR, numsamples); + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + procL = hpL[0].process(procL); + procR = hpR[0].process(procR); + break; + case MODE24DB: + procL = hpL[1].process(hpL[0].process(procL)); + procR = hpR[1].process(hpR[0].process(procR)); + break; + case MODE36DB: + procL = hpL[2].process(hpL[1].process(hpL[0].process(procL))); + procR = hpR[2].process(hpR[1].process(hpR[0].process(procR))); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + procL = lpL[0].process(procL); + procR = lpR[0].process(procR); + break; + case MODE24DB: + procL = lpL[1].process(lpL[0].process(procL)); + procR = lpR[1].process(lpR[0].process(procR)); + break; + case MODE36DB: + procL = lpL[2].process(lpL[1].process(lpL[0].process(procL))); + procR = lpR[2].process(lpR[1].process(lpR[0].process(procR))); + break; + } + } + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + if(*params[param_p4_active] > 0.f) { + procL = pL[3].process(procL); + procR = pR[3].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(inL > 1.f) { + clip_inL = srate >> 3; + } + if(inR > 1.f) { + clip_inR = srate >> 3; + } + if(outL > 1.f) { + clip_outL = srate >> 3; + } + if(outR > 1.f) { + clip_outR = srate >> 3; + } + // set up in / out meters + if(inL > meter_inL) { + meter_inL = inL; + } + if(inR > meter_inR) { + meter_inR = inR; + } + if(outL > meter_outL) { + meter_outL = outL; + } + if(outR > meter_outR) { + meter_outR = outR; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + for(int i = 0; i < 3; ++i) { + hpL[i].sanitize(); + hpR[i].sanitize(); + lpL[i].sanitize(); + lpR[i].sanitize(); + } + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 4; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // 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; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer8band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer8band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer8band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_hp_freq] != hp_freq_old1 + or *params[param_hp_mode] != hp_mode_old1 + or *params[param_lp_freq] != lp_freq_old1 + or *params[param_lp_mode] != lp_mode_old1 + + or *params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2] + + or *params[param_p4_freq] != p_freq_old1[3] + or *params[param_p4_level] != p_level_old1[3] + or *params[param_p4_q] != p_q_old1[3]) + { + + hp_freq_old1 = *params[param_hp_freq]; + hp_mode_old1 = *params[param_hp_mode]; + lp_freq_old1 = *params[param_lp_freq]; + lp_mode_old1 = *params[param_lp_mode]; + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + p_freq_old1[3] = *params[param_p4_freq]; + p_level_old1[3] = *params[param_p4_level]; + p_q_old1[3] = *params[param_p4_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Equalizer 5 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer5band_audio_module::equalizer5band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; +} + +void equalizer5band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer5band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer5band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } +} + +void equalizer5band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer5band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; + } else { + + clip_in -= std::min(clip_in, numsamples); + clip_out -= std::min(clip_out, numsamples); + meter_in = 0.f; + meter_out = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + float maxIn = std::max(fabs(inL), fabs(inR)); + float maxOut = std::max(fabs(outL), fabs(outR)); + + if(maxIn > 1.f) { + clip_in = srate >> 3; + } + if(maxOut > 1.f) { + clip_out = srate >> 3; + } + // set up in / out meters + if(maxIn > meter_in) { + meter_in = maxIn; + } + if(maxOut > meter_out) { + meter_out = maxOut; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 3; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // 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; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer5band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer5band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer5band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2]) + { + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +}