From b167f834997d80676aff62889ca19b973d26a159 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Wed, 20 Oct 2010 23:40:23 +0100 Subject: [PATCH 1/9] Unbreak Monosynth by changing listview to use a 'key' attribute instead of 'param'. The table-edit-iface names are keys of configure variables, not real parameters (control ports), so using the 'param' is basically incorrect. (cherry picked from commit ab96b105e50d4de1ea423941dbc12208a997a78e) --- plugins/ladspa_effect/calf/src/calf/modules_synths.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/ladspa_effect/calf/src/calf/modules_synths.h b/plugins/ladspa_effect/calf/src/calf/modules_synths.h index ee4ae42e1..f847a2c9d 100644 --- a/plugins/ladspa_effect/calf/src/calf/modules_synths.h +++ b/plugins/ladspa_effect/calf/src/calf/modules_synths.h @@ -178,6 +178,8 @@ public: void apply_fadeout(); /// Main processing function uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); + /// Lookup of table edit interface + virtual table_edit_iface *get_table_edit_iface(const char *key) { if (!strcmp(key, "mod_matrix")) return static_cast(this); else return NULL; } }; }; From 71930a1dbbf14cf4d14d9728286892032f54fb74 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 6 Nov 2010 22:07:17 +0000 Subject: [PATCH 2/9] Initialise the vintage delay properly... hopefully this time. (cherry picked from commit c96ff1d680148cc877fab3b641d666068eea06aa) --- plugins/ladspa_effect/calf/src/modules.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/ladspa_effect/calf/src/modules.cpp b/plugins/ladspa_effect/calf/src/modules.cpp index fdfab11cc..ab2d44e19 100644 --- a/plugins/ladspa_effect/calf/src/modules.cpp +++ b/plugins/ladspa_effect/calf/src/modules.cpp @@ -189,6 +189,7 @@ static inline void delayline_impl(int age, int deltime, float dry_value, const f // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros if (age <= deltime) { out = 0; + del = dry_value; amt.step(); fb.step(); } @@ -206,6 +207,7 @@ static inline void delayline2_impl(int age, int deltime, float dry_value, const { if (age <= deltime) { out = 0; + del = dry_value; amt.step(); fb.step(); } From 90e288976f4f7dcedfdec227fc2f19c571878ff4 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 6 Nov 2010 22:53:40 +0000 Subject: [PATCH 3/9] Fix a few bugs in compilation of limited versions (DSSI without GUI, no JACK host). (cherry picked from commit c260e0d491235f7332f54ab8eb67105052d8149d) --- plugins/ladspa_effect/calf/src/plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ladspa_effect/calf/src/plugin.cpp b/plugins/ladspa_effect/calf/src/plugin.cpp index cd466c4e9..1c8663637 100644 --- a/plugins/ladspa_effect/calf/src/plugin.cpp +++ b/plugins/ladspa_effect/calf/src/plugin.cpp @@ -116,7 +116,7 @@ void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Even char *ladspa_instance::configure(const char *key, const char *value) { -#if USE_DSSI +#if USE_DSSI_GUI if (!strcmp(key, "OSC:FEEDBACK_URI")) { const line_graph_iface *lgi = dynamic_cast(metadata); From a9a91053d97642d14f4959c61b0e0c68a8383563 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 6 Nov 2010 23:44:11 +0000 Subject: [PATCH 4/9] Use symmetric dB range for EQ plugins. (cherry picked from commit cb3e7e001da3e0f43b3da8eed3f9660698f87ca2) --- plugins/ladspa_effect/calf/src/calf/giface.h | 10 +++++----- plugins/ladspa_effect/calf/src/modules_eq.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 4bb5df90e..746200bd5 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -634,22 +634,22 @@ public: extern const char *calf_copyright_info; -bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true); +bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true, float res = 256, float ofs = 0.4); /// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0) -static inline float dB_grid(float amp) +static inline float dB_grid(float amp, float res = 256, float ofs = 0.4) { - return log(amp) * (1.0 / log(256.0)) + 0.4; + return log(amp) * (1.0 / log(res)) + ofs; } template -static bool get_graph(Fx &fx, int subindex, float *data, int points) +static bool get_graph(Fx &fx, int subindex, float *data, int points, float res = 256, float ofs = 0.4) { for (int i = 0; i < points; i++) { typedef std::complex cfloat; double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate)); + data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate), res, ofs); } return true; } diff --git a/plugins/ladspa_effect/calf/src/modules_eq.cpp b/plugins/ladspa_effect/calf/src/modules_eq.cpp index 04cd0ae2d..35a1a80d9 100644 --- a/plugins/ladspa_effect/calf/src/modules_eq.cpp +++ b/plugins/ladspa_effect/calf/src/modules_eq.cpp @@ -248,7 +248,7 @@ bool equalizerNband_audio_module::get_graph(int index, int return false; if (index == AM::param_p1_freq && !subindex) { context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); + return ::get_graph(*this, subindex, data, points, 32, 0); } return false; } @@ -259,7 +259,7 @@ bool equalizerNband_audio_module::get_gridline(int index, i if (!is_active) { return false; } else { - return get_freq_gridline(subindex, pos, vertical, legend, context); + return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0); } } From 262edd6e8a519b1e7a4224a70852f3d5ac6fc455 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 6 Nov 2010 23:46:24 +0000 Subject: [PATCH 5/9] The range given in the comment wasn't really correct. (cherry picked from commit 292cdaa81dab7e7d948f597041cb86d70dc5ff92) --- plugins/ladspa_effect/calf/src/calf/giface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 746200bd5..bc01da33a 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -636,7 +636,7 @@ extern const char *calf_copyright_info; bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true, float res = 256, float ofs = 0.4); -/// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0) +/// convert amplitude value to normalized grid-ish value static inline float dB_grid(float amp, float res = 256, float ofs = 0.4) { return log(amp) * (1.0 / log(res)) + ofs; From 313c268e20bd1fa54d21f1c333a7b78ec70cf71d Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Mon, 8 Nov 2010 21:08:03 +0000 Subject: [PATCH 6/9] Fix the infamous crash on install. (cherry picked from commit f0568e2f8a4c7d0003cc5a15e300aa2ebb3f93cb) --- plugins/ladspa_effect/calf/src/calf/giface.h | 2 +- plugins/ladspa_effect/calf/src/calf/metadata.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index bc01da33a..3ee1309b3 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -625,7 +625,7 @@ public: }; #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata::port_names[] -#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata::param_props[] +#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata::param_props[name##_metadata::param_count + 1] #define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata::plugin_info #define PLUGIN_NAME_ID_LABEL(name, id, label) \ static const char *impl_get_name() { return name; } \ diff --git a/plugins/ladspa_effect/calf/src/calf/metadata.h b/plugins/ladspa_effect/calf/src/calf/metadata.h index 2941df591..68c004f67 100644 --- a/plugins/ladspa_effect/calf/src/calf/metadata.h +++ b/plugins/ladspa_effect/calf/src/calf/metadata.h @@ -348,7 +348,6 @@ struct organ_enums par_bassgain, par_treblefreq, par_treblegain, - par_var_mapcurve, param_count }; enum { From 661da8e8028ff56af1c2424d3d158234d7a0d99c Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Mon, 8 Nov 2010 22:33:02 +0000 Subject: [PATCH 7/9] Fix another install-related crash, this time due to invalid params in fluidsynth. (cherry picked from commit 034e3a47cd40eb6bb7d221274fda2a5c1c79f42f) --- plugins/ladspa_effect/calf/src/calf/metadata.h | 5 +---- plugins/ladspa_effect/calf/src/organ.cpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/metadata.h b/plugins/ladspa_effect/calf/src/calf/metadata.h index 68c004f67..f170bc2b7 100644 --- a/plugins/ladspa_effect/calf/src/calf/metadata.h +++ b/plugins/ladspa_effect/calf/src/calf/metadata.h @@ -350,9 +350,6 @@ struct organ_enums par_treblegain, param_count }; - enum { - var_count = 1 - }; enum organ_waveform { wave_sine, wave_sinepl1, wave_sinepl2, wave_sinepl3, @@ -411,7 +408,7 @@ public: /// FluidSynth - metadata struct fluidsynth_metadata: public plugin_metadata { - enum { par_master, par_interpolation, par_reverb, par_chorus, par_soundfont, par_preset_key_set, param_count }; + enum { par_master, par_interpolation, par_reverb, par_chorus, param_count }; enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false }; PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth") diff --git a/plugins/ladspa_effect/calf/src/organ.cpp b/plugins/ladspa_effect/calf/src/organ.cpp index bfd676099..c885eaf83 100644 --- a/plugins/ladspa_effect/calf/src/organ.cpp +++ b/plugins/ladspa_effect/calf/src/organ.cpp @@ -62,7 +62,7 @@ uint32_t organ_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_ } void organ_audio_module::params_changed() { - for (int i = 0; i < param_count - var_count; i++) + for (int i = 0; i < param_count; i++) ((float *)&par_values)[i] = *params[i]; unsigned int old_poly = polyphony_limit; From 8053f5adcfa06ba099c663b9ea535acf025877cb Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Mon, 8 Nov 2010 22:35:40 +0000 Subject: [PATCH 8/9] Add extra checks to detect when param_count != param array size - 1. (cherry picked from commit 6c8c91c4e03c3d0bc4b860db293549b45303ebc8) --- plugins/ladspa_effect/calf/src/metadata.cpp | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plugins/ladspa_effect/calf/src/metadata.cpp b/plugins/ladspa_effect/calf/src/metadata.cpp index 9feccb7b2..c14206a44 100644 --- a/plugins/ladspa_effect/calf/src/metadata.cpp +++ b/plugins/ladspa_effect/calf/src/metadata.cpp @@ -41,6 +41,7 @@ CALF_PORT_PROPS(flanger) = { { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, { 1, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, + {} }; CALF_PLUGIN_INFO(flanger) = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "FlangerPlugin" }; @@ -82,6 +83,7 @@ CALF_PORT_PROPS(reverb) = { { 0, 0, 50, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "predelay", "Pre Delay" }, { 300, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "bass_cut", "Bass Cut" }, { 5000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_cut", "Treble Cut" }, + {} }; CALF_PLUGIN_INFO(reverb) = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ReverbPlugin" }; @@ -129,7 +131,8 @@ CALF_PORT_PROPS(filterclavier) = { biquad_filter_module::mode_12db_lp, biquad_filter_module::mode_count - 1, 1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, filter_choices, "mode", "Mode" }, - { 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"} + { 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"}, + {} }; CALF_PLUGIN_INFO(filterclavier) = { 0x849f, "Filterclavier", "Calf Filterclavier", "Krzysztof Foltman / Hans Baier", calf_plugins::calf_copyright_info, "FilterclavierPlugin" }; @@ -162,6 +165,7 @@ CALF_PORT_PROPS(vintage_delay) = { { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, vintage_delay_fbmodes, "medium", "Medium" }, { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, { 1.0, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "width", "Stereo Width" }, + {} }; CALF_PLUGIN_INFO(vintage_delay) = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "DelayPlugin" }; @@ -183,6 +187,7 @@ CALF_PORT_PROPS(rotary_speaker) = { { 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" }, { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" }, { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" }, + {} }; CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulatorPlugin" }; @@ -231,6 +236,7 @@ CALF_PORT_PROPS(compressor) = { { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" }, { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" }, { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Reduction" }, + {} }; CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; @@ -278,6 +284,7 @@ CALF_PORT_PROPS(sidechaincompressor) = { { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" }, + {} }; CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; @@ -364,6 +371,7 @@ CALF_PORT_PROPS(multibandcompressor) = { { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" }, { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute 4" }, + {} }; CALF_PLUGIN_INFO(multibandcompressor) = { 0x8516, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; @@ -395,6 +403,7 @@ CALF_PORT_PROPS(deesser) = { { 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, { 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, + {} }; CALF_PLUGIN_INFO(deesser) = { 0x8515, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; @@ -423,6 +432,7 @@ CALF_PORT_PROPS(gate) = { { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_detection_names, "detection", "Detection" }, { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_stereo_link_names, "stereo_link", "Stereo Link" }, { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating", "Gating" }, + {} }; CALF_PLUGIN_INFO(gate) = { 0x8503, "Gate", "Calf Gate", "Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" }; @@ -471,6 +481,7 @@ CALF_PORT_PROPS(sidechaingate) = { { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" }, + {} }; CALF_PLUGIN_INFO(sidechaingate) = { 0x8504, "Sidechaingate", "Calf Sidechain Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" }; @@ -527,6 +538,7 @@ CALF_PORT_PROPS(equalizer5band) = { EQ_BAND_PARAMS(1, 250) EQ_BAND_PARAMS(2, 1000) EQ_BAND_PARAMS(3, 2500) + {} }; CALF_PLUGIN_INFO(equalizer5band) = { 0x8511, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; @@ -546,6 +558,7 @@ CALF_PORT_PROPS(equalizer8band) = { EQ_BAND_PARAMS(2, 1000) EQ_BAND_PARAMS(3, 2500) EQ_BAND_PARAMS(4, 5000) + {} }; CALF_PLUGIN_INFO(equalizer8band) = { 0x8512, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; @@ -567,6 +580,7 @@ CALF_PORT_PROPS(equalizer12band) = { EQ_BAND_PARAMS(6, 2500) EQ_BAND_PARAMS(7, 4000) EQ_BAND_PARAMS(8, 6000) + {} }; CALF_PLUGIN_INFO(equalizer12band) = { 0x8513, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; @@ -586,6 +600,7 @@ CALF_PORT_PROPS(pulsator) = { { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "offset", "Offset L/R" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mono", "Mono-in" }, { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, + {} }; CALF_PLUGIN_INFO(pulsator) = { 0x8514, "Pulsator", "Calf Pulsator", "Markus Schmidt", calf_plugins::calf_copyright_info, "ModulationPlugin" }; @@ -617,6 +632,7 @@ CALF_PORT_PROPS(saturator) = { { 2000, 80, 8000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p_freq", "Tone" }, { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p_level", "Amount" }, { 1, 0.1, 10, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p_q", "Gradient" }, + {} }; CALF_PLUGIN_INFO(saturator) = { 0x8530, "Saturator", "Calf Saturator", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; @@ -641,6 +657,7 @@ CALF_PORT_PROPS(exciter) = { { 6000, 2000, 12000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" }, + {} }; CALF_PLUGIN_INFO(exciter) = { 0x8531, "Exciter", "Calf Exciter", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; @@ -665,6 +682,7 @@ CALF_PORT_PROPS(bassenhancer) = { { 120, 10, 250, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" }, + {} }; CALF_PLUGIN_INFO(bassenhancer) = { 0x8532, "BassEnhancer", "Calf Bass Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; @@ -756,6 +774,7 @@ CALF_PORT_PROPS(monosynth) = { { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, monosynth_lfotrig_names, "lfo2_trig", "LFO2 Trigger Mode" }, { 5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lfo2_rate", "LFO1 Rate" }, { 0.5, 0.1, 5, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "lfo2_delay", "LFO1 Delay" }, + {} }; //////////////////////////////////////////////////////////////////////////// @@ -1061,6 +1080,7 @@ CALF_PORT_PROPS(wavetable) = { { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" }, { 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" }, + {} }; //////////////////////////////////////////////////////////////////////////// From 43e2886e79f20c4164a696bf21a2a87f2235d407 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Thu, 2 Dec 2010 21:06:45 +0000 Subject: [PATCH 9/9] Reimplement modulation matrix (and tables in general) using configure variables. Slow and most likely incomplete, but a good start. --- plugins/ladspa_effect/calf/src/calf/giface.h | 73 ++- .../ladspa_effect/calf/src/calf/ladspa_wrap.h | 1 - plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 18 +- .../ladspa_effect/calf/src/calf/metadata.h | 13 + .../ladspa_effect/calf/src/calf/modmatrix.h | 42 +- .../calf/src/calf/modules_synths.h | 8 +- .../ladspa_effect/calf/src/calf/wavetable.h | 164 ++++++ plugins/ladspa_effect/calf/src/giface.cpp | 103 ++-- plugins/ladspa_effect/calf/src/metadata.cpp | 60 +- plugins/ladspa_effect/calf/src/modmatrix.cpp | 93 +-- plugins/ladspa_effect/calf/src/monosynth.cpp | 28 +- plugins/ladspa_effect/calf/src/wavetable.cpp | 552 ++++++++++++++++++ 12 files changed, 973 insertions(+), 182 deletions(-) create mode 100644 plugins/ladspa_effect/calf/src/calf/wavetable.h create mode 100644 plugins/ladspa_effect/calf/src/wavetable.cpp diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 3ee1309b3..f930a0ae6 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -222,27 +222,15 @@ struct table_column_info }; /// 'has string parameters containing tabular data' interface -struct table_edit_iface +struct table_metadata_iface { /// retrieve the table layout for specific parameter virtual const table_column_info *get_table_columns() const = 0; - /// return the current number of rows + /// return the fixed number of rows, or 0 if the number of rows is variable virtual uint32_t get_table_rows() const = 0; - /// retrieve data item from the plugin - virtual std::string get_cell(int row, int column) const; - - /// set data item to the plugin - virtual void set_cell(int row, int column, const std::string &src, std::string &error) { error.clear(); } - - /// return a line graph interface for a specific parameter/column (unused for now) - virtual const line_graph_iface *get_graph_iface(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 column) const { return NULL; } - - virtual ~table_edit_iface() {} + virtual ~table_metadata_iface() {} }; /// 'may receive configure variables' interface @@ -331,6 +319,8 @@ struct plugin_metadata_iface virtual bool requires_configure() const = 0; /// obtain array of names of configure variables (or NULL is none needed) virtual const char *const *get_configure_vars() const { return NULL; } + /// @return table_metadata_iface if any + virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { return NULL; } /// Do-nothing destructor to silence compiler warning virtual ~plugin_metadata_iface() {} @@ -365,8 +355,6 @@ struct plugin_ctl_iface virtual const plugin_metadata_iface *get_metadata_iface() const = 0; /// @return line_graph_iface if any 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(const char *key) = 0; /// Do-nothing destructor to silence compiler warning virtual ~plugin_ctl_iface() {} }; @@ -447,8 +435,6 @@ struct audio_module_iface virtual uint32_t message_run(const void *valid_ports, void *output_ports) = 0; /// @return line_graph_iface if any virtual const line_graph_iface *get_line_graph_iface() const = 0; - /// @return table_edit_iface if any for given parameter - virtual table_edit_iface *get_table_edit_iface(const char *key) = 0; virtual ~audio_module_iface() {} }; @@ -548,8 +534,6 @@ public: } /// @return line_graph_iface if any virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast(this); } - virtual table_edit_iface *get_table_edit_iface(const char *key) { const char *key_us = get_table_edit_iface_key(); return (key_us && !strcmp(key, key_us)) ? dynamic_cast(this) : NULL; } - virtual const char *get_table_edit_iface_key() const { return NULL; } }; #if USE_EXEC_GUI || USE_DSSI @@ -678,8 +662,46 @@ struct preset_access_iface virtual ~preset_access_iface() {} }; +/// Implementation of table_metadata_iface providing metadata for mod matrices +class mod_matrix_metadata: public table_metadata_iface +{ +public: + /// Mapping modes + enum mapping_mode { + map_positive, ///< 0..100% + map_bipolar, ///< -100%..100% + map_negative, ///< -100%..0% + map_squared, ///< x^2 + map_squared_bipolar, ///< x^2 scaled to -100%..100% + map_antisquared, ///< 1-(1-x)^2 scaled to 0..100% + map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100% + map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0) + map_type_count + }; + const char **mod_src_names, **mod_dest_names; + + mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names); + virtual const table_column_info *get_table_columns() const; + virtual uint32_t get_table_rows() const; + +protected: + /// Column descriptions for table widget + table_column_info table_columns[6]; + + unsigned int matrix_rows; +}; + +/// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column) +/// @arg key key to parse +/// @arg prefix table prefix (e.g. "modmatrix:") +/// @arg is_rows[out] set to true if key == prefix + "rows" +/// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1 +/// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1 +/// @retval true if this is one of the recognized string forms +extern bool parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column); + #if USE_EXEC_GUI -class table_via_configure: public table_edit_iface +class table_via_configure { protected: typedef std::pair coord; @@ -689,13 +711,6 @@ protected: public: table_via_configure(); void configure(const char *key, const char *value); - - virtual const table_column_info *get_table_columns() const; - virtual uint32_t get_table_rows() const; - virtual std::string get_cell(int row, int column) const; - virtual void set_cell(int row, int column, const std::string &src, std::string &error); - virtual const line_graph_iface *get_graph_iface(int column) const; - virtual const char *get_cell_editor(int column) const; virtual ~table_via_configure(); }; #endif diff --git a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h index 7908ab103..d94ebcea3 100644 --- a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h @@ -48,7 +48,6 @@ struct ladspa_instance: public plugin_ctl_iface ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate); virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } - virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); } virtual float get_param_value(int param_no); virtual void set_param_value(int param_no, float value); virtual bool activate_preset(int bank, int program); diff --git a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h index 638eeadd0..77293307e 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -91,11 +91,15 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface const char *const *vars = module->get_metadata_iface()->get_configure_vars(); if (!vars) return; + assert(uri_map); + uint32_t string_type = uri_map->uri_to_id(uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String"); + assert(string_type); for (unsigned int i = 0; vars[i]; i++) { size_t len = 0; - const void *ptr = (*retrieve)(callback_data, vars[i], &len); - if (ptr) + uint32_t type = 0; + const void *ptr = (*retrieve)(callback_data, vars[i], &len, &type); + if (ptr && type == string_type) { printf("Calling configure on %s\n", vars[i]); configure(vars[i], std::string((const char *)ptr, len).c_str()); @@ -160,7 +164,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface } virtual const plugin_metadata_iface *get_metadata_iface() const { return metadata; } virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } - virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); } virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } }; @@ -297,15 +300,20 @@ struct lv2_wrapper { LV2_Persist_Store_Function store; void *callback_data; + uint32_t string_data_type; virtual void send_configure(const char *key, const char *value) { - (*store)(callback_data, key, value, strlen(value)); + (*store)(callback_data, key, value, strlen(value) + 1, string_data_type); } }; + // A host that supports a Persist extension should support an URI map extension as well. + assert(inst->uri_map); store_state s; s.store = store; s.callback_data = callback_data; + s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String"); + inst->send_configures(&s); } static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data) diff --git a/plugins/ladspa_effect/calf/src/calf/metadata.h b/plugins/ladspa_effect/calf/src/calf/metadata.h index f170bc2b7..ecf84e3c3 100644 --- a/plugins/ladspa_effect/calf/src/calf/metadata.h +++ b/plugins/ladspa_effect/calf/src/calf/metadata.h @@ -118,6 +118,7 @@ struct monosynth_metadata: public plugin_metadata param_count }; enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; enum { step_size = 64, step_shift = 6 }; + enum { mod_matrix_slots = 10 }; enum { modsrc_none, modsrc_velocity, @@ -143,6 +144,12 @@ struct monosynth_metadata: public plugin_metadata moddest_count, }; PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth") + + mod_matrix_metadata mm_metadata; + + monosynth_metadata(); + /// Lookup of table edit interface + virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; } }; /// Thor's compressor - metadata @@ -482,8 +489,14 @@ struct wavetable_metadata: public plugin_metadata par_pwhlrange, param_count }; enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; + enum { mod_matrix_slots = 10 }; enum { step_size = 64 }; PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable") + mod_matrix_metadata mm_metadata; + + wavetable_metadata(); + /// Lookup of table edit interface + virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; } }; }; diff --git a/plugins/ladspa_effect/calf/src/calf/modmatrix.h b/plugins/ladspa_effect/calf/src/calf/modmatrix.h index 17ebfd6c6..d66c32374 100644 --- a/plugins/ladspa_effect/calf/src/calf/modmatrix.h +++ b/plugins/ladspa_effect/calf/src/calf/modmatrix.h @@ -25,26 +25,13 @@ namespace dsp { -/// Mapping modes -enum mapping_mode { - map_positive, ///< 0..100% - map_bipolar, ///< -100%..100% - map_negative, ///< -100%..0% - map_squared, ///< x^2 - map_squared_bipolar, ///< x^2 scaled to -100%..100% - map_antisquared, ///< 1-(1-x)^2 scaled to 0..100% - map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100% - map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0) - map_type_count -}; - /// Single entry in modulation matrix struct modulation_entry { /// Mapped source int src1; /// Source mapping mode - mapping_mode mapping; + calf_plugins::mod_matrix_metadata::mapping_mode mapping; /// Unmapped modulating source int src2; /// Modulation amount @@ -60,7 +47,7 @@ struct modulation_entry void reset() { src1 = 0; src2 = 0; - mapping = map_positive; + mapping = calf_plugins::mod_matrix_metadata::map_positive; amount = 0.f; dest = 0; } @@ -70,24 +57,17 @@ struct modulation_entry namespace calf_plugins { -class mod_matrix: public table_edit_iface +class mod_matrix_impl { protected: - /// Polynomials for different scaling modes (1, x, x^2) - static const float scaling_coeffs[dsp::map_type_count][3]; - /// Column descriptions for table widget - table_column_info table_columns[6]; - dsp::modulation_entry *matrix; + mod_matrix_metadata *metadata; unsigned int matrix_rows; - const char **mod_src_names, **mod_dest_names; + /// Polynomials for different scaling modes (1, x, x^2) + static const float scaling_coeffs[calf_plugins::mod_matrix_metadata::map_type_count][3]; - 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() const; - virtual uint32_t get_table_rows() const; - virtual std::string get_cell(int row, int column) const; - virtual void set_cell(int row, int column, const std::string &src, std::string &error); + mod_matrix_impl(dsp::modulation_entry *_matrix, calf_plugins::mod_matrix_metadata *_metadata); /// Process modulation matrix, calculate outputs from inputs inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc) @@ -105,8 +85,14 @@ public: } } } -}; + void send_configures(send_configure_iface *); + char *configure(const char *key, const char *value); +private: + std::string get_cell(int row, int column) const; + void set_cell(int row, int column, const std::string &src, std::string &error); +}; + }; #endif diff --git a/plugins/ladspa_effect/calf/src/calf/modules_synths.h b/plugins/ladspa_effect/calf/src/calf/modules_synths.h index f847a2c9d..2e8dc8ed4 100644 --- a/plugins/ladspa_effect/calf/src/calf/modules_synths.h +++ b/plugins/ladspa_effect/calf/src/calf/modules_synths.h @@ -37,10 +37,9 @@ namespace calf_plugins { /// Monosynth-in-making. Parameters may change at any point, so don't make songs with it! /// It lacks inertia for parameters, even for those that really need it. -class monosynth_audio_module: public audio_module, public line_graph_iface, public mod_matrix +class monosynth_audio_module: public audio_module, public line_graph_iface, public mod_matrix_impl { public: - enum { mod_matrix_slots = 10 }; uint32_t srate, crate; static dsp::waveform_family *waves; dsp::waveform_oscillator osc1, osc2; @@ -178,8 +177,9 @@ public: void apply_fadeout(); /// Main processing function uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - /// Lookup of table edit interface - virtual table_edit_iface *get_table_edit_iface(const char *key) { if (!strcmp(key, "mod_matrix")) return static_cast(this); else return NULL; } + /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands) + virtual void send_configures(send_configure_iface *sci) { return mod_matrix_impl::send_configures(sci); } + virtual char *configure(const char *key, const char *value) { return mod_matrix_impl::configure(key, value); } }; }; diff --git a/plugins/ladspa_effect/calf/src/calf/wavetable.h b/plugins/ladspa_effect/calf/src/calf/wavetable.h new file mode 100644 index 000000000..5c4492cec --- /dev/null +++ b/plugins/ladspa_effect/calf/src/calf/wavetable.h @@ -0,0 +1,164 @@ +#ifndef __CALF_WAVETABLE_H +#define __CALF_WAVETABLE_H + +#include +#include "biquad.h" +#include "onepole.h" +#include "audio_fx.h" +#include "inertia.h" +#include "osc.h" +#include "synth.h" +#include "envelope.h" +#include "modmatrix.h" + +namespace calf_plugins { + +#define WAVETABLE_WAVE_BITS 8 + +class wavetable_audio_module; + +struct wavetable_oscillator: public dsp::simple_oscillator +{ + enum { SIZE = 1 << 8, MASK = SIZE - 1, SCALE = 1 << (32 - 8) }; + int16_t (*tables)[256]; + inline float get(uint16_t slice) + { + float fracslice = (slice & 255) * (1.0 / 256.0); + slice = slice >> 8; + int16_t *waveform = tables[slice]; + int16_t *waveform2 = tables[slice + 1]; + float value1 = 0.f, value2 = 0.f; + uint32_t cphase = phase, cphasedelta = phasedelta >> 3; + for (int j = 0; j < 8; j++) + { + uint32_t wpos = cphase >> (32 - 8); + uint32_t wpos2 = (wpos + 1) & MASK; + float frac = (cphase & (SCALE - 1)) * (1.0f / SCALE); + value1 += dsp::lerp((float)waveform[wpos], (float)waveform[wpos2], frac); + value2 += dsp::lerp((float)waveform2[wpos], (float)waveform2[wpos2], frac); + cphase += cphasedelta; + } + phase += phasedelta; + return dsp::lerp(value1, value2, fracslice) * (1.0 / 8.0) * (1.0 / 32768.0);; + } +}; + +class wavetable_voice: public dsp::voice +{ +public: + enum { Channels = 2, BlockSize = 64, EnvCount = 3, OscCount = 2 }; + float output_buffer[BlockSize][Channels]; +protected: + int note; + wavetable_audio_module *parent; + float **params; + dsp::decay amp; + wavetable_oscillator oscs[OscCount]; + dsp::adsr envs[EnvCount]; + /// Current MIDI velocity + float velocity; + /// Current calculated mod matrix outputs + float moddest[wavetable_metadata::moddest_count]; + /// Last oscillator shift (wavetable index) of each oscillator + float last_oscshift[OscCount]; + /// Last oscillator amplitude of each oscillator + float last_oscamp[OscCount]; + /// Current osc amplitude + float cur_oscamp[OscCount]; +public: + wavetable_voice(); + void set_params_ptr(wavetable_audio_module *_parent, int _srate); + void reset(); + void note_on(int note, int vel); + void note_off(int /* vel */); + void channel_pressure(int value); + void steal(); + void render_block(); + virtual int get_current_note() { + return note; + } + virtual bool get_active() { + // printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active()); + return (note != -1) && (amp.get_active()) && !envs[0].stopped(); + } + inline void calc_derived_dests() { + float cv = dsp::clip(0.5f + moddest[wavetable_metadata::moddest_oscmix], 0.f, 1.f); + cur_oscamp[0] = (cv) * *params[wavetable_metadata::par_o1level]; + cur_oscamp[1] = (1 - cv) * *params[wavetable_metadata::par_o2level]; + } +}; + +class wavetable_audio_module: public audio_module, public dsp::basic_synth, public mod_matrix_impl +{ +public: + using dsp::basic_synth::note_on; + using dsp::basic_synth::note_off; + using dsp::basic_synth::control_change; + using dsp::basic_synth::pitch_bend; + +protected: + uint32_t crate; + bool panic_flag; + +public: + int16_t tables[wt_count][129][256]; // one dummy level for interpolation + /// Rows of the modulation matrix + dsp::modulation_entry mod_matrix_data[mod_matrix_slots]; + /// Smoothed cutoff value + dsp::inertia inertia_cutoff; + /// Smoothed pitch bend value + dsp::inertia inertia_pitchbend; + /// Smoothed channel pressure value + dsp::inertia inertia_pressure; + /// Unsmoothed mod wheel value + float modwheel_value; + +public: + wavetable_audio_module(); + + dsp::voice *alloc_voice() { + dsp::block_voice *v = new dsp::block_voice(); + v->set_params_ptr(this, sample_rate); + return v; + } + + /// process function copied from Organ (will probably need some adjustments as well as implementing the panic flag elsewhere + uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) { + float *o[2] = { outs[0] + offset, outs[1] + offset }; + if (panic_flag) + { + control_change(120, 0); // stop all sounds + control_change(121, 0); // reset all controllers + panic_flag = false; + } + float buf[4096][2]; + dsp::zero(&buf[0][0], 2 * nsamples); + basic_synth::render_to(buf, nsamples); + float gain = 1.0f; + for (uint32_t i=0; i= 32) return false; float gain = 16.0 / (1 << subindex); - pos = dB_grid(gain); + pos = dB_grid(gain, res, ofs); if (pos < -1) return false; if (subindex != 4) @@ -319,11 +319,67 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char } return NULL; } + /////////////////////////////////////////////////////////////////////////////////////// -std::string table_edit_iface::get_cell(int row, int column) const +bool calf_plugins::parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column) { - return calf_utils::i2s(row)+":"+calf_utils::i2s(column); + is_rows = false; + row = -1; + column = -1; + if (0 != strncmp(key, prefix, strlen(prefix))) + return false; + + key += strlen(prefix); + + if (!strcmp(key, "rows")) + { + is_rows = true; + return true; + } + + const char *comma = strchr(key, ','); + if (comma) + { + row = atoi(string(key, comma - key).c_str()); + column = atoi(comma + 1); + return true; + } + + printf("Unknown key %s under prefix %s", key, prefix); + + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////// + +const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL }; + +mod_matrix_metadata::mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names) +: mod_src_names(_src_names) +, mod_dest_names(_dest_names) +, matrix_rows(_rows) +{ + table_column_info tci[6] = { + { "Source", TCT_ENUM, 0, 0, 0, mod_src_names }, + { "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names }, + { "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names }, + { "Amount", TCT_FLOAT, 0, 1, 1, NULL}, + { "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names }, + { NULL } + }; + assert(sizeof(table_columns) == sizeof(tci)); + memcpy(table_columns, tci, sizeof(table_columns)); +} + +const table_column_info *mod_matrix_metadata::get_table_columns() const +{ + return table_columns; +} + +uint32_t mod_matrix_metadata::get_table_rows() const +{ + return matrix_rows; } /////////////////////////////////////////////////////////////////////////////////////// @@ -435,45 +491,6 @@ table_via_configure::table_via_configure() rows = 0; } -const table_column_info *table_via_configure::get_table_columns() const -{ - return &columns[0]; -} - -uint32_t table_via_configure::get_table_rows() const -{ - return rows; -} - -string table_via_configure::get_cell(int row, int column) const -{ - if (row >= rows) - return string(); - coord c = make_pair(row, column); - std::map::const_iterator i = values.find(c); - if (i == values.end()) - return std::string(); - else - return i->second; -} - -void table_via_configure::set_cell(int row, int column, const std::string &src, std::string &error) -{ - coord c = make_pair(row, column); - values[c] = src; - error = ""; -} - -const line_graph_iface *table_via_configure::get_graph_iface(int column) const -{ - return NULL; -} - -const char *table_via_configure::get_cell_editor(int column) const -{ - return NULL; -} - table_via_configure::~table_via_configure() { } diff --git a/plugins/ladspa_effect/calf/src/metadata.cpp b/plugins/ladspa_effect/calf/src/metadata.cpp index c14206a44..2a76fc588 100644 --- a/plugins/ladspa_effect/calf/src/metadata.cpp +++ b/plugins/ladspa_effect/calf/src/metadata.cpp @@ -777,6 +777,37 @@ CALF_PORT_PROPS(monosynth) = { {} }; +static const char *monosynth_mod_src_names[] = { + "None", + "Velocity", + "Pressure", + "ModWheel", + "Envelope 1", + "Envelope 2", + "LFO 1", + "LFO 2", + NULL +}; + +static const char *monosynth_mod_dest_names[] = { + "None", + "Attenuation", + "Osc Mix Ratio (%)", + "Cutoff [ct]", + "Resonance", + "O1: Detune [ct]", + "O2: Detune [ct]", + "O1: PW (%)", + "O2: PW (%)", + "O1: Stretch", + NULL +}; + +monosynth_metadata::monosynth_metadata() +: mm_metadata(mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names) +{ +} + //////////////////////////////////////////////////////////////////////////// CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; @@ -1037,7 +1068,29 @@ const char *wavetable_names[] = { "Multi 2", }; -const char *wavetable_init_soundfont = ""; +static const char *wavetable_mod_src_names[] = { + "None", + "Velocity", + "Pressure", + "ModWheel", + "Env 1", + "Env 2", + "Env 3", + NULL +}; + +static const char *wavetable_mod_dest_names[] = { + "None", + "Attenuation", + "Osc Mix Ratio (%)", + "Cutoff [ct]", + "Resonance", + "O1: Shift (%)", + "O2: Shift (%)", + "O1: Detune [ct]", + "O2: Detune [ct]", + NULL +}; CALF_PORT_NAMES(wavetable) = { "Out L", "Out R", @@ -1083,6 +1136,11 @@ CALF_PORT_PROPS(wavetable) = { {} }; +wavetable_metadata::wavetable_metadata() +: mm_metadata(mod_matrix_slots, wavetable_mod_src_names, wavetable_mod_dest_names) +{ +} + //////////////////////////////////////////////////////////////////////////// calf_plugins::plugin_registry::plugin_registry() diff --git a/plugins/ladspa_effect/calf/src/modmatrix.cpp b/plugins/ladspa_effect/calf/src/modmatrix.cpp index 64ef330bb..670051b17 100644 --- a/plugins/ladspa_effect/calf/src/modmatrix.cpp +++ b/plugins/ladspa_effect/calf/src/modmatrix.cpp @@ -26,10 +26,18 @@ using namespace std; using namespace dsp; using namespace calf_plugins; +using namespace calf_utils; -const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL }; +mod_matrix_impl::mod_matrix_impl(dsp::modulation_entry *_matrix, mod_matrix_metadata *_metadata) +: matrix(_matrix) +, metadata(_metadata) +{ + matrix_rows = metadata->get_table_rows(); + for (unsigned int i = 0; i < matrix_rows; i++) + matrix[i].reset(); +} -const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = { +const float mod_matrix_impl::scaling_coeffs[mod_matrix_metadata::map_type_count][3] = { { 0, 1, 0 }, { -1, 2, 0 }, { -1, 1, 0 }, @@ -40,66 +48,33 @@ const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = { { 0, 4, -4 }, }; -mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names) -: matrix(_matrix) -, matrix_rows(_rows) -, mod_src_names(_src_names) -, mod_dest_names(_dest_names) -{ - table_column_info tci[6] = { - { "Source", TCT_ENUM, 0, 0, 0, mod_src_names }, - { "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names }, - { "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names }, - { "Amount", TCT_FLOAT, 0, 1, 1, NULL}, - { "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names }, - { NULL } - }; - assert(sizeof(table_columns) == sizeof(tci)); - memcpy(table_columns, tci, sizeof(table_columns)); - for (unsigned int i = 0; i < matrix_rows; i++) - matrix[i].reset(); -} - -const table_column_info *mod_matrix::get_table_columns() const -{ - return table_columns; -} - -uint32_t mod_matrix::get_table_rows() const -{ - return matrix_rows; -} - -std::string mod_matrix::get_cell(int row, int column) const +std::string mod_matrix_impl::get_cell(int row, int column) const { assert(row >= 0 && row < (int)matrix_rows); modulation_entry &slot = matrix[row]; + const char **arr = metadata->get_table_columns()[column].values; switch(column) { case 0: // source 1 - return mod_src_names[slot.src1]; + return arr[slot.src1]; case 1: // mapping mode - return mod_mapping_names[slot.mapping]; + return arr[slot.mapping]; case 2: // source 2 - return mod_src_names[slot.src2]; + return arr[slot.src2]; case 3: // amount return calf_utils::f2s(slot.amount); case 4: // destination - return mod_dest_names[slot.dest]; + return arr[slot.dest]; default: assert(0); return ""; } } -void mod_matrix::set_cell(int row, int column, const std::string &src, std::string &error) +void mod_matrix_impl::set_cell(int row, int column, const std::string &src, std::string &error) { assert(row >= 0 && row < (int)matrix_rows); modulation_entry &slot = matrix[row]; - const char **arr = mod_src_names; - if (column == 1) - arr = mod_mapping_names; - if (column == 4) - arr = mod_dest_names; + const char **arr = metadata->get_table_columns()[column].values; switch(column) { case 0: case 1: @@ -113,7 +88,7 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri if (column == 0) slot.src1 = i; else if (column == 1) - slot.mapping = (mapping_mode)i; + slot.mapping = (mod_matrix_metadata::mapping_mode)i; else if (column == 2) slot.src2 = i; else if (column == 4) @@ -135,3 +110,33 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri } } +void mod_matrix_impl::send_configures(send_configure_iface *sci) +{ + for (int i = 0; i < (int)matrix_rows; i++) + { + for (int j = 0; j < 5; j++) + { + string key = "mod_matrix:" + i2s(i) + "," + i2s(j); + sci->send_configure(key.c_str(), get_cell(i, j).c_str()); + } + } +} + +char *mod_matrix_impl::configure(const char *key, const char *value) +{ + bool is_rows; + int row, column; + if (!parse_table_key(key, "mod_matrix:", is_rows, row, column)) + return NULL; + if (is_rows) + return strdup("Unexpected key"); + + if (row != -1 && column != -1) + { + string error; + set_cell(row, column, value, error); + if (!error.empty()) + return strdup(error.c_str()); + } + return NULL; +} diff --git a/plugins/ladspa_effect/calf/src/monosynth.cpp b/plugins/ladspa_effect/calf/src/monosynth.cpp index 2f2b731ad..a277ae162 100644 --- a/plugins/ladspa_effect/calf/src/monosynth.cpp +++ b/plugins/ladspa_effect/calf/src/monosynth.cpp @@ -27,34 +27,8 @@ using namespace std; float silence[4097]; -static const char *monosynth_mod_src_names[] = { - "None", - "Velocity", - "Pressure", - "ModWheel", - "Envelope 1", - "Envelope 2", - "LFO 1", - "LFO 2", - NULL -}; - -static const char *monosynth_mod_dest_names[] = { - "None", - "Attenuation", - "Osc Mix Ratio (%)", - "Cutoff [ct]", - "Resonance", - "O1: Detune [ct]", - "O2: Detune [ct]", - "O1: PW (%)", - "O2: PW (%)", - "O1: Stretch", - NULL -}; - monosynth_audio_module::monosynth_audio_module() -: mod_matrix(mod_matrix_data, mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names) +: mod_matrix_impl(mod_matrix_data, &mm_metadata) , inertia_cutoff(1) , inertia_pitchbend(1) , inertia_pressure(64) diff --git a/plugins/ladspa_effect/calf/src/wavetable.cpp b/plugins/ladspa_effect/calf/src/wavetable.cpp new file mode 100644 index 000000000..e5ef25904 --- /dev/null +++ b/plugins/ladspa_effect/calf/src/wavetable.cpp @@ -0,0 +1,552 @@ +/* Calf DSP Library + * Example audio modules - wavetable synthesizer + * + * Copyright (C) 2009 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 + +#if ENABLE_EXPERIMENTAL + +#include +#include +#include + +using namespace dsp; +using namespace calf_plugins; + +wavetable_voice::wavetable_voice() +{ + sample_rate = -1; +} + +void wavetable_voice::set_params_ptr(wavetable_audio_module *_parent, int _srate) +{ + parent = _parent; + params = parent->params; + sample_rate = _srate; +} + +void wavetable_voice::reset() +{ + note = -1; +} + +void wavetable_voice::note_on(int note, int vel) +{ + typedef wavetable_metadata md; + this->note = note; + velocity = vel / 127.0; + amp.set(1.0); + for (int i = 0; i < OscCount; i++) { + oscs[i].reset(); + oscs[i].set_freq(note_to_hz(note, 0), sample_rate); + last_oscshift[i] = 0; + } + int cr = sample_rate / BlockSize; + for (int i = 0; i < EnvCount; i++) { + envs[i].set(0.01, 0.1, 0.5, 1, cr); + envs[i].note_on(); + } + float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value}; + parent->calculate_modmatrix(moddest, md::moddest_count, modsrc); + calc_derived_dests(); + + float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] }; + memcpy(last_oscshift, oscshift, sizeof(oscshift)); + memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp)); +} + +void wavetable_voice::note_off(int vel) +{ + for (int i = 0; i < EnvCount; i++) + envs[i].note_off(); +} + +void wavetable_voice::steal() +{ +} + +void wavetable_voice::render_block() +{ + typedef wavetable_metadata md; + + const float step = 1.f / BlockSize; + + float s = 0.001; + float scl[EnvCount]; + int espc = md::par_eg2attack - md::par_eg1attack; + for (int j = 0; j < EnvCount; j++) { + int o = j*espc; + envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s); + scl[j] = dsp::lerp(1.f, velocity, *params[md::par_eg1velscl + o]);; + } + + for (int i = 0; i < EnvCount; i++) + envs[i].advance(); + + float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value}; + parent->calculate_modmatrix(moddest, md::moddest_count, modsrc); + calc_derived_dests(); + + int ospc = md::par_o2level - md::par_o1level; + for (int j = 0; j < OscCount; j++) { + oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]]; + oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc] + moddest[md::moddest_o1detune]), sample_rate); + } + + float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] }; + float osstep[2] = { (oscshift[0] - last_oscshift[0]) * step, (oscshift[1] - last_oscshift[1]) * step }; + float oastep[2] = { (cur_oscamp[0] - last_oscamp[0]) * step, (cur_oscamp[1] - last_oscamp[1]) * step }; + for (int i = 0; i < BlockSize; i++) { + float value = 0.f; + + for (int j = 0; j < OscCount; j++) { + float o = last_oscshift[j] * 0.01; + value += last_oscamp[j] * oscs[j].get(dsp::clip(fastf2i_drm((o + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256)); + last_oscshift[j] += osstep[j]; + last_oscamp[j] += oastep[j]; + } + + output_buffer[i][0] = output_buffer[i][1] = value; + } + if (envs[0].stopped()) + released = true; + memcpy(last_oscshift, oscshift, sizeof(oscshift)); + memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp)); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +static inline float sincl(float x, float clip) +{ + if (fabs(x) > clip) + return 0; + return sin(M_PI * x); +} + +static inline float blip(float x, float center, float range) +{ + if (x < center - range || x > center + range) + return 0; + return 1 - fabs(x - center)/range; +} + +static void interpolate_wt(int16_t table[129][256], int step) +{ + for (int i = 0; i < 128; i++) + { + if (!(i % step)) + continue; + int prev = i - i % step; + int next = prev + step; + for (int j = 0; j < 256; j++) + { + table[i][j] = table[prev][j] + (i - prev) * (table[next][j] - table[prev][j]) / step; + } + } +} + +wavetable_audio_module::wavetable_audio_module() +: mod_matrix_impl(mod_matrix_data, &mm_metadata) +, inertia_cutoff(1) +, inertia_pitchbend(1) +, inertia_pressure(64) +{ + panic_flag = false; + modwheel_value = 0.; + for (int i = 0; i < 129; i += 8) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + int harm = 1 + 2 * (i / 8); + float ii = i / 128.0; + float rezo1 = sin(harm * ph) * sin(ph); + float rezo2 = sin((harm+1) * ph) * sin(ph * 2); + float rezo3 = sin((harm+3) * ph) * sin(ph * 4); + float rezo = (rezo1 + rezo2 + rezo3) / 3; + float v = (sin (ph) + ii * ii * rezo) / 2; + tables[0][i][j] = 32767 * v; + } + } + interpolate_wt(tables[0], 8); + for (int i = 0; i < 129; i += 4) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + int harm = 1 + (i / 4); + float ii = i / 128.0; + float h = sin(harm * ph); + float rezo1 = h * sin(ph); + float rezo2 = h * sin(ph * 2)/2; + float rezo3 = h * sin(ph * 3)/3; + float rezo4 = h * sin(ph * 4)/4; + float rezo5 = h * sin(ph * 5)/5; + float rezo = (rezo1 + rezo2 + rezo3 + rezo4 + rezo5) / 3; + float v = sin (ph + ii * rezo); + tables[1][i][j] = 32767 * v; + } + } + interpolate_wt(tables[1], 4); + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = (i & ~3) / 128.0; + float ii2 = ((i & ~3) + 4) / 128.0; + float peak = (32 * ii); + float rezo1 = sin(floor(peak) * ph); + float rezo2 = sin(floor(peak + 1) * ph); + float widener = (0.5 + 0.3 * sin(ph) + 0.2 * sin (3 * ph)); + float v1 = 0.5 * sin (ph) + 0.5 * ii * ii * rezo1 * widener; + float v2 = 0.5 * sin (ph) + 0.5 * ii2 * ii2 * rezo2 * widener; + tables[wavetable_metadata::wt_rezo][i][j] = 32767 * lerp(v1, v2, (i & 3) / 4.0); + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 6 * ii * ii * sin(6 * ph)) + ii * ii * ii * ii * sin(ph + 11 * ii * ii * ii * ii * sin(11 * ph))) / 4; + tables[wavetable_metadata::wt_metal][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * sin(5 * ph - 5 * ii * ii * ii * ii * sin(11 * ph))) / 3; + tables[wavetable_metadata::wt_bell][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + //float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 3 * ii * ii * sin(3 * ph)) + ii * ii * ii * sin(ph + 5 * ii * ii * ii * sin(5 * ph))) / 4; + float v = (sin(ph) + sin(ph - 3 * sin(ii * 5 - 2) * sin(ph)) + sin(ii * 4 - 1.3) * sin(5 * ph + 3 * ii * ii * sin(6 * ph))) / 3; + tables[wavetable_metadata::wt_blah][i][j] = 32767 * v; + } + } + for (int i = 0; i < 256; i++) + { + tables[wavetable_metadata::wt_pluck][128][i] = (i < 128) ? 32000 * fabs(sin(i / 32.0 * M_PI) * sin(i / 13.0 * M_PI) * sin(i / 19.0 * M_PI)) : 0; + } + for (int i = 127; i >= 0; i--) + { + int16_t *parent = tables[wavetable_metadata::wt_pluck][i + 1]; + float damp = 0.05; + for (int j = 0; j < 256; j++) + { + tables[wavetable_metadata::wt_pluck][i][j] = (1 - 2*damp) * parent[j] + damp * parent[(j+1)&255] + damp * parent[(j+2)&255];// + 0.1 * parent[(j-1)&255]+ 0.1 * parent[(j-2)&255]; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j / 128.0 - 1.0; + float ii = i / 128.0; + float v = sincl(ph * (1 + 15 * ii), 1); + tables[wavetable_metadata::wt_stretch][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j / 128.0 - 1.0; + float ii = i / 128.0; + float v = sincl(ph * (1 + 15 * ii), 4) * sincl(j / 256.0, 1); + tables[wavetable_metadata::wt_stretch2][i][j] = 32000 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j / 128.0 - 1.0; + float ii = i / 128.0; + float w = sincl(ph * (1 + 15 * ii), 4); + float v = pow(w, 9) * sincl(j / 256.0, 1); + tables[wavetable_metadata::wt_hardsync][i][j] = 32000 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j / 128.0 - 1.0; + float ii = i / 128.0; + float w = sincl(ph * (1 + 31 * ii), 3); + float v = pow(w, 5) * sincl(j / 256.0, 1); + tables[wavetable_metadata::wt_hardsync2][i][j] = 32000 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j / 128.0 - 1.0; + float ii = i / 128.0; + float w = sincl(ph * ph * (1 + 15 * ii), 2); + float v = pow(w, 4) * sincl(j / 256.0, 1); + tables[wavetable_metadata::wt_softsync][i][j] = 32000 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(7 * ph - 2 * ii * ii * ii * ii * sin(13 * ph))) / 3; + tables[wavetable_metadata::wt_bell2][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(9 * ph - ii * ii * sin(11 * ph))) / 3; + tables[wavetable_metadata::wt_bell3][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph + ii * sin(ph - 3 * ii * sin(ph) + ii * ii * ii * sin(5 * ph - ii * ii * sin(7 * ph))))); + tables[wavetable_metadata::wt_tine][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float v = (sin(ph + ii * sin(ph - 2 * ii * sin(ph) + ii * ii * ii * sin(3 * ph - ii * ii * sin(4 * ph))))); + tables[wavetable_metadata::wt_tine2][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ph2 = j / 128.0 - 1; + float ii = i / 128.0; + float w = sincl(ph2 * (1 + 7 * ii * ii), 4) * pow(sincl(j / 256.0, 1), 2); + float v = sin(ph + ii * sin(ph - 2 * ii * w)); + tables[wavetable_metadata::wt_clav][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ph2 = j / 128.0 - 1; + float ii = i / 128.0; + float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * sincl(j / 256.0, 1); + float v = sin(ph + ii * sin(3 * ph - 2 * ii * w)); + tables[wavetable_metadata::wt_clav2][i][j] = 32767 * v; + } + } + /* + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ph2 = j / 128.0 - 1; + float ii = i / 128.0; + float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * pow(sincl(j / 256.0, 1), 1); + float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w)); + tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v; + } + } + */ + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = ii; + float w = pow(sincl(j / 256.0, 1), 1); + float v = sin(ph + ii2 * ii2 * ii2 * sin(3 * ph - ii2 * ii2 * ii2 * w * sin(ph + sin(3 * ph) + ii * sin(11 * ph) + ii * ii * sin(25 * ph)))); + tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = dsp::clip(ii - 0.5, 0.0, 1.0); + float w = pow(sincl(j / 256.0, 1), 1); + float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w * sin(ph + sin(3 * ph + ii2 * sin(13 * ph))))); + tables[wavetable_metadata::wt_gtr2][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0); + //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); + float w = pow(sincl(j / 256.0, 1), 1); + float v = sin(ph + ii * sin(3 * ph - ii * w * sin(ph + sin(3 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph)))))); + tables[wavetable_metadata::wt_gtr3][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0); + //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); + float w = pow(sincl(j / 256.0, 1), 1); + float v = sin(ph + ii * sin(3 * ph - ii * w * sin(2 * ph + sin(5 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph)))))); + tables[wavetable_metadata::wt_gtr4][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0); + //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); + float w = pow(sincl(j / 256.0, 1), 3); + float v = sin(ph + (ii + 0.05) * sin(3 * ph - 2 * ii * w * sin(5 * ph + sin(7 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(11 * ph)))))); + tables[wavetable_metadata::wt_gtr5][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float w = pow(sincl(2 * (j / 256.0), 2), 3); + float v = sin(ph + (ii + 0.05) * sin(7 * ph - 2 * ii * w * sin(11 * ph))); + tables[wavetable_metadata::wt_reed][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0); + float ii3 = dsp::clip((ii - 0.5)/0.5, 0.0, 1.0); + float v = sin(ph + (ii + 0.05) * sin(ii * sin(2 * ph) - 2 * ii2 * sin(2 * ph + ii2 * sin(3 * ph)) + 3 * ii3 * sin(3 * ph))); + tables[wavetable_metadata::wt_reed2][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float mod = 0; + for (int k = 0; k < 13; k++) + { + mod += blip(i, k * 10, 30) * sin (ph * (5 + 3 * k) + ii * cos(ph * (2 + 2 * k))); + } + float v = sin(ph + ii * mod); + tables[wavetable_metadata::wt_silver][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float mod = 0; + for (int k = 0; k < 16; k++) + { + mod += 2 * blip(i, k * 8, k * 4 + 10) * cos (ph * (k + 1)); + } + float v = sin(ph + ii * mod); + tables[wavetable_metadata::wt_brass][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i++) + { + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float ii = i / 128.0; + float mod = 0; + for (int k = 0; k < 16; k++) + { + mod += 2 * blip(i, k * 8, 16) * cos (ph * (2 * k + 1)); + } + float v = (sin(ph + ii * mod) + ii * sin(2 * ph + ii * mod)) / 2; + tables[wavetable_metadata::wt_multi][i][j] = 32767 * v; + } + } + for (int i = 0; i < 129; i ++) + { + float h = 1 + i / 16.0; + for (int j = 0; j < 256; j++) + { + float ph = j * 2 * M_PI / 256; + float v = sin(ph), tv = 1; + for (int k = 1; k < 24; k++) { + float amp = blip(i, k * 6, 20) / k; + v += amp * sin((k + 1) * ph + h * sin(ph)); + tv += amp; + } + tables[wavetable_metadata::wt_multi2][i][j] = 32767 * v / tv; + } + } +} + +void wavetable_audio_module::channel_pressure(int value) +{ + inertia_pressure.set_inertia(value * (1.0 / 127.0)); +} + +#endif