Merge branch 'master' into windows
[ardour.git] / libs / ardour / vst_plugin.cc
index 7c31dcff109a37188f0ca910c0805ff540c5c553..5eafe7a612664991ba3bf94639f0b4296e36fd3c 100644 (file)
@@ -23,6 +23,7 @@
 #include <glibmm/fileutils.h>
 #include <glibmm/miscutils.h>
 
+#include "pbd/floating.h"
 #include "pbd/locale_guard.h"
 #include "pbd/pathscanner.h"
 
@@ -99,10 +100,22 @@ VSTPlugin::get_parameter (uint32_t which) const
 }
 
 void 
-VSTPlugin::set_parameter (uint32_t which, float val)
+VSTPlugin::set_parameter (uint32_t which, float newval)
 {
-       _plugin->setParameter (_plugin, which, val);
-       Plugin::set_parameter (which, val);
+       float oldval = get_parameter (which);
+
+       if (PBD::floateq (oldval, newval, 1)) {
+               return;
+       }
+
+       _plugin->setParameter (_plugin, which, newval);
+       
+       float curval = get_parameter (which);
+
+       if (!PBD::floateq (curval, oldval, 1)) {
+               /* value has changed, follow rest of the notification path */
+               Plugin::set_parameter (which, newval);
+       }
 }
 
 uint32_t
@@ -184,14 +197,15 @@ int
 VSTPlugin::set_state (const XMLNode& node, int version)
 {
        LocaleGuard lg (X_("POSIX"));
+       int ret = -1;
 
        if (node.name() != state_node_name()) {
                error << _("Bad node sent to VSTPlugin::set_state") << endmsg;
                return 0;
        }
 
+#ifndef NO_PLUGIN_STATE
        XMLNode* child;
-       int ret = -1;
 
        if ((child = find_named_node (node, X_("chunk"))) != 0) {
 
@@ -224,6 +238,7 @@ VSTPlugin::set_state (const XMLNode& node, int version)
                ret = 0;
 
        }
+#endif
 
        Plugin::set_state (node, version);
        return ret;
@@ -282,10 +297,11 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
                /* old style */
 
                char label[64];
-               label[0] = '\0';
+               /* some VST plugins expect this buffer to be zero-filled */
+               memset (label, sizeof (label), 0);
 
                _plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0);
-
+               
                desc.label = label;
                desc.integer_step = false;
                desc.lower = 0.0f;
@@ -469,8 +485,17 @@ VSTPlugin::do_remove_preset (string name)
 string 
 VSTPlugin::describe_parameter (Evoral::Parameter param)
 {
-       char name[64] = "Unkown";
+       char name[64];
+       memset (name, sizeof (name), 0);
+
+       /* some VST plugins expect this buffer to be zero-filled */
+
        _plugin->dispatcher (_plugin, effGetParamName, param.id(), 0, name, 0);
+
+       if (name[0] == '\0') {
+               strcpy (name, _("Unknown"));
+       }
+
        return name;
 }
 
@@ -503,8 +528,9 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
 {
        Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
 
-       float *ins[_plugin->numInputs];
-       float *outs[_plugin->numOutputs];
+       // VC++ doesn't support this C99 extension. Use alloca instead of dynamic array (rather than std::vector which allocs on the heap)
+       float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*));
+       float** outs = (float**)alloca(_plugin->numInputs*sizeof(float*));
        int32_t i;
 
        const uint32_t nbufs = bufs.count().n_audio();
@@ -527,7 +553,7 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
        }
 
        /* we already know it can support processReplacing */
-       _plugin->processReplacing (_plugin, ins, outs, nframes);
+       _plugin->processReplacing (_plugin, &ins[0], &outs[0], nframes);
 
        return 0;
 }