X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fvst_plugin.cc;h=4183283bffe0f4acf158c6132fcf9a4c7317eebc;hb=5fa05b403ca21a6573d07b921dc14f0769dc9fc7;hp=787210af6aa6d41f1eaccb3f7534df1563f2dc57;hpb=d85ce601589451f834b690c3c0da1df66d025700;p=ardour.git diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 787210af6a..4183283bff 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -27,10 +27,10 @@ #include "pbd/floating.h" #include "pbd/locale_guard.h" +#include "ardour/vst_types.h" #include "ardour/vst_plugin.h" -#include "ardour/vestige/aeffectx.h" +#include "ardour/vestige/vestige.h" #include "ardour/session.h" -#include "ardour/vst_types.h" #include "ardour/filesystem_paths.h" #include "ardour/audio_buffer.h" @@ -47,7 +47,7 @@ VSTPlugin::VSTPlugin (AudioEngine& engine, Session& session, VSTHandle* handle) , _plugin (0) , _pi (0) , _num (0) - , _transport_frame (0) + , _transport_sample (0) , _transport_speed (0.f) , _eff_bypassed (false) { @@ -62,7 +62,7 @@ VSTPlugin::VSTPlugin (const VSTPlugin& other) , _pi (other._pi) , _num (other._num) , _midi_out_buf (other._midi_out_buf) - , _transport_frame (0) + , _transport_sample (0) , _transport_speed (0.f) , _parameter_defaults (other._parameter_defaults) , _eff_bypassed (other._eff_bypassed) @@ -79,8 +79,8 @@ void VSTPlugin::open_plugin () { _plugin = _state->plugin; - assert (_plugin->user == this); // should have been set by {mac_vst|fst|lxvst}_instantiate - _plugin->user = this; + assert (_plugin->ptr1 == this); // should have been set by {mac_vst|fst|lxvst}_instantiate + _plugin->ptr1 = this; _state->plugin->dispatcher (_plugin, effOpen, 0, 0, 0, 0); _state->vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, 0, 0); } @@ -89,7 +89,7 @@ void VSTPlugin::init_plugin () { /* set rate and blocksize */ - _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) _session.frame_rate()); + _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) _session.sample_rate()); _plugin->dispatcher (_plugin, effSetBlockSize, 0, _session.get_block_size(), NULL, 0.0f); } @@ -139,6 +139,31 @@ VSTPlugin::set_block_size (pframes_t nframes) return 0; } +bool +VSTPlugin::requires_fixed_sized_buffers () const +{ + /* This controls if Ardour will split the plugin's run() + * on automation events in order to pass sample-accurate automation + * via standard control-ports. + * + * When returning true Ardour will *not* sub-divide the process-cycle. + * Automation events that happen between cycle-start and cycle-end will be + * ignored (ctrl values are interpolated to cycle-start). + * + * Note: This does not guarantee a fixed block-size. + * e.g The process cycle may be split when looping, also + * the period-size may change any time: see set_block_size() + */ + if (get_info()->n_inputs.n_midi() > 0) { + /* we don't yet implement midi buffer offsets (for split cycles). + * Also session_vst callbacls uses _session.transport_sample() directly + * (for BBT) which is not offset for plugin cycle split. + */ + return true; + } + return false; +} + float VSTPlugin::default_value (uint32_t which) { @@ -260,6 +285,8 @@ VSTPlugin::add_state (XMLNode* root) const chunk_node->add_content (data); g_free (data); + chunk_node->set_property ("program", (int) _plugin->dispatcher (_plugin, effGetProgram, 0, 0, NULL, 0)); + root->add_child_nocopy (*chunk_node); } else { @@ -287,6 +314,11 @@ VSTPlugin::set_state (const XMLNode& node, int version) if ((child = find_named_node (node, X_("chunk"))) != 0) { + int pgm = -1; + if (child->get_property (X_("program"), pgm)) { + _plugin->dispatcher (_plugin, effSetProgram, 0, pgm, NULL, 0); + }; + XMLPropertyList::const_iterator i; XMLNodeList::const_iterator n; @@ -342,27 +374,22 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) desc.upper = 1.0; } - if (prop.flags & kVstParameterUsesIntStep) { + const float range = desc.upper - desc.lower; + if (prop.flags & kVstParameterUsesIntStep && prop.stepInteger < range) { desc.step = prop.stepInteger; desc.smallstep = prop.stepInteger; desc.largestep = prop.stepInteger; desc.integer_step = true; - - } else if (prop.flags & kVstParameterUsesFloatStep) { - + desc.rangesteps = 1 + ceilf (range / desc.step); + } else if (prop.flags & kVstParameterUsesFloatStep && prop.stepFloat < range) { desc.step = prop.stepFloat; desc.smallstep = prop.smallStepFloat; desc.largestep = prop.largeStepFloat; - // desc.rangesteps = (desc.upper - desc.lower) / prop.smallStepFloat; // XXX - + desc.rangesteps = 1 + ceilf (range / desc.step); } else { - - float range = desc.upper - desc.lower; - - desc.step = range / 100.0f; - desc.smallstep = desc.step / 2.0f; - desc.largestep = desc.step * 10.0f; + desc.smallstep = desc.step = range / 300.0f; + desc.largestep = range / 30.0f; } if (strlen(prop.label) == 0) { @@ -385,11 +412,16 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) desc.label = Glib::locale_to_utf8 (label); desc.lower = 0.0f; desc.upper = 1.0f; - desc.step = 0.01f; - desc.smallstep = 0.005f; - desc.largestep = 0.1f; + desc.smallstep = desc.step = 1.f / 300.f; + desc.largestep = 1.f / 30.f; } + /* TODO we should really call + * desc.update_steps () + * instead of manually assigning steps. Yet, VST prop is (again) + * the odd one out compared to other plugin formats. + */ + if (_parameter_defaults.find (which) == _parameter_defaults.end ()) { _parameter_defaults[which] = get_parameter (which); } else { @@ -535,20 +567,24 @@ VSTPlugin::do_save_preset (string name) string const uri = string_compose (X_("VST:%1:x%2"), unique_id (), hash); if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { - p = new XMLNode (X_("ChunkPreset")); - p->set_property (X_("uri"), uri); - p->set_property (X_("label"), name); + } else { + p = new XMLNode (X_("Preset")); + } + + p->set_property (X_("uri"), uri); + p->set_property (X_("version"), version ()); + p->set_property (X_("label"), name); + p->set_property (X_("numParams"), parameter_count ()); + + if (_plugin->flags & 32) { + gchar* data = get_chunk (true); p->add_content (string (data)); g_free (data); } else { - p = new XMLNode (X_("Preset")); - p->set_property (X_("uri"), uri); - p->set_property (X_("label"), name); - for (uint32_t i = 0; i < parameter_count(); ++i) { if (parameter_is_input (i)) { XMLNode* c = new XMLNode (X_("Parameter")); @@ -606,7 +642,7 @@ VSTPlugin::describe_parameter (Evoral::Parameter param) return name; } -framecnt_t +samplecnt_t VSTPlugin::signal_latency () const { if (_user_latency) { @@ -634,9 +670,9 @@ VSTPlugin::automatable () const int VSTPlugin::connect_and_run (BufferSet& bufs, - framepos_t start, framepos_t end, double speed, - ChanMapping in_map, ChanMapping out_map, - pframes_t nframes, framecnt_t offset) + samplepos_t start, samplepos_t end, double speed, + ChanMapping const& in_map, ChanMapping const& out_map, + pframes_t nframes, samplecnt_t offset) { Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset); @@ -650,7 +686,7 @@ VSTPlugin::connect_and_run (BufferSet& bufs, return 0; } - _transport_frame = start; + _transport_sample = start; _transport_speed = speed; ChanCount bufs_count; @@ -698,6 +734,7 @@ VSTPlugin::connect_and_run (BufferSet& bufs, VstEvents* v = 0; bool valid = false; const uint32_t buf_index_in = in_map.get(DataType::MIDI, 0, &valid); + /* TODO: apply offset to MIDI buffer and trim at nframes */ if (valid) { v = bufs.get_vst_midi (buf_index_in); } @@ -705,7 +742,8 @@ VSTPlugin::connect_and_run (BufferSet& bufs, const uint32_t buf_index_out = out_map.get(DataType::MIDI, 0, &valid); if (valid) { _midi_out_buf = &bufs.get_midi(buf_index_out); - _midi_out_buf->silence(0, 0); + /* TODO: apply offset to MIDI buffer and trim at nframes */ + _midi_out_buf->silence(nframes, offset); } else { _midi_out_buf = 0; } @@ -754,6 +792,12 @@ VSTPlugin::label () const return _handle->name; } +int32_t +VSTPlugin::version () const +{ + return _plugin->version; +} + uint32_t VSTPlugin::parameter_count () const { @@ -796,7 +840,8 @@ VSTPlugin::find_presets () int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0); for (int i = 0; i < _plugin->numPrograms; ++i) { - PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", false); + + PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), std::setw(4), std::setfill('0'), i), "", false); if (vst_version >= 2) { char buf[256]; @@ -878,3 +923,31 @@ VSTPlugin::presets_file () const return string("vst-") + unique_id (); } + +VSTPluginInfo::VSTPluginInfo (VSTInfo* nfo) +{ + + char buf[32]; + snprintf (buf, sizeof (buf), "%d", nfo->UniqueID); + unique_id = buf; + + index = 0; + + name = nfo->name; + creator = nfo->creator; + n_inputs.set_audio (nfo->numInputs); + n_outputs.set_audio (nfo->numOutputs); + n_inputs.set_midi ((nfo->wantMidi & 1) ? 1 : 0); + n_outputs.set_midi ((nfo->wantMidi & 2) ? 1 : 0); + + _is_instrument = nfo->isInstrument; +} + +bool +VSTPluginInfo::is_instrument () const +{ + if (_is_instrument) { + return true; + } + return PluginInfo::is_instrument (); +}