From 4b92af788b901f7b92ef3c4a8de79d338b833ac6 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 12 Sep 2010 00:24:45 +0100 Subject: [PATCH 01/11] Fix handling of very short notes in Monosynth. (cherry picked from commit 5965d9922a0753e2dce4f743a23b9512be01a7ac) --- .../calf/src/calf/modules_synths.h | 4 ++ plugins/ladspa_effect/calf/src/monosynth.cpp | 55 +++++++++++++------ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/modules_synths.h b/plugins/ladspa_effect/calf/src/calf/modules_synths.h index 8cd1c0ba4..ee4ae42e1 100644 --- a/plugins/ladspa_effect/calf/src/calf/modules_synths.h +++ b/plugins/ladspa_effect/calf/src/calf/modules_synths.h @@ -88,6 +88,8 @@ public: int32_t last_stretch1; /// Next note to play on the next calculate_step int queue_note_on; + /// Whether the queued note has been already released + bool queue_note_on_and_off; /// Velocity of the next note to play float queue_vel; /// Integer value for modwheel (0-16383, read from CC1 - MSBs and CC33 - LSBs) @@ -122,6 +124,8 @@ public: static void precalculate_waves(progress_report_iface *reporter); void set_sample_rate(uint32_t sr); void delayed_note_on(); + /// Release a note (physically), called from note-off handler or when note-off has been scheduled after note-on (very short queued note) + void end_note(); /// Handle MIDI Note On message (does not immediately trigger a note, as it must start on /// boundary of step_size samples). void note_on(int note, int vel); diff --git a/plugins/ladspa_effect/calf/src/monosynth.cpp b/plugins/ladspa_effect/calf/src/monosynth.cpp index d5c77c16f..2f2b731ad 100644 --- a/plugins/ladspa_effect/calf/src/monosynth.cpp +++ b/plugins/ladspa_effect/calf/src/monosynth.cpp @@ -76,6 +76,7 @@ void monosynth_audio_module::activate() { stack.clear(); last_pwshift1 = last_pwshift2 = 0; last_stretch1 = 65536; + queue_note_on_and_off = false; } waveform_family *monosynth_audio_module::waves; @@ -433,6 +434,12 @@ void monosynth_audio_module::delayed_note_on() queue_note_on = -1; float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get_last(), modwheel_value, envelope1.value, envelope2.value, 0.5+0.5*lfo1.last, 0.5+0.5*lfo2.last}; calculate_modmatrix(moddest, moddest_count, modsrc); + + if (queue_note_on_and_off) + { + end_note(); + queue_note_on_and_off = false; + } } void monosynth_audio_module::set_sample_rate(uint32_t sr) { @@ -629,6 +636,7 @@ void monosynth_audio_module::apply_fadeout() void monosynth_audio_module::note_on(int note, int vel) { queue_note_on = note; + queue_note_on_and_off = false; last_key = note; queue_vel = vel / 127.f; stack.push(note); @@ -637,29 +645,40 @@ void monosynth_audio_module::note_on(int note, int vel) void monosynth_audio_module::note_off(int note, int vel) { stack.pop(note); + if (note == queue_note_on) + { + queue_note_on_and_off = true; + return; + } // If releasing the currently played note, try to get another one from note stack. if (note == last_key) { - if (stack.count()) - { - last_key = note = stack.nth(stack.count() - 1); - start_freq = freq; - target_freq = freq = dsp::note_to_hz(note); - porta_time = 0; - set_frequency(); - if (!(legato & 1)) { - envelope1.note_on(); - envelope2.note_on(); - stopping = false; - running = true; - } - return; - } - gate = false; - envelope1.note_off(); - envelope2.note_off(); + end_note(); } } +void monosynth_audio_module::end_note() +{ + if (stack.count()) + { + int note; + last_key = note = stack.nth(stack.count() - 1); + start_freq = freq; + target_freq = freq = dsp::note_to_hz(note); + porta_time = 0; + set_frequency(); + if (!(legato & 1)) { + envelope1.note_on(); + envelope2.note_on(); + stopping = false; + running = true; + } + return; + } + gate = false; + envelope1.note_off(); + envelope2.note_off(); +} + void monosynth_audio_module::channel_pressure(int value) { inertia_pressure.set_inertia(value * (1.0 / 127.0)); From 2831eb8c59713c22e7257c5e9c9b03012226b506 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 19 Sep 2010 21:41:29 +0100 Subject: [PATCH 02/11] More refactoring of the VUs. The goal: to be able to add peak meters without major hassle. (cherry picked from commit 00ee132cc2ebe3b664c7d5760260d76dda37bf26) --- .../ladspa_effect/calf/src/calf/metadata.h | 38 ++++++------ .../ladspa_effect/calf/src/calf/modules_eq.h | 4 +- .../calf/src/calf/plugin_tools.h | 57 +++++++++++++++--- plugins/ladspa_effect/calf/src/calf/vumeter.h | 21 +++++++ .../ladspa_effect/calf/src/modules_dist.cpp | 2 - plugins/ladspa_effect/calf/src/modules_eq.cpp | 59 ++----------------- 6 files changed, 97 insertions(+), 84 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/metadata.h b/plugins/ladspa_effect/calf/src/calf/metadata.h index 1c2e1f92f..7f6f3240d 100644 --- a/plugins/ladspa_effect/calf/src/calf/metadata.h +++ b/plugins/ladspa_effect/calf/src/calf/metadata.h @@ -25,6 +25,9 @@ #include "giface.h" +#define MONO_VU_METER_PARAMS param_meter_in, param_meter_out, param_clip_in, param_clip_out +#define STEREO_VU_METER_PARAMS param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR + namespace calf_plugins { struct flanger_metadata: public plugin_metadata @@ -147,7 +150,7 @@ struct monosynth_metadata: public plugin_metadata struct compressor_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, param_count }; PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor") @@ -157,7 +160,7 @@ struct compressor_metadata: public plugin_metadata struct sidechaincompressor_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_sc_listen, param_f1_active, param_f2_active, param_count }; @@ -168,8 +171,8 @@ struct sidechaincompressor_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, - param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + enum { param_bypass, param_level_in, param_level_out, + STEREO_VU_METER_PARAMS, param_freq0, param_freq1, param_freq2, param_sep0, param_sep1, param_sep2, param_q0, param_q1, param_q2, @@ -202,7 +205,7 @@ struct deesser_metadata: public plugin_metadata struct gate_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating, param_count }; PLUGIN_NAME_ID_LABEL("gate", "gate", "Gate") @@ -212,7 +215,7 @@ struct gate_metadata: public plugin_metadata struct sidechaingate_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating, param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_sc_listen, param_f1_active, param_f2_active, param_count }; @@ -223,8 +226,7 @@ struct sidechaingate_metadata: public plugin_metadata struct equalizer5band_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, - param_meter_outL, param_meter_outR, param_clip_inL, param_clip_outL, param_clip_inR, param_clip_outR, + enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS, param_ls_active, param_ls_level, param_ls_freq, param_hs_active, param_hs_level, param_hs_freq, param_p1_active, param_p1_level, param_p1_freq, param_p1_q, @@ -241,8 +243,8 @@ struct equalizer5band_metadata: public plugin_metadata struct equalizer8band_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, - param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + enum { param_bypass, param_level_in, param_level_out, + STEREO_VU_METER_PARAMS, param_hp_active, param_hp_freq, param_hp_mode, param_lp_active, param_lp_freq, param_lp_mode, param_ls_active, param_ls_level, param_ls_freq, @@ -259,8 +261,8 @@ struct equalizer8band_metadata: public plugin_metadata struct equalizer12band_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, - param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + enum { param_bypass, param_level_in, param_level_out, + STEREO_VU_METER_PARAMS, param_hp_active, param_hp_freq, param_hp_mode, param_lp_active, param_lp_freq, param_lp_mode, param_ls_active, param_ls_level, param_ls_freq, @@ -282,8 +284,7 @@ struct equalizer12band_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, - param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS, param_mode, param_freq, param_amount, param_offset, param_mono, param_reset, param_count }; PLUGIN_NAME_ID_LABEL("pulsator", "pulsator", "Pulsator") }; @@ -292,8 +293,7 @@ struct pulsator_metadata: public plugin_metadata struct saturator_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_mix, param_meter_in, - param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive, + enum { param_bypass, param_level_in, param_level_out, param_mix, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, param_lp_pre_freq, param_hp_pre_freq, param_lp_post_freq, param_hp_post_freq, param_p_freq, param_p_level, param_p_q, param_count }; PLUGIN_NAME_ID_LABEL("saturator", "saturator", "Saturator") @@ -302,8 +302,7 @@ struct saturator_metadata: public plugin_metadata struct exciter_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_amount, param_meter_in, - param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive, + enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, param_freq, param_listen, param_count }; PLUGIN_NAME_ID_LABEL("exciter", "exciter", "Exciter") }; @@ -311,8 +310,7 @@ struct exciter_metadata: public plugin_metadata struct bassenhancer_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_amount, param_meter_in, - param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive, + enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, param_freq, param_listen, param_count }; PLUGIN_NAME_ID_LABEL("bassenhancer", "bassenhancer", "Bass Enhancer") }; diff --git a/plugins/ladspa_effect/calf/src/calf/modules_eq.h b/plugins/ladspa_effect/calf/src/calf/modules_eq.h index 14cad3ce8..e37816999 100644 --- a/plugins/ladspa_effect/calf/src/calf/modules_eq.h +++ b/plugins/ladspa_effect/calf/src/calf/modules_eq.h @@ -28,6 +28,7 @@ #include "audio_fx.h" #include "giface.h" #include "metadata.h" +#include "plugin_tools.h" namespace calf_plugins { @@ -51,8 +52,7 @@ private: float hs_level_old, hs_freq_old; float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands]; 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; + dual_in_out_metering meters; CalfEqMode hp_mode, lp_mode; dsp::biquad_d2 hp[3][2], lp[3][2]; dsp::biquad_d2 lsL, lsR, hsL, hsR; diff --git a/plugins/ladspa_effect/calf/src/calf/plugin_tools.h b/plugins/ladspa_effect/calf/src/calf/plugin_tools.h index cd497b2e9..a9e20946e 100644 --- a/plugins/ladspa_effect/calf/src/calf/plugin_tools.h +++ b/plugins/ladspa_effect/calf/src/calf/plugin_tools.h @@ -28,12 +28,12 @@ namespace calf_plugins { -/// Base class for universal stereo level metering -struct stereo_in_out_metering_base +template +struct in_out_metering_base { - dsp::vumeter vumeter_in, vumeter_out; - - stereo_in_out_metering_base() + typedef Meter meter; + meter vumeter_in, vumeter_out; + in_out_metering_base() { reset(); } @@ -44,9 +44,9 @@ struct stereo_in_out_metering_base } }; -/// Universal stereo level metering for a specific plugin +/// Universal single stereo level metering for a specific plugin template -class stereo_in_out_metering: public stereo_in_out_metering_base +class stereo_in_out_metering: public in_out_metering_base { public: inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples) @@ -79,6 +79,49 @@ public: } }; +/// Universal dual level metering for a specific plugin +template +class dual_in_out_metering: public in_out_metering_base +{ +public: + inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples) + { + if (params[Metadata::param_meter_inL] || params[Metadata::param_clip_inL] || params[Metadata::param_meter_inR] || params[Metadata::param_clip_inR]) { + if (inputs) + vumeter_in.update_stereo(inputs[0] ? inputs[0] + offset : NULL, inputs[1] ? inputs[1] + offset : NULL, nsamples); + else + vumeter_in.update_zeros(nsamples); + if (params[Metadata::param_meter_inL]) + *params[Metadata::param_meter_inL] = vumeter_in.left.level; + if (params[Metadata::param_meter_inR]) + *params[Metadata::param_meter_inR] = vumeter_in.right.level; + if (params[Metadata::param_clip_inL]) + *params[Metadata::param_clip_inL] = vumeter_in.left.clip > 0 ? 1.f : 0.f; + if (params[Metadata::param_clip_inR]) + *params[Metadata::param_clip_inR] = vumeter_in.right.clip > 0 ? 1.f : 0.f; + } + if (params[Metadata::param_meter_outL] || params[Metadata::param_clip_outL] || params[Metadata::param_meter_outR] || params[Metadata::param_clip_outR]) { + if (outputs) + vumeter_out.update_stereo(outputs[0] ? outputs[0] + offset : NULL, outputs[1] ? outputs[1] + offset : NULL, nsamples); + else + vumeter_out.update_zeros(nsamples); + if (params[Metadata::param_meter_outL]) + *params[Metadata::param_meter_outL] = vumeter_out.left.level; + if (params[Metadata::param_meter_outR]) + *params[Metadata::param_meter_outR] = vumeter_out.right.level; + if (params[Metadata::param_clip_outL]) + *params[Metadata::param_clip_outL] = vumeter_out.left.clip > 0 ? 1.f : 0.f; + if (params[Metadata::param_clip_outR]) + *params[Metadata::param_clip_outR] = vumeter_out.right.clip > 0 ? 1.f : 0.f; + } + } + void bypassed(float *const *params, unsigned int nsamples) + { + reset(); + process(params, NULL, NULL, 0, nsamples); + } +}; + }; #endif diff --git a/plugins/ladspa_effect/calf/src/calf/vumeter.h b/plugins/ladspa_effect/calf/src/calf/vumeter.h index 6ef1e7622..cd1125271 100644 --- a/plugins/ladspa_effect/calf/src/calf/vumeter.h +++ b/plugins/ladspa_effect/calf/src/calf/vumeter.h @@ -90,6 +90,27 @@ struct vumeter } }; +struct dual_vumeter +{ + vumeter left, right; + + inline void update_stereo(const float *src1, const float *src2, unsigned int len) + { + left.update_stereo(src1, NULL, len); + right.update_stereo(NULL, src2, len); + } + inline void update_zeros(unsigned int len) + { + left.update_zeros(len); + right.update_zeros(len); + } + inline void reset() + { + left.reset(); + right.reset(); + } +}; + }; #endif diff --git a/plugins/ladspa_effect/calf/src/modules_dist.cpp b/plugins/ladspa_effect/calf/src/modules_dist.cpp index 4d6a89160..725e05bc9 100644 --- a/plugins/ladspa_effect/calf/src/modules_dist.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dist.cpp @@ -26,8 +26,6 @@ using namespace dsp; using namespace calf_plugins; -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - /// Saturator Band by Markus Schmidt /// /// This module is based on Krzysztof's filters and Tom Szilagyi's distortion routine. diff --git a/plugins/ladspa_effect/calf/src/modules_eq.cpp b/plugins/ladspa_effect/calf/src/modules_eq.cpp index d4ea0bcc4..04cd0ae2d 100644 --- a/plugins/ladspa_effect/calf/src/modules_eq.cpp +++ b/plugins/ladspa_effect/calf/src/modules_eq.cpp @@ -26,8 +26,6 @@ using namespace dsp; using namespace calf_plugins; -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - /// Equalizer 12 Band by Markus Schmidt /// /// This module is based on Krzysztof's filters. It provides a couple @@ -40,8 +38,6 @@ equalizerNband_audio_module::equalizerNband_audio_module() is_active = false; srate = 0; last_generation = 0; - clip_inL = clip_inR = clip_outL = clip_outR = 0.f; - meter_inL = meter_inR = meter_outL = meter_outR = 0.f; } template @@ -50,6 +46,7 @@ void equalizerNband_audio_module::activate() is_active = true; // set all filters params_changed(); + meters.reset(); } template @@ -170,6 +167,8 @@ template uint32_t equalizerNband_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { bool bypass = *params[AM::param_bypass] > 0.f; + uint32_t orig_offset = offset; + uint32_t orig_numsamples = numsamples; numsamples += offset; if(bypass) { // everything bypassed @@ -179,19 +178,8 @@ uint32_t equalizerNband_audio_module::process(uint32_t offs ++offset; } // displays, too - clip_inL = clip_inR = clip_outL = clip_outR = 0.f; - meter_inL = meter_inR = meter_outL = meter_outR = 0.f; + meters.bypassed(params, orig_numsamples); } else { - - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - // process while(offset < numsamples) { // cycle through samples @@ -230,37 +218,11 @@ uint32_t equalizerNband_audio_module::process(uint32_t offs // send to output outs[0][offset] = outL; outs[1][offset] = outR; - - // clip LED's - if(inL > 1.f) { - clip_inL = srate >> 3; - } - if(inR > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(inL > meter_inL) { - meter_inL = inL; - } - if(inR > meter_inR) { - meter_inR = inR; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - + // next sample ++offset; } // cycle trough samples + meters.process(params, ins, outs, orig_offset, orig_numsamples); // clean up for(int i = 0; i < 3; ++i) { hp[i][0].sanitize(); @@ -275,15 +237,6 @@ uint32_t equalizerNband_audio_module::process(uint32_t offs pR[i].sanitize(); } } - // draw meters - SET_IF_CONNECTED(clip_inL) - SET_IF_CONNECTED(clip_inR) - SET_IF_CONNECTED(clip_outL) - SET_IF_CONNECTED(clip_outR) - SET_IF_CONNECTED(meter_inL) - SET_IF_CONNECTED(meter_inR) - SET_IF_CONNECTED(meter_outL) - SET_IF_CONNECTED(meter_outR) // whatever has to be returned x) return outputs_mask; } From 48f9008f423212fba240c452d9914b7f5f599321 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 19 Sep 2010 22:02:38 +0100 Subject: [PATCH 03/11] Add LV2 persist extension by paniq. (cherry picked from commit 1965282a28c6940164ffff7ebd106b27cafd7f2a) --- src/calf/lv2_persist.h | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/calf/lv2_persist.h diff --git a/src/calf/lv2_persist.h b/src/calf/lv2_persist.h new file mode 100644 index 000000000..56b9990d9 --- /dev/null +++ b/src/calf/lv2_persist.h @@ -0,0 +1,130 @@ +// This file is in the public domain. +// Written by Leonard Ritter + +#ifndef __LV2_PERSIST_H__ +#define __LV2_PERSIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Indicates that the plugin supports persistence, which means + being able to save and restore internal state, allowing hosts to + save configuration with a project, or to clone a plugin, including + internal state. + + The plugin should always expose this feature as optional. +*/ +#define LV2_PERSIST_URI "http://paniq.org/lv2/persist" + + +/* + Causes the host to store a binary blob in a map. + + A callback provided by the host to LV2_Persist.save(). 'callback_data' + must be the callback_data argument passed to save(). 'key' is a private + string or URI under which the data is to be stored. 'value' points to + the binary blob to be stored. 'size' is the size of the binary blob in + bytes. + + The host must store a copy of the blob under the provided key in a map + until returning from the save() call. + + A size of 0 indicates that value points to a zero-terminated string. + This is a convenience function which requires the host to calculate the + length as strlen(value)+1. +*/ +typedef void (*LV2_Persist_Store_Function)(void *callback_data, const char *key, + const void *value, size_t size); + +/* + Causes the host to retrieve a binary blob from the map. + + A callback provided by the host to LV2_Persist.restore(). 'callback_data' + must be the callback_data argument passed to restore(). 'key' is a private + string or UI under which a blob has been previously stored. + + When the blob could be successfully retrieved, retrieve() must return + a pointer to the blob and set 'size' to the length of value in bytes. + + 'size' may be NULL. In this case, no return of the blob size is required. + This is a convenience function to retrieve zero-terminated strings. + + The returned value must remain valid until restore() returns. The plugin + is required to make a copy if it needs to continue working with the + data. It must not attempt to access a retrieved blob pointer outside + of the restore context. +*/ +typedef const void *(*LV2_Persist_Retrieve_Function)(void *callback_data, + const char *key, size_t *size); + +/* + When the plugins extension_data is called with argument LV2_PERSIST_URI, + the plugin is expected to return an LV2_Persist structure, which remains + valid indefinitely. + + The host can use the exposed function pointers to save and restore + the state of a plugin to a map of string keys to binary blobs at any + time. + + The usual application would be to save the plugins state when the + project document is to be saved, and to restore the state when + a project document has been loaded. Other applications are possible. + + Blob maps are meant to be only compatible between instances of the + same plugin. However, should a future extension require persistent + data to follow an URI key naming scheme, this restriction no longer + applies. +*/ +struct LV2_Persist { + /* + Causes the plugin to save state data which it wants to preserve + across plugin lifetime using a store callback provided by + the host. + + 'instance' is the instance handle of the plugin. 'callback_data' + is an opaque pointer to host data, e.g. the map or file where + the blobs are to be stored, it should be passed to 'store', + which is a host-supplied function to store a blob. For more + information, see LV2_Persist_Store_Function. + + The map on which save() operates must always be empty before + the first call to store(). The plugin is expected to store all + blobs of interests. + + The callback data pointer and store function may not be used + beyond the scope of save(). + */ + void (*save)(LV2_Handle instance, + LV2_Persist_Store_Function store, void *callback_data); + + /* + Causes the plugin to restore state data using a retrieve callback + provided by the host. + + 'instance' is the instance handle of the plugin. 'callback_data' + is an opaque pointer to host data, e.g. the map or file where + the blobs are to be retrieved from; it should be passed to + 'retrieve', which is a host-supplied function to retrieve blobs. + For more information, see LV2_Persist_Retrieve_Function. + + The map on which restore() operates must contain values stored + by a plugin instance of the same class, or be empty. + + The plugin must gracefully fall back to a default value + when a blob can not be retrieved. This allows the host to reset + the plugin state with an empty map. + + The callback data pointer and store function may not be used + beyond the scope of save(). + */ + void (*restore)(LV2_Handle instance, + LV2_Persist_Retrieve_Function retrieve, void *callback_data); +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __LV2_PERSIST_H__ */ From fbc364e68e284e24a39e56062d752f9ebe6734b3 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 19 Sep 2010 23:14:40 +0100 Subject: [PATCH 04/11] Add a crude incomplete implementation of persist extension support. (cherry picked from commit 3ec11c04799fc08fd408c4ef2350df65f88ccfde) --- plugins/ladspa_effect/calf/src/calf/giface.h | 10 ++ plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 96 ++++++++++++++++--- plugins/ladspa_effect/calf/src/plugin.cpp | 3 + src/calf/lv2_persist.h | 18 ++-- 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 08954c695..752519753 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -28,6 +28,8 @@ #include #include +// #define USE_PERSIST_EXTENSION 1 + namespace osctl { struct osc_client; } @@ -299,6 +301,8 @@ struct plugin_metadata_iface virtual const char *get_label() const = 0; /// @return total number of parameters virtual int get_param_count() const = 0; + /// @return total number of parameters that aren't configure variables + virtual int get_nonstring_param_count() const = 0; /// Return custom XML virtual const char *get_gui_xml() const = 0; /// @return number of audio inputs @@ -633,6 +637,12 @@ public: ports.push_back(i); } } + int get_nonstring_param_count() const { + int i = Metadata::param_count; + while(i > 0 && (param_props[i - 1].flags & PF_TYPEMASK) == PF_STRING) + i--; + return i; + } }; #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata::port_names[] diff --git a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h index 6a9bc40d0..d38b8eaf6 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface LV2_Progress *progress_report_feature; float **ins, **outs, **params; int out_count; + int real_param_count; lv2_instance(audio_module_iface *_module) { module = _module; @@ -59,6 +61,11 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface metadata = module->get_metadata_iface(); metadata->get_message_context_parameters(message_params); out_count = metadata->get_output_count(); +#if USE_PERSIST_EXTENSION + real_param_count = metadata->get_nonstring_param_count(); +#else + real_param_count = metadata->get_param_count(); +#endif uri_map = NULL; midi_data = NULL; @@ -107,6 +114,27 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface } return module->message_run(valid_inputs, output_ports); } +#if USE_PERSIST_EXTENSION + void impl_restore(LV2_Persist_Retrieve_Function retrieve, void *callback_data) + { + for (unsigned int i = 0; i < message_params.size(); i++) + { + int pn = message_params[i]; + const parameter_properties &pp = *metadata->get_param_props(pn); + if ((pp.flags & PF_TYPEMASK) == PF_STRING) { + size_t len = 0; + const void *ptr = (*retrieve)(callback_data, pp.short_name, &len); + if (ptr) + { + printf("Calling configure on %s\n", pp.short_name); + configure(pp.short_name, std::string((const char *)ptr, len).c_str()); + } + else + configure(pp.short_name, pp.choices[0]); + } + } + } +#endif char *configure(const char *key, const char *value) { // disambiguation - the plugin_ctl_iface version is just a stub, so don't use it return module->configure(key, value); @@ -150,14 +178,14 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface virtual float get_param_value(int param_no) { // XXXKF hack - if (param_no >= metadata->get_param_count()) + if (param_no >= real_param_count) return 0; return (*params)[param_no]; } virtual void set_param_value(int param_no, float value) { // XXXKF hack - if (param_no >= metadata->get_param_count()) + if (param_no >= real_param_count) return; *params[param_no] = value; } @@ -177,6 +205,7 @@ struct lv2_wrapper static LV2_Descriptor descriptor; static LV2_Calf_Descriptor calf_descriptor; static LV2MessageContext message_context; + static LV2_Persist persist; std::string uri; lv2_wrapper() @@ -191,17 +220,26 @@ struct lv2_wrapper descriptor.deactivate = cb_deactivate; descriptor.cleanup = cb_cleanup; descriptor.extension_data = cb_ext_data; +#if USE_PERSIST_EXTENSION + persist.save = cb_persist_save; + persist.restore = cb_persist_restore; +#endif calf_descriptor.get_pci = cb_get_pci; message_context.message_connect_port = cb_connect; message_context.message_run = cb_message_run; } - static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) { + static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) + { instance *const mod = (instance *)Instance; const plugin_metadata_iface *md = mod->metadata; unsigned long ins = md->get_input_count(); unsigned long outs = md->get_output_count(); +#if USE_PERSIST_EXTENSION + unsigned long params = md->get_nonstring_param_count(); +#else unsigned long params = md->get_param_count(); +#endif if (port < ins) mod->ins[port] = (float *)DataLocation; else if (port < ins + outs) @@ -215,12 +253,14 @@ struct lv2_wrapper } } - static void cb_activate(LV2_Handle Instance) { + static void cb_activate(LV2_Handle Instance) + { instance *const mod = (instance *)Instance; mod->set_srate = true; } - static void cb_deactivate(LV2_Handle Instance) { + static void cb_deactivate(LV2_Handle Instance) + { instance *const mod = (instance *)Instance; mod->module->deactivate(); } @@ -259,11 +299,13 @@ struct lv2_wrapper return static_cast(Instance); } - static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written) { + static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written) + { instance *mod = (instance *)Instance; return mod->impl_message_run(valid_inputs, outputs_written); } - static void cb_run(LV2_Handle Instance, uint32_t SampleCount) { + static void cb_run(LV2_Handle Instance, uint32_t SampleCount) + { instance *const inst = (instance *)Instance; audio_module_iface *mod = inst->module; if (inst->set_srate) { @@ -279,20 +321,52 @@ struct lv2_wrapper } inst->module->process_slice(offset, SampleCount); } - static void cb_cleanup(LV2_Handle Instance) { + static void cb_cleanup(LV2_Handle Instance) + { instance *const mod = (instance *)Instance; delete mod; } - static const void *cb_ext_data(const char *URI) { + static const void *cb_ext_data(const char *URI) + { if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance")) return &calf_descriptor; if (!strcmp(URI, LV2_CONTEXT_MESSAGE)) return &message_context; +#if USE_PERSIST_EXTENSION + if (!strcmp(URI, LV2_PERSIST_URI)) + return &persist; +#endif return NULL; } +#if USE_PERSIST_EXTENSION + static void cb_persist_save(LV2_Handle Instance, LV2_Persist_Store_Function store, void *callback_data) + { + instance *const inst = (instance *)Instance; + struct store_state: public send_configure_iface + { + LV2_Persist_Store_Function store; + void *callback_data; + + virtual void send_configure(const char *key, const char *value) + { + (*store)(callback_data, key, value, strlen(value)); + } + }; + store_state s; + s.store = store; + s.callback_data = callback_data; + inst->send_configures(&s); + } + static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data) + { + instance *const inst = (instance *)Instance; + inst->impl_restore(retrieve, callback_data); + } +#endif + static lv2_wrapper &get() { - static lv2_wrapper instance; - return instance; + static lv2_wrapper *instance = new lv2_wrapper; + return *instance; } }; diff --git a/plugins/ladspa_effect/calf/src/plugin.cpp b/plugins/ladspa_effect/calf/src/plugin.cpp index 9a4b97615..6588f67c6 100644 --- a/plugins/ladspa_effect/calf/src/plugin.cpp +++ b/plugins/ladspa_effect/calf/src/plugin.cpp @@ -485,6 +485,9 @@ ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set() template LV2_Descriptor calf_plugins::lv2_wrapper::descriptor; template LV2_Calf_Descriptor calf_plugins::lv2_wrapper::calf_descriptor; template LV2MessageContext calf_plugins::lv2_wrapper::message_context; +#if USE_PERSIST_EXTENSION +template LV2_Persist calf_plugins::lv2_wrapper::persist; +#endif extern "C" { diff --git a/src/calf/lv2_persist.h b/src/calf/lv2_persist.h index 56b9990d9..86ac86596 100644 --- a/src/calf/lv2_persist.h +++ b/src/calf/lv2_persist.h @@ -17,7 +17,6 @@ extern "C" { The plugin should always expose this feature as optional. */ #define LV2_PERSIST_URI "http://paniq.org/lv2/persist" - /* Causes the host to store a binary blob in a map. @@ -28,22 +27,23 @@ extern "C" { the binary blob to be stored. 'size' is the size of the binary blob in bytes. - The host must store a copy of the blob under the provided key in a map - until returning from the save() call. + The host is expected store a copy of the blob under the provided key. - A size of 0 indicates that value points to a zero-terminated string. + A 'size' of 0 is valid. The host may choose to store nothing. + + A 'size' of -1 indicates that 'value' points to a zero-terminated string. This is a convenience function which requires the host to calculate the - length as strlen(value)+1. + size from strlen(value)+1. */ typedef void (*LV2_Persist_Store_Function)(void *callback_data, const char *key, - const void *value, size_t size); + const void *value, ssize_t size); /* Causes the host to retrieve a binary blob from the map. A callback provided by the host to LV2_Persist.restore(). 'callback_data' must be the callback_data argument passed to restore(). 'key' is a private - string or UI under which a blob has been previously stored. + string or URI under which a blob has been previously stored. When the blob could be successfully retrieved, retrieve() must return a pointer to the blob and set 'size' to the length of value in bytes. @@ -91,7 +91,7 @@ struct LV2_Persist { The map on which save() operates must always be empty before the first call to store(). The plugin is expected to store all - blobs of interests. + blobs of interest. The callback data pointer and store function may not be used beyond the scope of save(). @@ -127,4 +127,4 @@ struct LV2_Persist { } /* extern "C" */ #endif -#endif /* __LV2_PERSIST_H__ */ +#endif /* __LV2_PERSIST_H__ */ \ No newline at end of file From f40e2c85bc7afb2e13c4e68ecb7910cf62b3e431 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 19 Sep 2010 23:26:07 +0100 Subject: [PATCH 05/11] Comment out the barfage when passing configure variables via message_run. (cherry picked from commit 1e767ff88578011c2f65466d5516953271e2cafd) --- plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h index d38b8eaf6..2c130be12 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -108,7 +108,7 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface int ppn = pn + ofs; if ((pp.flags & PF_TYPEMASK) == PF_STRING && (vi[ppn >> 3] & (1 << (ppn & 7))) && (((LV2_String_Data *)params[pn])->flags & LV2_STRING_DATA_CHANGED_FLAG)) { - printf("Calling configure on %s\n", pp.short_name); + // printf("Calling configure on %s\n", pp.short_name); configure(pp.short_name, ((LV2_String_Data *)params[pn])->data); } } From 9179bf41ee085fd084b2e61b920f48213e576eef Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Tue, 21 Sep 2010 00:07:46 +0100 Subject: [PATCH 06/11] Replace string port/message context using persist extension. (cherry picked from commit b8e69ceb2ff7aca549efd939d04447e2f08ad5a8) --- plugins/ladspa_effect/calf/src/calf/giface.h | 34 ++------- .../ladspa_effect/calf/src/calf/ladspa_wrap.h | 2 +- plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 72 ++++--------------- .../ladspa_effect/calf/src/calf/metadata.h | 6 ++ plugins/ladspa_effect/calf/src/giface.cpp | 38 ++-------- plugins/ladspa_effect/calf/src/metadata.cpp | 16 +++-- plugins/ladspa_effect/calf/src/plugin.cpp | 18 ++--- 7 files changed, 48 insertions(+), 138 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 752519753..d4eb287e3 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -28,8 +28,6 @@ #include #include -// #define USE_PERSIST_EXTENSION 1 - namespace osctl { struct osc_client; } @@ -49,7 +47,6 @@ enum parameter_flags PF_BOOL = 0x0002, ///< bool value (usually >=0.5f is treated as TRUE, which is inconsistent with LV2 etc. which treats anything >0 as TRUE) PF_ENUM = 0x0003, ///< enum value (min, min+1, ..., max, only guaranteed to work when min = 0) PF_ENUM_MULTI = 0x0004, ///< SET / multiple-choice - PF_STRING = 0x0005, ///< see: http://lv2plug.in/docs/index.php?title=String_port PF_SCALEMASK = 0xF0, ///< bit mask for scale PF_SCALE_DEFAULT = 0x00, ///< no scale given @@ -84,7 +81,6 @@ enum parameter_flags PF_PROP_OUTPUT = 0x080000, ///< output port PF_PROP_OPTIONAL = 0x100000, ///< connection optional PF_PROP_GRAPH = 0x200000, ///< add graph - PF_PROP_MSGCONTEXT= 0x400000, ///< message context PF_UNITMASK = 0xFF000000, ///< bit mask for units \todo reduce to use only 5 bits PF_UNIT_DB = 0x01000000, ///< decibels @@ -301,8 +297,6 @@ struct plugin_metadata_iface virtual const char *get_label() const = 0; /// @return total number of parameters virtual int get_param_count() const = 0; - /// @return total number of parameters that aren't configure variables - virtual int get_nonstring_param_count() const = 0; /// Return custom XML virtual const char *get_gui_xml() const = 0; /// @return number of audio inputs @@ -335,12 +329,10 @@ struct plugin_metadata_iface virtual bool is_cv(int param_no) const = 0; /// is the given parameter non-interpolated? 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() const = 0; /// does the plugin require string port extension? (or DSSI configure) may be slow - 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) const = 0; + 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; } /// Do-nothing destructor to silence compiler warning virtual ~plugin_metadata_iface() {} @@ -431,7 +423,7 @@ struct audio_module_iface virtual void set_sample_rate(uint32_t sr) = 0; /// Execute menu command with given number virtual void execute(int cmd_no) = 0; - /// DSSI configure call + /// DSSI configure call, value = NULL = reset to default virtual char *configure(const char *key, const char *value) = 0; /// Send all understood configure vars (none by default) virtual void send_configures(send_configure_iface *sci) = 0; @@ -556,9 +548,6 @@ public: virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast(this); } }; -extern bool check_for_message_context_ports(const parameter_properties *parameters, int count); -extern bool check_for_string_ports(const parameter_properties *parameters, int count); - #if USE_EXEC_GUI || USE_DSSI enum line_graph_item @@ -629,20 +618,7 @@ public: 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); - } - } - int get_nonstring_param_count() const { - int i = Metadata::param_count; - while(i > 0 && (param_props[i - 1].flags & PF_TYPEMASK) == PF_STRING) - i--; - return i; - } + bool requires_configure() const { return false; } }; #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata::port_names[] diff --git a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h index 68009b8cb..d94ebcea3 100644 --- a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h @@ -88,7 +88,7 @@ struct ladspa_plugin_metadata_set std::vector *preset_descs; #endif - int input_count, output_count, param_count, real_param_count; + int input_count, output_count, param_count; const plugin_metadata_iface *metadata; ladspa_plugin_metadata_set(); diff --git a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h index 2c130be12..8fda6d958 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -28,11 +28,9 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -49,7 +47,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface LV2_URI_Map_Feature *uri_map; LV2_Event_Feature *event_feature; uint32_t midi_event_type; - std::vector message_params; LV2_Progress *progress_report_feature; float **ins, **outs, **params; int out_count; @@ -59,13 +56,8 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface module = _module; module->get_port_arrays(ins, outs, params); metadata = module->get_metadata_iface(); - metadata->get_message_context_parameters(message_params); out_count = metadata->get_output_count(); -#if USE_PERSIST_EXTENSION - real_param_count = metadata->get_nonstring_param_count(); -#else real_param_count = metadata->get_param_count(); -#endif uri_map = NULL; midi_data = NULL; @@ -75,7 +67,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface srate_to_set = 44100; set_srate = true; - // printf("message params %d\n", (int)message_params.size()); } /// This, and not Module::post_instantiate, is actually called by lv2_wrapper class void post_instantiate() @@ -98,43 +89,24 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface void send_configures(send_configure_iface *sci) { module->send_configures(sci); } - uint32_t impl_message_run(const void *valid_inputs, void *output_ports) { - uint8_t *vi = (uint8_t *)valid_inputs; - int ofs = metadata->get_param_port_offset(); - for (unsigned int i = 0; i < message_params.size(); i++) - { - int pn = message_params[i]; - const parameter_properties &pp = *metadata->get_param_props(pn); - int ppn = pn + ofs; - if ((pp.flags & PF_TYPEMASK) == PF_STRING && (vi[ppn >> 3] & (1 << (ppn & 7))) - && (((LV2_String_Data *)params[pn])->flags & LV2_STRING_DATA_CHANGED_FLAG)) { - // printf("Calling configure on %s\n", pp.short_name); - configure(pp.short_name, ((LV2_String_Data *)params[pn])->data); - } - } - return module->message_run(valid_inputs, output_ports); - } -#if USE_PERSIST_EXTENSION void impl_restore(LV2_Persist_Retrieve_Function retrieve, void *callback_data) { - for (unsigned int i = 0; i < message_params.size(); i++) + const char *const *vars = module->get_metadata_iface()->get_configure_vars(); + if (!vars) + return; + for (unsigned int i = 0; vars[i]; i++) { - int pn = message_params[i]; - const parameter_properties &pp = *metadata->get_param_props(pn); - if ((pp.flags & PF_TYPEMASK) == PF_STRING) { - size_t len = 0; - const void *ptr = (*retrieve)(callback_data, pp.short_name, &len); - if (ptr) - { - printf("Calling configure on %s\n", pp.short_name); - configure(pp.short_name, std::string((const char *)ptr, len).c_str()); - } - else - configure(pp.short_name, pp.choices[0]); + size_t len = 0; + const void *ptr = (*retrieve)(callback_data, vars[i], &len); + if (ptr) + { + printf("Calling configure on %s\n", vars[i]); + configure(vars[i], std::string((const char *)ptr, len).c_str()); } + else + configure(vars[i], NULL); } } -#endif char *configure(const char *key, const char *value) { // disambiguation - the plugin_ctl_iface version is just a stub, so don't use it return module->configure(key, value); @@ -204,7 +176,6 @@ struct lv2_wrapper typedef lv2_instance instance; static LV2_Descriptor descriptor; static LV2_Calf_Descriptor calf_descriptor; - static LV2MessageContext message_context; static LV2_Persist persist; std::string uri; @@ -220,13 +191,9 @@ struct lv2_wrapper descriptor.deactivate = cb_deactivate; descriptor.cleanup = cb_cleanup; descriptor.extension_data = cb_ext_data; -#if USE_PERSIST_EXTENSION persist.save = cb_persist_save; persist.restore = cb_persist_restore; -#endif calf_descriptor.get_pci = cb_get_pci; - message_context.message_connect_port = cb_connect; - message_context.message_run = cb_message_run; } static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) @@ -235,11 +202,7 @@ struct lv2_wrapper const plugin_metadata_iface *md = mod->metadata; unsigned long ins = md->get_input_count(); unsigned long outs = md->get_output_count(); -#if USE_PERSIST_EXTENSION - unsigned long params = md->get_nonstring_param_count(); -#else unsigned long params = md->get_param_count(); -#endif if (port < ins) mod->ins[port] = (float *)DataLocation; else if (port < ins + outs) @@ -299,11 +262,6 @@ struct lv2_wrapper return static_cast(Instance); } - static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written) - { - instance *mod = (instance *)Instance; - return mod->impl_message_run(valid_inputs, outputs_written); - } static void cb_run(LV2_Handle Instance, uint32_t SampleCount) { instance *const inst = (instance *)Instance; @@ -330,15 +288,10 @@ struct lv2_wrapper { if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance")) return &calf_descriptor; - if (!strcmp(URI, LV2_CONTEXT_MESSAGE)) - return &message_context; -#if USE_PERSIST_EXTENSION if (!strcmp(URI, LV2_PERSIST_URI)) return &persist; -#endif return NULL; } -#if USE_PERSIST_EXTENSION static void cb_persist_save(LV2_Handle Instance, LV2_Persist_Store_Function store, void *callback_data) { instance *const inst = (instance *)Instance; @@ -362,7 +315,6 @@ struct lv2_wrapper instance *const inst = (instance *)Instance; inst->impl_restore(retrieve, callback_data); } -#endif static lv2_wrapper &get() { static lv2_wrapper *instance = new lv2_wrapper; diff --git a/plugins/ladspa_effect/calf/src/calf/metadata.h b/plugins/ladspa_effect/calf/src/calf/metadata.h index 7f6f3240d..2941df591 100644 --- a/plugins/ladspa_effect/calf/src/calf/metadata.h +++ b/plugins/ladspa_effect/calf/src/calf/metadata.h @@ -403,7 +403,10 @@ struct organ_metadata: public organ_enums, public plugin_metadata enum { par_master, par_interpolation, par_reverb, par_chorus, par_soundfont, par_preset_key_set, 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") + +public: + const char *const *get_configure_vars() const; }; /// Wavetable - metadata diff --git a/plugins/ladspa_effect/calf/src/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index f94fa207e..0823a48b6 100644 --- a/plugins/ladspa_effect/calf/src/giface.cpp +++ b/plugins/ladspa_effect/calf/src/giface.cpp @@ -150,8 +150,6 @@ std::string parameter_properties::to_string(float value) const } switch(flags & PF_TYPEMASK) { - case PF_STRING: - return "N/A"; case PF_INT: case PF_BOOL: case PF_ENUM: @@ -190,16 +188,14 @@ std::string parameter_properties::to_string(float value) const void calf_plugins::plugin_ctl_iface::clear_preset() { int param_count = get_metadata_iface()->get_param_count(); - for (int i=0; i < param_count; i++) + for (int i = 0; i < param_count; i++) { const parameter_properties &pp = *get_metadata_iface()->get_param_props(i); - if ((pp.flags & PF_TYPEMASK) == PF_STRING) - { - configure(pp.short_name, pp.choices ? pp.choices[0] : ""); - } - else - set_param_value(i, pp.def_value); + set_param_value(i, pp.def_value); } + const char *const *vars = get_metadata_iface()->get_configure_vars(); + for (int i = 0; vars[i]; i++) + configure(vars[i], NULL); } const char *calf_plugins::load_gui_xml(const std::string &plugin_id) @@ -209,32 +205,10 @@ const char *calf_plugins::load_gui_xml(const std::string &plugin_id) return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/gui-" + plugin_id + ".xml").c_str()).c_str()); } catch(file_exception e) -#endif { return NULL; } -} - -bool calf_plugins::check_for_message_context_ports(const parameter_properties *parameters, int count) -{ - for (int i = count - 1; i >= 0; i--) - { - if (parameters[i].flags & PF_PROP_MSGCONTEXT) - return true; - } - return false; -} - -bool calf_plugins::check_for_string_ports(const parameter_properties *parameters, int count) -{ - for (int i = count - 1; i >= 0; i--) - { - if ((parameters[i].flags & PF_TYPEMASK) == PF_STRING) - return true; - if ((parameters[i].flags & PF_TYPEMASK) < PF_STRING) - return false; - } - return false; +#endif } bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies) diff --git a/plugins/ladspa_effect/calf/src/metadata.cpp b/plugins/ladspa_effect/calf/src/metadata.cpp index d655a486f..9feccb7b2 100644 --- a/plugins/ladspa_effect/calf/src/metadata.cpp +++ b/plugins/ladspa_effect/calf/src/metadata.cpp @@ -950,10 +950,14 @@ CALF_PORT_PROPS(organ) = { { 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "bass_gain", "Bass Gain" }, { 12000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_freq", "Treble Freq" }, { 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "treble_gain", "Treble Gain" }, - - { 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &organ_init_map_curve, "map_curve", "Key mapping curve" }, }; +const char *const *organ_metadata::get_configure_vars() const +{ + static const char *names[] = {"map_curve", NULL}; + return names; +} + //////////////////////////////////////////////////////////////////////////// const char *fluidsynth_init_soundfont = ""; @@ -972,10 +976,14 @@ CALF_PORT_PROPS(fluidsynth) = { { 2, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, fluidsynth_interpolation_names, "interpolation", "Interpolation" }, { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Reverb" }, { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Chorus" }, - { 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_soundfont, "soundfont", "Soundfont" }, - { 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_presetkeyset, "preset_key_set", "Set Preset" }, }; +const char *const *fluidsynth_metadata::get_configure_vars() const +{ + static const char *names[] = {"soundfont", "preset_key_set", NULL}; + return names; +} + //////////////////////////////////////////////////////////////////////////// const char *wavetable_names[] = { diff --git a/plugins/ladspa_effect/calf/src/plugin.cpp b/plugins/ladspa_effect/calf/src/plugin.cpp index 6588f67c6..cd466c4e9 100644 --- a/plugins/ladspa_effect/calf/src/plugin.cpp +++ b/plugins/ladspa_effect/calf/src/plugin.cpp @@ -58,7 +58,7 @@ ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_meta float ladspa_instance::get_param_value(int param_no) { // XXXKF hack - if (param_no >= ladspa->real_param_count) + if (param_no >= ladspa->param_count) return 0; return *params[param_no]; } @@ -66,7 +66,7 @@ float ladspa_instance::get_param_value(int param_no) void ladspa_instance::set_param_value(int param_no, float value) { // XXXKF hack - if (param_no >= ladspa->real_param_count) + if (param_no >= ladspa->param_count) return; *params[param_no] = value; } @@ -231,7 +231,7 @@ static void cb_connect(LADSPA_Handle Instance, unsigned long port, LADSPA_Data * int first_out = mod->ladspa->input_count; int first_param = first_out + mod->ladspa->output_count; - int ladspa_port_count = first_param + mod->ladspa->real_param_count; + int ladspa_port_count = first_param + mod->ladspa->param_count; if ((int)port < first_out) mod->ins[port] = DataLocation; @@ -292,7 +292,7 @@ static void cb_select_program(LADSPA_Handle Instance, unsigned long Bank, unsign unsigned int no = (Bank << 7) + Program - 1; // printf("no = %d presets = %p:%d\n", no, presets, presets->size()); if (no == -1U) { - int rpc = ladspa->real_param_count; + int rpc = ladspa->param_count; for (int i =0 ; i < rpc; i++) *mod->params[i] = mod->metadata->get_param_props(i)->def_value; return; @@ -328,9 +328,6 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA input_count = md->get_input_count(); output_count = md->get_output_count(); param_count = md->get_param_count(); // XXXKF ladspa_instance::real_param_count(); - real_param_count = 0; - while(real_param_count < md->get_param_count() && (metadata->get_param_props(real_param_count)->flags & PF_TYPEMASK) < PF_STRING) - real_param_count++; const ladspa_plugin_info &plugin_info = md->get_plugin_info(); descriptor.UniqueID = plugin_info.unique_id; @@ -339,7 +336,7 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA descriptor.Maker = plugin_info.maker; descriptor.Copyright = plugin_info.copyright; descriptor.Properties = md->is_rt_capable() ? LADSPA_PROPERTY_HARD_RT_CAPABLE : 0; - descriptor.PortCount = input_count + output_count + real_param_count; + descriptor.PortCount = input_count + output_count + param_count; descriptor.PortNames = new char *[descriptor.PortCount]; descriptor.PortDescriptors = new LADSPA_PortDescriptor[descriptor.PortCount]; descriptor.PortRangeHints = new LADSPA_PortRangeHint[descriptor.PortCount]; @@ -352,7 +349,7 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA prh.HintDescriptor = 0; ((const char **)descriptor.PortNames)[i] = md->get_port_names()[i]; } - for (; i < input_count + output_count + real_param_count; i++) + for (; i < input_count + output_count + param_count; i++) { LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i]; const parameter_properties &pp = *md->get_param_props(i - input_count - output_count); @@ -484,10 +481,7 @@ ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set() // instantiate descriptor templates template LV2_Descriptor calf_plugins::lv2_wrapper::descriptor; template LV2_Calf_Descriptor calf_plugins::lv2_wrapper::calf_descriptor; -template LV2MessageContext calf_plugins::lv2_wrapper::message_context; -#if USE_PERSIST_EXTENSION template LV2_Persist calf_plugins::lv2_wrapper::persist; -#endif extern "C" { From 8ff5a375848beb29a9b0714decbd27cf2435ceeb Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 24 Sep 2010 20:06:19 +0100 Subject: [PATCH 07/11] Remove the forgotten leftover references to the old extensions. (cherry picked from commit deb8b77bdb1e1648a38589b3be3d4d66175b4934) --- plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h index 8fda6d958..198b713e3 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -42,7 +41,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface audio_module_iface *module; bool set_srate; int srate_to_set; - LV2_MIDI *midi_data; LV2_Event_Buffer *event_data; LV2_URI_Map_Feature *uri_map; LV2_Event_Feature *event_feature; @@ -60,7 +58,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface real_param_count = metadata->get_param_count(); uri_map = NULL; - midi_data = NULL; event_data = NULL; progress_report_feature = NULL; midi_event_type = 0xFFFFFFFF; From 2ff3c32d7ba0e33a7d911bcedec8fdb1ce2d11c2 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Fri, 24 Sep 2010 22:22:56 +0100 Subject: [PATCH 08/11] Fix organ crash in calfjackhost. (cherry picked from commit b2853103199b3f5f3a5d22271c5d89122514dd53) --- plugins/ladspa_effect/calf/src/organ.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/ladspa_effect/calf/src/organ.cpp b/plugins/ladspa_effect/calf/src/organ.cpp index b28cbaaa1..bfd676099 100644 --- a/plugins/ladspa_effect/calf/src/organ.cpp +++ b/plugins/ladspa_effect/calf/src/organ.cpp @@ -950,6 +950,8 @@ char *organ_audio_module::configure(const char *key, const char *value) { if (!strcmp(key, "map_curve")) { + if (!value) + value = "2\n0 1\n1 1\n"; var_map_curve = value; stringstream ss(value); int i = 0; From 16f24125fd96e322ae051fb64c8169a1de82374b Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sat, 25 Sep 2010 21:39:34 +0100 Subject: [PATCH 09/11] Move the table_edit_iface out of plugin_metadata_iface, where it should have never been in first place. (cherry picked from commit 6907dc9670eae2313707b142c552a8d9e8b477b5) --- plugins/ladspa_effect/calf/src/calf/giface.h | 8 +++++--- plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h | 1 + plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index d4eb287e3..55e8323e5 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -315,8 +315,6 @@ struct plugin_metadata_iface 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() const = 0; - /// @return table_edit_iface if any - virtual const table_edit_iface *get_table_edit_iface() const = 0; /// @return NULL-terminated list of menu commands virtual plugin_command_info *get_commands() const { return NULL; } /// @return description structure for given parameter @@ -367,6 +365,8 @@ 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 const table_edit_iface *get_table_edit_iface() const = 0; /// Do-nothing destructor to silence compiler warning virtual ~plugin_ctl_iface() {} }; @@ -447,6 +447,8 @@ 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 + virtual const table_edit_iface *get_table_edit_iface() const = 0; virtual ~audio_module_iface() {} }; @@ -546,6 +548,7 @@ public: } /// @return line_graph_iface if any virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast(this); } + virtual const table_edit_iface *get_table_edit_iface() const { return dynamic_cast(this); } }; #if USE_EXEC_GUI || USE_DSSI @@ -609,7 +612,6 @@ public: 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 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; } diff --git a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h index d94ebcea3..8859b989a 100644 --- a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h @@ -48,6 +48,7 @@ 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 const table_edit_iface *get_table_edit_iface() const { return module->get_table_edit_iface(); } 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 198b713e3..c43237fa9 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -160,6 +160,7 @@ 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 const table_edit_iface *get_table_edit_iface() const { return module->get_table_edit_iface(); } virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } }; From a572acb35f9e9fb54b0a5239252d6745f87453d4 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 26 Sep 2010 22:50:30 +0100 Subject: [PATCH 10/11] One table_edit_iface per table; start implementing a bridge class. (cherry picked from commit 2019ae2d8f9636b7d5cdb0c1fdd5f0d6f2b47e3d) --- plugins/ladspa_effect/calf/src/calf/giface.h | 43 ++++++++++---- .../ladspa_effect/calf/src/calf/ladspa_wrap.h | 2 +- plugins/ladspa_effect/calf/src/calf/lv2wrap.h | 2 +- .../ladspa_effect/calf/src/calf/modmatrix.h | 8 +-- plugins/ladspa_effect/calf/src/giface.cpp | 59 +++++++++++++++++-- plugins/ladspa_effect/calf/src/modmatrix.cpp | 8 +-- 6 files changed, 98 insertions(+), 24 deletions(-) diff --git a/plugins/ladspa_effect/calf/src/calf/giface.h b/plugins/ladspa_effect/calf/src/calf/giface.h index 55e8323e5..4bb5df90e 100644 --- a/plugins/ladspa_effect/calf/src/calf/giface.h +++ b/plugins/ladspa_effect/calf/src/calf/giface.h @@ -225,22 +225,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) const = 0; + virtual const table_column_info *get_table_columns() const = 0; /// return the current number of rows - virtual uint32_t get_table_rows(int param) const = 0; + virtual uint32_t get_table_rows() const = 0; /// retrieve data item from the plugin - virtual std::string get_cell(int param, int row, int column) const; + virtual std::string get_cell(int row, int column) const; /// set data item to the plugin - virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const { error.clear(); } + 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 param, int column) const { return NULL; } + 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 param, int column) const { return NULL; } + virtual const char *get_cell_editor(int column) const { return NULL; } virtual ~table_edit_iface() {} }; @@ -366,7 +366,7 @@ struct plugin_ctl_iface /// @return line_graph_iface if any virtual const line_graph_iface *get_line_graph_iface() const = 0; /// @return table_edit_iface if any - virtual const table_edit_iface *get_table_edit_iface() const = 0; + 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 +447,8 @@ 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 - virtual const table_edit_iface *get_table_edit_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,7 +548,8 @@ public: } /// @return line_graph_iface if any virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast(this); } - virtual const table_edit_iface *get_table_edit_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 @@ -677,6 +678,28 @@ struct preset_access_iface virtual ~preset_access_iface() {} }; +#if USE_EXEC_GUI +class table_via_configure: public table_edit_iface +{ +protected: + typedef std::pair coord; + std::vector columns; + std::map values; + int rows; +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 + }; #endif diff --git a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h index 8859b989a..7908ab103 100644 --- a/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/ladspa_wrap.h @@ -48,7 +48,7 @@ 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 const table_edit_iface *get_table_edit_iface() const { return module->get_table_edit_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 c43237fa9..638eeadd0 100644 --- a/plugins/ladspa_effect/calf/src/calf/lv2wrap.h +++ b/plugins/ladspa_effect/calf/src/calf/lv2wrap.h @@ -160,7 +160,7 @@ 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 const table_edit_iface *get_table_edit_iface() const { return module->get_table_edit_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); } }; diff --git a/plugins/ladspa_effect/calf/src/calf/modmatrix.h b/plugins/ladspa_effect/calf/src/calf/modmatrix.h index 5db95fc92..17ebfd6c6 100644 --- a/plugins/ladspa_effect/calf/src/calf/modmatrix.h +++ b/plugins/ladspa_effect/calf/src/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) 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; + 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); /// 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/src/giface.cpp b/plugins/ladspa_effect/calf/src/giface.cpp index 0823a48b6..f9324e7db 100644 --- a/plugins/ladspa_effect/calf/src/giface.cpp +++ b/plugins/ladspa_effect/calf/src/giface.cpp @@ -194,8 +194,11 @@ void calf_plugins::plugin_ctl_iface::clear_preset() { set_param_value(i, pp.def_value); } const char *const *vars = get_metadata_iface()->get_configure_vars(); - for (int i = 0; vars[i]; i++) - configure(vars[i], NULL); + if (vars) + { + for (int i = 0; vars[i]; i++) + configure(vars[i], NULL); + } } const char *calf_plugins::load_gui_xml(const std::string &plugin_id) @@ -205,10 +208,10 @@ const char *calf_plugins::load_gui_xml(const std::string &plugin_id) return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/gui-" + plugin_id + ".xml").c_str()).c_str()); } catch(file_exception e) +#endif { return NULL; } -#endif } bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies) @@ -318,7 +321,7 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char } /////////////////////////////////////////////////////////////////////////////////////// -std::string table_edit_iface::get_cell(int param, int row, int column) const +std::string table_edit_iface::get_cell(int row, int column) const { return calf_utils::i2s(row)+":"+calf_utils::i2s(column); } @@ -427,4 +430,52 @@ calf_plugins::dssi_feedback_sender::~dssi_feedback_sender() delete client; } +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() +{ +} + #endif diff --git a/plugins/ladspa_effect/calf/src/modmatrix.cpp b/plugins/ladspa_effect/calf/src/modmatrix.cpp index 2ef798aca..64ef330bb 100644 --- a/plugins/ladspa_effect/calf/src/modmatrix.cpp +++ b/plugins/ladspa_effect/calf/src/modmatrix.cpp @@ -60,17 +60,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 +const table_column_info *mod_matrix::get_table_columns() const { return table_columns; } -uint32_t mod_matrix::get_table_rows(int param) const +uint32_t mod_matrix::get_table_rows() const { return matrix_rows; } -std::string mod_matrix::get_cell(int param, int row, int column) const +std::string mod_matrix::get_cell(int row, int column) const { assert(row >= 0 && row < (int)matrix_rows); modulation_entry &slot = matrix[row]; @@ -91,7 +91,7 @@ std::string mod_matrix::get_cell(int param, int row, int column) const } } -void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error) const +void mod_matrix::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]; From cb05af03f794a2c94430c7838144cceef7b6ad98 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Tue, 28 Sep 2010 23:39:28 +0200 Subject: [PATCH 11/11] LADSPA/CALF: removed unused file We do not need lv2_persist.h for building the LADSPA version of CALF, therefore remove it. --- src/calf/lv2_persist.h | 130 ----------------------------------------- 1 file changed, 130 deletions(-) delete mode 100644 src/calf/lv2_persist.h diff --git a/src/calf/lv2_persist.h b/src/calf/lv2_persist.h deleted file mode 100644 index 86ac86596..000000000 --- a/src/calf/lv2_persist.h +++ /dev/null @@ -1,130 +0,0 @@ -// This file is in the public domain. -// Written by Leonard Ritter - -#ifndef __LV2_PERSIST_H__ -#define __LV2_PERSIST_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - Indicates that the plugin supports persistence, which means - being able to save and restore internal state, allowing hosts to - save configuration with a project, or to clone a plugin, including - internal state. - - The plugin should always expose this feature as optional. -*/ -#define LV2_PERSIST_URI "http://paniq.org/lv2/persist" - -/* - Causes the host to store a binary blob in a map. - - A callback provided by the host to LV2_Persist.save(). 'callback_data' - must be the callback_data argument passed to save(). 'key' is a private - string or URI under which the data is to be stored. 'value' points to - the binary blob to be stored. 'size' is the size of the binary blob in - bytes. - - The host is expected store a copy of the blob under the provided key. - - A 'size' of 0 is valid. The host may choose to store nothing. - - A 'size' of -1 indicates that 'value' points to a zero-terminated string. - This is a convenience function which requires the host to calculate the - size from strlen(value)+1. -*/ -typedef void (*LV2_Persist_Store_Function)(void *callback_data, const char *key, - const void *value, ssize_t size); - -/* - Causes the host to retrieve a binary blob from the map. - - A callback provided by the host to LV2_Persist.restore(). 'callback_data' - must be the callback_data argument passed to restore(). 'key' is a private - string or URI under which a blob has been previously stored. - - When the blob could be successfully retrieved, retrieve() must return - a pointer to the blob and set 'size' to the length of value in bytes. - - 'size' may be NULL. In this case, no return of the blob size is required. - This is a convenience function to retrieve zero-terminated strings. - - The returned value must remain valid until restore() returns. The plugin - is required to make a copy if it needs to continue working with the - data. It must not attempt to access a retrieved blob pointer outside - of the restore context. -*/ -typedef const void *(*LV2_Persist_Retrieve_Function)(void *callback_data, - const char *key, size_t *size); - -/* - When the plugins extension_data is called with argument LV2_PERSIST_URI, - the plugin is expected to return an LV2_Persist structure, which remains - valid indefinitely. - - The host can use the exposed function pointers to save and restore - the state of a plugin to a map of string keys to binary blobs at any - time. - - The usual application would be to save the plugins state when the - project document is to be saved, and to restore the state when - a project document has been loaded. Other applications are possible. - - Blob maps are meant to be only compatible between instances of the - same plugin. However, should a future extension require persistent - data to follow an URI key naming scheme, this restriction no longer - applies. -*/ -struct LV2_Persist { - /* - Causes the plugin to save state data which it wants to preserve - across plugin lifetime using a store callback provided by - the host. - - 'instance' is the instance handle of the plugin. 'callback_data' - is an opaque pointer to host data, e.g. the map or file where - the blobs are to be stored, it should be passed to 'store', - which is a host-supplied function to store a blob. For more - information, see LV2_Persist_Store_Function. - - The map on which save() operates must always be empty before - the first call to store(). The plugin is expected to store all - blobs of interest. - - The callback data pointer and store function may not be used - beyond the scope of save(). - */ - void (*save)(LV2_Handle instance, - LV2_Persist_Store_Function store, void *callback_data); - - /* - Causes the plugin to restore state data using a retrieve callback - provided by the host. - - 'instance' is the instance handle of the plugin. 'callback_data' - is an opaque pointer to host data, e.g. the map or file where - the blobs are to be retrieved from; it should be passed to - 'retrieve', which is a host-supplied function to retrieve blobs. - For more information, see LV2_Persist_Retrieve_Function. - - The map on which restore() operates must contain values stored - by a plugin instance of the same class, or be empty. - - The plugin must gracefully fall back to a default value - when a blob can not be retrieved. This allows the host to reset - the plugin state with an empty map. - - The callback data pointer and store function may not be used - beyond the scope of save(). - */ - void (*restore)(LV2_Handle instance, - LV2_Persist_Retrieve_Function retrieve, void *callback_data); -}; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __LV2_PERSIST_H__ */ \ No newline at end of file