X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fvst_plugin.cc;h=80631ac840d35200c1f2e2a8abdff418304db332;hb=7d96960b162d25da87c388a3083775e8770bba56;hp=afba6b5cfbe8dc6e0bbf8754695d533d6c6d1b51;hpb=6532413fa6e8b2343569c0f8e0dc79569345ce28;p=ardour.git diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index afba6b5cfb..80631ac840 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 Paul Davis + Copyright (C) 2004 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,32 +20,37 @@ #include #include #include -#include +#include #include #include // so libraptor doesn't complain #include #include -#include // for memmove +#include // for memmove #include #include +#include +#include + #include #include -#include -#include -#include -#include +#include "pbd/compose.h" +#include "pbd/error.h" +#include "pbd/pathscanner.h" +#include "pbd/xml++.h" -#include +#include -#include -#include -#include -#include +#include "ardour/session.h" +#include "ardour/audioengine.h" +#include "ardour/filesystem_paths.h" +#include "ardour/vst_plugin.h" +#include "ardour/buffer_set.h" +#include "ardour/audio_buffer.h" -#include +#include "pbd/stl_delete.h" #include "i18n.h" #include @@ -69,16 +74,16 @@ VSTPlugin::VSTPlugin (AudioEngine& e, Session& session, FSTHandle* h) /* set rate and blocksize */ - _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, + _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) session.frame_rate()); - _plugin->dispatcher (_plugin, effSetBlockSize, 0, + _plugin->dispatcher (_plugin, effSetBlockSize, 0, session.get_block_size(), NULL, 0.0f); - + /* set program to zero */ _plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f); - - Plugin::setup_controls (); + + // Plugin::setup_controls (); } VSTPlugin::VSTPlugin (const VSTPlugin &other) @@ -91,13 +96,12 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other) } _plugin = _fst->plugin; - Plugin::setup_controls (); + // Plugin::setup_controls (); } VSTPlugin::~VSTPlugin () { deactivate (); - GoingAway (); /* EMIT SIGNAL */ fst_close (_fst); } @@ -113,20 +117,20 @@ float VSTPlugin::default_value (uint32_t port) { return 0; -} +} void VSTPlugin::set_parameter (uint32_t which, float val) { _plugin->setParameter (_plugin, which, val); - ParameterChanged (which, val); /* EMIT SIGNAL */ + //ParameterChanged (which, val); /* EMIT SIGNAL */ } float VSTPlugin::get_parameter (uint32_t which) const { return _plugin->getParameter (_plugin, which); - + } uint32_t @@ -141,57 +145,34 @@ VSTPlugin::get_state() { XMLNode *root = new XMLNode (state_node_name()); LocaleGuard lg (X_("POSIX")); - - if (_plugin->flags & effFlagsProgramChunks) { - - /* fetch the current chunk */ - - void* data; - long data_size; - - if ((data_size = _plugin->dispatcher (_plugin, effGetChunk, 0, 0, &data, false)) == 0) { - return *root; - } - /* save it to a file */ - - string path; - struct stat sbuf; - - path = getenv ("HOME"); - path += "/.ardour/vst"; + if (_fst->current_program != -1) { + char buf[32]; + snprintf (buf, sizeof (buf), "%d", _fst->current_program); + root->add_property ("current-program", buf); + } - if (stat (path.c_str(), &sbuf)) { - if (errno == ENOENT) { - if (g_mkdir_with_parents (path.c_str(), 0600)) { - error << string_compose (_("cannot create VST chunk directory: %1"), - strerror (errno)) - << endmsg; - return *root; - } + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { - } else { + /* fetch the current chunk */ - warning << string_compose (_("cannot check VST chunk directory: %1"), strerror (errno)) - << endmsg; - return *root; - } + guchar* data; + long data_size; - } else if (!S_ISDIR (sbuf.st_mode)) { - error << string_compose (_("%1 exists but is not a directory"), path) - << endmsg; + if ((data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, 0, 0, &data, false)) == 0) { return *root; } - - path += "something"; - + /* store information */ XMLNode* chunk_node = new XMLNode (X_("chunk")); - chunk_node->add_property ("path", path); - + + gchar * encoded_data = g_base64_encode (data, data_size); + chunk_node->add_content (encoded_data); + g_free (encoded_data); + root->add_child_nocopy (*chunk_node); - + } else { XMLNode* parameters = new XMLNode ("parameters"); @@ -220,14 +201,33 @@ VSTPlugin::set_state(const XMLNode& node) return 0; } + const XMLProperty* prop; + + if ((prop = node.property ("current-program")) != 0) { + _fst->current_program = atoi (prop->value()); + } + XMLNode* child; + int ret = -1; - if ((child = find_named_node (node, X_("chunks"))) != 0) { + if ((child = find_named_node (node, X_("chunk"))) != 0) { - return 0; + XMLPropertyList::const_iterator i; + XMLNodeList::const_iterator n; + int ret = -1; + + for (n = child->children ().begin (); n != child->children ().end (); ++n) { + if ((*n)->is_content ()) { + gsize chunk_size = 0; + guchar * data = g_base64_decode ((*n)->content ().c_str (), &chunk_size); + //cerr << "Dispatch setChunk for " << name() << endl; + ret = _plugin->dispatcher (_plugin, 24 /* effSetChunk */, 0, chunk_size, data, 0); + g_free (data); + } + } } else if ((child = find_named_node (node, X_("parameters"))) != 0) { - + XMLPropertyList::const_iterator i; for (i = child->properties().begin(); i != child->properties().end(); ++i) { @@ -240,10 +240,15 @@ VSTPlugin::set_state(const XMLNode& node) _plugin->setParameter (_plugin, param, val); } - return 0; + /* program number is not knowable */ + + _fst->current_program = -1; + + ret = 0; + } - return -1; + return ret; } int @@ -253,9 +258,12 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) desc.min_unbound = false; desc.max_unbound = false; + prop.flags = 0; if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) { +#ifdef VESTIGE_COMPLETE + /* i have yet to find or hear of a VST plugin that uses this */ if (prop.flags & kVstParameterUsesIntegerMinMax) { @@ -265,32 +273,33 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) desc.lower = 0; desc.upper = 1.0; } - + if (prop.flags & kVstParameterUsesIntStep) { - + desc.step = prop.stepInteger; desc.smallstep = prop.stepInteger; desc.largestep = prop.stepInteger; - + } else if (prop.flags & kVstParameterUsesFloatStep) { - + desc.step = prop.stepFloat; desc.smallstep = prop.smallStepFloat; desc.largestep = prop.largeStepFloat; - + } 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.toggled = prop.flags & kVstParameterIsSwitch; desc.logarithmic = false; desc.sr_dependent = false; desc.label = prop.label; +#endif } else { @@ -319,7 +328,7 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) bool VSTPlugin::load_preset (string name) { - if (_plugin->flags & effFlagsProgramChunks) { + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { error << _("no support for presets using chunks at this time") << endmsg; return false; @@ -330,7 +339,7 @@ VSTPlugin::load_preset (string name) bool VSTPlugin::save_preset (string name) { - if (_plugin->flags & effFlagsProgramChunks) { + if (_plugin->flags & 32 /* effFlagsProgramsChunks */) { error << _("no support for presets using chunks at this time") << endmsg; return false; @@ -339,51 +348,63 @@ VSTPlugin::save_preset (string name) } string -VSTPlugin::describe_parameter (uint32_t param) +VSTPlugin::describe_parameter (Evoral::Parameter param) { char name[64]; - _plugin->dispatcher (_plugin, effGetParamName, param, 0, name, 0); + _plugin->dispatcher (_plugin, effGetParamName, param.id(), 0, name, 0); return name; } nframes_t -VSTPlugin::latency () const +VSTPlugin::signal_latency () const { - return _plugin->initialDelay; + if (_user_latency) { + return _user_latency; + } + +#ifdef VESTIGE_HEADER + return *((nframes_t *) (((char *) &_plugin->flags) + 12)); /* initialDelay */ +#else + return _plugin->initial_delay; +#endif } -set +set VSTPlugin::automatable () const { - set ret; + set ret; for (uint32_t i = 0; i < parameter_count(); ++i){ - ret.insert (ret.end(), i); + ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i)); } return ret; } int -VSTPlugin::connect_and_run (vector& bufs, uint32_t maxbuf, int32_t& in_index, int32_t& out_index, nframes_t nframes, nframes_t offset) +VSTPlugin::connect_and_run (BufferSet& bufs, + ChanMapping in_map, ChanMapping out_map, + nframes_t nframes, nframes_t offset) { float *ins[_plugin->numInputs]; float *outs[_plugin->numOutputs]; int32_t i; + const uint32_t nbufs = bufs.count().n_audio(); + for (i = 0; i < (int32_t) _plugin->numInputs; ++i) { - ins[i] = bufs[min((uint32_t) in_index,maxbuf - 1)] + offset; + ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset; in_index++; } for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) { - outs[i] = bufs[min((uint32_t) out_index,maxbuf - 1)] + offset; + outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset; /* unbelievably, several VST plugins still rely on Cubase - behaviour and do not silence the buffer in processReplacing + behaviour and do not silence the buffer in processReplacing when they have no output. */ - + // memset (outs[i], 0, sizeof (Sample) * nframes); out_index++; } @@ -392,7 +413,7 @@ VSTPlugin::connect_and_run (vector& bufs, uint32_t maxbuf, int32_t& in_ /* we already know it can support processReplacing */ _plugin->processReplacing (_plugin, ins, outs, nframes); - + return 0; } @@ -408,10 +429,17 @@ VSTPlugin::activate () _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f); } -uint32_t +string VSTPlugin::unique_id() const { - return _plugin->uniqueID; + char buf[32]; + +#ifdef VESTIGE_HEADER + snprintf (buf, sizeof (buf), "%d", *((int32_t*) &_plugin->unused_id)); +#else + snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID); +#endif + return string (buf); } @@ -448,11 +476,9 @@ VSTPlugin::has_editor () const void VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const { - char lab[9]; char *first_nonws; - _plugin->dispatcher (_plugin, effGetParamLabel, param, 0, lab, 0); - _plugin->dispatcher (_plugin, effGetParamDisplay, param, 0, buf, 0); + _plugin->dispatcher (_plugin, 7 /* effGetParamDisplay */, param, 0, buf, 0); if (buf[0] == '\0') { return; @@ -477,9 +503,9 @@ VSTPluginInfo::load (Session& session) if (Config->get_use_vst()) { FSTHandle* handle; - + handle = fst_load(path.c_str()); - + if ( (int)handle == -1) { error << string_compose(_("VST: cannot load module from \"%1\""), path) << endmsg; } else { @@ -492,7 +518,7 @@ VSTPluginInfo::load (Session& session) plugin->set_info(PluginInfoPtr(new VSTPluginInfo(*this))); return plugin; - } + } catch (failed_constructor &err) { return PluginPtr ((Plugin*) 0);