first part of fixing up send/return metering ; make send-controlling faders work...
[ardour.git] / libs / ardour / vst_plugin.cc
index cd2531d52296882feeb3abb9aa7e6794298ca8da..0aca13715010520b718ef59e4cebba257cc1ec8d 100644 (file)
 #include "pbd/pathscanner.h"
 #include "pbd/xml++.h"
 
-#include <vst/aeffectx.h>
+#include <fst.h>
 
 #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 "pbd/stl_delete.h"
 
@@ -82,7 +83,7 @@ VSTPlugin::VSTPlugin (AudioEngine& e, Session& session, FSTHandle* h)
 
        _plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f);
        
-       Plugin::setup_controls ();
+       // Plugin::setup_controls ();
 }
 
 VSTPlugin::VSTPlugin (const VSTPlugin &other)
@@ -94,8 +95,8 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
                throw failed_constructor();
        }
        _plugin = _fst->plugin;
-
-       Plugin::setup_controls ();
+       
+       // Plugin::setup_controls ();
 }
 
 VSTPlugin::~VSTPlugin ()
@@ -146,56 +147,31 @@ VSTPlugin::get_state()
        XMLNode *root = new XMLNode (state_node_name());
        LocaleGuard lg (X_("POSIX"));
 
+       if (_fst->current_program != -1) {
+               char buf[32];
+               snprintf (buf, sizeof (buf), "%d", _fst->current_program);
+               root->add_property ("current-program", buf);
+       }
+
        if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
 
                /* fetch the current chunk */
                
-               void* data;
+               guchar* data;
                long  data_size;
                
                if ((data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, 0, 0, &data, false)) == 0) {
                        return *root;
                }
 
-               /* save it to a file */
-
-               Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "vst");
-               struct stat sbuf;
-
-               sys::path user_vst_directory(user_config_directory());
-       
-               user_vst_directory /= "vst";
-               path = user_vst_directory.to_string();
-
-               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;
-                               }
-
-                       } else {
-
-                               warning << string_compose (_("cannot check VST chunk directory: %1"), strerror (errno))
-                                       << endmsg;
-                               return *root;
-                       }
-
-               } else if (!S_ISDIR (sbuf.st_mode)) {
-                       error << string_compose (_("%1 exists but is not a directory"), path)
-                             << endmsg;
-                       return *root;
-               }
-               
-               path = Glib::build_filename (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 {
@@ -226,11 +202,30 @@ VSTPlugin::set_state(const XMLNode& node)
                return 0;
        }
 
-       XMLNode* child;
+       const XMLProperty* prop;
 
-       if ((child = find_named_node (node, X_("chunks"))) != 0) {
+       if ((prop = node.property ("current-program")) != 0) {
+               _fst->current_program = atoi (prop->value());
+       }
 
-               return 0;
+       XMLNode* child;
+       int ret = -1;
+       
+       if ((child = find_named_node (node, X_("chunk"))) != 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) {
                
@@ -246,10 +241,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
@@ -259,6 +259,7 @@ 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)) {
 
@@ -348,10 +349,10 @@ 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;
 }
 
@@ -369,20 +370,22 @@ VSTPlugin::signal_latency () const
 #endif
 }
 
-set<uint32_t>
+set<Evoral::Parameter>
 VSTPlugin::automatable () const
 {
-       set<uint32_t> ret;
+       set<Evoral::Parameter> 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 (BufferSet& bufs, uint32_t& in_index, uint32_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];
@@ -474,11 +477,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;