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..e6c0736b3 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,10 +377,24 @@ 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); -/// Get a list of all "small" (module) plugins -extern void get_all_small_plugins(plugin_list_info_iface *plii); +/// A class to retrieve and query the list of Calf plugins +class plugin_registry +{ +public: + typedef std::vector plugin_vector; +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); +}; + /// Load and strdup a text file with GUI definition extern const char *load_gui_xml(const std::string &plugin_id); @@ -489,30 +503,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); @@ -527,33 +541,33 @@ 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; } - 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); } + 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(); } + 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/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 */ 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/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.h b/plugins/ladspa_effect/calf/calf/modules.h index ee8906772..6bce138e3 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,15 +783,16 @@ 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); + void update_curve(); void process(float &left, float &right, float det_left = NULL, float det_right = NULL); void activate(); void deactivate(); @@ -867,10 +800,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 +819,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 +847,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 +863,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 +892,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,15 +902,16 @@ 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 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; @@ -996,10 +931,11 @@ 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); + 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; + 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 +945,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 +958,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 +990,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 +1006,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 +1042,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 +1075,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 +1165,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_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/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/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/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index bd71b2720..e9984e84f 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; +} + +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)) + 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..66eba417d 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -31,14 +31,16 @@ 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) +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 +69,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 +81,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 +110,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 +122,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 +152,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 +163,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 +187,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 +270,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 +286,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 +299,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 +309,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 +326,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 +339,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); @@ -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 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) +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) -{ - // 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; - } +bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const +{ + 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) +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; } @@ -884,28 +798,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 +1116,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 +1129,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 +1139,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 +1151,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 +1365,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 +1376,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; @@ -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; @@ -1576,11 +1495,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 +1556,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 +1581,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 +1600,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 +1619,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; @@ -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) { @@ -1988,7 +1905,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 +1917,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 +1927,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 +1959,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 +1976,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 +2021,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 +2088,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 +2099,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 +2294,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 +2311,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 +2329,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/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/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); 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 } };