From f344d4c1fe089dc687dca17c5d60d1155bc62281 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 00:01:11 +0100 Subject: [PATCH 1/7] + LV2: add external UI header (not used for anything yet) (cherry picked from commit f0719b1e8926595d869936865ba84f60284dd660) --- .../ladspa_effect/calf/calf/lv2_external_ui.h | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 plugins/ladspa_effect/calf/calf/lv2_external_ui.h diff --git a/plugins/ladspa_effect/calf/calf/lv2_external_ui.h b/plugins/ladspa_effect/calf/calf/lv2_external_ui.h new file mode 100644 index 000000000..242271ecc --- /dev/null +++ b/plugins/ladspa_effect/calf/calf/lv2_external_ui.h @@ -0,0 +1,101 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ +/***************************************************************************** + * + * This work is in public domain. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * If you have questions, contact Nedko Arnaudov or + * ask in #lad channel, FreeNode IRC network. + * + *****************************************************************************/ + +#ifndef LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED +#define LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED + +/** UI extension suitable for out-of-process UIs */ +#define LV2_EXTERNAL_UI_URI "http://lv2plug.in/ns/extensions/ui#external" + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +} /* Adjust editor indent */ +#endif + +/** + * When LV2_EXTERNAL_UI_URI UI is instantiated, the returned + * LV2UI_Widget handle must be cast to pointer to struct lv2_external_ui. + * UI is created in invisible state. + */ +struct lv2_external_ui +{ + /** + * Host calls this function regulary. UI library implementing the + * callback may do IPC or redraw the UI. + * + * @param _this_ the UI context + */ + void (* run)(struct lv2_external_ui * _this_); + + /** + * Host calls this function to make the plugin UI visible. + * + * @param _this_ the UI context + */ + void (* show)(struct lv2_external_ui * _this_); + + /** + * Host calls this function to make the plugin UI invisible again. + * + * @param _this_ the UI context + */ + void (* hide)(struct lv2_external_ui * _this_); +}; + +#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr) +#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr) +#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr) + +/** + * On UI instantiation, host must supply LV2_EXTERNAL_UI_URI + * feature. LV2_Feature::data must be pointer to struct lv2_external_ui_host. */ +struct lv2_external_ui_host +{ + /** + * Callback that plugin UI will call + * when UI (GUI window) is closed by user. + * This callback wil; be called during execution of lv2_external_ui::run() + * (i.e. not from background thread). + * + * After this callback is called, UI is defunct. Host must call + * LV2UI_Descriptor::cleanup(). If host wants to make the UI visible + * again UI must be reinstantiated. + * + * @param controller Host context associated with plugin UI, as + * supplied to LV2UI_Descriptor::instantiate() + */ + void (* ui_closed)(LV2UI_Controller controller); + + /** + * Optional (may be NULL) "user friendly" identifier which the UI + * may display to allow a user to easily associate this particular + * UI instance with the correct plugin instance as it is represented + * by the host (e.g. "track 1" or "channel 4"). + * + * If supplied by host, the string will be referenced only during + * LV2UI_Descriptor::instantiate() + */ + const char * plugin_human_id; +}; + +#if 0 +{ /* Adjust editor indent */ +#endif +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* #ifndef LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED */ From 4a59150d4ba3805390aff6ac3be89e8e586ae286 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 22:53:54 +0100 Subject: [PATCH 2/7] General refactoring. Start implementing external GUI. Constify metadata functions. Constify other functions that really needed it. Make variables keeping old state mutable for now. Move filter composition operations into biquad.h. Replace global function get_all_plugins with a singleton class that returns the same list (as const) or a single plugin by URI. Add a skeleton implementation of functions in lv2_external_ui and skeleton UI related functions for external UI. (cherry picked from commit ae7f7293961a3ea3b194b73ab35886f94e562cd7) --- plugins/ladspa_effect/calf/calf/audio_fx.h | 38 ++-- plugins/ladspa_effect/calf/calf/biquad.h | 76 ++++++- plugins/ladspa_effect/calf/calf/giface.h | 182 +++++++++-------- plugins/ladspa_effect/calf/calf/ladspa_wrap.h | 4 +- plugins/ladspa_effect/calf/calf/lv2wrap.h | 16 +- plugins/ladspa_effect/calf/calf/modmatrix.h | 8 +- plugins/ladspa_effect/calf/calf/modules.h | 193 ++++++------------ .../ladspa_effect/calf/calf/modules_synths.h | 6 +- plugins/ladspa_effect/calf/calf/multichorus.h | 4 +- plugins/ladspa_effect/calf/calf/onepole.h | 6 +- plugins/ladspa_effect/calf/src/giface.cpp | 24 +++ plugins/ladspa_effect/calf/src/modmatrix.cpp | 8 +- plugins/ladspa_effect/calf/src/modules.cpp | 2 +- .../ladspa_effect/calf/src/modules_dsp.cpp | 101 ++++----- plugins/ladspa_effect/calf/src/monosynth.cpp | 4 +- 15 files changed, 356 insertions(+), 316 deletions(-) diff --git a/plugins/ladspa_effect/calf/calf/audio_fx.h b/plugins/ladspa_effect/calf/calf/audio_fx.h index 56d08f6d6..bf61f9498 100644 --- a/plugins/ladspa_effect/calf/calf/audio_fx.h +++ b/plugins/ladspa_effect/calf/calf/audio_fx.h @@ -53,21 +53,21 @@ protected: gain_smoothing gs_wet, gs_dry; public: fixed_point phase, dphase; - float get_rate() { + float get_rate() const { return rate; } void set_rate(float rate) { this->rate = rate; dphase = rate/sample_rate*4096; } - float get_wet() { + float get_wet() const { return wet; } void set_wet(float wet) { this->wet = wet; gs_wet.set_inertia(wet); } - float get_dry() { + float get_dry() const { return dry; } void set_dry(float dry) { @@ -115,13 +115,13 @@ public: stages = 0; set_stages(6); } - float get_base_frq() { + float get_base_frq() const { return base_frq; } void set_base_frq(float _base_frq) { base_frq = _base_frq; } - int get_stages() { + int get_stages() const { return stages; } void set_stages(int _stages) { @@ -135,13 +135,13 @@ public: } stages = _stages; } - float get_mod_depth() { + float get_mod_depth() const { return mod_depth; } void set_mod_depth(float _mod_depth) { mod_depth = _mod_depth; } - float get_fb() { + float get_fb() const { return fb; } void set_fb(float fb) { @@ -196,7 +196,7 @@ public: *buf_out++ = sdry + swet; } } - float freq_gain(float freq, float sr) + float freq_gain(float freq, float sr) const { typedef std::complex cfloat; freq *= 2.0 * M_PI / sr; @@ -225,14 +225,14 @@ protected: float min_delay, mod_depth; sine_table sine; public: - float get_min_delay() { + float get_min_delay() const { return min_delay; } void set_min_delay(float min_delay) { this->min_delay = min_delay; this->min_delay_samples = (int)(min_delay * 65536.0 * sample_rate); } - float get_mod_depth() { + float get_mod_depth() const { return mod_depth; } void set_mod_depth(float mod_depth) { @@ -319,7 +319,7 @@ public: set_rate(get_rate()); set_min_delay(get_min_delay()); } - float get_fb() { + float get_fb() const { return fb; } void set_fb(float fb) { @@ -386,7 +386,7 @@ public: } last_delay_pos = delay_pos; } - float freq_gain(float freq, float sr) + float freq_gain(float freq, float sr) const { typedef std::complex cfloat; freq *= 2.0 * M_PI / sr; @@ -504,7 +504,7 @@ public: rdec[i]=exp(-float(tr[i] >> 16) / fDec); } } - float get_time() { + float get_time() const { return time; } void set_time(float time) { @@ -512,14 +512,14 @@ public: // fb = pow(1.0f/4096.0f, (float)(1700/(time*sr))); fb = 1.0 - 0.3 / (time * sr / 44100.0); } - float get_type() { + float get_type() const { return type; } void set_type(int type) { this->type = type; update_times(); } - float get_diffusion() { + float get_diffusion() const { return diffusion; } void set_diffusion(float diffusion) { @@ -531,7 +531,7 @@ public: this->diffusion = diffusion; update_times(); } - float get_fb() + float get_fb() const { return this->fb; } @@ -539,7 +539,7 @@ public: { this->fb = fb; } - float get_cutoff() { + float get_cutoff() const { return cutoff; } void set_cutoff(float cutoff) { @@ -604,7 +604,7 @@ public: virtual void filter_activate() = 0; virtual void sanitize() = 0; virtual int process_channel(uint16_t channel_no, float *in, float *out, uint32_t numsamples, int inmask) = 0; - virtual float freq_gain(int subindex, float freq, float srate) = 0; + virtual float freq_gain(int subindex, float freq, float srate) const = 0; virtual ~filter_module_iface() {} }; @@ -730,7 +730,7 @@ public: return filter[order - 1].empty() ? 0 : inmask; } - float freq_gain(int subindex, float freq, float srate) + float freq_gain(int subindex, float freq, float srate) const { float level = 1.0; for (int j = 0; j < order; j++) diff --git a/plugins/ladspa_effect/calf/calf/biquad.h b/plugins/ladspa_effect/calf/calf/biquad.h index e1f419508..99cf2a40a 100644 --- a/plugins/ladspa_effect/calf/calf/biquad.h +++ b/plugins/ladspa_effect/calf/calf/biquad.h @@ -305,7 +305,7 @@ public: /// Return the filter's gain at frequency freq /// @param freq Frequency to look up /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) + float freq_gain(float freq, float sr) const { typedef std::complex cfloat; freq *= 2.0 * M_PI / sr; @@ -316,7 +316,7 @@ public: /// Return H(z) the filter's gain at frequency freq /// @param z Z variable (e^jw) - cfloat h_z(const cfloat &z) + cfloat h_z(const cfloat &z) const { return (cfloat(a0) + double(a1) * z + double(a2) * z*z) / (cfloat(1.0) + double(b1) * z + double(b2) * z*z); @@ -396,7 +396,7 @@ struct biquad_d1: public biquad_coeffs dsp::zero(x2); dsp::zero(y2); } - inline bool empty() { + inline bool empty() const { return (y1 == 0.f && y2 == 0.f); } @@ -448,7 +448,7 @@ struct biquad_d2: public biquad_coeffs } /// Is the filter state completely silent? (i.e. set to 0 by sanitize function) - inline bool empty() { + inline bool empty() const { return (w1 == 0.f && w2 == 0.f); } @@ -575,6 +575,74 @@ struct biquad_d1_lerp: public biquad_coeffs }; +/// Compose two filters in series +template +class filter_compose { +public: + typedef std::complex cfloat; + F1 f1; + F2 f2; +public: + float process(float value) { + return f2.process(f1.process(value)); + } + + inline cfloat h_z(const cfloat &z) const { + return f1.h_z(z) * f2.h_z(z); + } + + /// Return the filter's gain at frequency freq + /// @param freq Frequency to look up + /// @param sr Filter sample rate (used to convert frequency to angular frequency) + float freq_gain(float freq, float sr) const + { + typedef std::complex cfloat; + freq *= 2.0 * M_PI / sr; + cfloat z = 1.0 / exp(cfloat(0.0, freq)); + + return std::abs(h_z(z)); + } + + void sanitize() { + f1.sanitize(); + f2.sanitize(); + } +}; + +/// Compose two filters in parallel +template +class filter_sum { +public: + typedef std::complex cfloat; + F1 f1; + F2 f2; +public: + float process(float value) { + return f2.process(value) + f1.process(value); + } + + inline cfloat h_z(const cfloat &z) const { + return f1.h_z(z) + f2.h_z(z); + } + + /// Return the filter's gain at frequency freq + /// @param freq Frequency to look up + /// @param sr Filter sample rate (used to convert frequency to angular frequency) + float freq_gain(float freq, float sr) const + { + typedef std::complex cfloat; + freq *= 2.0 * M_PI / sr; + cfloat z = 1.0 / exp(cfloat(0.0, freq)); + + return std::abs(h_z(z)); + } + + void sanitize() { + f1.sanitize(); + f2.sanitize(); + } +}; + }; #endif diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index a41db4ca3..eace9027b 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -168,17 +168,17 @@ struct line_graph_iface /// @param context cairo context to adjust (for multicolour graphs etc.) /// @retval true graph data was returned; subindex+1 graph may or may not be available /// @retval false graph data was not returned; subindex+1 graph does not exist either - virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) { return false; } + virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { return false; } /// Obtain subindex'th dot of parameter 'index' /// @param index parameter/dot number (usually tied to particular plugin control port) /// @param subindex dot number (there may be multiple dots graphs for one parameter) - virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) { return false; } + virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { return false; } /// Obtain subindex'th dot of parameter 'index' /// @param index parameter/dot number (usually tied to particular plugin control port) /// @param subindex dot number (there may be multiple dots graphs for one parameter) - virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) { return false; } + virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return false; } /// Obtain subindex'th static graph of parameter index (static graphs are only dependent on parameter value, not plugin state) /// @param index parameter/graph number (usually tied to particular plugin control port) @@ -189,7 +189,7 @@ struct line_graph_iface /// @param context cairo context to adjust (for multicolour graphs etc.) /// @retval true graph data was returned; subindex+1 graph may or may not be available /// @retval false graph data was not returned; subindex+1 graph does not exist either - virtual bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context) { return false; } + virtual bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context) const { return false; } /// Return which graphs need to be redrawn and which can be cached for later reuse /// @param index Parameter/graph number (usually tied to particular plugin control port) @@ -198,7 +198,7 @@ struct line_graph_iface /// @param subindex_dot First dot that has to be redrawn /// @param subindex_gridline First gridline/legend that has to be redrawn /// @retval Current generation (to pass when calling the function next time); if different than passed generation value, call the function again to retrieve which graph offsets should be put into cache - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) { subindex_graph = subindex_dot = subindex_gridline = 0; return 0; } + virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { subindex_graph = subindex_dot = subindex_gridline = 0; return 0; } /// Standard destructor to make compiler happy virtual ~line_graph_iface() {} @@ -229,22 +229,22 @@ struct table_column_info struct table_edit_iface { /// retrieve the table layout for specific parameter - virtual const table_column_info *get_table_columns(int param) = 0; + virtual const table_column_info *get_table_columns(int param) const = 0; /// return the current number of rows - virtual uint32_t get_table_rows(int param) = 0; + virtual uint32_t get_table_rows(int param) const = 0; /// retrieve data item from the plugin - virtual std::string get_cell(int param, int row, int column) { return calf_utils::i2s(row)+":"+calf_utils::i2s(column); } + virtual std::string get_cell(int param, int row, int column) const { return calf_utils::i2s(row)+":"+calf_utils::i2s(column); } /// set data item to the plugin - virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) { error.clear(); } + virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const { error.clear(); } /// return a line graph interface for a specific parameter/column (unused for now) - virtual line_graph_iface *get_graph_iface(int param, int column) { return NULL; } + virtual const line_graph_iface *get_graph_iface(int param, int column) const { return NULL; } /// return an editor name for a specific grid cell (unused for now - I don't even know how editors be implemented) - virtual const char *get_cell_editor(int param, int column) { return NULL; } + virtual const char *get_cell_editor(int param, int column) const { return NULL; } virtual ~table_edit_iface() {} }; @@ -294,53 +294,53 @@ struct ladspa_plugin_info struct plugin_metadata_iface { /// @return plugin long name - virtual const char *get_name() = 0; + virtual const char *get_name() const = 0; /// @return plugin LV2 label - virtual const char *get_id() = 0; + virtual const char *get_id() const = 0; /// @return plugin human-readable label - virtual const char *get_label() = 0; + virtual const char *get_label() const = 0; /// @return total number of parameters - virtual int get_param_count() = 0; + virtual int get_param_count() const = 0; /// Return custom XML - virtual const char *get_gui_xml() = 0; + virtual const char *get_gui_xml() const = 0; /// @return number of audio inputs - virtual int get_input_count()=0; + virtual int get_input_count() const =0; /// @return number of audio outputs - virtual int get_output_count()=0; + virtual int get_output_count() const =0; /// @return number of optional inputs - virtual int get_inputs_optional()=0; + virtual int get_inputs_optional() const =0; /// @return number of optional outputs - virtual int get_outputs_optional()=0; + virtual int get_outputs_optional() const =0; /// @return true if plugin can work in hard-realtime conditions - virtual bool is_rt_capable()=0; + virtual bool is_rt_capable() const =0; /// @return true if plugin has MIDI input - virtual bool get_midi()=0; + virtual bool get_midi() const =0; /// @return true if plugin has MIDI input - virtual bool requires_midi()=0; + virtual bool requires_midi() const =0; /// @return port offset of first control (parameter) port (= number of audio inputs + number of audio outputs in all existing plugins as for 1 Aug 2008) - virtual int get_param_port_offset() = 0; + virtual int get_param_port_offset() const = 0; /// @return line_graph_iface if any - virtual line_graph_iface *get_line_graph_iface() = 0; + virtual const line_graph_iface *get_line_graph_iface() const = 0; /// @return table_edit_iface if any - virtual table_edit_iface *get_table_edit_iface() = 0; + virtual const table_edit_iface *get_table_edit_iface() const = 0; /// @return NULL-terminated list of menu commands - virtual plugin_command_info *get_commands() { return NULL; } + virtual plugin_command_info *get_commands() const { return NULL; } /// @return description structure for given parameter - virtual parameter_properties *get_param_props(int param_no) = 0; + virtual parameter_properties *get_param_props(int param_no) const = 0; /// @return retrieve names of audio ports (@note control ports are named in parameter_properties, not here) - virtual const char **get_port_names() = 0; + virtual const char **get_port_names() const = 0; /// @return description structure for the plugin - virtual const ladspa_plugin_info &get_plugin_info() = 0; + virtual const ladspa_plugin_info &get_plugin_info() const = 0; /// is a given parameter a control voltage? - virtual bool is_cv(int param_no) = 0; + virtual bool is_cv(int param_no) const = 0; /// is the given parameter non-interpolated? - virtual bool is_noisy(int param_no) = 0; + virtual bool is_noisy(int param_no) const = 0; /// does the plugin require message context? (or DSSI configure) may be slow - virtual bool requires_message_context() = 0; + virtual bool requires_message_context() const = 0; /// does the plugin require string port extension? (or DSSI configure) may be slow - virtual bool requires_string_ports() = 0; + virtual bool requires_string_ports() const = 0; /// add all message context parameter numbers to the ports vector - virtual void get_message_context_parameters(std::vector &ports) = 0; + virtual void get_message_context_parameters(std::vector &ports) const = 0; /// Do-nothing destructor to silence compiler warning virtual ~plugin_metadata_iface() {} @@ -377,8 +377,20 @@ struct plugin_ctl_iface: public virtual plugin_metadata_iface struct plugin_list_info_iface; -/// Get a list of all "large" (effect/synthesizer) plugins -extern void get_all_plugins(std::vector &plugins); +class plugin_registry +{ +public: + typedef std::vector plugin_vector; +private: + plugin_vector plugins; + plugin_registry(); +public: + static plugin_registry &instance(); + + const plugin_vector &get_all() { return plugins; } + plugin_metadata_iface *get_by_uri(const char *URI); +}; + /// Get a list of all "small" (module) plugins extern void get_all_small_plugins(plugin_list_info_iface *plii); /// Load and strdup a text file with GUI definition @@ -489,30 +501,30 @@ public: // These below are stock implementations based on enums and static members in Metadata classes // they may be overridden to provide more interesting functionality - const char *get_name() { return Metadata::impl_get_name(); } - const char *get_id() { return Metadata::impl_get_id(); } - 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; } - bool is_rt_capable() { return Metadata::rt_capable; } - line_graph_iface *get_line_graph_iface() { return dynamic_cast(this); } - table_edit_iface *get_table_edit_iface() { return dynamic_cast(this); } - int get_param_port_offset() { return Metadata::in_count + Metadata::out_count; } - const char *get_gui_xml() { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; } - plugin_command_info *get_commands() { return NULL; } - parameter_properties *get_param_props(int param_no) { return ¶m_props[param_no]; } - const char **get_port_names() { return port_names; } - bool is_cv(int param_no) { return true; } - bool is_noisy(int param_no) { return false; } - const ladspa_plugin_info &get_plugin_info() { return plugin_info; } - bool requires_message_context() { return check_for_message_context_ports(param_props, Metadata::param_count); } - bool requires_string_ports() { return check_for_string_ports(param_props, Metadata::param_count); } - void get_message_context_parameters(std::vector &ports) { + const char *get_name() const { return Metadata::impl_get_name(); } + const char *get_id() const { return Metadata::impl_get_id(); } + const char *get_label() const { return Metadata::impl_get_label(); } + int get_input_count() const { return Metadata::in_count; } + int get_output_count() const { return Metadata::out_count; } + int get_inputs_optional() const { return Metadata::ins_optional; } + int get_outputs_optional() const { return Metadata::outs_optional; } + int get_param_count() const { return Metadata::param_count; } + bool get_midi() const { return Metadata::support_midi; } + bool requires_midi() const { return Metadata::require_midi; } + bool is_rt_capable() const { return Metadata::rt_capable; } + const line_graph_iface *get_line_graph_iface() const { return dynamic_cast(this); } + const table_edit_iface *get_table_edit_iface() const { return dynamic_cast(this); } + int get_param_port_offset() const { return Metadata::in_count + Metadata::out_count; } + const char *get_gui_xml() const { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; } + plugin_command_info *get_commands() const { return NULL; } + parameter_properties *get_param_props(int param_no) const { return ¶m_props[param_no]; } + const char **get_port_names() const { return port_names; } + bool is_cv(int param_no) const { return true; } + bool is_noisy(int param_no) const { return false; } + const ladspa_plugin_info &get_plugin_info() const { return plugin_info; } + bool requires_message_context() const { return check_for_message_context_ports(param_props, Metadata::param_count); } + bool requires_string_ports() const { return check_for_string_ports(param_props, Metadata::param_count); } + void get_message_context_parameters(std::vector &ports) const { for (int i = 0; i < get_param_count(); ++i) { if (get_param_props(i)->flags & PF_PROP_MSGCONTEXT) ports.push_back(i); @@ -530,30 +542,30 @@ public: plugin_metadata_iface *impl; public: plugin_metadata_proxy(plugin_metadata_iface *_impl) { impl = _impl; } - const char *get_name() { return impl->get_name(); } - const char *get_id() { return impl->get_id(); } - 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(); } - bool is_rt_capable() { return impl->is_rt_capable(); } - line_graph_iface *get_line_graph_iface() { return impl->get_line_graph_iface(); } - table_edit_iface *get_table_edit_iface() { return impl->get_table_edit_iface(); } - int get_param_port_offset() { return impl->get_param_port_offset(); } - const char *get_gui_xml() { return impl->get_gui_xml(); } - plugin_command_info *get_commands() { return impl->get_commands(); } - parameter_properties *get_param_props(int param_no) { return impl->get_param_props(param_no); } - const char **get_port_names() { return impl->get_port_names(); } - bool is_cv(int param_no) { return impl->is_cv(param_no); } - bool is_noisy(int param_no) { return impl->is_noisy(param_no); } - const ladspa_plugin_info &get_plugin_info() { return impl->get_plugin_info(); } - bool requires_message_context() { return impl->requires_message_context(); } - bool requires_string_ports() { return impl->requires_string_ports(); } - void get_message_context_parameters(std::vector &ports) { impl->get_message_context_parameters(ports); } + const char *get_name() const { return impl->get_name(); } + const char *get_id() const { return impl->get_id(); } + const char *get_label() const { return impl->get_label(); } + int get_input_count() const { return impl->get_input_count(); } + int get_output_count() const { return impl->get_output_count(); } + int get_inputs_optional() const { return impl->get_inputs_optional(); } + int get_outputs_optional() const { return impl->get_outputs_optional(); } + int get_param_count() const { return impl->get_param_count(); } + bool get_midi() const { return impl->get_midi(); } + bool requires_midi() const { return impl->requires_midi(); } + bool is_rt_capable() const { return impl->is_rt_capable(); } + const line_graph_iface *get_line_graph_iface() const { return impl->get_line_graph_iface(); } + const table_edit_iface *get_table_edit_iface() const { return impl->get_table_edit_iface(); } + int get_param_port_offset() const { return impl->get_param_port_offset(); } + const char *get_gui_xml() const { return impl->get_gui_xml(); } + plugin_command_info *get_commands() const { return impl->get_commands(); } + parameter_properties *get_param_props(int param_no) const { return impl->get_param_props(param_no); } + const char **get_port_names() const { return impl->get_port_names(); } + bool is_cv(int param_no) const { return impl->is_cv(param_no); } + bool is_noisy(int param_no) const { return impl->is_noisy(param_no); } + const ladspa_plugin_info &get_plugin_info() const { return impl->get_plugin_info(); } + bool requires_message_context() const { return impl->requires_message_context(); } + bool requires_string_ports() const { return impl->requires_string_ports(); } + void get_message_context_parameters(std::vector &ports) const { impl->get_message_context_parameters(ports); } }; #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata::port_names[] diff --git a/plugins/ladspa_effect/calf/calf/ladspa_wrap.h b/plugins/ladspa_effect/calf/calf/ladspa_wrap.h index 73c396914..2f98dcf83 100644 --- a/plugins/ladspa_effect/calf/calf/ladspa_wrap.h +++ b/plugins/ladspa_effect/calf/calf/ladspa_wrap.h @@ -99,9 +99,9 @@ struct ladspa_instance: public Module, public plugin_ctl_iface virtual const char *get_gui_xml() { return Module::get_gui_xml(); } - virtual line_graph_iface *get_line_graph_iface() + virtual const line_graph_iface *get_line_graph_iface() const { - return dynamic_cast(this); + return dynamic_cast(this); } virtual bool activate_preset(int bank, int program) { return false; diff --git a/plugins/ladspa_effect/calf/calf/lv2wrap.h b/plugins/ladspa_effect/calf/calf/lv2wrap.h index 8d2f172c8..fcbff1023 100644 --- a/plugins/ladspa_effect/calf/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/calf/lv2wrap.h @@ -96,28 +96,28 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface, publ virtual const char *get_gui_xml() { return Module::get_gui_xml(); } - virtual line_graph_iface *get_line_graph_iface() + virtual const line_graph_iface *get_line_graph_iface() const { - return dynamic_cast(this); + return dynamic_cast(this); } virtual bool activate_preset(int bank, int program) { return false; } - virtual const char *get_name() + virtual const char *get_name() const { return Module::get_name(); } - virtual const char *get_id() + virtual const char *get_id() const { return Module::get_id(); } - virtual const char *get_label() + virtual const char *get_label() const { return Module::get_label(); } - virtual int get_input_count() { return Module::in_count; } - virtual int get_output_count() { return Module::out_count; } - virtual bool get_midi() { return Module::support_midi; } + virtual int get_input_count() const { return Module::in_count; } + virtual int get_output_count() const { return Module::out_count; } + virtual bool get_midi() const { return Module::support_midi; } virtual float get_level(unsigned int port) { return 0.f; } virtual void execute(int cmd_no) { Module::execute(cmd_no); diff --git a/plugins/ladspa_effect/calf/calf/modmatrix.h b/plugins/ladspa_effect/calf/calf/modmatrix.h index e43e09f7a..5db95fc92 100644 --- a/plugins/ladspa_effect/calf/calf/modmatrix.h +++ b/plugins/ladspa_effect/calf/calf/modmatrix.h @@ -84,10 +84,10 @@ protected: mod_matrix(dsp::modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names); public: - virtual const table_column_info *get_table_columns(int param); - virtual uint32_t get_table_rows(int param); - virtual std::string get_cell(int param, int row, int column); - virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error); + virtual const table_column_info *get_table_columns(int param) const; + virtual uint32_t get_table_rows(int param) const; + virtual std::string get_cell(int param, int row, int column) const; + virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const; /// Process modulation matrix, calculate outputs from inputs inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc) diff --git a/plugins/ladspa_effect/calf/calf/modules.h b/plugins/ladspa_effect/calf/calf/modules.h index ee8906772..b3ed83b89 100644 --- a/plugins/ladspa_effect/calf/calf/modules.h +++ b/plugins/ladspa_effect/calf/calf/modules.h @@ -65,8 +65,8 @@ public: class frequency_response_line_graph: public line_graph_iface { public: - 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); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; class flanger_audio_module: public audio_module, public frequency_response_line_graph @@ -126,8 +126,8 @@ public: right.process(outs[1] + offset, ins[1] + offset, nsamples); return outputs_mask; // XXXKF allow some delay after input going blank } - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); - float freq_gain(int subindex, float freq, float srate); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + float freq_gain(int subindex, float freq, float srate) const; }; class phaser_audio_module: public audio_module, public frequency_response_line_graph @@ -189,9 +189,9 @@ public: right.process(outs[1] + offset, ins[1] + offset, nsamples); return outputs_mask; // XXXKF allow some delay after input going blank } - 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); - float freq_gain(int subindex, float freq, float srate); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + float freq_gain(int subindex, float freq, float srate) const; }; class reverb_audio_module: public audio_module @@ -571,74 +571,6 @@ public: virtual void control_change(int ctl, int val); }; -/// Compose two filters in series -template -class filter_compose { -public: - typedef std::complex cfloat; - F1 f1; - F2 f2; -public: - float process(float value) { - return f2.process(f1.process(value)); - } - - cfloat h_z(const cfloat &z) { - return f1.h_z(z) * f2.h_z(z); - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - void sanitize() { - f1.sanitize(); - f2.sanitize(); - } -}; - -/// Compose two filters in parallel -template -class filter_sum { -public: - typedef std::complex cfloat; - F1 f1; - F2 f2; -public: - float process(float value) { - return f2.process(value) + f1.process(value); - } - - inline cfloat h_z(const cfloat &z) { - return f1.h_z(z) + f2.h_z(z); - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - void sanitize() { - f1.sanitize(); - f2.sanitize(); - } -}; - template class filter_module_with_inertia: public FilterClass { @@ -652,7 +584,7 @@ public: inertia inertia_cutoff, inertia_resonance, inertia_gain; once_per_n timer; bool is_active; - volatile int last_generation, last_calculated_generation; + mutable volatile int last_generation, last_calculated_generation; filter_module_with_inertia() : inertia_cutoff(exponential_ramp(128), 20) @@ -749,7 +681,7 @@ class filter_audio_module: public filter_module_with_inertia, public frequency_response_line_graph { - float old_cutoff, old_resonance, old_mode; + mutable float old_cutoff, old_resonance, old_mode; public: filter_audio_module() { @@ -778,8 +710,8 @@ public: inertia_filter_module::deactivate(); } - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// A multitap stereo chorus thing - processing @@ -840,10 +772,10 @@ public: void activate(); void deactivate(); void set_sample_rate(uint32_t sr); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); - float freq_gain(int subindex, float freq, float srate); - 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); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + float freq_gain(int subindex, float freq, float srate) const; + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; }; class gain_reduction_audio_module { @@ -851,12 +783,12 @@ private: float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; float compressedKneeStop, adjKneeStart, thres; float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; - float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; - int last_generation; + mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; + mutable volatile int last_generation; uint32_t srate; bool is_active; - inline float output_level(float slope); - inline float output_gain(float linSlope, bool rms); + inline float output_level(float slope) const; + inline float output_gain(float linSlope, bool rms) const; public: gain_reduction_audio_module(); void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu); @@ -867,10 +799,10 @@ public: void set_sample_rate(uint32_t sr); float get_output_level(); float get_comp_level(); - virtual bool get_graph(int subindex, float *data, int points, cairo_iface *context); - virtual bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context); - virtual bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); - virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); + virtual bool get_graph(int subindex, float *data, int points, cairo_iface *context) const; + virtual bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const; + virtual bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// Compressor by Thor @@ -886,17 +818,17 @@ public: float *params[param_count]; uint32_t srate; bool is_active; - volatile int last_generation, last_calculated_generation; + mutable 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); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) @@ -914,9 +846,10 @@ private: BANDPASS_1, BANDPASS_2 }; - float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; - float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; - CalfScModes sc_mode, sc_mode_old, sc_mode_old1; + mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; + mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; + CalfScModes sc_mode; + mutable CalfScModes sc_mode_old, sc_mode_old1; float f1_active, f2_active; uint32_t clip_in, clip_out; float meter_in, meter_out; @@ -929,12 +862,12 @@ public: float *params[param_count]; uint32_t srate; bool is_active; - volatile int last_generation, last_calculated_generation; + mutable volatile int last_generation, last_calculated_generation; sidechaincompressor_audio_module(); void activate(); void deactivate(); void params_changed(); - inline cfloat h_z(const cfloat &z) { + inline cfloat h_z(const cfloat &z) const { switch (sc_mode) { default: case WIDEBAND: @@ -958,7 +891,7 @@ public: } } - float freq_gain(int index, double freq, uint32_t sr) + float freq_gain(int index, double freq, uint32_t sr) const { typedef std::complex cfloat; freq *= 2.0 * M_PI / sr; @@ -968,10 +901,10 @@ public: } 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); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// Multibandcompressor by Markus Schmidt @@ -996,10 +929,10 @@ public: void params_changed(); uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); 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); + virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; + virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// Deesser by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) @@ -1009,8 +942,8 @@ private: WIDE, SPLIT }; - float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old; - float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1; + mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old; + mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1; uint32_t detected_led; float detected, clip_out; uint32_t clip_led; @@ -1022,20 +955,20 @@ public: float *params[param_count]; uint32_t srate; bool is_active; - volatile int last_generation, last_calculated_generation; + mutable volatile int last_generation, last_calculated_generation; deesser_audio_module(); void activate(); void deactivate(); void params_changed(); - float freq_gain(int index, double freq, uint32_t sr) + float freq_gain(int index, double freq, uint32_t sr) const { return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr); } void set_sample_rate(uint32_t sr); uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; /// Equalizer N Band by Markus Schmidt (based on Krzysztof's filters) @@ -1054,7 +987,7 @@ private: float ls_level_old, ls_freq_old; float hs_level_old, hs_freq_old; float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands]; - float old_params_for_graph[graph_param_count]; + mutable 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; CalfEqMode hp_mode, lp_mode; @@ -1070,21 +1003,21 @@ public: float *params[param_count]; uint32_t srate; bool is_active; - volatile int last_generation, last_calculated_generation; + mutable volatile int last_generation, last_calculated_generation; 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) const; void set_sample_rate(uint32_t sr) { srate = 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); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; }; typedef equalizerNband_audio_module equalizer5band_audio_module; @@ -1106,9 +1039,9 @@ public: void set_phase(float ph); void activate(); void deactivate(); - 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); + float get_value_from_phase(float ph, float off) const; + virtual bool get_graph(float *data, int points, cairo_iface *context) const; + virtual bool get_dot(float &x, float &y, int &size, cairo_iface *context) const; }; /// Pulsator by Markus Schmidt @@ -1139,9 +1072,9 @@ public: } } 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); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; }; /// Filterclavier --- MIDI controlled filter by Hans Baier @@ -1229,7 +1162,7 @@ public: } } - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; private: void adjust_gain_according_to_filter_mode(int velocity) { diff --git a/plugins/ladspa_effect/calf/calf/modules_synths.h b/plugins/ladspa_effect/calf/calf/modules_synths.h index 090acbdca..d57f61f7b 100644 --- a/plugins/ladspa_effect/calf/calf/modules_synths.h +++ b/plugins/ladspa_effect/calf/calf/modules_synths.h @@ -132,7 +132,7 @@ public: /// Run two filters (one per channel) to produce stereo output samples. void calculate_buffer_stereo(); /// Retrieve filter graph (which is 'live' so it cannot be generated by get_static_graph), or fall back to get_static_graph. - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; /// @retval true if the filter 1 is to be used for the left channel and filter 2 for the right channel /// @retval false if filters are to be connected in series and sent (mono) to both channels inline bool is_stereo_filter() const @@ -140,9 +140,9 @@ public: return filter_type == flt_2lp12 || filter_type == flt_2bp6; } /// No CV inputs for now - bool is_cv(int param_no) { return false; } + bool is_cv(int param_no) const { return false; } /// Practically all the stuff here is noisy - bool is_noisy(int param_no) { return param_no != par_cutoff; } + bool is_noisy(int param_no) const { return param_no != par_cutoff; } /// Calculate control signals and produce step_size samples of output. void calculate_step(); /// Main processing function diff --git a/plugins/ladspa_effect/calf/calf/multichorus.h b/plugins/ladspa_effect/calf/calf/multichorus.h index 23a1f4fde..b954603ab 100644 --- a/plugins/ladspa_effect/calf/calf/multichorus.h +++ b/plugins/ladspa_effect/calf/calf/multichorus.h @@ -80,7 +80,7 @@ public: voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling); } /// Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close) - inline int get_value(uint32_t voice) { + inline int get_value(uint32_t voice) const { // find this voice's phase (= phase + voice * 360 degrees / number of voices) chorus_phase voice_phase = phase + vphase * (int)voice; // find table offset @@ -178,7 +178,7 @@ public: } post.sanitize(); } - float freq_gain(float freq, float sr) + float freq_gain(float freq, float sr) const { typedef std::complex cfloat; freq *= 2.0 * M_PI / sr; diff --git a/plugins/ladspa_effect/calf/calf/onepole.h b/plugins/ladspa_effect/calf/calf/onepole.h index 2bc23257b..5fdc66942 100644 --- a/plugins/ladspa_effect/calf/calf/onepole.h +++ b/plugins/ladspa_effect/calf/calf/onepole.h @@ -144,7 +144,7 @@ public: return out; } - inline bool empty() { + inline bool empty() const { return y1 == 0; } @@ -171,7 +171,7 @@ public: /// Return the filter's gain at frequency freq /// @param freq Frequency to look up /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) + float freq_gain(float freq, float sr) const { freq *= 2.0 * M_PI / sr; cfloat z = 1.0 / exp(cfloat(0.0, freq)); @@ -181,7 +181,7 @@ public: /// Return H(z) the filter's gain at frequency freq /// @param z Z variable (e^jw) - cfloat h_z(const cfloat &z) + cfloat h_z(const cfloat &z) const { return (cfloat(a0) + double(a1) * z) / (cfloat(1.0) + double(b1) * z); } diff --git a/plugins/ladspa_effect/calf/src/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index bd71b2720..365f0fb17 100644 --- a/plugins/ladspa_effect/calf/src/giface.cpp +++ b/plugins/ladspa_effect/calf/src/giface.cpp @@ -292,6 +292,30 @@ void calf_plugins::set_channel_color(cairo_iface *context, int channel) context->set_line_width(1.5); } +/////////////////////////////////////////////////////////////////////////////////////// + +calf_plugins::plugin_registry &calf_plugins::plugin_registry::instance() +{ + static calf_plugins::plugin_registry registry; + return registry; +} + +plugin_metadata_iface *calf_plugins::plugin_registry::get_by_uri(const char *plugin_uri) +{ + static const char prefix[] = "http://calf.sourceforge.net/plugins/"; + if (strncmp(plugin_uri, prefix, sizeof(prefix) - 1)) + return NULL; + const char *label = plugin_uri + sizeof(prefix) - 1; + for (unsigned int i = 0; i < plugins.size(); i++) + { + if (!strcmp(plugins[i]->get_plugin_info().label, label)) + return plugins[i]; + } + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////////////// + #if USE_DSSI struct osc_cairo_control: public cairo_iface { diff --git a/plugins/ladspa_effect/calf/src/modmatrix.cpp b/plugins/ladspa_effect/calf/src/modmatrix.cpp index cba6ced8b..c3bb4f762 100644 --- a/plugins/ladspa_effect/calf/src/modmatrix.cpp +++ b/plugins/ladspa_effect/calf/src/modmatrix.cpp @@ -59,17 +59,17 @@ mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char matrix[i].reset(); } -const table_column_info *mod_matrix::get_table_columns(int param) +const table_column_info *mod_matrix::get_table_columns(int param) const { return table_columns; } -uint32_t mod_matrix::get_table_rows(int param) +uint32_t mod_matrix::get_table_rows(int param) const { return matrix_rows; } -std::string mod_matrix::get_cell(int param, int row, int column) +std::string mod_matrix::get_cell(int param, int row, int column) const { assert(row >= 0 && row < (int)matrix_rows); modulation_entry &slot = matrix[row]; @@ -90,7 +90,7 @@ std::string mod_matrix::get_cell(int param, int row, int column) } } -void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error) +void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error) const { assert(row >= 0 && row < (int)matrix_rows); modulation_entry &slot = matrix[row]; diff --git a/plugins/ladspa_effect/calf/src/modules.cpp b/plugins/ladspa_effect/calf/src/modules.cpp index 1c6a939ff..ce74d5a17 100644 --- a/plugins/ladspa_effect/calf/src/modules.cpp +++ b/plugins/ladspa_effect/calf/src/modules.cpp @@ -889,7 +889,7 @@ CALF_PORT_PROPS(wavetable) = { //////////////////////////////////////////////////////////////////////////// -void calf_plugins::get_all_plugins(std::vector &plugins) +calf_plugins::plugin_registry::plugin_registry() { #define PER_MODULE_ITEM(name, isSynth, jackname) plugins.push_back(new name##_metadata); #define PER_SMALL_MODULE_ITEM(...) diff --git a/plugins/ladspa_effect/calf/src/modules_dsp.cpp b/plugins/ladspa_effect/calf/src/modules_dsp.cpp index d30672ca3..d7f03b025 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -33,12 +33,12 @@ using namespace calf_plugins; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return get_freq_gridline(subindex, pos, vertical, legend, context); } -int frequency_response_line_graph::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int frequency_response_line_graph::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { subindex_graph = 0; subindex_dot = 0; @@ -67,7 +67,7 @@ void flanger_audio_module::deactivate() { is_active = false; } -bool flanger_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool flanger_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -79,7 +79,7 @@ bool flanger_audio_module::get_graph(int index, int subindex, float *data, int p return false; } -float flanger_audio_module::freq_gain(int subindex, float freq, float srate) +float flanger_audio_module::freq_gain(int subindex, float freq, float srate) const { return (subindex ? right : left).freq_gain(freq, srate); } @@ -108,7 +108,7 @@ void phaser_audio_module::deactivate() is_active = false; } -bool phaser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool phaser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -120,12 +120,12 @@ bool phaser_audio_module::get_graph(int index, int subindex, float *data, int po return false; } -float phaser_audio_module::freq_gain(int subindex, float freq, float srate) +float phaser_audio_module::freq_gain(int subindex, float freq, float srate) const { return (subindex ? right : left).freq_gain(freq, srate); } -bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return get_freq_gridline(subindex, pos, vertical, legend, context); } @@ -150,7 +150,7 @@ void reverb_audio_module::set_sample_rate(uint32_t sr) /////////////////////////////////////////////////////////////////////////////////////////////// -bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -161,7 +161,7 @@ bool filter_audio_module::get_graph(int index, int subindex, float *data, int po return false; } -int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { if (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) { @@ -185,7 +185,7 @@ int filter_audio_module::get_changed_offsets(int index, int generation, int &sub /////////////////////////////////////////////////////////////////////////////////////////////// -bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active || index != par_mode) { return false; @@ -268,7 +268,7 @@ void multichorus_audio_module::set_sample_rate(uint32_t sr) { right.setup(sr); } -bool multichorus_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool multichorus_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -284,7 +284,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i return ::get_graph(*this, subindex, data, points); } if (index == par_rate && subindex < nvoices) { - sine_multi_lfo &lfo = left.lfo; + const sine_multi_lfo &lfo = left.lfo; for (int i = 0; i < points; i++) { float phase = i * 2 * M_PI / points; // original -65536 to 65535 value @@ -297,7 +297,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i return false; } -bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { int voice = subindex >> 1; int nvoices = (int)*params[par_voices]; @@ -307,7 +307,7 @@ bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float float unit = (1 - *params[par_overlap]); float scw = 1 + unit * (nvoices - 1); set_channel_color(context, subindex); - sine_multi_lfo &lfo = (subindex & 1 ? right : left).lfo; + const sine_multi_lfo &lfo = (subindex & 1 ? right : left).lfo; if (index == par_rate) { x = (double)(lfo.phase + lfo.vphase * voice) / 4096.0; @@ -324,7 +324,7 @@ bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float return true; } -bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { if (index == par_rate && !subindex) { @@ -337,7 +337,7 @@ bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, return false; } -float multichorus_audio_module::freq_gain(int subindex, float freq, float srate) +float multichorus_audio_module::freq_gain(int subindex, float freq, float srate) const { if (subindex == 2) return *params[par_amount] * left.post.freq_gain(freq, srate); @@ -677,7 +677,7 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num // whatever has to be returned x) return outputs_mask; } -bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { // let's handle by the corresponding strip switch (index) { @@ -697,7 +697,7 @@ bool multibandcompressor_audio_module::get_graph(int index, int subindex, float return false; } -bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { // let's handle by the corresponding strip switch (index) { @@ -717,8 +717,8 @@ bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x return false; } -bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) -{ +bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const +{ // let's handle by the corresponding strip switch (index) { case param_compression0: @@ -737,7 +737,7 @@ bool multibandcompressor_audio_module::get_gridline(int index, int subindex, flo return false; } -int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { // let's handle by the corresponding strip switch (index) { @@ -884,28 +884,28 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, // 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) +bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { 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) +bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { 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) +bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { 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) +int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { if (!is_active) return false; @@ -1202,7 +1202,7 @@ uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t num // whatever has to be returned x) return outputs_mask; } -bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -1215,7 +1215,7 @@ bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float return false; } -bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { if (!is_active) return false; @@ -1225,7 +1225,7 @@ bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x return false; } -bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { if (!is_active) return false; @@ -1237,7 +1237,7 @@ bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, flo // return false; } -int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { if (!is_active) return false; @@ -1451,7 +1451,7 @@ uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uin // whatever has to be returned x) return outputs_mask; } -bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -1462,14 +1462,14 @@ bool deesser_audio_module::get_graph(int index, int subindex, float *data, int p return false; } -bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return get_freq_gridline(subindex, pos, vertical, legend, context); // return false; } -int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { if (!is_active) { return false; @@ -1576,11 +1576,11 @@ void gain_reduction_audio_module::process(float &left, float &right, float det_l } } -float gain_reduction_audio_module::output_level(float slope) { +float gain_reduction_audio_module::output_level(float slope) const { return slope * output_gain(slope, false) * makeup; } -float gain_reduction_audio_module::output_gain(float linSlope, bool rms) { +float gain_reduction_audio_module::output_gain(float linSlope, bool rms) const { //this calculation is also thor's work if(linSlope > (rms ? adjKneeStart : linKneeStart)) { float slope = log(linSlope); @@ -1637,7 +1637,7 @@ float gain_reduction_audio_module::get_comp_level() { return meter_comp; } -bool gain_reduction_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context) +bool gain_reduction_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -1662,7 +1662,7 @@ bool gain_reduction_audio_module::get_graph(int subindex, float *data, int point return true; } -bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) +bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const { if (!is_active) return false; @@ -1681,7 +1681,7 @@ bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int return false; } -bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { bool tmp; vertical = (subindex & 1) != 0; @@ -1700,7 +1700,7 @@ bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &v return result; } -int gain_reduction_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int gain_reduction_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { subindex_graph = 0; subindex_dot = 0; @@ -1988,7 +1988,7 @@ uint32_t equalizerNband_audio_module::process(uint32_t offs #undef SET_IF_CONNECTED template -bool equalizerNband_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool equalizerNband_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -2000,7 +2000,7 @@ bool equalizerNband_audio_module::get_graph(int index, int } template -bool equalizerNband_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +bool equalizerNband_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { if (!is_active) { return false; @@ -2010,7 +2010,7 @@ bool equalizerNband_audio_module::get_gridline(int index, i } template -int equalizerNband_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +int equalizerNband_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { if (!is_active) { return false; @@ -2042,7 +2042,7 @@ int equalizerNband_audio_module::get_changed_offsets(int in return false; } -static inline float adjusted_lphp_gain(float **params, int param_active, int param_mode, biquad_d2 filter, float freq, float srate) +static inline float adjusted_lphp_gain(const float *const *params, int param_active, int param_mode, const biquad_d2 &filter, float freq, float srate) { if(*params[param_active] > 0.f) { float gain = filter.freq_gain(freq, srate); @@ -2059,7 +2059,7 @@ static inline float adjusted_lphp_gain(float **params, int param_active, int par } template -float equalizerNband_audio_module::freq_gain(int index, double freq, uint32_t sr) +float equalizerNband_audio_module::freq_gain(int index, double freq, uint32_t sr) const { float ret = 1.f; if (use_hplp) @@ -2104,7 +2104,7 @@ 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 lfo_audio_module::get_value_from_phase(float ph, float off) const { float val = 0.f; float phs = ph + off; @@ -2171,7 +2171,7 @@ void lfo_audio_module::set_params(float f, int m, float o, uint32_t sr, float a) amount = a; } -bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context) +bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context) const { if (!is_active) return false; @@ -2182,7 +2182,7 @@ bool lfo_audio_module::get_graph(float *data, int points, cairo_iface *context) return true; } -bool lfo_audio_module::get_dot(float &x, float &y, int &size, cairo_iface *context) +bool lfo_audio_module::get_dot(float &x, float &y, int &size, cairo_iface *context) const { if (!is_active) return false; @@ -2377,7 +2377,8 @@ uint32_t pulsator_audio_module::process(uint32_t offset, uint32_t numsamples, ui // whatever has to be returned x) return outputs_mask; } -bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) + +bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { if (!is_active) { return false; @@ -2393,7 +2394,8 @@ bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int } return false; } -bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) + +bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { if (!is_active) { return false; @@ -2410,7 +2412,8 @@ bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, } return false; } -bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) + +bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { if (index == param_freq && !subindex) { diff --git a/plugins/ladspa_effect/calf/src/monosynth.cpp b/plugins/ladspa_effect/calf/src/monosynth.cpp index 33b24f3ae..6d76134ad 100644 --- a/plugins/ladspa_effect/calf/src/monosynth.cpp +++ b/plugins/ladspa_effect/calf/src/monosynth.cpp @@ -204,7 +204,7 @@ void monosynth_audio_module::precalculate_waves(progress_report_iface *reporter) } -bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { monosynth_audio_module::precalculate_waves(NULL); // printf("get_graph %d %p %d wave1=%d wave2=%d\n", index, data, points, wave1, wave2); @@ -239,7 +239,7 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int typedef complex cfloat; double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - dsp::biquad_d1_lerp &f = subindex ? filter2 : filter; + const dsp::biquad_d1_lerp &f = subindex ? filter2 : filter; float level = f.freq_gain(freq, srate); if (!is_stereo_filter()) level *= filter2.freq_gain(freq, srate); From 47a46da43d94556c329ede341e281ca279c3f3ae Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 23:06:31 +0100 Subject: [PATCH 3/7] More refactoring. Make the result of plugin_registry::get_by_uri() const, as no external code should modify metadata objects. (cherry picked from commit 2f9ae953b30bc8702d302df58f0c7f1a589a15c3) --- plugins/ladspa_effect/calf/calf/giface.h | 6 +++--- plugins/ladspa_effect/calf/src/giface.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index eace9027b..a96899561 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -388,7 +388,7 @@ public: static plugin_registry &instance(); const plugin_vector &get_all() { return plugins; } - plugin_metadata_iface *get_by_uri(const char *URI); + const plugin_metadata_iface *get_by_uri(const char *URI); }; /// Get a list of all "small" (module) plugins @@ -539,9 +539,9 @@ public: class plugin_metadata_proxy: public virtual plugin_metadata_iface { public: - plugin_metadata_iface *impl; + const plugin_metadata_iface *impl; public: - plugin_metadata_proxy(plugin_metadata_iface *_impl) { impl = _impl; } + plugin_metadata_proxy(const plugin_metadata_iface *_impl) { impl = _impl; } const char *get_name() const { return impl->get_name(); } const char *get_id() const { return impl->get_id(); } const char *get_label() const { return impl->get_label(); } diff --git a/plugins/ladspa_effect/calf/src/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index 365f0fb17..e9984e84f 100644 --- a/plugins/ladspa_effect/calf/src/giface.cpp +++ b/plugins/ladspa_effect/calf/src/giface.cpp @@ -300,7 +300,7 @@ calf_plugins::plugin_registry &calf_plugins::plugin_registry::instance() return registry; } -plugin_metadata_iface *calf_plugins::plugin_registry::get_by_uri(const char *plugin_uri) +const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_uri(const char *plugin_uri) { static const char prefix[] = "http://calf.sourceforge.net/plugins/"; if (strncmp(plugin_uri, prefix, sizeof(prefix) - 1)) From 6c59404c32c03b9bd671ecac87527c500cdf83d3 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 23:18:52 +0100 Subject: [PATCH 4/7] Add Doxygen documentation for plugin_registry class. (cherry picked from commit 4c093bf60cc6257232927d907106551293913384) --- plugins/ladspa_effect/calf/calf/giface.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index a96899561..36ab043b3 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -377,6 +377,7 @@ struct plugin_ctl_iface: public virtual plugin_metadata_iface struct plugin_list_info_iface; +/// A class to retrieve and query the list of Calf plugins class plugin_registry { public: @@ -385,9 +386,12 @@ private: plugin_vector plugins; plugin_registry(); public: + /// Get the singleton object. static plugin_registry &instance(); + /// Get all plugin metadata objects const plugin_vector &get_all() { return plugins; } + /// Get single plugin metadata object by URI const plugin_metadata_iface *get_by_uri(const char *URI); }; From 0ab27d30c3f008f606d42367ab0ba3d12900bff7 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 23:28:30 +0100 Subject: [PATCH 5/7] Remove small plugins together with all the supporting infrastructure. The small plugins don't really fit into the project and should be moved somewhere else instead. Unfortunately, I don't have enough time to do it myself, so if anyone needs them, feel free to make a separate project out of them, or merge them (if possible, it may be very hard) into some other small plugin library. (cherry picked from commit e03505a778ac3b8edb7a389a11eae03cbacc79fe) --- plugins/ladspa_effect/calf/calf/modulelist.h | 77 - .../ladspa_effect/calf/calf/modules_small.h | 202 -- plugins/ladspa_effect/calf/calf/plugininfo.h | 105 - .../ladspa_effect/calf/src/modules_small.cpp | 1916 ----------------- plugins/ladspa_effect/calf/src/plugin.cpp | 5 - 5 files changed, 2305 deletions(-) delete mode 100644 plugins/ladspa_effect/calf/calf/modules_small.h delete mode 100644 plugins/ladspa_effect/calf/calf/plugininfo.h delete mode 100644 plugins/ladspa_effect/calf/src/modules_small.cpp diff --git a/plugins/ladspa_effect/calf/calf/modulelist.h b/plugins/ladspa_effect/calf/calf/modulelist.h index fd1531f36..dabd2c355 100644 --- a/plugins/ladspa_effect/calf/calf/modulelist.h +++ b/plugins/ladspa_effect/calf/calf/modulelist.h @@ -23,80 +23,3 @@ #endif #undef PER_MODULE_ITEM #endif -#ifdef PER_SMALL_MODULE_ITEM -#ifdef ENABLE_EXPERIMENTAL - PER_SMALL_MODULE_ITEM(lp_filter, "lowpass12") - PER_SMALL_MODULE_ITEM(hp_filter, "highpass12") - PER_SMALL_MODULE_ITEM(bp_filter, "bandpass6") - PER_SMALL_MODULE_ITEM(br_filter, "notch6") - PER_SMALL_MODULE_ITEM(onepole_lp_filter, "lowpass6") - PER_SMALL_MODULE_ITEM(onepole_hp_filter, "highpass6") - PER_SMALL_MODULE_ITEM(onepole_ap_filter, "allpass") - PER_SMALL_MODULE_ITEM(min, "min") - PER_SMALL_MODULE_ITEM(max, "max") - PER_SMALL_MODULE_ITEM(minus, "minus") - PER_SMALL_MODULE_ITEM(mul, "mul") - PER_SMALL_MODULE_ITEM(neg, "neg") - PER_SMALL_MODULE_ITEM(min_c, "min_c") - PER_SMALL_MODULE_ITEM(max_c, "max_c") - PER_SMALL_MODULE_ITEM(minus_c, "minus_c") - PER_SMALL_MODULE_ITEM(mul_c, "mul_c") - PER_SMALL_MODULE_ITEM(neg_c, "neg_c") - PER_SMALL_MODULE_ITEM(level2edge_c, "level2edge_c") - PER_SMALL_MODULE_ITEM(map_lin2exp, "lin2exp") - PER_SMALL_MODULE_ITEM(square_osc, "square_osc") - PER_SMALL_MODULE_ITEM(saw_osc, "saw_osc") - PER_SMALL_MODULE_ITEM(square_lfo, "square_lfo") - PER_SMALL_MODULE_ITEM(saw_lfo, "saw_lfo") - PER_SMALL_MODULE_ITEM(pulse_lfo, "pulse_lfo") - PER_SMALL_MODULE_ITEM(print_a, "print_a") - PER_SMALL_MODULE_ITEM(print_c, "print_c") - PER_SMALL_MODULE_ITEM(print_e, "print_e") - PER_SMALL_MODULE_ITEM(print_em, "print_em") - PER_SMALL_MODULE_ITEM(copy_em, "copy_em") - PER_SMALL_MODULE_ITEM(notefilter_m, "notefilter_m") - PER_SMALL_MODULE_ITEM(ccfilter_m, "ccfilter_m") - PER_SMALL_MODULE_ITEM(pcfilter_m, "pcfilter_m") - PER_SMALL_MODULE_ITEM(pressurefilter_m, "pressurefilter_m") - PER_SMALL_MODULE_ITEM(pitchbendfilter_m, "pitchbendfilter_m") - PER_SMALL_MODULE_ITEM(systemfilter_m, "systemfilter_m") - PER_SMALL_MODULE_ITEM(channelfilter_m, "channelfilter_m") - PER_SMALL_MODULE_ITEM(keyfilter_m, "keyfilter_m") - PER_SMALL_MODULE_ITEM(setchannel_m, "setchannel_m") - PER_SMALL_MODULE_ITEM(key_less_than_m, "key_less_than_m") - PER_SMALL_MODULE_ITEM(channel_less_than_m, "channel_less_than_m") - PER_SMALL_MODULE_ITEM(transpose_m, "transpose_m") - PER_SMALL_MODULE_ITEM(eventmerge_e, "eventmerge_e") - PER_SMALL_MODULE_ITEM(quadpower_a, "quadpower_a") - PER_SMALL_MODULE_ITEM(quadpower_c, "quadpower_c") - PER_SMALL_MODULE_ITEM(crossfader2_a, "crossfader2_a") - PER_SMALL_MODULE_ITEM(crossfader2_c, "crossfader2_c") - PER_SMALL_MODULE_ITEM(linear_inertia_c, "linear_inertia_c") - PER_SMALL_MODULE_ITEM(exp_inertia_c, "exp_inertia_c") - PER_SMALL_MODULE_ITEM(sample_hold_edge_c, "sample_hold_edge_c") - PER_SMALL_MODULE_ITEM(sample_hold_level_c, "sample_hold_level_c") - PER_SMALL_MODULE_ITEM(bit_and_c, "bit_and_c") - PER_SMALL_MODULE_ITEM(bit_or_c, "bit_or_c") - PER_SMALL_MODULE_ITEM(bit_xor_c, "bit_xor_c") - PER_SMALL_MODULE_ITEM(logical_and_c, "logical_and_c") - PER_SMALL_MODULE_ITEM(logical_or_c, "logical_or_c") - PER_SMALL_MODULE_ITEM(logical_xor_c, "logical_xor_c") - PER_SMALL_MODULE_ITEM(logical_not_c, "logical_not_c") - PER_SMALL_MODULE_ITEM(flipflop_c, "flipflop_c") - PER_SMALL_MODULE_ITEM(schmitt_c, "schmitt_c") - PER_SMALL_MODULE_ITEM(between_c, "between_c") - PER_SMALL_MODULE_ITEM(less_c, "less_c") - PER_SMALL_MODULE_ITEM(clip_c, "clip_c") - PER_SMALL_MODULE_ITEM(trigger_a2c, "trigger_a2c") - PER_SMALL_MODULE_ITEM(timer_c, "timer_c") - PER_SMALL_MODULE_ITEM(prio_mux_c, "prio_mux_c") - PER_SMALL_MODULE_ITEM(prio_enc8_c, "prio_enc8_c") - PER_SMALL_MODULE_ITEM(ifthenelse_c, "ifthenelse_c") - PER_SMALL_MODULE_ITEM(counter_c, "counter_c") - PER_SMALL_MODULE_ITEM(mux4_c, "mux4_c") - PER_SMALL_MODULE_ITEM(mux8_c, "mux8_c") - PER_SMALL_MODULE_ITEM(mux16_c, "mux16_c") - PER_SMALL_MODULE_ITEM(msgread_e, "msgread_e") -#endif -#undef PER_SMALL_MODULE_ITEM -#endif diff --git a/plugins/ladspa_effect/calf/calf/modules_small.h b/plugins/ladspa_effect/calf/calf/modules_small.h deleted file mode 100644 index c186e9972..000000000 --- a/plugins/ladspa_effect/calf/calf/modules_small.h +++ /dev/null @@ -1,202 +0,0 @@ -/* Calf DSP Library - * "Small" audio modules for modular synthesis - * - * Copyright (C) 2001-2007 Krzysztof Foltman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02111-1307, USA. - */ -#ifndef __CALF_MODULES_SMALL_H -#define __CALF_MODULES_SMALL_H - -#if USE_LV2 - -#include -#include "plugininfo.h" -#include "lv2_polymorphic_port.h" -#include "lv2helpers.h" - -namespace calf_plugins { - -/// Empty implementations for plugin functions. Note, that some functions aren't virtual, because they're called via the particular -/// subclass via template wrappers (ladspa_small_wrapper<> etc), not via base class pointer/reference. On the other hand, -/// other functions are virtual when overhead is acceptable (instantiation time functions etc.) -class null_small_audio_module: public uri_map_access -{ -public: - uint32_t srate; - double odsr; - uint32_t poly_type_control, poly_type_audio; - /// for polymorphic ports: "is audio" flags for first 32 ports (should be sufficient for most plugins) - uint32_t poly_port_types; - - null_small_audio_module() - : srate((uint32_t)-1) - , odsr(0.) - , poly_type_control(0) - , poly_type_audio(0) - , poly_port_types(0) - { - } - - /// Called when host changes type of the polymorphic port - inline void set_port_type(uint32_t port, uint32_t type, void *type_data) { - if (port >= 32) - return; - uint32_t port_mask = 1 << port; - if (type == poly_type_control) - poly_port_types &= ~port_mask; - else if (type == poly_type_audio) - poly_port_types |= port_mask; - on_port_types_changed(); - } - - /// Returns 1 for audio ports and 0 for control ports - inline unsigned int port_is_audio(unsigned int port) { - return (poly_port_types >> port) & 1; - } - - /// Returns (unsigned)-1 for audio ports and 0 for control ports - inline unsigned int port_audio_mask(unsigned int port) { - return 0 - ((poly_port_types >> port) & 1); - } - - /// Returns (unsigned)-1 for audio ports and 0 for control ports - static inline unsigned int port_audio_mask(unsigned int port, uint32_t poly_port_types) { - return 0 - ((poly_port_types >> port) & 1); - } - - virtual void on_port_types_changed() {} - inline void set_bundle_path(const char *path) {} - /// Called to map all the necessary URIs - virtual void map_uris() - { - poly_type_control = map_uri(LV2_POLYMORPHIC_PORT_URI, "http://lv2plug.in/ns/lv2core#ControlPort"); - poly_type_audio = map_uri(LV2_POLYMORPHIC_PORT_URI, "http://lv2plug.in/ns/lv2core#AudioPort"); - } - /// Called on instantiation with the list of LV2 features called - virtual void use_features(const LV2_Feature *const *features) { - while(*features) - { - use_feature((*features)->URI, (*features)->data); - features++; - } - } - /// LADSPA-esque activate function, except it is called after ports are connected, not before - inline void activate() {} - /// LADSPA-esque deactivate function - inline void deactivate() {} - /// Set sample rate for the plugin - inline void set_sample_rate(uint32_t sr) { srate = sr; odsr = 1.0 / sr; } - static inline const void *ext_data(const char *URI) { return NULL; } -}; - -/// Templatized version useful when the number of inputs and outputs is small -template -class small_audio_module_base: public null_small_audio_module -{ -public: - enum { in_count = Inputs, out_count = Outputs }; - /// Input pointers - float *ins[in_count]; - /// Output pointers - float *outs[out_count]; -}; - -template -struct lv2_small_wrapper -{ - typedef Module instance; - static LV2_Descriptor descriptor; - std::string uri; - static uint32_t poly_port_types; - - lv2_small_wrapper(const char *id) - { - uri = "http://calf.sourceforge.net/small_plugins/" + std::string(id); - descriptor.URI = uri.c_str(); - descriptor.instantiate = cb_instantiate; - descriptor.connect_port = cb_connect; - descriptor.activate = cb_activate; - descriptor.run = cb_run; - descriptor.deactivate = cb_deactivate; - descriptor.cleanup = cb_cleanup; - descriptor.extension_data = cb_ext_data; - - plugin_port_type_grabber ptg(poly_port_types); - Module::plugin_info(&ptg); - } - - static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) { - unsigned long ins = Module::in_count; - unsigned long outs = Module::out_count; - instance *const mod = (instance *)Instance; - if (port < ins) - mod->ins[port] = (float *)DataLocation; - else if (port < ins + outs) - mod->outs[port - ins] = (float *)DataLocation; - } - - static void cb_activate(LV2_Handle Instance) { - // Note the changed semantics (now more LV2-like) - instance *const mod = (instance *)Instance; - mod->activate(); - } - - static void cb_deactivate(LV2_Handle Instance) { - instance *const mod = (instance *)Instance; - mod->deactivate(); - } - - static uint32_t cb_set_type(LV2_Handle Instance, uint32_t port, uint32_t type, void *type_data) - { - instance *const mod = (instance *)Instance; - mod->set_port_type(port, type, type_data); - return 0; - } - - static LV2_Handle cb_instantiate(const LV2_Descriptor * Descriptor, double sample_rate, const char *bundle_path, const LV2_Feature *const *features) - { - instance *mod = new instance(); - mod->poly_port_types = poly_port_types; - // XXXKF some people use fractional sample rates; we respect them ;-) - mod->set_bundle_path(bundle_path); - mod->use_features(features); - mod->set_sample_rate((uint32_t)sample_rate); - return mod; - } - - static void cb_run(LV2_Handle Instance, uint32_t SampleCount) { - instance *const mod = (instance *)Instance; - mod->process(SampleCount); - } - - static void cb_cleanup(LV2_Handle Instance) { - instance *const mod = (instance *)Instance; - delete mod; - } - - static const void *cb_ext_data(const char *URI) { - return Module::ext_data(URI); - } -}; - -extern const LV2_Descriptor *lv2_small_descriptor(uint32_t index); - -}; - -#endif - -#endif diff --git a/plugins/ladspa_effect/calf/calf/plugininfo.h b/plugins/ladspa_effect/calf/calf/plugininfo.h deleted file mode 100644 index 46181998d..000000000 --- a/plugins/ladspa_effect/calf/calf/plugininfo.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Calf DSP Library - * Plugin introspection interface - * - * Copyright (C) 2008 Krzysztof Foltman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __CALF_PLUGININFO_H -#define __CALF_PLUGININFO_H - -#include - -namespace calf_plugins { - -/// A sink to send information about an audio port -struct plain_port_info_iface -{ - /// Called if it's an input port - virtual plain_port_info_iface& input() { return *this; } - /// Called if it's an output port - virtual plain_port_info_iface& output() { return *this; } - virtual plain_port_info_iface& lv2_ttl(const std::string &text) { return *this; } - virtual ~plain_port_info_iface() {} -}; - -/// A sink to send information about a control port (very incomplete, missing stuff: units, integer, boolean, toggled, notAutomatic, notGUI...) -struct control_port_info_iface -{ - /// Called if it's an input port - virtual control_port_info_iface& input() { return *this; } - /// Called if it's an output port - virtual control_port_info_iface& output() { return *this; } - /// Called to mark the port as using linear range [from, to] - virtual control_port_info_iface& lin_range(double from, double to) { return *this; } - /// Called to mark the port as using log range [from, to] - virtual control_port_info_iface& log_range(double from, double to) { return *this; } - virtual control_port_info_iface& toggle() { return *this; } - virtual control_port_info_iface& trigger() { return *this; } - virtual control_port_info_iface& integer() { return *this; } - virtual control_port_info_iface& lv2_ttl(const std::string &text) { return *this; } - virtual control_port_info_iface& polymorphic() { return lv2_ttl("a poly:PolymorphicPort ;"); } - virtual control_port_info_iface& poly_audio() { return lv2_ttl("poly:supportsType lv2:AudioPort ;"); } - virtual ~control_port_info_iface() {} -}; - -/// A sink to send information about a plugin -struct plugin_info_iface -{ - /// Set plugin names (ID, name and label) - virtual void names(const std::string &name, const std::string &label, const std::string &category, const std::string µname = std::string()) {} - /// Add an audio port (returns a sink which accepts further description) - virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A"))=0; - /// Add an event port (returns a sink which accepts further description) - virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A"))=0; - /// Add a control port (returns a sink which accepts further description) - virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string µname = "N/A")=0; - /// Add arbitrary TTL clauses - virtual void lv2_ttl(const std::string &text) {} - /// Add small plugin GUI - virtual void has_gui() { lv2_ttl("uiext:ui ;"); } - /// Called after plugin has reported all the information - virtual void finalize() {} - virtual ~plugin_info_iface() {} -}; - -struct plugin_port_type_grabber: public plugin_info_iface, public control_port_info_iface -{ - uint32_t ⌖ - uint32_t index; - - plain_port_info_iface pp; - control_port_info_iface cp; - - plugin_port_type_grabber(uint32_t &_target) : target(_target), index(0) { target = 0; } - - virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A")) { target |= (1 << index); index++; return pp; } - virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A")) { index++; return pp; } - virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string µname = "N/A") { index++; return cp; } -}; - -/// A sink to send information about plugins -struct plugin_list_info_iface -{ - /// Add an empty plugin object and return the sink to be filled with information - virtual plugin_info_iface &plugin(const std::string &id) = 0; - virtual ~plugin_list_info_iface() {} -}; - -}; - -#endif diff --git a/plugins/ladspa_effect/calf/src/modules_small.cpp b/plugins/ladspa_effect/calf/src/modules_small.cpp deleted file mode 100644 index 24e141819..000000000 --- a/plugins/ladspa_effect/calf/src/modules_small.cpp +++ /dev/null @@ -1,1916 +0,0 @@ -/* Calf DSP Library - * Small modules for modular synthesizers - * - * Copyright (C) 2001-2008 Krzysztof Foltman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ENABLE_EXPERIMENTAL - -#if USE_LV2 -#define LV2_SMALL_WRAPPER(mod, name) static calf_plugins::lv2_small_wrapper lv2_small_##mod(name); -#else -#define LV2_SMALL_WRAPPER(...) -#endif - -#define SMALL_WRAPPERS(mod, name) LV2_SMALL_WRAPPER(mod, name) - -#if USE_LV2 - -using namespace calf_plugins; -using namespace dsp; -using namespace std; - -template LV2_Descriptor lv2_small_wrapper::descriptor; -template uint32_t lv2_small_wrapper::poly_port_types; - -namespace small_plugins -{ - -class filter_base: public null_small_audio_module -{ -public: - enum { in_signal, in_cutoff, in_resonance, in_count }; - enum { out_signal, out_count}; - float *ins[in_count]; - float *outs[out_count]; - static void port_info(plugin_info_iface *pii) - { - pii->audio_port("in", "In").input(); - pii->control_port("cutoff", "Cutoff", 1000).input().log_range(20, 20000); - pii->control_port("res", "Resonance", 0.707).input().log_range(0.707, 20); - pii->audio_port("out", "Out").output(); - } - dsp::biquad_d1 filter; - - void activate() { - filter.reset(); - } - inline void process_inner(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[out_signal][i] = filter.process(ins[in_signal][i]); - filter.sanitize(); - } -}; - -class lp_filter_audio_module: public filter_base -{ -public: - inline void process(uint32_t count) { - filter.set_lp_rbj(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), *ins[in_resonance], srate); - process_inner(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("lowpass12", "12dB/oct RBJ Lowpass", "lv2:LowpassPlugin"); - port_info(pii); - } -}; - -class hp_filter_audio_module: public filter_base -{ -public: - inline void process(uint32_t count) { - filter.set_hp_rbj(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), *ins[in_resonance], srate); - process_inner(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("highpass12", "12dB/oct RBJ Highpass", "lv2:HighpassPlugin"); - port_info(pii); - } -}; - -class bp_filter_audio_module: public filter_base -{ -public: - inline void process(uint32_t count) { - filter.set_bp_rbj(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), *ins[in_resonance], srate); - process_inner(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("bandpass6", "6dB/oct RBJ Bandpass", "lv2:BandpassPlugin"); - port_info(pii); - } -}; - -class br_filter_audio_module: public filter_base -{ -public: - inline void process(uint32_t count) { - filter.set_br_rbj(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), *ins[in_resonance], srate); - process_inner(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("notch6", "6dB/oct RBJ Bandpass", "lv2:FilterPlugin"); - port_info(pii); - } -}; - -class onepole_filter_base: public null_small_audio_module -{ -public: - enum { in_signal, in_cutoff, in_count }; - enum { out_signal, out_count}; - float *ins[in_count]; - float *outs[out_count]; - dsp::onepole filter; - static parameter_properties param_props[]; - - static void port_info(plugin_info_iface *pii) - { - pii->audio_port("In", "in").input(); - pii->control_port("Cutoff", "cutoff", 1000).input().log_range(20, 20000); - pii->audio_port("Out", "out").output(); - } - /// do not export mode and inertia as CVs, as those are settings and not parameters - void activate() { - filter.reset(); - } -}; - -class onepole_lp_filter_audio_module: public onepole_filter_base -{ -public: - void process(uint32_t count) { - filter.set_lp(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), srate); - for (uint32_t i = 0; i < count; i++) - outs[0][i] = filter.process_lp(ins[0][i]); - filter.sanitize(); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("lowpass6", "6dB/oct Lowpass Filter", "lv2:LowpassPlugin"); - port_info(pii); - } -}; - -class onepole_hp_filter_audio_module: public onepole_filter_base -{ -public: - void process(uint32_t count) { - filter.set_hp(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), srate); - for (uint32_t i = 0; i < count; i++) - outs[0][i] = filter.process_hp(ins[0][i]); - filter.sanitize(); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("highpass6", "6dB/oct Highpass Filter", "lv2:HighpassPlugin"); - port_info(pii); - } -}; - -class onepole_ap_filter_audio_module: public onepole_filter_base -{ -public: - void process(uint32_t count) { - filter.set_ap(clip(*ins[in_cutoff], 0.0001, 0.48 * srate), srate); - for (uint32_t i = 0; i < count; i++) - outs[0][i] = filter.process_ap(ins[0][i]); - filter.sanitize(); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("allpass", "1-pole 1-zero Allpass Filter", "lv2:AllpassPlugin"); - port_info(pii); - } -}; - -/// This works for 1 or 2 operands only... -template -class audio_operator_audio_module: public small_audio_module_base -{ -public: - static void port_info(plugin_info_iface *pii) - { - if (Inputs == 1) - pii->audio_port("in", "In", "").input(); - else - { - pii->audio_port("in_1", "In 1", "").input(); - pii->audio_port("in_2", "In 2", "").input(); - } - pii->audio_port("out", "Out", "").output(); - } -}; - -class min_audio_module: public audio_operator_audio_module<2> -{ -public: - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[0][i] = std::min(ins[0][i], ins[1][i]); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("min", "Minimum (A)", "kf:MathOperatorPlugin", "min"); - port_info(pii); - } -}; - -class max_audio_module: public audio_operator_audio_module<2> -{ -public: - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[0][i] = std::max(ins[0][i], ins[1][i]); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("max", "Maximum (A)", "kf:MathOperatorPlugin", "max"); - port_info(pii); - } -}; - -class minus_audio_module: public audio_operator_audio_module<2> -{ -public: - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[0][i] = ins[0][i] - ins[1][i]; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("minus", "Subtract (A)", "kf:MathOperatorPlugin", "-"); - port_info(pii); - } -}; - -class mul_audio_module: public audio_operator_audio_module<2> -{ -public: - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[0][i] = ins[0][i] * ins[1][i]; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("mul", "Multiply (A)", "kf:MathOperatorPlugin", "*"); - port_info(pii); - } -}; - -class neg_audio_module: public audio_operator_audio_module<1> -{ -public: - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - outs[0][i] = -ins[0][i]; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("neg", "Negative (A)", "kf:MathOperatorPlugin", "-"); - port_info(pii); - } -}; - -template struct polymorphic_process; - -template struct polymorphic_process -{ - static inline void run(float **ins, float **outs, uint32_t count, uint32_t poly_port_types) { - if (poly_port_types < 2) // control to control or audio to control - *outs[0] = T::process_single(*ins[0]); - else if (poly_port_types == 2) { - outs[0][0] = T::process_single(ins[0][0]); // same as above, but the index might not be 0 in later versions - for (uint32_t i = 1; i < count; i++) - outs[0][i] = outs[0][0]; - } - else { // audio to audio - for (uint32_t i = 0; i < count; i++) - outs[0][i] = T::process_single(ins[0][i]); - } - }; -}; - -template struct polymorphic_process -{ - static inline void run(float **ins, float **outs, uint32_t count, uint32_t poly_port_types) { - poly_port_types &= ~1; - if (poly_port_types < 4) // any to control - *outs[0] = T::process_single(*ins[0], *ins[1]); - else if (poly_port_types == 4) { // control+control to audio - outs[0][0] = T::process_single(*ins[0], *ins[1]); // same as above, but the index might not be 0 in later versions - for (uint32_t i = 1; i < count; i++) - outs[0][i] = outs[0][0]; - } - else { // {control+audio or audio+control or audio+audio} to audio - // use masks to force 0 for index for control ports - uint32_t mask1 = null_small_audio_module::port_audio_mask(0, poly_port_types); - uint32_t mask2 = null_small_audio_module::port_audio_mask(1, poly_port_types); - for (uint32_t i = 0; i < count; i++) - outs[0][i] = T::process_single(ins[0][i & mask1], ins[1][i & mask2]); - } - }; -}; - -/// This works for 1 or 2 operands only... -template -class control_operator_audio_module: public small_audio_module_base -{ -public: - using small_audio_module_base::ins; - using small_audio_module_base::outs; - using small_audio_module_base::poly_port_types; - static void port_info(plugin_info_iface *pii, control_port_info_iface *cports[Inputs + 1], float in1 = 0, float in2 = 0) - { - int idx = 0; - if (Inputs == 1) - cports[idx++] = &pii->control_port("in", "In", in1, "").polymorphic().poly_audio().input(); - else - { - cports[idx++] = &pii->control_port("in_1", "In 1", in1, "").polymorphic().poly_audio().input(); - cports[idx++] = &pii->control_port("in_2", "In 2", in2, "").polymorphic().poly_audio().input(); - } - cports[idx++] = &pii->control_port("out", "Out", 0, "").poly_audio().output(); - } - - template inline void do_process(uint32_t count) { - polymorphic_process::run(ins, outs, count, poly_port_types); - } -}; - -class minus_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return x - y; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("minus_c", "Subtract (C)", "kf:MathOperatorPlugin", "-"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - } -}; - -class mul_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return x * y; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("mul_c", "Multiply (C)", "kf:MathOperatorPlugin", "*"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - } -}; - -class neg_c_audio_module: public control_operator_audio_module<1> -{ -public: - static inline float process_single(float x) { - return -x; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("neg_c", "Negative (C)", "kf:MathOperatorPlugin", "-"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - } -}; - -class min_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return std::min(x, y); - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("min_c", "Minimum (C)", "kf:MathOperatorPlugin", "min"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - } -}; - -class max_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return std::max(x, y); - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("max_c", "Maximum (C)", "kf:MathOperatorPlugin", "max"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - } -}; - -class less_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return x < y; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("less_c", "Less than (C)", "kf:MathOperatorPlugin", "<"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - cports[2]->toggle(); - } -}; - -class level2edge_c_audio_module: public control_operator_audio_module<1> -{ -public: - bool last_value; - void activate() { - last_value = false; - } - void process(uint32_t count) { - *outs[0] = (*ins[0] > 0 && !last_value) ? 1.f : 0.f; - last_value = *ins[0] > 0; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("level2edge_c", "Level to edge (C)", "kf:BooleanPlugin"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - cports[0]->toggle(); - cports[1]->toggle().trigger(); - } -}; - -class int_c_audio_module: public control_operator_audio_module<1> -{ -public: - static inline float process_single(float x) { - return (int)x; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("int_c", "Integer value (C)", "kf:IntegerPlugin"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - cports[0]->integer(); - cports[1]->integer(); - } -}; - -class bitwise_op_c_module_base: public control_operator_audio_module<2> -{ -public: - static void port_info(plugin_info_iface *pii) - { - pii->control_port("in_1", "In 1", 0, "").polymorphic().poly_audio().integer().input(); - pii->control_port("in_2", "In 2", 0, "").polymorphic().poly_audio().integer().input(); - pii->control_port("out", "Out", 0, "").polymorphic().poly_audio().integer().output(); - } -}; -class bit_and_c_audio_module: public bitwise_op_c_module_base -{ -public: - static inline float process_single(float x, float y) { - return ((int)x) & ((int)y); - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("bit_and_c", "Bitwise AND (C)", "kf:IntegerPlugin"); - port_info(pii); - } -}; - -class bit_or_c_audio_module: public bitwise_op_c_module_base -{ -public: - static inline float process_single(float x, float y) { - return ((int)x) | ((int)y); - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("bit_or_c", "Bitwise OR (C)", "kf:IntegerPlugin"); - port_info(pii); - } -}; - -class bit_xor_c_audio_module: public bitwise_op_c_module_base -{ -public: - static inline float process_single(float x, float y) { - return ((int)x) ^ ((int)y); - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("bit_xor_c", "Bitwise XOR (C)", "kf:IntegerPlugin"); - port_info(pii); - } -}; - -class flipflop_c_audio_module: public control_operator_audio_module<1> -{ -public: - bool last_value, output; - void activate() { - last_value = false; - output = false; - } - void process(uint32_t count) { - if (*ins[0] > 0 && !last_value) - output = !output; - *outs[0] = output ? 1.f : 0.f; - last_value = *ins[0] > 0; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("flipflop_c", "T Flip-Flop (C)", "kf:BooleanPlugin"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - cports[0]->toggle().trigger(); - cports[1]->toggle(); - } -}; - -class logical_and_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return (x > 0 && y > 0) ? 1.f : 0.f; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("logical_and_c", "Logical AND (C)", "kf:BooleanPlugin", "&&"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - cports[0]->toggle(); - cports[1]->toggle(); - cports[2]->toggle(); - } -}; - -class logical_or_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return (x > 0 || y > 0) ? 1.f : 0.f; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("logical_or_c", "Logical OR (C)", "kf:BooleanPlugin", "||"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - cports[0]->toggle(); - cports[1]->toggle(); - cports[2]->toggle(); - } -}; - -class logical_xor_c_audio_module: public control_operator_audio_module<2> -{ -public: - static inline float process_single(float x, float y) { - return ((x > 0) != (y > 0)) ? 1.f : 0.f; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("logical_xor_c", "Logical XOR (C)", "kf:BooleanPlugin", "xor"); - control_port_info_iface *cports[3]; - port_info(pii, cports); - cports[0]->toggle(); - cports[1]->toggle(); - cports[2]->toggle(); - } -}; - -class logical_not_c_audio_module: public control_operator_audio_module<1> -{ -public: - static inline float process_single(float x) { - return (x <= 0) ? 1.f : 0.f; - } - void process(uint32_t count) { - do_process(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("logical_not_c", "Logical NOT (C)", "kf:BooleanPlugin", "!"); - control_port_info_iface *cports[2]; - port_info(pii, cports); - cports[0]->toggle(); - cports[1]->toggle(); - } -}; - -/// converter of trigger signals from audio to control rate -class trigger_a2c_audio_module: public null_small_audio_module -{ -public: - enum { in_count = 1, out_count = 1 }; - float *ins[in_count]; - float *outs[out_count]; - void process(uint32_t count) { - for (uint32_t i = 0; i < count; i++) - { - if (ins[0][i] > 0) - { - *outs[0] = 1.f; - return; - } - } - *outs[0] = 0.f; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("trigger_a2c", "Audio-to-control OR", "kf:BooleanPlugin", "ta2c"); - pii->audio_port("in", "In").input(); - pii->control_port("out", "Out", 0.f).output().toggle(); - } -}; - -/// Monostable multivibrator like 74121 or 74123, with reset input, progress output (0 to 1), "finished" signal, configurable to allow or forbid retriggering. -class timer_c_audio_module: public null_small_audio_module -{ -public: - enum { in_trigger, in_time, in_reset, in_allow_retrig, in_count }; - enum { out_running, out_finished, out_progress, out_count }; - float *ins[in_count]; - float *outs[out_count]; - bool running, finished, old_trigger; - double state; - - void activate() - { - state = 0.f; - running = false; - finished = false; - old_trigger = false; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("timer_c", "Timer (C)", "lv2:UtilityPlugin"); - pii->control_port("trigger", "Trigger", 0.f).input().toggle().trigger(); - pii->control_port("time", "Time", 0.f).input(); - pii->control_port("reset", "Reset", 0).input().toggle(); - pii->control_port("allow_retrig", "Allow retrig", 0).input().toggle(); - pii->control_port("running", "Running", 0.f).output().toggle(); - pii->control_port("finished", "Finished", 0.f).output().toggle(); - pii->control_port("progress", "Progress", 0.f).output().lin_range(0, 1); - } - void process(uint32_t count) - { - // This is a branch city, which is definitely a bad thing. - // Perhaps I'll add a bunch of __builtin_expect hints some day, but somebody would have to start using it first. - if (*ins[in_reset] > 0) - { - state = 0.0; - running = finished = false; - } - else - if (!old_trigger && *ins[in_trigger] > 0 && (!running || *ins[in_allow_retrig] > 0)) - { - state = 0.0; - running = true; - finished = false; - } - else - if (running) - { - float rate = (1.0 / std::max(0.0000001f, *ins[in_time])); - state += rate * odsr * count; - if (state >= 1.0) - { - running = false; - finished = true; - state = 1.0; - } - } - old_trigger = *ins[in_trigger] > 0; - *outs[out_running] = running ? 1.f : 0.f; - *outs[out_finished] = finished ? 1.f : 0.f; - *outs[out_progress] = state; - } -}; - -/// 4-input priority multiplexer - without inertia. Outputs the first input if gate_1 is true, else second input if gate_2 is true, else... else "Else" input -class prio_mux_c_audio_module: public null_small_audio_module -{ -public: - enum { in_in1, in_gate1, in_in2, in_gate2, in_in3, in_gate3, in_in4, in_gate4, in_else, in_count }; - enum { out_value, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("prio_mux_c", "Priority Multiplexer (C)", "kf:BooleanPlugin"); - for (int i = 1; i <= 4; i++) - { - stringstream numb; - numb << i; - string num = numb.str(); - pii->control_port("in_"+num, "In "+num, 0.f).input(); - pii->control_port("gate_"+num, "Gate "+num, 0.f).input().toggle(); - } - pii->control_port("in_else", "Else", 0.f).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - for (int i = 0; i < 4; i++) - { - if (*ins[i * 2 + in_gate1] > 0) - { - *outs[out_value] = *ins[i * 2 + in_in1]; - return; - } - } - *outs[out_value] = *ins[in_else]; - } -}; - -/// 8-input priority encoder - outputs the index of the first port whose value is >0. 'Any' output is set whenever any of gates is set (which tells -/// apart no inputs set and 0th input set). -template -class prio_enc_c_audio_module: public null_small_audio_module -{ -public: - enum { in_gate1, in_count = in_gate1 + N}; - enum { out_value, out_any, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - char buf[32], buf2[64]; - sprintf(buf, "prio_enc%d_c", N); - sprintf(buf2, "%d-input Priority Encoder (C)", N); - pii->names(buf, buf2, "kf:IntegerPlugin"); - for (int i = 0; i < N; i++) - { - stringstream numb; - numb << i; - string num = numb.str(); - pii->control_port("gate_"+num, "Gate "+num, 0.f).input().toggle(); - } - pii->control_port("out", "Out", -1).output().integer(); - pii->control_port("any", "Any", -1).output().toggle(); - } - void process(uint32_t count) - { - for (int i = 0; i < N; i++) - { - if (*ins[in_gate1 + i] > 0) - { - *outs[out_value] = i; - *outs[out_any] = 1; - return; - } - } - *outs[out_value] = 0; - *outs[out_any] = 0; - } -}; - -typedef prio_enc_c_audio_module<8> prio_enc8_c_audio_module; - -/// 8-input integer multiplexer, outputs the input selected by ((int)select input & 7) -template -class mux_c_audio_module: public null_small_audio_module -{ -public: - enum { in_select, in_in1, in_count = in_in1 + N}; - enum { out_value, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - char buf[32], buf2[64]; - sprintf(buf, "mux%d_c", N); - sprintf(buf2, "%d-input Multiplexer (C)", N); - pii->names(buf, buf2, "kf:IntegerPlugin"); - pii->control_port("select", "Select", 0.f).input().integer().lin_range(0, N - 1); - for (int i = 0; i < N; i++) - { - stringstream numb; - numb << i; - string num = numb.str(); - pii->control_port("in_"+num, "In "+num, 0.f).input(); - } - pii->control_port("out", "Out", -1).output(); - } - void process(uint32_t count) - { - *outs[out_value] = *ins[in_in1 + ((N - 1) & (int)*ins[in_select])]; - } -}; - -typedef mux_c_audio_module<4> mux4_c_audio_module; -typedef mux_c_audio_module<8> mux8_c_audio_module; -typedef mux_c_audio_module<16> mux16_c_audio_module; - -/// Linear-to-exponential mapper -class map_lin2exp_audio_module: public null_small_audio_module -{ -public: - enum { in_signal, in_from_min, in_from_max, in_to_min, in_to_max, in_count }; - enum { out_signal, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("lin2exp", "Lin-Exp Mapper", "lv2:UtilityPlugin"); - pii->control_port("in", "In", 0.f).input(); - pii->control_port("from_min", "Min (from)", 0).input(); - pii->control_port("from_max", "Max (from)", 1).input(); - pii->control_port("to_min", "Min (to)", 20).input(); - pii->control_port("to_max", "Max (to)", 20000).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - float normalized = (*ins[in_signal] - *ins[in_from_min]) / (*ins[in_from_max] - *ins[in_from_min]); - *outs[out_signal] = *ins[in_to_min] * pow(*ins[in_to_max] / *ins[in_to_min], normalized); - } -}; - -/// Schmitt trigger - http://en.wikipedia.org/wiki/Schmitt_trigger - also outputs a change signal (positive spike whenever output value is changed) -class schmitt_c_audio_module: public null_small_audio_module -{ -public: - enum { in_signal, in_low, in_high, in_count }; - enum { out_signal, out_change, out_count }; - float *ins[in_count]; - float *outs[out_count]; - bool state; - - void activate() - { - state = false; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("schmitt_c", "Schmitt Trigger (C)", "kf:BooleanPlugin"); - pii->control_port("in", "In", 0.f).input(); - pii->control_port("low", "Low threshold", 0).input(); - pii->control_port("high", "High threshold", 0.5).input(); - pii->control_port("out", "Out", 0.f).output(); - pii->control_port("change", "Change", 0.f).output(); - } - void process(uint32_t count) - { - float value = *ins[in_signal]; - bool new_state = state; - if (value <= *ins[in_low]) - new_state = false; - if (value >= *ins[in_high]) - new_state = true; - *outs[out_signal] = new_state ? 1.f : 0.f; - *outs[out_change] = (new_state != state) ? 1.f : 0.f; - state = new_state; - } -}; - -/// Stateless 'between' operator (lo <= in <= hi) -class between_c_audio_module: public null_small_audio_module -{ -public: - enum { in_signal, in_low, in_high, in_count }; - enum { out_signal, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("between_c", "Between (C)", "kf:MathOperatorPlugin"); - pii->control_port("in", "In", 0.f).input(); - pii->control_port("low", "Low threshold", 0).input(); - pii->control_port("high", "High threshold", 1).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - float value = *ins[in_signal]; - *outs[out_signal] = (value >= *ins[in_low] && value <= *ins[in_high]) ? 1.f : 0.f; - } -}; - -/// Clip to range -class clip_c_audio_module: public null_small_audio_module -{ -public: - enum { in_signal, in_min, in_max, in_count }; - enum { out_signal, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("clip_c", "Clip (C)", "kf:MathOperatorPlugin", "clip"); - pii->control_port("in", "In", 0.f).input(); - pii->control_port("min", "Min", 0).input(); - pii->control_port("max", "Max", 1).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - float value = *ins[in_signal]; - *outs[out_signal] = std::min(*ins[in_max], std::max(value, *ins[in_min])); - } -}; - -/// Two input control crossfader -class crossfader2_c_audio_module: public null_small_audio_module -{ -public: - enum { in_a, in_b, in_ctl, in_count }; - enum { out_value, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("crossfader2_c", "2-in crossfader (C)", "kf:MathOperatorPlugin", "xfC"); - pii->control_port("in_a", "In A", 0.f).input(); - pii->control_port("in_b", "In B", 0).input(); - pii->control_port("mix", "B in mix", 0.5).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - *outs[out_value] = *ins[in_a] + (*ins[in_b] - *ins[in_a]) * dsp::clip(*ins[in_ctl], 0.f, 1.f); - } -}; - -/// 2-input multiplexer (if-then-else) -class ifthenelse_c_audio_module: public null_small_audio_module -{ -public: - enum { in_if, in_then, in_else, in_count }; - enum { out_value, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("ifthenelse_c", "If-Then-Else (C)", "kf:BooleanPlugin", "if"); - pii->control_port("if", "If", 0.f).input().toggle(); - pii->control_port("then", "Then", 0).input(); - pii->control_port("else", "Else", 0).input(); - pii->control_port("out", "Out", 0.f).output(); - } - void process(uint32_t count) - { - *outs[out_value] = *ins[in_if] > 0 ? *ins[in_then] : *ins[in_else]; - } -}; - -/// Integer counter with definable ranges -class counter_c_audio_module: public null_small_audio_module -{ -public: - enum { in_clock, in_min, in_max, in_steps, in_reset, in_count }; - enum { out_value, out_carry, out_count }; - float *ins[in_count]; - float *outs[out_count]; - bool state; - int value; - - void activate() - { - state = false; - value = 0; - } - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("counter_c", "Counter (C)", "kf:IntegerPlugin", "cnt"); - pii->control_port("clock", "Clock", 0.f).input().toggle().trigger(); - pii->control_port("min", "Min", 0).input(); - pii->control_port("max", "Max", 15).input(); - pii->control_port("steps", "Steps", 16).input().integer(); - pii->control_port("reset", "Reset", 0).input().toggle(); - pii->control_port("out", "Out", 0.f).output(); - pii->control_port("carry", "Carry", 0.f).output().toggle().trigger(); - } - void process(uint32_t count) - { - // Yes, this is slower than it should be. I will bother optimizing it when someone starts actually using it. - if (*ins[in_reset] > 0 || *ins[in_steps] < 2.0) - { - state = false; - value = 0; - *outs[out_value] = *ins[in_min]; - *outs[out_carry] = 0.f; - return; - } - *outs[out_carry] = 0; - if (!state && *ins[in_clock] > 0) - { - value++; - state = true; - if (value >= (int)*ins[in_steps]) - { - value = 0; - *outs[out_carry] = 1; - } - } - else - state = *ins[in_clock] > 0; - *outs[out_value] = *ins[in_min] + (*ins[in_max] - *ins[in_min]) * value / (int)(*ins[in_steps] - 1); - } -}; - -/// Two input audio crossfader -class crossfader2_a_audio_module: public null_small_audio_module -{ -public: - enum { in_a, in_b, in_ctl, in_count }; - enum { out_value, out_count }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - pii->names("crossfader2_a", "2-in crossfader (A)", "kf:MathOperatorPlugin", "xfA"); - pii->audio_port("in_a", "In A").input(); - pii->audio_port("in_b", "In B").input(); - pii->audio_port("mix", "B in mix").input(); - pii->audio_port("out", "Out").output(); - } - void process(uint32_t count) - { - for (uint32_t i = 0; i < count; i++) - outs[out_value][i] = ins[in_a][i] + (ins[in_b][i] - ins[in_a][i]) * dsp::clip(ins[in_ctl][i], 0.f, 1.f); - } -}; - -/// Base class for LFOs with frequency and reset inputs -class freq_phase_lfo_base: public small_audio_module_base<2, 1> -{ -public: - enum { in_freq, in_reset }; - double phase; - inline void activate() - { - phase = 0; - } - static void port_info(plugin_info_iface *pii) - { - pii->control_port("freq", "Frequency", 1).input().log_range(0.02, 100); - pii->control_port("reset", "Reset", 0).input().toggle(); - pii->control_port("out", "Out", 0).output(); - } - inline void check_inputs() - { - if (*ins[in_reset]) - phase = 0; - } - inline void advance(uint32_t count) - { - phase += count * *ins[in_freq] * odsr; - if (phase >= 1.0) - phase = fmod(phase, 1.0); - } -}; - -class square_lfo_audio_module: public freq_phase_lfo_base -{ -public: - void process(uint32_t count) - { - check_inputs(); - *outs[0] = (phase < 0.5) ? -1 : +1; - advance(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("square_lfo", "Square LFO", "lv2:OscillatorPlugin"); - port_info(pii); - } -}; - -class saw_lfo_audio_module: public freq_phase_lfo_base -{ -public: - void process(uint32_t count) - { - check_inputs(); - *outs[0] = -1 + 2 * phase; - advance(count); - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("saw_lfo", "Saw LFO", "lv2:OscillatorPlugin"); - port_info(pii); - } -}; - -class pulse_lfo_audio_module: public freq_phase_lfo_base -{ -public: - inline void activate() - { - phase = 1.0; - } - void process(uint32_t count) - { - check_inputs(); - double oldphase = phase; - advance(count); - *outs[0] = (phase < oldphase) ? 1.f : 0.f; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("pulse_lfo", "Pulse LFO", "lv2:OscillatorPlugin"); - port_info(pii); - } -}; - -#define SMALL_OSC_TABLE_BITS 12 - -class freq_only_osc_base_common: public null_small_audio_module -{ -public: - typedef waveform_family waves_type; - enum { in_freq, in_count }; - enum { out_signal, out_count}; - enum { wave_size = 1 << SMALL_OSC_TABLE_BITS }; - float *ins[in_count]; - float *outs[out_count]; - waves_type *waves; - waveform_oscillator osc; - - /// Fill the array with the original, non-bandlimited, waveform - virtual void get_original_waveform(float data[wave_size]) = 0; - /// This function needs to be virtual to ensure a separate wave family for each class (but not each instance) - virtual waves_type *get_waves() = 0; - void activate() { - waves = get_waves(); - } - void process(uint32_t count) - { - osc.set_freq_odsr(*ins[in_freq], odsr); - osc.waveform = waves->get_level(osc.phasedelta); - if (osc.waveform) - { - for (uint32_t i = 0; i < count; i++) - outs[out_signal][i] = osc.get(); - } - else - dsp::zero(outs[out_signal], count); - } - static void port_info(plugin_info_iface *pii) - { - pii->control_port("freq", "Frequency", 440).input().log_range(20, 20000); - pii->audio_port("out", "Out").output(); - } - /// Generate a wave family (bandlimit levels) from the original wave - waves_type *create_waves() { - waves_type *ptr = new waves_type; - float source[wave_size]; - get_original_waveform(source); - bandlimiter bl; - ptr->make(bl, source); - return ptr; - } -}; - -template -class freq_only_osc_base: public freq_only_osc_base_common -{ - virtual waves_type *get_waves() { - static waves_type *waves = NULL; - if (!waves) - waves = create_waves(); - return waves; - } -}; - -class square_osc_audio_module: public freq_only_osc_base -{ -public: - virtual void get_original_waveform(float data[wave_size]) { - for (int i = 0; i < wave_size; i++) - data[i] = (i < wave_size / 2) ? +1 : -1; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("squareosc", "Square Oscillator", "lv2:OscillatorPlugin"); - port_info(pii); - } -}; - -class saw_osc_audio_module: public freq_only_osc_base -{ -public: - virtual void get_original_waveform(float data[wave_size]) { - for (int i = 0; i < wave_size; i++) - data[i] = (i * 2.0 / wave_size) - 1; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("sawosc", "Saw Oscillator", "lv2:OscillatorPlugin"); - port_info(pii); - } -}; - -class print_c_audio_module: public small_audio_module_base<1, 0> -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("print_c", "Print To Console (C)", "lv2:UtilityPlugin"); - pii->control_port("in", "In", 0).input(); - } - void process(uint32_t) - { - printf("%f\n", *ins[0]); - } -}; - -class print_e_audio_module: public small_audio_module_base<1, 0> -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("print_e", "Print To Console (E)", "lv2:UtilityPlugin"); - pii->event_port("in", "In").input(); - } - void dump(LV2_Event_Buffer *event_data) - { - event_port_read_iterator ei(event_data); - while(ei) - { - const lv2_event &event = *ei++; - printf("Event at %d.%d, type %d, size %d:", event.frames, event.subframes, (int)event.type, (int)event.size); - uint32_t size = std::min((uint16_t)16, event.size); - - for (uint32_t j = 0; j < size; j++) - printf(" %02X", (uint32_t)event.data[j]); - if (event.size > size) - printf("...\n"); - else - printf("\n"); - } - } - void process(uint32_t) - { - LV2_Event_Buffer *event_data = (LV2_Event_Buffer *)ins[0]; - dump(event_data); - } -}; - -class print_em_audio_module: public print_e_audio_module -{ -public: - LV2_Event_Buffer *events; - static void plugin_info(plugin_info_iface *pii) - { - pii->names("print_em", "Print To Console (EM)", "lv2:UtilityPlugin"); - pii->lv2_ttl("lv2:requiredFeature ;"); - pii->lv2_ttl("lv2:requiredFeature lv2ctx:MessageContext ;"); - pii->lv2_ttl("lv2ctx:requiredContext lv2ctx:MessageContext ;"); - pii->event_port("in", "In").input().lv2_ttl("lv2ctx:context lv2ctx:MessageContext ;"); - } - void process(uint32_t) - { - } - static uint32_t message_run(LV2_Handle instance, const void *valid_inputs, void *outputs_written) - { - print_em_audio_module *self = (print_em_audio_module *)instance; - if (lv2_contexts_port_is_valid(valid_inputs, 0)) - { - printf("message_run (events = %p, count = %d)\n", self->events, self->events->event_count); - self->dump(self->events); - } - return 0; - } - static void message_connect_port(LV2_Handle instance, uint32_t port, void* data) - { - print_em_audio_module *self = (print_em_audio_module *)instance; - printf("message_connect_port %d -> %p\n", port, data); - assert(!port); - self->events = (LV2_Event_Buffer *)data; - } - static inline const void *ext_data(const char *URI) { - static LV2MessageContext ctx_ext_data = { message_run, message_connect_port }; - printf("URI=%s\n", URI); - if (!strcmp(URI, LV2_CONTEXT_MESSAGE)) - { - return &ctx_ext_data; - } - return NULL; - } -}; - -class copy_em_audio_module: public small_audio_module_base<0, 0> -{ -public: - LV2_Event_Buffer *events_in, *events_out; - static void plugin_info(plugin_info_iface *pii) - { - pii->names("copy_em", "Message pass-through (EM)", "lv2:UtilityPlugin"); - pii->lv2_ttl("lv2:requiredFeature lv2ctx:MessageContext ;"); - pii->lv2_ttl("lv2:requiredFeature ;"); - pii->lv2_ttl("lv2:requiredContext lv2ctx:MessageContext ;"); - pii->event_port("in", "In").input().lv2_ttl("lv2ctx:context lv2ctx:MessageContext ;"); - pii->event_port("out", "Out").output().lv2_ttl("lv2ctx:context lv2ctx:MessageContext ;"); - } - void process(uint32_t) - { - } - static uint32_t message_run(LV2_Handle instance, const void *valid_inputs, void *outputs_written) - { - copy_em_audio_module *self = (copy_em_audio_module *)instance; - return self->message_run(valid_inputs, outputs_written); - } - uint32_t message_run(const void *inputs_written, void *outputs_written) - { - if (lv2_contexts_port_is_valid(inputs_written, 0)) - { - event_port_read_iterator ri(events_in); - event_port_write_iterator wi(events_out); - if (events_in->size > events_out->capacity) - { - printf("Buffer capacity exceeded!\n"); - return false; - } - while(ri) - { - const lv2_event &event = *ri++; - *wi++ = event; - } - if (events_in->event_count != 0) - { - lv2_contexts_set_port_valid(outputs_written, 1); - return 1; - } - } - lv2_contexts_unset_port_valid(outputs_written, 1); - return 0; - } - static void message_connect_port(LV2_Handle instance, uint32_t port, void* data) - { - copy_em_audio_module *self = (copy_em_audio_module *)instance; - printf("message_connect_port %d -> %p\n", port, data); - if (port == 0) self->events_in = (LV2_Event_Buffer *)data; - if (port == 1) self->events_out = (LV2_Event_Buffer *)data; - } - static inline const void *ext_data(const char *URI) { - static LV2MessageContext ctx_ext_data = { message_run, message_connect_port }; - if (!strcmp(URI, LV2_CONTEXT_MESSAGE)) - { - printf("URI=%s\n", URI); - return &ctx_ext_data; - } - return NULL; - } -}; - -template -class miditypefilter_m_audio_module: public midi_mixin > -{ -public: - static inline void extra_inputs(plugin_info_iface *pii) - { - } - static inline const char *plugin_symbol() { return Range::strings()[0]; } - static inline const char *plugin_name() { return Range::strings()[1]; } - static inline const char *port_symbol() { return Range::strings()[2]; } - static inline const char *port_name() { return Range::strings()[3]; } - static void plugin_info(plugin_info_iface *pii) - { - pii->names(Range::plugin_symbol(), Range::plugin_name(), "kf:MIDIPlugin"); - pii->event_port("in", "In").input(); - Range::extra_inputs(pii); - pii->event_port(Range::port_symbol(), Range::port_name()).output(); - pii->event_port("others", "Others").output(); - } - void process(uint32_t) - { - event_port_read_iterator ri((LV2_Event_Buffer *)this->ins[0]); - event_port_write_iterator wi((LV2_Event_Buffer *)this->outs[0]); - event_port_write_iterator wi2((LV2_Event_Buffer *)this->outs[1]); - while(ri) - { - const lv2_event &event = *ri++; - if (event.type == this->midi_event_type && event.size && Range::is_in_range(event.data, this->ins)) - *wi++ = event; - else - *wi2++ = event; - } - } -}; - -class notefilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0x80 && data[0] <= 0x9F; } - static inline const char **strings() { static const char *s[] = { "notefilter_m", "Note Filter", "note", "Note" }; return s;} -}; - -class pcfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xA0 && data[0] <= 0xAF; } - static inline const char **strings() { static const char *s[] = { "pcfilter_m", "Program Change Filter", "pc", "PC" }; return s;} -}; - -class ccfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xB0 && data[0] <= 0xBF; } - static inline const char **strings() { static const char *s[] = { "ccfilter_m", "Control Change Filter", "cc", "CC" }; return s;} -}; - -class pressurefilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xC0 && data[0] <= 0xDF; } - static inline const char **strings() { static const char *s[] = { "pressurefilter_m", "Pressure Filter", "pressure", "Pressure" }; return s;} -}; - -class pitchbendfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xE0 && data[0] <= 0xEF; } - static inline const char **strings() { static const char *s[] = { "pitchbendfilter_m", "Pitch Bend Filter", "pbend", "Pitch Bend" }; return s;} -}; - -class systemfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline bool is_in_range(const uint8_t *data, float **) { return data[0] >= 0xF0; } - static inline const char **strings() { static const char *s[] = { "systemfilter_m", "System Msg Filter", "system", "System" }; return s;} -}; - -class channelfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline void extra_inputs(plugin_info_iface *pii) - { - pii->control_port("min", "Min Channel", 1).input().integer().lin_range(1, 16); - pii->control_port("max", "Max Channel", 16).input().integer().lin_range(1, 16); - } - static inline bool is_in_range(const uint8_t *data, float **ins) { - int chnl = 1 + (data[0] & 0xF); - return data[0] < 0xF0 && chnl >= *ins[1] && chnl <= *ins[2]; - } - static inline const char **strings() { static const char *s[] = { "channelfilter_m", "Channel Range Filter", "range", "Range" }; return s;} -}; - -class keyfilter_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline void extra_inputs(plugin_info_iface *pii) - { - pii->control_port("min", "Min Note", 0).input().integer().lin_range(0, 127); - pii->control_port("max", "Max Note", 127).input().integer().lin_range(0, 127); - } - static inline bool is_in_range(const uint8_t *data, float **ins) { - // XXXKF doesn't handle polyphonic aftertouch - return (data[0] >= 0x80 && data[0] <= 0x9F) && data[0] >= *ins[1] && data[1] <= *ins[2]; - } - static inline const char **strings() { static const char *s[] = { "keyfilter_m", "Key Range Filter", "range", "Range" }; return s;} -}; - -class key_less_than_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline void extra_inputs(plugin_info_iface *pii) - { - pii->control_port("threshold", "Threshold", 60).input().integer().lin_range(0, 128); - } - static inline bool is_in_range(const uint8_t *data, float **ins) { - // XXXKF doesn't handle polyphonic aftertouch - return (data[0] >= 0x80 && data[0] <= 0x9F) && data[1] < *ins[1]; - } - static inline const char **strings() { static const char *s[] = { "key_less_than_m", "Key Less-Than Filter", "less", "Less" }; return s;} -}; - -class channel_less_than_m_audio_module: public miditypefilter_m_audio_module -{ -public: - static inline void extra_inputs(plugin_info_iface *pii) - { - pii->control_port("threshold", "Threshold", 10).input().integer().lin_range(1, 16); - } - static inline bool is_in_range(const uint8_t *data, float **ins) { - // XXXKF doesn't handle polyphonic aftertouch - return (data[0] < 0xF0) && (1 + (data[0] & 0xF)) < *ins[1]; - } - static inline const char **strings() { static const char *s[] = { "channel_less_than_m", "Channel Less-Than Filter", "less", "Less" }; return s;} -}; - -class transpose_m_audio_module: public midi_mixin > -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("transpose_m", "Transpose", "kf:MIDIPlugin"); - pii->event_port("in", "In").input(); - pii->control_port("transpose", "Transpose", 12).input().integer(); - pii->event_port("out", "Out").output(); - } - void process(uint32_t) - { - event_port_read_iterator ri((LV2_Event_Buffer *)ins[0]); - event_port_write_iterator wi((LV2_Event_Buffer *)outs[0]); - while(ri) - { - const lv2_event &event = *ri++; - if (event.type == this->midi_event_type && event.size == 3 && (event.data[0] >= 0x80 && event.data[0] <= 0x9F)) - { - int new_note = event.data[1] + (int)*ins[1]; - // ignore out-of-range notes - if (new_note >= 0 && new_note <= 127) - { - // it is not possible to create copies here because they are variable length and would "nicely" overwrite the stack - // so write the original event instead, and then modify the pitch - *wi = event; - wi->data[1] = new_note; - wi++; - } - } - else - *wi++ = event; - } - } -}; - -class setchannel_m_audio_module: public midi_mixin > -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("setchannel_m", "Set Channel", "kf:MIDIPlugin"); - pii->event_port("in", "In").input(); - pii->control_port("channel", "Channel", 1).input().integer().lin_range(1, 16); - pii->event_port("out", "Out").output(); - } - void process(uint32_t) - { - event_port_read_iterator ri((LV2_Event_Buffer *)ins[0]); - event_port_write_iterator wi((LV2_Event_Buffer *)outs[0]); - while(ri) - { - const lv2_event &event = *ri++; - if (event.type == this->midi_event_type && (event.data[0] >= 0x80 && event.data[0] <= 0xEF)) - { - *wi = event; - // modify channel number in the first byte - wi->data[0] = (wi->data[0] & 0xF0) | (((int)*ins[1] - 1) & 0xF); - wi++; - } - else - *wi++ = event; - } - } -}; - -class eventmerge_e_audio_module: public event_mixin > -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("eventmerge_e", "Event Merge (E)", "lv2:UtilityPlugin"); - pii->event_port("in_1", "In 1").input(); - pii->event_port("in_2", "In 2").input(); - pii->event_port("out", "Out").output(); - } - void process(uint32_t) - { - event_port_merge_iterator ri((const LV2_Event_Buffer *)ins[0], (const LV2_Event_Buffer *)ins[1]); - event_port_write_iterator wi((LV2_Event_Buffer *)outs[0]); - while(ri) - *wi++ = *ri++; - } -}; - -class print_a_audio_module: public small_audio_module_base<1, 0> -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("print_a", "Print To Console (A)", "lv2:UtilityPlugin"); - pii->audio_port("in", "In").input(); - } - void process(uint32_t) - { - printf("%f\n", *ins[0]); - } -}; - -template -class quadpower_base: public null_small_audio_module -{ -public: - enum { in_value, in_factor, in_count , out_count = 4 }; - float *ins[in_count]; - float *outs[out_count]; - - static void plugin_info(plugin_info_iface *pii) - { - const char *names[8] = {"xa", "x*a^1", "xaa", "x*a^2", "xaaa", "x*a^3", "xaaaa", "x*a^4" }; - if (audio) - pii->names("quadpower_a", "Quad Power (A)", "kf:MathOperatorPlugin"); - else - pii->names("quadpower_c", "Quad Power (C)", "kf:MathOperatorPlugin"); - if (audio) - pii->audio_port("x", "x").input(); - else - pii->control_port("x", "x", 1).input(); - pii->control_port("a", "a", 1).input(); - for (int i = 0; i < 8; i += 2) - if (audio) - pii->audio_port(names[i], names[i+1]).output(); - else - pii->control_port(names[i], names[i+1], 0).output(); - } -}; - -class quadpower_a_audio_module: public quadpower_base -{ -public: - void process(uint32_t count) - { - float a = *ins[in_factor]; - for (uint32_t i = 0; i < count; i++) - { - float x = ins[in_value][i]; - outs[0][i] = x * a; - outs[1][i] = x * a * a; - outs[2][i] = x * a * a * a; - outs[3][i] = x * a * a * a * a; - } - } -}; - -class quadpower_c_audio_module: public quadpower_base -{ -public: - void process(uint32_t) - { - float x = *ins[in_value]; - float a = *ins[in_factor]; - *outs[0] = x * a; - *outs[1] = x * a * a; - *outs[2] = x * a * a * a; - *outs[3] = x * a * a * a * a; - } -}; - -template -class inertia_c_module_base: public small_audio_module_base<3, 1> -{ -public: - enum { in_value, in_inertia, in_immediate }; - bool reset; - inertia state; - inertia_c_module_base() - : state(Ramp(1)) - {} - void activate() - { - reset = true; - } - static void port_info(plugin_info_iface *pii) - { - pii->control_port("in", "In", 0).input(); - pii->control_port("time", "Inertia time", 100).input(); - pii->control_port("reset", "Reset", 0).input().toggle().trigger(); - pii->control_port("out", "Out", 0).output(); - } - void process(uint32_t count) - { - float value = *ins[in_value]; - if (reset || *ins[in_immediate] > 0) - { - *outs[0] = value; - state.set_now(value); - reset = false; - } - else - { - if (value != state.get_last()) - { - state.ramp.set_length(dsp::clip((int)(srate * 0.001 * *ins[in_inertia]), 1, 10000000)); - } - state.set_inertia(value); - *outs[0] = state.get_last(); - if (count) - state.step_many(count); - } - } -}; - -class linear_inertia_c_audio_module: public inertia_c_module_base -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("linear_inertia_c", "Linear Inertia (C)", "lv2:FilterPlugin"); - port_info(pii); - } -}; - -class exp_inertia_c_audio_module: public inertia_c_module_base -{ -public: - static void plugin_info(plugin_info_iface *pii) - { - pii->names("exp_inertia_c", "Exponential Inertia (C)", "lv2:FilterPlugin"); - port_info(pii); - } -}; - -class sample_hold_base: public small_audio_module_base<2, 1> -{ -public: - enum { in_value, in_gate }; - static void port_info(plugin_info_iface *pii, const char *clock_symbol, const char *clock_name) - { - pii->control_port("in", "In", 0).input(); - pii->control_port(clock_symbol, clock_name, 0).input().toggle().trigger(); - pii->control_port("out", "Out", 0).output(); - } -}; - -class sample_hold_edge_c_audio_module: public sample_hold_base -{ -public: - bool prev_clock; - float value; - void activate() - { - prev_clock = false; - value = 0; - } - void process(uint32_t count) - { - if (!prev_clock && *ins[in_gate] > 0) - value = *ins[in_value]; - prev_clock = *ins[in_gate] > 0; - *outs[0] = value; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("sample_hold_edge", "Sample&Hold (Edge, C)", "lv2:UtilityPlugin"); - port_info(pii, "clock", "Clock"); - } -}; - -class sample_hold_level_c_audio_module: public sample_hold_base -{ -public: - float value; - void activate() - { - value = 0; - } - void process(uint32_t count) - { - if (*ins[in_gate] > 0) - value = *ins[in_value]; - *outs[0] = value; - } - static void plugin_info(plugin_info_iface *pii) - { - pii->names("sample_hold_level", "Sample&Hold (Level, C)", "lv2:UtilityPlugin"); - port_info(pii, "gate", "Gate"); - } -}; - -class msgread_e_audio_module: public message_mixin > -{ -public: - uint32_t set_float_msg, float_type; - static void plugin_info(plugin_info_iface *pii) - { - pii->names("msgread_e", "Msg Read", "lv2:UtilityPlugin"); - pii->has_gui(); - pii->event_port("in", "In").input(); - pii->control_port("out", "Out", 0).output(); - } - virtual void map_uris() - { - message_mixin >::map_uris(); - set_float_msg = map_uri("http://lv2plug.in/ns/dev/msg", "http://foltman.com/garbage/setFloat"); - float_type = map_uri("http://lv2plug.in/ns/dev/types", "http://lv2plug.in/ns/dev/types#float"); - } - void process(uint32_t count) - { - event_port_read_iterator ri((const LV2_Event_Buffer *)ins[0]); - while(ri) - { - const lv2_event *event = &*ri++; - if (event->type == message_event_type) - { - struct payload { - uint32_t selector; - uint32_t serial_no; - uint32_t data_size; - uint32_t parg_count; - uint32_t data_type; - float data_value; - uint32_t narg_count; - }; - const payload *p = (const payload *)event->data; - if (p->selector == set_float_msg) { - assert(p->parg_count == 1); - assert(p->data_size == 16); - assert(p->data_type == float_type); - *outs[0] = p->data_value; - assert(p->narg_count == 0); // this is just for testing - passing - } - } - } - } -}; - -}; - -#define PER_SMALL_MODULE_ITEM(name, id) SMALL_WRAPPERS(name, id) -#include - -const LV2_Descriptor *calf_plugins::lv2_small_descriptor(uint32_t index) -{ - #define PER_SMALL_MODULE_ITEM(name, id) if (!(index--)) return &::lv2_small_##name.descriptor; - #include - return NULL; -} -#endif -#endif - -void calf_plugins::get_all_small_plugins(plugin_list_info_iface *iface) -{ -#if USE_LV2 - #define PER_SMALL_MODULE_ITEM(name, id) { plugin_info_iface *pii = &iface->plugin(id); small_plugins::name##_audio_module::plugin_info(pii); pii->finalize(); } - #include -#endif -} - diff --git a/plugins/ladspa_effect/calf/src/plugin.cpp b/plugins/ladspa_effect/calf/src/plugin.cpp index 2887904d1..2467d5348 100644 --- a/plugins/ladspa_effect/calf/src/plugin.cpp +++ b/plugins/ladspa_effect/calf/src/plugin.cpp @@ -22,7 +22,6 @@ #include #include #include -#include using namespace calf_plugins; @@ -61,11 +60,7 @@ const LV2_Descriptor *lv2_descriptor(uint32_t index) { #define PER_MODULE_ITEM(name, isSynth, jackname) if (!(index--)) return &lv2_wrapper::get().descriptor; #include -#ifdef ENABLE_EXPERIMENTAL - return lv2_small_descriptor(index); -#else return NULL; -#endif } }; From f8cb1120b0f3f44d85a406f4bf412ca4b1f67f01 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 2 Apr 2010 23:33:37 +0100 Subject: [PATCH 6/7] Remove zombie small plugin code. (cherry picked from commit ed69e7d41246d169ffccdc97cc666b111bdc6710) --- plugins/ladspa_effect/calf/calf/giface.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index 36ab043b3..e6c0736b3 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -395,8 +395,6 @@ public: const plugin_metadata_iface *get_by_uri(const char *URI); }; -/// Get a list of all "small" (module) plugins -extern void get_all_small_plugins(plugin_list_info_iface *plii); /// Load and strdup a text file with GUI definition extern const char *load_gui_xml(const std::string &plugin_id); From 527a02d648387bc8d666b5adb34abc03e6b7cda0 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 3 Apr 2010 01:35:22 +0100 Subject: [PATCH 7/7] Simplify Multiband Compressor code and fix several bugs. Eliminated some (not all) repetition in the code. Fixed a bug where old value for Q and separation was taken from the wrong variable. Fixed a bug where having a band bypassed or muted caused the graph to stop redrawing properly. (cherry picked from commit 3be583385b0bfb69bb7e52ee7426fe27d515560c) --- plugins/ladspa_effect/calf/calf/modules.h | 3 + .../ladspa_effect/calf/src/modules_dsp.cpp | 237 ++++++------------ 2 files changed, 80 insertions(+), 160 deletions(-) diff --git a/plugins/ladspa_effect/calf/calf/modules.h b/plugins/ladspa_effect/calf/calf/modules.h index b3ed83b89..6bce138e3 100644 --- a/plugins/ladspa_effect/calf/calf/modules.h +++ b/plugins/ladspa_effect/calf/calf/modules.h @@ -792,6 +792,7 @@ private: public: gain_reduction_audio_module(); void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu); + void update_curve(); void process(float &left, float &right, float det_left = NULL, float det_right = NULL); void activate(); void deactivate(); @@ -910,6 +911,7 @@ public: /// Multibandcompressor by Markus Schmidt class multibandcompressor_audio_module: public audio_module, public line_graph_iface { private: + typedef multibandcompressor_audio_module AM; static const int strips = 4; bool mute[strips]; uint32_t clip_inL, clip_inR, clip_outL, clip_outR; @@ -929,6 +931,7 @@ public: void params_changed(); uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); void set_sample_rate(uint32_t sr); + const gain_reduction_audio_module *get_strip_by_param_index(int index) const; virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; diff --git a/plugins/ladspa_effect/calf/src/modules_dsp.cpp b/plugins/ladspa_effect/calf/src/modules_dsp.cpp index d7f03b025..66eba417d 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -31,6 +31,8 @@ using namespace dsp; using namespace calf_plugins; +#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const @@ -398,8 +400,8 @@ void multibandcompressor_audio_module::params_changed() hpL0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); hpR0.copy_coeffs(hpL0); freq_old[0] = *params[param_freq0]; - sep_old[0] = *params[param_sep2]; - q_old[0] = *params[param_q2]; + sep_old[0] = *params[param_sep0]; + q_old[0] = *params[param_q0]; } if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1]) { lpL1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); @@ -407,8 +409,8 @@ void multibandcompressor_audio_module::params_changed() hpL1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); hpR1.copy_coeffs(hpL1); freq_old[1] = *params[param_freq1]; - sep_old[1] = *params[param_sep2]; - q_old[1] = *params[param_q2]; + sep_old[1] = *params[param_sep1]; + q_old[1] = *params[param_q1]; } if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2]) { lpL2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); @@ -420,22 +422,10 @@ void multibandcompressor_audio_module::params_changed() q_old[2] = *params[param_q2]; } // set the params of all strips - for (int j = 0; j < strips; j ++) { - switch (j) { - case 0: - strip[j].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], *params[param_mute0]); - break; - case 1: - strip[j].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], *params[param_mute1]); - break; - case 2: - strip[j].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], *params[param_mute2]); - break; - case 3: - strip[j].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], *params[param_mute3]); - break; - } - } + strip[0].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], *params[param_mute0]); + strip[1].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], *params[param_mute1]); + strip[2].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], *params[param_mute2]); + strip[3].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], *params[param_mute3]); } void multibandcompressor_audio_module::set_sample_rate(uint32_t sr) @@ -447,10 +437,24 @@ void multibandcompressor_audio_module::set_sample_rate(uint32_t sr) } } +#define BYPASSED_COMPRESSION(index) \ + if(params[param_compression##index] != NULL) \ + *params[param_compression##index] = 1.0; \ + if(params[param_output##index] != NULL) \ + *params[param_output##index] = 0.0; + +#define ACTIVE_COMPRESSION(index) \ + if(params[param_compression##index] != NULL) \ + *params[param_compression##index] = strip[index].get_comp_level(); \ + if(params[param_output##index] != NULL) \ + *params[param_output##index] = strip[index].get_output_level(); + uint32_t multibandcompressor_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; + for (int i = 0; i < strips; i++) + strip[i].update_curve(); if(bypass) { // everything bypassed while(offset < numsamples) { @@ -595,165 +599,75 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num } // process all strips (no bypass) // 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); // draw strip meters if(bypass > 0.5f) { - if(params[param_compression0] != NULL) { - *params[param_compression0] = 1.0f; - } - if(params[param_compression1] != NULL) { - *params[param_compression1] = 1.0f; - } - if(params[param_compression2] != NULL) { - *params[param_compression2] = 1.0f; - } - if(params[param_compression3] != NULL) { - *params[param_compression3] = 1.0f; - } - - if(params[param_output0] != NULL) { - *params[param_output0] = 0.0f; - } - if(params[param_output1] != NULL) { - *params[param_output1] = 0.0f; - } - if(params[param_output2] != NULL) { - *params[param_output2] = 0.0f; - } - if(params[param_output3] != NULL) { - *params[param_output3] = 0.0f; - } + BYPASSED_COMPRESSION(0) + BYPASSED_COMPRESSION(1) + BYPASSED_COMPRESSION(2) + BYPASSED_COMPRESSION(3) } else { - if(params[param_compression0] != NULL) { - *params[param_compression0] = strip[0].get_comp_level(); - } - if(params[param_compression1] != NULL) { - *params[param_compression1] = strip[1].get_comp_level(); - } - if(params[param_compression2] != NULL) { - *params[param_compression2] = strip[2].get_comp_level(); - } - if(params[param_compression3] != NULL) { - *params[param_compression3] = strip[3].get_comp_level(); - } - - if(params[param_output0] != NULL) { - *params[param_output0] = strip[0].get_output_level(); - } - if(params[param_output1] != NULL) { - *params[param_output1] = strip[1].get_output_level(); - } - if(params[param_output2] != NULL) { - *params[param_output2] = strip[2].get_output_level(); - } - if(params[param_output3] != NULL) { - *params[param_output3] = strip[3].get_output_level(); - } + ACTIVE_COMPRESSION(0) + ACTIVE_COMPRESSION(1) + ACTIVE_COMPRESSION(2) + ACTIVE_COMPRESSION(3) } // whatever has to be returned x) return outputs_mask; } -bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const + +const gain_reduction_audio_module *multibandcompressor_audio_module::get_strip_by_param_index(int index) const { // let's handle by the corresponding strip switch (index) { case param_compression0: - return strip[0].get_graph(subindex, data, points, context); - break; + return &strip[0]; case param_compression1: - return strip[1].get_graph(subindex, data, points, context); - break; + return &strip[1]; case param_compression2: - return strip[2].get_graph(subindex, data, points, context); - break; + return &strip[2]; case param_compression3: - return strip[3].get_graph(subindex, data, points, context); - break; + return &strip[3]; } + return NULL; +} + +bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const +{ + const gain_reduction_audio_module *m = get_strip_by_param_index(index); + if (m) + return m->get_graph(subindex, data, points, context); return false; } bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { - // let's handle by the corresponding strip - switch (index) { - case param_compression0: - return strip[0].get_dot(subindex, x, y, size, context); - break; - case param_compression1: - return strip[1].get_dot(subindex, x, y, size, context); - break; - case param_compression2: - return strip[2].get_dot(subindex, x, y, size, context); - break; - case param_compression3: - return strip[3].get_dot(subindex, x, y, size, context); - break; - } + const gain_reduction_audio_module *m = get_strip_by_param_index(index); + if (m) + return m->get_dot(subindex, x, y, size, context); return false; } bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { - // let's handle by the corresponding strip - switch (index) { - case param_compression0: - return strip[0].get_gridline(subindex, pos, vertical, legend, context); - break; - case param_compression1: - return strip[1].get_gridline(subindex, pos, vertical, legend, context); - break; - case param_compression2: - return strip[2].get_gridline(subindex, pos, vertical, legend, context); - break; - case param_compression3: - return strip[3].get_gridline(subindex, pos, vertical, legend, context); - break; - } + const gain_reduction_audio_module *m = get_strip_by_param_index(index); + if (m) + return m->get_gridline(subindex, pos, vertical, legend, context); return false; } int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { - // let's handle by the corresponding strip - switch (index) { - case param_compression0: - return strip[0].get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - break; - case param_compression1: - return strip[1].get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - break; - case param_compression2: - return strip[2].get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - break; - case param_compression3: - return strip[3].get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - break; - } + const gain_reduction_audio_module *m = get_strip_by_param_index(index); + if (m) + return m->get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); return 0; } @@ -1533,6 +1447,19 @@ void gain_reduction_audio_module::deactivate() is_active = false; } +void gain_reduction_audio_module::update_curve() +{ + float linThreshold = threshold; + float linKneeSqrt = sqrt(knee); + linKneeStart = linThreshold / linKneeSqrt; + adjKneeStart = linKneeStart*linKneeStart; + float linKneeStop = linThreshold * linKneeSqrt; + thres = log(linThreshold); + kneeStart = log(linKneeStart); + kneeStop = log(linKneeStop); + compressedKneeStop = (kneeStop - thres) / ratio + thres; +} + void gain_reduction_audio_module::process(float &left, float &right, float det_left, float det_right) { if(!det_left) { @@ -1547,17 +1474,9 @@ void gain_reduction_audio_module::process(float &left, float &right, float det_l // greatest sounding compressor I've heard! bool rms = detection == 0; bool average = stereo_link == 0; - float linThreshold = threshold; float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); - float linKneeSqrt = sqrt(knee); - linKneeStart = linThreshold / linKneeSqrt; - adjKneeStart = linKneeStart*linKneeStart; - float linKneeStop = linThreshold * linKneeSqrt; - thres = log(linThreshold); - kneeStart = log(linKneeStart); - kneeStop = log(linKneeStop); - compressedKneeStop = (kneeStop - thres) / ratio + thres; + update_curve(); float absample = average ? (fabs(det_left) + fabs(det_right)) * 0.5f : std::max(fabs(det_left), fabs(det_right)); if(rms) absample *= absample; @@ -1861,8 +1780,6 @@ inline void equalizerNband_audio_module::process_hplp(float } } -#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) {