diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index 56305bcb99..a41db4ca35 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "primitives.h" #include "preset.h" @@ -306,6 +307,10 @@ struct plugin_metadata_iface virtual int get_input_count()=0; /// @return number of audio outputs virtual int get_output_count()=0; + /// @return number of optional inputs + virtual int get_inputs_optional()=0; + /// @return number of optional outputs + virtual int get_outputs_optional()=0; /// @return true if plugin can work in hard-realtime conditions virtual bool is_rt_capable()=0; /// @return true if plugin has MIDI input @@ -489,6 +494,8 @@ public: const char *get_label() { return Metadata::impl_get_label(); } int get_input_count() { return Metadata::in_count; } int get_output_count() { return Metadata::out_count; } + int get_inputs_optional() { return Metadata::ins_optional; } + int get_outputs_optional() { return Metadata::outs_optional; } int get_param_count() { return Metadata::param_count; } bool get_midi() { return Metadata::support_midi; } bool requires_midi() { return Metadata::require_midi; } @@ -528,6 +535,8 @@ public: const char *get_label() { return impl->get_label(); } int get_input_count() { return impl->get_input_count(); } int get_output_count() { return impl->get_output_count(); } + int get_inputs_optional() { return impl->get_inputs_optional(); } + int get_outputs_optional() { return impl->get_outputs_optional(); } int get_param_count() { return impl->get_param_count(); } bool get_midi() { return impl->get_midi(); } bool requires_midi() { return impl->requires_midi(); } @@ -555,9 +564,37 @@ public: static const char *impl_get_id() { return id; } \ static const char *impl_get_label() { return label; } \ - extern const char *calf_copyright_info; +bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true); + +/// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0) +static inline float dB_grid(float amp) +{ + return log(amp) * (1.0 / log(256.0)) + 0.4; +} + +template +static bool get_graph(Fx &fx, int subindex, float *data, int points) +{ + for (int i = 0; i < points; i++) + { + typedef std::complex cfloat; + double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); + data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate)); + } + return true; +} + +/// convert normalized grid-ish value back to amplitude value +static inline float dB_grid_inv(float pos) +{ + return pow(256.0, pos - 0.4); +} + +/// set drawing color based on channel index (0 or 1) +void set_channel_color(cairo_iface *context, int channel); + }; #endif diff --git a/plugins/ladspa_effect/calf/calf/metadata.h b/plugins/ladspa_effect/calf/calf/metadata.h index c959e1940b..22d9f22a56 100644 --- a/plugins/ladspa_effect/calf/calf/metadata.h +++ b/plugins/ladspa_effect/calf/calf/metadata.h @@ -31,21 +31,21 @@ struct flanger_metadata: public plugin_metadata { public: enum { par_delay, par_depth, par_rate, par_fb, par_stereo, par_reset, par_amount, par_dryamount, param_count }; - enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("flanger", "flanger", "Flanger") }; struct phaser_metadata: public plugin_metadata { enum { par_freq, par_depth, par_rate, par_fb, par_stages, par_stereo, par_reset, par_amount, par_dryamount, param_count }; - enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("phaser", "phaser", "Phaser") }; struct filter_metadata: public plugin_metadata { enum { par_cutoff, par_resonance, par_mode, par_inertia, param_count }; - enum { in_count = 2, out_count = 2, rt_capable = true, require_midi = false, support_midi = false }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = false, support_midi = false }; PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter") /// do not export mode and inertia as CVs, as those are settings and not parameters bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } @@ -55,7 +55,7 @@ struct filter_metadata: public plugin_metadata struct filterclavier_metadata: public plugin_metadata { enum { par_transpose, par_detune, par_max_resonance, par_mode, par_inertia, param_count }; - enum { in_count = 2, out_count = 2, rt_capable = true, require_midi = true, support_midi = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = true, support_midi = true }; PLUGIN_NAME_ID_LABEL("filterclavier", "filterclavier", "Filterclavier") /// do not export mode and inertia as CVs, as those are settings and not parameters bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } @@ -64,14 +64,14 @@ struct filterclavier_metadata: public plugin_metadata struct reverb_metadata: public plugin_metadata { 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 }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb") }; struct vintage_delay_metadata: public plugin_metadata { enum { par_bpm, par_divide, par_time_l, par_time_r, par_feedback, par_amount, par_mixmode, par_medium, par_dryamount, param_count }; - enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false }; PLUGIN_NAME_ID_LABEL("vintage_delay", "vintagedelay", "Vintage Delay") }; @@ -79,7 +79,7 @@ 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, par_meter_l, par_meter_h, param_count }; - enum { in_count = 2, out_count = 2, support_midi = true, require_midi = false, rt_capable = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker") }; @@ -88,10 +88,16 @@ struct multichorus_metadata: public plugin_metadata { public: enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, par_overlap, param_count }; - enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false }; PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus") }; +enum CalfEqMode { + MODE12DB, + MODE24DB, + MODE36DB +}; + /// Monosynth - metadata struct monosynth_metadata: public plugin_metadata { @@ -101,7 +107,7 @@ struct monosynth_metadata: public plugin_metadata par_keyfollow, par_legato, par_portamento, par_vel2filter, par_vel2amp, par_master, par_pwhlrange, par_lforate, par_lfodelay, par_lfofilter, par_lfopitch, par_lfopw, par_mwhl_lfo, par_scaledetune, param_count }; - enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true }; + enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; enum { step_size = 64, step_shift = 6 }; enum { modsrc_none, @@ -128,18 +134,20 @@ struct monosynth_metadata: public plugin_metadata }; /// Thor's compressor - metadata +/// Added some meters and stripped the weighting part 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_input,// param_freq, param_bw, - param_count }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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_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 { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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, @@ -150,7 +158,7 @@ struct sidechaincompressor_metadata: public plugin_metadata { - enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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_freq0, param_freq1, param_freq2, @@ -171,7 +179,7 @@ struct multibandcompressor_metadata: public plugin_metadata { - enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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, @@ -183,21 +191,25 @@ struct deesser_metadata: public plugin_metadata /// 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, + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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_outL, param_clip_inR, param_clip_outR, 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") + // dummy parameter numbers, shouldn't be used EVER, they're only there to avoid pushing LP/HP filters to a separate class + // and potentially making inlining and optimization harder for the compiler + enum { param_lp_active = 0xDEADBEEF, param_hp_active, param_hp_mode, param_lp_mode, param_hp_freq, param_lp_freq }; + enum { PeakBands = 3, first_graph_param = param_ls_active, last_graph_param = param_p3_q }; + PLUGIN_NAME_ID_LABEL("equalizer5band", "eq5", "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 { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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, @@ -209,12 +221,13 @@ struct equalizer8band_metadata: public plugin_metadata 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") + enum { PeakBands = 4, first_graph_param = param_hp_active, last_graph_param = param_p4_q }; + PLUGIN_NAME_ID_LABEL("equalizer8band", "eq8", "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 { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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, @@ -230,7 +243,18 @@ struct equalizer12band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, 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_mode, param_freq, param_amount, param_offset, param_mono, param_reset, param_count }; + PLUGIN_NAME_ID_LABEL("pulsator", "pulsator", "Pulsator") }; /// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was @@ -319,7 +343,7 @@ struct organ_enums /// Organ - metadata struct organ_metadata: public organ_enums, public plugin_metadata { - enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true }; + enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ") plugin_command_info *get_commands(); const char **get_default_configure_vars(); @@ -329,7 +353,7 @@ struct organ_metadata: public organ_enums, public plugin_metadata { enum { par_master, par_soundfont, par_interpolation, par_reverb, par_chorus, param_count }; - enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = false }; + enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false }; PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth") const char **get_default_configure_vars(); }; @@ -399,7 +423,7 @@ struct wavetable_metadata: public plugin_metadata par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3fade, par_eg3release, par_eg3velscl, par_pwhlrange, param_count }; - enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true }; + enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; enum { step_size = 64 }; PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable") }; diff --git a/plugins/ladspa_effect/calf/calf/modulelist.h b/plugins/ladspa_effect/calf/calf/modulelist.h index 83c123cad1..fd1531f366 100644 --- a/plugins/ladspa_effect/calf/calf/modulelist.h +++ b/plugins/ladspa_effect/calf/calf/modulelist.h @@ -13,9 +13,10 @@ 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") + PER_MODULE_ITEM(pulsator, false, "pulsator") + PER_MODULE_ITEM(equalizer5band, false, "eq5") + PER_MODULE_ITEM(equalizer8band, false, "eq8") + PER_MODULE_ITEM(equalizer12band, false, "eq12") #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 e8c4a5e223..ee8906772d 100644 --- a/plugins/ladspa_effect/calf/calf/modules.h +++ b/plugins/ladspa_effect/calf/calf/modules.h @@ -37,7 +37,7 @@ namespace calf_plugins { using namespace dsp; struct ladspa_plugin_info; - + #if 0 class amp_audio_module: public null_audio_module { @@ -846,82 +846,6 @@ public: bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); }; -class compressor_audio_module: public audio_module, public line_graph_iface { -private: - float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, threshold, ratio, knee, makeup, compressedKneeStop, adjKneeStart; - float old_threshold, old_ratio, old_knee, old_makeup, old_bypass; - int last_generation; - uint32_t clip; - aweighter awL, awR; - biquad_d2 bpL, bpR; -public: - float *ins[in_count]; - float *outs[out_count]; - float *params[param_count]; - uint32_t srate; - bool is_active; - compressor_audio_module(); - void activate(); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - - inline float output_level(float slope) { - return slope * output_gain(slope, false) * makeup; - } - - inline float output_gain(float linSlope, bool rms) { - if(linSlope > (rms ? adjKneeStart : linKneeStart)) { - float slope = log(linSlope); - if(rms) slope *= 0.5f; - - float gain = 0.f; - float delta = 0.f; - if(IS_FAKE_INFINITY(ratio)) { - gain = threshold; - delta = 0.f; - } else { - gain = (slope - threshold) / ratio + threshold; - delta = 1.f / ratio; - } - - if(knee > 1.f && slope < kneeStop) { - gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta); - } - - return exp(gain - slope); - } - - return 1.f; - } - - void set_sample_rate(uint32_t sr); - - virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); - virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context); - virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); - - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) - { - subindex_graph = 0; - subindex_dot = 0; - subindex_gridline = generation ? INT_MAX : 0; - - if (fabs(threshold-old_threshold) + fabs(ratio - old_ratio) + fabs(knee - old_knee) + fabs( makeup - old_makeup) + fabs( *params[param_bypass] - old_bypass) > 0.01f) - { - old_threshold = threshold; - old_ratio = ratio; - old_knee = knee; - old_makeup = makeup; - old_bypass = *params[param_bypass]; - last_generation++; - } - - if (generation == last_generation) - subindex_graph = 2; - return last_generation; - } -}; - class gain_reduction_audio_module { private: float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; @@ -949,6 +873,32 @@ public: virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); }; +/// Compressor by Thor +class compressor_audio_module: public audio_module, public line_graph_iface { +private: + uint32_t clip_in, clip_out; + float meter_in, meter_out; + gain_reduction_audio_module compressor; +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; + compressor_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + 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); +}; + /// 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: @@ -1088,30 +1038,31 @@ public: 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 { +/// Equalizer N Band by Markus Schmidt (based on Krzysztof's filters) +template +class equalizerNband_audio_module: public audio_module, public frequency_response_line_graph { +public: + typedef audio_module AM; + using AM::in_count; + using AM::out_count; + using AM::param_count; + using AM::PeakBands; private: + enum { graph_param_count = BaseClass::last_graph_param - BaseClass::first_graph_param + 1, params_per_band = AM::param_p2_active - AM::param_p1_active }; 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]; + float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands]; + float old_params_for_graph[graph_param_count]; 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]; + CalfEqMode hp_mode, lp_mode; + biquad_d2 hp[3][2], lp[3][2]; biquad_d2 lsL, lsR, hsL, hsR; - biquad_d2 pL[8], pR[8]; + biquad_d2 pL[PeakBands], pR[PeakBands]; + + inline void process_hplp(float &left, float &right); public: typedef std::complex cfloat; float *ins[in_count]; @@ -1120,190 +1071,77 @@ public: uint32_t srate; bool is_active; volatile int last_generation, last_calculated_generation; - equalizer12band_audio_module(); + equalizerNband_audio_module(); void activate(); void deactivate(); + void params_changed(); - float freq_gain(int index, double freq, uint32_t sr) + float freq_gain(int index, double freq, uint32_t sr); + void set_sample_rate(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; + srate = 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 8 Band by Markus Schmidt (based on Krzysztof's filters) -class equalizer8band_audio_module: public audio_module, public frequency_response_line_graph { +typedef equalizerNband_audio_module equalizer5band_audio_module; +typedef equalizerNband_audio_module equalizer8band_audio_module; +typedef equalizerNband_audio_module equalizer12band_audio_module; + +/// LFO by Markus +class lfo_audio_module { 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]; + float phase, freq, offset, amount; + int mode; uint32_t srate; bool is_active; - volatile int last_generation, last_calculated_generation; - equalizer8band_audio_module(); +public: + lfo_audio_module(); + void set_params(float f, int m, float o, uint32_t sr, float amount = 1.f); + float get_value(); + void advance(uint32_t count); + void set_phase(float ph); 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); + float get_value_from_phase(float ph, float off); + virtual bool get_graph(float *data, int points, cairo_iface *context); + virtual bool get_dot(float &x, float &y, int &size, cairo_iface *context); }; -/// Equalizer 5 Band by Markus Schmidt (based on Krzysztof's filters) -class equalizer5band_audio_module: public audio_module, public frequency_response_line_graph { +/// Pulsator by Markus Schmidt +class pulsator_audio_module: public audio_module, public frequency_response_line_graph { private: - 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 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]; + uint32_t clip_inL, clip_inR, clip_outL, clip_outR; + float meter_inL, meter_inR, meter_outL, meter_outR; + float offset_old; + int mode_old; + bool clear_reset; + lfo_audio_module lfoL, lfoR; 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(); + pulsator_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); + void params_reset() + { + if (clear_reset) { + *params[param_reset] = 0.f; + clear_reset = false; + } + } 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); }; /// Filterclavier --- MIDI controlled filter by Hans Baier diff --git a/plugins/ladspa_effect/calf/calf/preset.h b/plugins/ladspa_effect/calf/calf/preset.h index c6a6ec4f8a..c74a8fe0d1 100644 --- a/plugins/ladspa_effect/calf/calf/preset.h +++ b/plugins/ladspa_effect/calf/calf/preset.h @@ -89,6 +89,26 @@ typedef std::vector preset_vector; /// A single list of presets (usually there are two - @see get_builtin_presets(), get_user_presets() ) struct preset_list { + /// Plugin list item + struct plugin_snapshot + { + /// Preset offset + int preset_offset; + /// Plugin type + std::string type; + /// Instance name + std::string instance_name; + /// Index of the first input port + int input_index; + /// Index of the first output port + int output_index; + /// Index of the first MIDI port + int midi_index; + + /// Reset to initial values + void reset(); + }; + /// Parser states enum parser_state { @@ -97,24 +117,33 @@ struct preset_list PRESET, ///< Inside preset definition VALUE, ///< Inside (empty) param tag VAR, ///< Inside (non-empty) var tag + PLUGIN, ///< Inside plugin element (calfjackhost snapshots only) + RACK, ///< Inside rack element (calfjackhost snapshots only) } state; /// Contained presets (usually for all plugins) preset_vector presets; /// Temporary preset used during parsing process plugin_preset parser_preset; + /// Temporary plugin desc used during parsing process + plugin_snapshot parser_plugin; /// Preset number counters for DSSI (currently broken) std::map last_preset_ids; /// The key used in current tag (for state == VAR) std::string current_key; + /// The file is loaded in rack mode (and rack/plugin elements are expected) + bool rack_mode; + /// List of plugin states for rack mode + std::vector plugins; /// Return the name of the built-in or user-defined preset file static std::string get_preset_filename(bool builtin); /// Load default preset list (built-in or user-defined) bool load_defaults(bool builtin); - void parse(const std::string &data); + /// Load preset list from an in-memory XML string + void parse(const std::string &data, bool in_rack_mode); /// Load preset list from XML file - void load(const char *filename); + void load(const char *filename, bool in_rack_mode); /// Save preset list as XML file void save(const char *filename); /// Append or replace a preset (replaces a preset with the same plugin and preset name) diff --git a/plugins/ladspa_effect/calf/calf/utils.h b/plugins/ladspa_effect/calf/calf/utils.h index 406c71ee74..ecb9105ded 100644 --- a/plugins/ladspa_effect/calf/calf/utils.h +++ b/plugins/ladspa_effect/calf/calf/utils.h @@ -147,6 +147,9 @@ extern std::string f2s(double value); /// float-to-string-that-doesn't-resemble-an-int extern std::string ff2s(double value); +/// Encode a key-value pair as XML attribute +std::string to_xml_attr(const std::string &key, const std::string &value); + /// Escape a string to be used in XML file std::string xml_escape(const std::string &src); diff --git a/plugins/ladspa_effect/calf/src/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index 62d5157ed7..bd71b27206 100644 --- a/plugins/ladspa_effect/calf/src/giface.cpp +++ b/plugins/ladspa_effect/calf/src/giface.cpp @@ -207,10 +207,10 @@ const char *calf_plugins::load_gui_xml(const std::string &plugin_id) return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/gui-" + plugin_id + ".xml").c_str()).c_str()); } catch(file_exception e) -#endif { return NULL; } +#endif } bool calf_plugins::check_for_message_context_ports(parameter_properties *parameters, int count) @@ -235,6 +235,63 @@ bool calf_plugins::check_for_string_ports(parameter_properties *parameters, int return false; } +bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies) +{ + if (subindex < 0 ) + return false; + if (use_frequencies) + { + if (subindex < 28) + { + vertical = true; + if (subindex == 9) legend = "100 Hz"; + if (subindex == 18) legend = "1 kHz"; + if (subindex == 27) legend = "10 kHz"; + float freq = 100; + if (subindex < 9) + freq = 10 * (subindex + 1); + else if (subindex < 18) + freq = 100 * (subindex - 9 + 1); + else if (subindex < 27) + freq = 1000 * (subindex - 18 + 1); + else + freq = 10000 * (subindex - 27 + 1); + pos = log(freq / 20.0) / log(1000); + if (!legend.empty()) + context->set_source_rgba(0, 0, 0, 0.2); + else + context->set_source_rgba(0, 0, 0, 0.1); + return true; + } + subindex -= 28; + } + if (subindex >= 32) + return false; + float gain = 16.0 / (1 << subindex); + pos = dB_grid(gain); + if (pos < -1) + return false; + if (subindex != 4) + context->set_source_rgba(0, 0, 0, subindex & 1 ? 0.1 : 0.2); + if (!(subindex & 1)) + { + std::stringstream ss; + ss << (24 - 6 * subindex) << " dB"; + legend = ss.str(); + } + vertical = false; + return true; +} + +void calf_plugins::set_channel_color(cairo_iface *context, int channel) +{ + if (channel & 1) + context->set_source_rgba(0.35, 0.4, 0.2, 1); + else + context->set_source_rgba(0.35, 0.4, 0.2, 0.5); + context->set_line_width(1.5); +} + #if USE_DSSI struct osc_cairo_control: public cairo_iface { @@ -322,4 +379,5 @@ calf_plugins::dssi_feedback_sender::~dssi_feedback_sender() // client->send("/iQuit"); delete client; } + #endif diff --git a/plugins/ladspa_effect/calf/src/modules.cpp b/plugins/ladspa_effect/calf/src/modules.cpp index 225e38712b..1c6a939ff4 100644 --- a/plugins/ladspa_effect/calf/src/modules.cpp +++ b/plugins/ladspa_effect/calf/src/modules.cpp @@ -30,7 +30,7 @@ using namespace dsp; using namespace calf_plugins; -const char *calf_plugins::calf_copyright_info = "(C) 2001-2008 Krzysztof Foltman, license: LGPL"; +const char *calf_plugins::calf_copyright_info = "(C) 2001-2009 Krzysztof Foltman, Thor Harald Johanssen, Markus Schmidt and others; license: LGPL"; //////////////////////////////////////////////////////////////////////////// @@ -215,25 +215,23 @@ CALF_PORT_NAMES(compressor) = {"In L", "In R", "Out L", "Out R"}; const char *compressor_detection_names[] = { "RMS", "Peak" }; const char *compressor_stereo_link_names[] = { "Average", "Maximum" }; -const char *compressor_weighting_names[] = { "Normal", "A-weighted", "Deesser (low)", "Deesser (med)", "Deesser (high)" }; CALF_PORT_PROPS(compressor) = { + { 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-In" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, { 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, 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, compressor_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" }, - { 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_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" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_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", "Reduction" }, }; CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; @@ -262,8 +260,8 @@ CALF_PORT_PROPS(sidechaincompressor) = { { 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, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, { 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" }, @@ -274,16 +272,16 @@ CALF_PORT_PROPS(sidechaincompressor) = { { 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" }, + { 250, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "F1 Freq" }, + { 4500, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "F2 Freq" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "F1 Level" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "F2 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" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" }, }; -CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8502, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; +CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; //////////////////////////////////////////////////////////////////////////// @@ -299,77 +297,77 @@ 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_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_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, { 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" }, { 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S" }, + { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S1" }, + { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" }, + { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" }, - { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q" }, - { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q" }, - { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q" }, + { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" }, + { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" }, + { 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" }, - { 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold" }, - { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack" }, - { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup0", "Makeup" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee0", "Knee" }, - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection" }, - { 1, 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, "compression0", "Gain Reduction" }, - { 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, "output0", "Output" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass0", "Bypass" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute0", "Mute" }, + { 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold 1" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio 1" }, + { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack 1" }, + { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release 1" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup0", "Makeup 1" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee0", "Knee 1" }, + { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection 1" }, + { 1, 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, "compression0", "Gain Reduction 1" }, + { 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, "output0", "Output 1" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass0", "Bypass 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute0", "Mute 1" }, - { 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold" }, - { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio" }, - { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup1", "Makeup" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee1", "Knee" }, - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection" }, - { 1, 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, "compression1", "Gain Reduction" }, - { 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, "output1", "Output" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass1", "Bypass" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute1", "Mute" }, + { 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold 2" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio 2" }, + { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack 2" }, + { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release 2" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup1", "Makeup 2" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee1", "Knee 2" }, + { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection 2" }, + { 1, 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, "compression1", "Gain Reduction 2" }, + { 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, "output1", "Output 2" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass1", "Bypass 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute1", "Mute 2" }, - { 0.015625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold" }, - { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio" }, - { 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack" }, - { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup2", "Makeup" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee2", "Knee" }, - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection" }, - { 1, 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, "compression2", "Gain Reduction" }, - { 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, "output2", "Output" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass2", "Bypass" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute2", "Mute" }, + { 0.015625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold 3" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio 3" }, + { 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack 3" }, + { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release 3" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup2", "Makeup 3" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee2", "Knee 3" }, + { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection 3" }, + { 1, 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, "compression2", "Gain Reduction 3" }, + { 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, "output2", "Output 3" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass2", "Bypass 3" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute2", "Mute 3" }, - { 0.0078125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold" }, - { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio" }, - { 6.25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack" }, - { 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup3", "Makeup" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee3", "Knee" }, - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection" }, - { 1, 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, "compression3", "Gain Reduction" }, - { 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, "output3", "Output" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute" }, + { 0.0078125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold 4" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio 4" }, + { 6.25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack 4" }, + { 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release 4" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup3", "Makeup 4" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee3", "Knee 4" }, + { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection 4" }, + { 1, 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, "compression3", "Gain Reduction 4" }, + { 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, "output3", "Output 4" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute 4" }, }; -CALF_PLUGIN_INFO(multibandcompressor) = { 0x8502, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; +CALF_PLUGIN_INFO(multibandcompressor) = { 0x8516, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; //////////////////////////////////////////////////////////////////////////// @@ -400,167 +398,121 @@ CALF_PORT_PROPS(deesser) = { { 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_PLUGIN_INFO(deesser) = { 0x8515, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; + +//////////////////////////////////////////////////////////////////////////// +// A few macros to make + +#define BYPASS_AND_LEVEL_PARAMS \ + { 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 Gain" }, \ + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output Gain" }, + +#define METERING_PARAMS \ + { 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", "Meter-InL" }, \ + { 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", "Meter-InR" }, \ + { 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", "Meter-OutL" }, \ + { 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", "Meter-OutR" }, \ + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, \ + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, \ + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, \ + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, + +#define LPHP_PARAMS \ + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "HP Active" }, \ + { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "HP Freq" }, \ + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "HP Mode" }, \ + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "LP Active" }, \ + { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "LP Freq" }, \ + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "LP Mode" }, \ + +#define SHELF_PARAMS \ + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "LS Active" }, \ + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level L" }, \ + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq L" }, \ + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "HS Active" }, \ + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level H" }, \ + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq H" }, + +#define EQ_BAND_PARAMS(band, frequency) \ + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p" #band "_active", "F" #band " Active" }, \ + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p" #band "_level", "Level " #band }, \ + { frequency, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p" #band "_freq", "Freq " #band }, \ + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p" #band "_q", "Q " #band }, //////////////////////////////////////////////////////////////////////////// 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" }, + BYPASS_AND_LEVEL_PARAMS + METERING_PARAMS + SHELF_PARAMS + EQ_BAND_PARAMS(1, 250) + EQ_BAND_PARAMS(2, 1000) + EQ_BAND_PARAMS(3, 2500) }; -CALF_PLUGIN_INFO(equalizer5band) = { 0x8501, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; +CALF_PLUGIN_INFO(equalizer5band) = { 0x8511, "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"}; +const char *rolloff_mode_names[] = {"12dB/oct", "24dB/oct", "36dB/oct"}; 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" }, + BYPASS_AND_LEVEL_PARAMS + METERING_PARAMS + LPHP_PARAMS + SHELF_PARAMS + EQ_BAND_PARAMS(1, 250) + EQ_BAND_PARAMS(2, 1000) + EQ_BAND_PARAMS(3, 2500) + EQ_BAND_PARAMS(4, 5000) }; -CALF_PLUGIN_INFO(equalizer8band) = { 0x8501, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; +CALF_PLUGIN_INFO(equalizer8band) = { 0x8512, "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" }, + BYPASS_AND_LEVEL_PARAMS + METERING_PARAMS + LPHP_PARAMS + SHELF_PARAMS + EQ_BAND_PARAMS(1, 60) + EQ_BAND_PARAMS(2, 120) + EQ_BAND_PARAMS(3, 250) + EQ_BAND_PARAMS(4, 500) + EQ_BAND_PARAMS(5, 1000) + EQ_BAND_PARAMS(6, 2500) + EQ_BAND_PARAMS(7, 4000) + EQ_BAND_PARAMS(8, 6000) }; -CALF_PLUGIN_INFO(equalizer12band) = { 0x8501, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; +CALF_PLUGIN_INFO(equalizer12band) = { 0x8513, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(pulsator) = {"In L", "In R", "Out L", "Out R"}; + +const char *pulsator_mode_names[] = { "Sine", "Triangle", "Square", "Saw up", "Saw down" }; + +CALF_PORT_PROPS(pulsator) = { + BYPASS_AND_LEVEL_PARAMS + METERING_PARAMS + { 0, 0, 4, 0, PF_ENUM | PF_CTL_COMBO, pulsator_mode_names, "mode", "Mode" }, + { 1, 0.01, 100, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Frequency" }, + { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "amount", "Modulation" }, + { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "offset", "Offset L/R" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mono", "Mono-in" }, + { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, +}; + +CALF_PLUGIN_INFO(pulsator) = { 0x8514, "Pulsator", "Calf Pulsator", "Markus Schmidt", calf_plugins::calf_copyright_info, "ModulationPlugin" }; //////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ladspa_effect/calf/src/modules_dsp.cpp b/plugins/ladspa_effect/calf/src/modules_dsp.cpp index 5258c04753..d30672ca31 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -31,87 +31,6 @@ using namespace dsp; using namespace calf_plugins; -/// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0) -static inline float dB_grid(float amp) -{ - return log(amp) * (1.0 / log(256.0)) + 0.4; -} - -template -static bool get_graph(Fx &fx, int subindex, float *data, int points) -{ - for (int i = 0; i < points; i++) - { - typedef std::complex cfloat; - double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate)); - } - return true; -} - -/// convert normalized grid-ish value back to amplitude value -static inline float dB_grid_inv(float pos) -{ - return pow(256.0, pos - 0.4); -} - -static void set_channel_color(cairo_iface *context, int channel) -{ - if (channel & 1) - context->set_source_rgba(0.35, 0.4, 0.2, 1); - else - context->set_source_rgba(0.35, 0.4, 0.2, 0.5); - context->set_line_width(1.5); -} - -static bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true) -{ - if (subindex < 0 ) - return false; - if (use_frequencies) - { - if (subindex < 28) - { - vertical = true; - if (subindex == 9) legend = "100 Hz"; - if (subindex == 18) legend = "1 kHz"; - if (subindex == 27) legend = "10 kHz"; - float freq = 100; - if (subindex < 9) - freq = 10 * (subindex + 1); - else if (subindex < 18) - freq = 100 * (subindex - 9 + 1); - else if (subindex < 27) - freq = 1000 * (subindex - 18 + 1); - else - freq = 10000 * (subindex - 27 + 1); - pos = log(freq / 20.0) / log(1000); - if (!legend.empty()) - context->set_source_rgba(0, 0, 0, 0.2); - else - context->set_source_rgba(0, 0, 0, 0.1); - return true; - } - subindex -= 28; - } - if (subindex >= 32) - return false; - float gain = 16.0 / (1 << subindex); - pos = dB_grid(gain); - if (pos < -1) - return false; - if (subindex != 4) - context->set_source_rgba(0, 0, 0, subindex & 1 ? 0.1 : 0.2); - if (!(subindex & 1)) - { - std::stringstream ss; - ss << (24 - 6 * subindex) << " dB"; - legend = ss.str(); - } - vertical = false; - return true; -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) @@ -425,218 +344,6 @@ float multichorus_audio_module::freq_gain(int subindex, float freq, float srate) return (subindex ? right : left).freq_gain(freq, srate); } -/////////////////////////////////////////////////////////////////////////////////////////////// - -compressor_audio_module::compressor_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; -} - -void compressor_audio_module::activate() -{ - is_active = true; - linSlope = 0.f; - peak = 0.f; - clip = 0.f; -} - -void compressor_audio_module::deactivate() -{ - is_active = false; -} - -void compressor_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - awL.set(sr); - awR.set(sr); -} - -bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) -{ - if (!is_active) - return false; - if (subindex > 1) // 1 - return false; - for (int i = 0; i < points; i++) - { - float input = dB_grid_inv(-1.0 + i * 2.0 / (points - 1)); - float output = output_level(input); - if (subindex == 0) - data[i] = dB_grid(input); - else - data[i] = dB_grid(output); - } - if (subindex == (*params[param_bypass] > 0.5f ? 1 : 0)) - context->set_source_rgba(0.35, 0.4, 0.2, 0.3); - else { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - context->set_line_width(2); - } - return true; -} - -bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) -{ - if (!is_active) - return false; - if (!subindex) - { - bool rms = *params[param_detection] == 0; - float det = rms ? sqrt(detected) : detected; - x = 0.5 + 0.5 * dB_grid(det); - y = dB_grid(*params[param_bypass] > 0.5f ? det : output_level(det)); - return *params[param_bypass] > 0.5f ? false : true; - } - return false; -} - -bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) -{ - bool tmp; - vertical = (subindex & 1) != 0; - bool result = get_freq_gridline(subindex >> 1, pos, tmp, legend, context, false); - if (result && vertical) { - if ((subindex & 4) && !legend.empty()) { - legend = ""; - } - else { - size_t pos = legend.find(" dB"); - if (pos != std::string::npos) - legend.erase(pos); - } - pos = 0.5 + 0.5 * pos; - } - return result; -} - -// In case of doubt: this function is written by Thor. I just moved it to this file, damaging -// the output of "git annotate" in the process. -uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - - if(bypass) { - numsamples += offset; - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - - if(params[param_compression] != NULL) { - *params[param_compression] = 1.f; - } - - if(params[param_clip] != NULL) { - *params[param_clip] = 0.f; - } - - if(params[param_peak] != NULL) { - *params[param_peak] = 0.f; - } - - return inputs_mask; - } - - bool rms = *params[param_detection] == 0; - bool average = *params[param_stereo_link] == 0; - int aweighting = fastf2i_drm(*params[param_aweighting]); - float linThreshold = *params[param_threshold]; - ratio = *params[param_ratio]; - float attack = *params[param_attack]; - float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); - float release = *params[param_release]; - float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); - makeup = *params[param_makeup]; - knee = *params[param_knee]; - - float linKneeSqrt = sqrt(knee); - linKneeStart = linThreshold / linKneeSqrt; - adjKneeStart = linKneeStart*linKneeStart; - float linKneeStop = linThreshold * linKneeSqrt; - - threshold = log(linThreshold); - kneeStart = log(linKneeStart); - kneeStop = log(linKneeStop); - compressedKneeStop = (kneeStop - threshold) / ratio + threshold; - - if (aweighting >= 2) - { - bpL.set_highshelf_rbj(5000, 0.707, 10 << (aweighting - 2), srate); - bpR.copy_coeffs(bpL); - bpL.sanitize(); - bpR.sanitize(); - } - - numsamples += offset; - - float compression = 1.f; - peak = 0.f; - clip -= std::min(clip, numsamples); - - while(offset < numsamples) { - float left = ins[0][offset] * *params[param_input]; - float right = ins[1][offset] * *params[param_input]; - - if(aweighting == 1) { - left = awL.process(left); - right = awR.process(right); - } - else if(aweighting >= 2) { - left = bpL.process(left); - right = bpR.process(right); - } - - float absample = average ? (fabs(left) + fabs(right)) * 0.5f : std::max(fabs(left), fabs(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; - - 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; - - ++offset; - - float maxLR = std::max(fabs(outL), fabs(outR)); - if(maxLR > peak) - peak = maxLR; - - if(peak > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */ - } - - detected = linSlope; - - if(params[param_compression] != NULL) { - *params[param_compression] = compression; - } - - if(params[param_clip] != NULL) { - *params[param_clip] = clip; - } - - if(params[param_peak] != NULL) { - *params[param_peak] = peak; - } - - return inputs_mask; -} - - /// Multibandcompressor by Markus Schmidt /// /// This module splits the signal in four different bands @@ -1050,6 +757,161 @@ int multibandcompressor_audio_module::get_changed_offsets(int index, int generat return 0; } +/// Compressor originally by Thor +/// +/// This module provides Thor's original compressor without any sidechain or weighting +/////////////////////////////////////////////////////////////////////////////////////////////// + +compressor_audio_module::compressor_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; +} + +void compressor_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 compressor_audio_module::deactivate() +{ + is_active = false; + compressor.deactivate(); +} + +void compressor_audio_module::params_changed() +{ + 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 compressor_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; + compressor.set_sample_rate(srate); +} + +uint32_t compressor_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; + + compressor.process(leftAC, rightAC, leftSC, rightSC); + + 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 + } + // 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 compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + return compressor.get_graph(subindex, data, points, context); +} + +bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +{ + if (!is_active) + return false; + return compressor.get_dot(subindex, x, y, size, context); +} + +bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) + return false; + return compressor.get_gridline(subindex, pos, vertical, legend, context); +} + +int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) + return false; + return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); +} + /// Sidecain Compressor by Markus Schmidt /// /// This module splits the signal in a sidechain- and a process signal. @@ -1867,131 +1729,144 @@ int gain_reduction_audio_module::get_changed_offsets(int generation, int &subind /// of different chained filters. /////////////////////////////////////////////////////////////////////////////////////////////// -equalizer12band_audio_module::equalizer12band_audio_module() +template +equalizerNband_audio_module::equalizerNband_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; + clip_inL = clip_inR = clip_outL = clip_outR = 0.f; + meter_inL = meter_inR = meter_outL = meter_outR = 0.f; } -void equalizer12band_audio_module::activate() +template +void equalizerNband_audio_module::activate() { is_active = true; // set all filters params_changed(); } -void equalizer12band_audio_module::deactivate() + +template +void equalizerNband_audio_module::deactivate() { is_active = false; } -void equalizer12band_audio_module::params_changed() +static inline void copy_lphp(biquad_d2 filters[3][2]) +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + if (i || j) + filters[i][j].copy_coeffs(filters[0][0]); +} + +template +void equalizerNband_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]; + + // lp/hp first (if available) + if (has_lphp) + { + hp_mode = (CalfEqMode)(int)*params[AM::param_hp_mode]; + lp_mode = (CalfEqMode)(int)*params[AM::param_lp_mode]; + + float hpfreq = *params[AM::param_hp_freq], lpfreq = *params[AM::param_lp_freq]; + + if(hpfreq != hp_freq_old) { + hp[0][0].set_hp_rbj(hpfreq, 0.707, (float)srate, 1.0); + copy_lphp(hp); + hp_freq_old = hpfreq; + } + if(lpfreq != lp_freq_old) { + lp[0][0].set_lp_rbj(lpfreq, 0.707, (float)srate, 1.0); + copy_lphp(lp); + lp_freq_old = lpfreq; + } } - 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); + + // then shelves + float hsfreq = *params[AM::param_hs_freq], hslevel = *params[AM::param_hs_level]; + float lsfreq = *params[AM::param_ls_freq], lslevel = *params[AM::param_ls_level]; + + if(lsfreq != ls_freq_old or lslevel != ls_level_old) { + lsL.set_lowshelf_rbj(lsfreq, 0.707, lslevel, (float)srate); lsR.copy_coeffs(lsL); - ls_level_old = *params[param_ls_level]; - ls_freq_old = *params[param_ls_freq]; + ls_level_old = lslevel; + ls_freq_old = lsfreq; } - 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); + if(hsfreq != hs_freq_old or hslevel != hs_level_old) { + hsL.set_highshelf_rbj(hsfreq, 0.707, hslevel, (float)srate); hsR.copy_coeffs(hsL); - hs_level_old = *params[param_hs_level]; - hs_freq_old = *params[param_hs_freq]; + hs_level_old = hslevel; + hs_freq_old = hsfreq; } - 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]; + for (int i = 0; i < AM::PeakBands; i++) + { + int offset = i * params_per_band; + float freq = *params[AM::param_p1_freq + offset]; + float level = *params[AM::param_p1_level + offset]; + float q = *params[AM::param_p1_q + offset]; + if(freq != p_freq_old[i] or level != p_level_old[i] or q != p_q_old[i]) { + pL[i].set_peakeq_rbj(freq, q, level, (float)srate); + pR[i].copy_coeffs(pL[i]); + p_freq_old[i] = freq; + p_level_old[i] = level; + p_q_old[i] = q; + } } } -void equalizer12band_audio_module::set_sample_rate(uint32_t sr) +template +inline void equalizerNband_audio_module::process_hplp(float &left, float &right) { - srate = sr; + if (!has_lphp) + return; + if (*params[AM::param_lp_active] > 0.f) + { + switch(lp_mode) + { + case MODE12DB: + left = lp[0][0].process(left); + right = lp[0][1].process(right); + break; + case MODE24DB: + left = lp[1][0].process(lp[0][0].process(left)); + right = lp[1][1].process(lp[0][1].process(right)); + break; + case MODE36DB: + left = lp[2][0].process(lp[1][0].process(lp[0][0].process(left))); + right = lp[2][1].process(lp[1][1].process(lp[0][1].process(right))); + break; + } + } + if (*params[AM::param_hp_active] > 0.f) + { + switch(hp_mode) + { + case MODE12DB: + left = hp[0][0].process(left); + right = hp[0][1].process(right); + break; + case MODE24DB: + left = hp[1][0].process(hp[0][0].process(left)); + right = hp[1][1].process(hp[0][1].process(right)); + break; + case MODE36DB: + left = hp[2][0].process(hp[1][0].process(hp[0][0].process(left))); + right = hp[2][1].process(hp[1][1].process(hp[0][1].process(right))); + break; + } + } } -uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +#define SET_IF_CONNECTED(param) if (params[AM::param_##param] != NULL) *params[AM::param_##param] = param; + +template +uint32_t equalizerNband_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - bool bypass = *params[param_bypass] > 0.5f; + bool bypass = *params[AM::param_bypass] > 0.f; numsamples += offset; if(bypass) { // everything bypassed @@ -2001,14 +1876,8 @@ uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamp ++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; + clip_inL = clip_inR = clip_outL = clip_outR = 0.f; + meter_inL = meter_inR = meter_outL = meter_outR = 0.f; } else { clip_inL -= std::min(clip_inL, numsamples); @@ -2028,88 +1897,32 @@ uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamp float inL = ins[0][offset]; float inR = ins[1][offset]; // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; + inR *= *params[AM::param_level_in]; + inL *= *params[AM::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) { + process_hplp(procL, procR); + if(*params[AM::param_ls_active] > 0.f) { procL = lsL.process(procL); procR = lsR.process(procR); } - if(*params[param_hs_active] > 0.f) { + if(*params[AM::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); + for (int i = 0; i < AM::PeakBands; i++) + { + if(*params[AM::param_p1_active + i * params_per_band] > 0.f) { + procL = pL[i].process(procL); + procR = pR[i].process(procR); + } } - outL = procL * *params[param_level_out]; - outR = procR * *params[param_level_out]; + outL = procL * *params[AM::param_level_out]; + outR = procR * *params[AM::param_level_out]; // send to output outs[0][offset] = outL; @@ -2147,59 +1960,47 @@ uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamp } // cycle trough samples // clean up for(int i = 0; i < 3; ++i) { - hpL[i].sanitize(); - hpR[i].sanitize(); - lpL[i].sanitize(); - lpR[i].sanitize(); + hp[i][0].sanitize(); + hp[i][1].sanitize(); + lp[i][0].sanitize(); + lp[i][1].sanitize(); } lsL.sanitize(); hsR.sanitize(); - for(int i = 0; i < 8; ++i) { + for(int i = 0; i < AM::PeakBands; ++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; - } + SET_IF_CONNECTED(clip_inL) + SET_IF_CONNECTED(clip_inR) + SET_IF_CONNECTED(clip_outL) + SET_IF_CONNECTED(clip_outR) + SET_IF_CONNECTED(meter_inL) + SET_IF_CONNECTED(meter_inR) + SET_IF_CONNECTED(meter_outL) + SET_IF_CONNECTED(meter_outR) // whatever has to be returned x) return outputs_mask; } -bool equalizer12band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) + +#undef SET_IF_CONNECTED + +template +bool equalizerNband_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) { + if (index == AM::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) +template +bool equalizerNband_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) { if (!is_active) { return false; @@ -2208,95 +2009,22 @@ bool equalizer12band_audio_module::get_gridline(int index, int subindex, float & } } -int equalizer12band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +template +int equalizerNband_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]) + bool changed = false; + for (int i = 0; i < graph_param_count && !changed; i++) { - - 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]; + if (*params[AM::first_graph_param + i] != old_params_for_graph[i]) + changed = true; + } + if (changed) + { + for (int i = 0; i < graph_param_count; i++) + old_params_for_graph[i] = *params[AM::first_graph_param + i]; last_generation++; subindex_graph = 0; @@ -2314,17 +2042,169 @@ int equalizer12band_audio_module::get_changed_offsets(int index, int generation, return false; } -/// Equalizer 8 Band by Markus Schmidt +static inline float adjusted_lphp_gain(float **params, int param_active, int param_mode, biquad_d2 filter, float freq, float srate) +{ + if(*params[param_active] > 0.f) { + float gain = filter.freq_gain(freq, srate); + switch((int)*params[param_mode]) { + case MODE12DB: + return gain; + case MODE24DB: + return gain * gain; + case MODE36DB: + return gain * gain * gain; + } + } + return 1; +} + +template +float equalizerNband_audio_module::freq_gain(int index, double freq, uint32_t sr) +{ + float ret = 1.f; + if (use_hplp) + { + ret *= adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)sr); + ret *= adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)sr); + } + ret *= (*params[AM::param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[AM::param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + for (int i = 0; i < PeakBands; i++) + ret *= (*params[AM::param_p1_active + i * params_per_band] > 0.f) ? pL[i].freq_gain(freq, (float)sr) : 1; + return ret; +} + +template class equalizerNband_audio_module; +template class equalizerNband_audio_module; +template class equalizerNband_audio_module; + +/// LFO module by Markus +/// This module provides simple LFO's (sine=0, triangle=1, square=2, saw_up=3, saw_down=4) +/// get_value() returns a value between -1 and 1 +//////////////////////////////////////////////////////////////////////////////// +lfo_audio_module::lfo_audio_module() +{ + is_active = false; + phase = 0.f; +} + +void lfo_audio_module::activate() +{ + is_active = true; + phase = 0.f; +} + +void lfo_audio_module::deactivate() +{ + is_active = false; +} + +float lfo_audio_module::get_value() +{ + return get_value_from_phase(phase, offset) * amount; +} + +float lfo_audio_module::get_value_from_phase(float ph, float off) +{ + float val = 0.f; + float phs = ph + off; + if (phs >= 1.0) + phs = fmod(phs, 1.f); + switch (mode) { + default: + case 0: + // sine + val = sin((phs * 360.f) * M_PI / 180); + break; + case 1: + // triangle + if(phs > 0.75) + val = (phs - 0.75) * 4 - 1; + else if(phs > 0.5) + val = (phs - 0.5) * 4 * -1; + else if(phs > 0.25) + val = 1 - (phs - 0.25) * 4; + else + val = phs * 4; + break; + case 2: + // square + val = (phs < 0.5) ? -1 : +1; + break; + case 3: + // saw up + val = phs * 2.f - 1; + break; + case 4: + // saw down + val = 1 - phs * 2.f; + break; + } + return val; +} + +void lfo_audio_module::advance(uint32_t count) +{ + //this function walks from 0.f to 1.f and starts all over again + phase += count * freq * (1.0 / srate); + if (phase >= 1.0) + phase = fmod(phase, 1.f); +} + +void lfo_audio_module::set_phase(float ph) +{ + //set the phase from outsinde + phase = fabs(ph); + if (phase >= 1.0) + phase = fmod(phase, 1.f); +} + +void lfo_audio_module::set_params(float f, int m, float o, uint32_t sr, float a) +{ + // freq: a value in Hz + // mode: sine=0, triangle=1, square=2, saw_up=3, saw_down=4 + // offset: value between 0.f and 1.f to offset the lfo in time + freq = f; + mode = m; + offset = o; + srate = sr; + amount = a; +} + +bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + for (int i = 0; i < points; i++) { + float ph = (float)i / (float)points; + data[i] = get_value_from_phase(ph, offset) * amount; + } + return true; +} + +bool lfo_audio_module::get_dot(float &x, float &y, int &size, cairo_iface *context) +{ + if (!is_active) + return false; + float phs = phase + offset; + if (phs >= 1.0) + phs = fmod(phs, 1.f); + x = phase; + y = get_value_from_phase(phase, offset) * amount; + return true; +} + +/// Pulsator by Markus Schmidt /// -/// This module is based on Krzysztof's filters. It provides a couple -/// of different chained filters. +/// This module provides a couple +/// of different LFO's for modulating the level of a signal. /////////////////////////////////////////////////////////////////////////////////////////////// -equalizer8band_audio_module::equalizer8band_audio_module() +pulsator_audio_module::pulsator_audio_module() { is_active = false; srate = 0; - last_generation = 0; +// last_generation = 0; clip_inL = 0.f; clip_inR = 0.f; clip_outL = 0.f; @@ -2335,92 +2215,44 @@ equalizer8band_audio_module::equalizer8band_audio_module() meter_outR = 0.f; } -void equalizer8band_audio_module::activate() +void pulsator_audio_module::activate() { is_active = true; - // set all filters + lfoL.activate(); + lfoR.activate(); params_changed(); } -void equalizer8band_audio_module::deactivate() +void pulsator_audio_module::deactivate() { is_active = false; + lfoL.deactivate(); + lfoR.deactivate(); } -void equalizer8band_audio_module::params_changed() +void pulsator_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]; + lfoL.set_params(*params[param_freq], *params[param_mode], 0.f, srate, *params[param_amount]); + lfoR.set_params(*params[param_freq], *params[param_mode], *params[param_offset], srate, *params[param_amount]); + clear_reset = false; + if (*params[param_reset] >= 0.5) { + clear_reset = true; + lfoL.set_phase(0.f); + lfoR.set_phase(0.f); } } -void equalizer8band_audio_module::set_sample_rate(uint32_t sr) +void pulsator_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) +uint32_t pulsator_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; + uint32_t samples = numsamples + offset; if(bypass) { // everything bypassed - while(offset < numsamples) { + while(offset < samples) { outs[0][offset] = ins[0][offset]; outs[1][offset] = ins[1][offset]; ++offset; @@ -2434,6 +2266,11 @@ uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsampl meter_inR = 0.f; meter_outL = 0.f; meter_outR = 0.f; + + // LFO's should go on + lfoL.advance(numsamples); + lfoR.advance(numsamples); + } else { clip_inL -= std::min(clip_inL, numsamples); @@ -2446,7 +2283,7 @@ uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsampl meter_outR = 0.f; // process - while(offset < numsamples) { + while(offset < samples) { // cycle through samples float outL = 0.f; float outR = 0.f; @@ -2456,69 +2293,21 @@ uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsampl inR *= *params[param_level_in]; inL *= *params[param_level_in]; + if(*params[param_mono] > 0.5) { + inL = (inL + inR) * 0.5; + inR = inL; + } 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); - } + procL *= (lfoL.get_value() * 0.5 + *params[param_amount] / 2); + procR *= (lfoR.get_value() * 0.5 + *params[param_amount] / 2); - outL = procL * *params[param_level_out]; - outR = procR * *params[param_level_out]; + outL = procL + inL * (1 - *params[param_amount]); + outR = procR + inR * (1 - *params[param_amount]); + + outL *= *params[param_level_out]; + outR *= *params[param_level_out]; // send to output outs[0][offset] = outL; @@ -2553,20 +2342,11 @@ uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsampl // next sample ++offset; + + // advance lfo's + lfoL.advance(1); + lfoR.advance(1); } // 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) { @@ -2597,355 +2377,46 @@ uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsampl // 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) +bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, 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 if(index == param_freq) { + if(subindex == 0) { + context->set_source_rgba(0.35, 0.4, 0.2, 1); + return lfoL.get_graph(data, points, context); } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + if(subindex == 1) { + context->set_source_rgba(0.35, 0.4, 0.2, 0.5); + return lfoR.get_graph(data, points, context); } - 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) +bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, 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) { + } else if(index == param_freq) { + if(subindex == 0) { + context->set_source_rgba(0.35, 0.4, 0.2, 1); + return lfoL.get_dot(x, y, size, context); + } + if(subindex == 1) { + context->set_source_rgba(0.35, 0.4, 0.2, 0.5); + return lfoR.get_dot(x, y, size, context); + } 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; +} +bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (index == param_freq && !subindex) + { + pos = 0; + vertical = false; + return true; } return false; } diff --git a/plugins/ladspa_effect/calf/src/utils.cpp b/plugins/ladspa_effect/calf/src/utils.cpp index 338587f2c3..8376987328 100644 --- a/plugins/ladspa_effect/calf/src/utils.cpp +++ b/plugins/ladspa_effect/calf/src/utils.cpp @@ -69,6 +69,11 @@ std::string xml_escape(const std::string &src) return dest; } +std::string to_xml_attr(const std::string &key, const std::string &value) +{ + return " " + key + "=\"" + xml_escape(value) + "\""; +} + std::string load_file(const std::string &src) { std::string str;