}
void
-VSTPlugin::set_parameter (uint32_t which, float val)
+VSTPlugin::set_parameter (uint32_t which, float newval)
{
- float v = get_parameter (which);
+ float oldval = get_parameter (which);
- cerr << name() << " setting parameter #" << which << " to " << val << " current " << v << " == ? " << (v == val) << " delta " << std::setprecision(15) << (v - val) << endl;
-
- if (PBD::floateq (get_parameter (which), val, 2)) {
+ if (PBD::floateq (oldval, newval, 1)) {
return;
}
- _plugin->setParameter (_plugin, which, val);
- Plugin::set_parameter (which, val);
+ _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
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) {
ret = 0;
}
+#endif
Plugin::set_state (node, version);
return ret;
/* old style */
char label[64];
- label[0] = '\0';
+ /* some VST plugins expect this buffer to be zero-filled */
+ memset (label, 0, sizeof (label));
_plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0);
-
+
desc.label = label;
desc.integer_step = false;
desc.lower = 0.0f;
string
VSTPlugin::describe_parameter (Evoral::Parameter param)
{
- char name[64] = "Unkown";
+ char name[64];
+ memset (name, 0, sizeof (name));
+
+ /* 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;
}
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
- float *ins[_plugin->numInputs];
- float *outs[_plugin->numOutputs];
- int32_t i;
+ ChanCount bufs_count;
+ bufs_count.set(DataType::AUDIO, 1);
+ bufs_count.set(DataType::MIDI, 1);
+
+ BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
+ BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
- const uint32_t nbufs = bufs.count().n_audio();
+ /* VC++ doesn't support the C99 extension that allows
+
+ typeName foo[variableDefiningSize];
+
+ Use alloca instead of dynamic array (rather than std::vector which
+ allocs on the heap) because this is realtime code.
+ */
+
+ float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*));
+ float** outs = (float**)alloca(_plugin->numInputs*sizeof(float*));
+
+ int32_t i;
- int in_index = 0;
+ uint32_t in_index = 0;
for (i = 0; i < (int32_t) _plugin->numInputs; ++i) {
- ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset;
- in_index++;
+ uint32_t index;
+ bool valid = false;
+ index = in_map.get(DataType::AUDIO, in_index++, &valid);
+ ins[i] = (valid)
+ ? bufs.get_audio(index).data(offset)
+ : silent_bufs.get_audio(0).data(offset);
}
- int out_index = 0;
+ uint32_t out_index = 0;
for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) {
- outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset;
- out_index++;
+ uint32_t index;
+ bool valid = false;
+ index = out_map.get(DataType::AUDIO, out_index++, &valid);
+ outs[i] = (valid)
+ ? bufs.get_audio(index).data(offset)
+ : scratch_bufs.get_audio(0).data(offset);
}
if (bufs.count().n_midi() > 0) {
}
/* we already know it can support processReplacing */
- _plugin->processReplacing (_plugin, ins, outs, nframes);
+ _plugin->processReplacing (_plugin, &ins[0], &outs[0], nframes);
return 0;
}