/*
- 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
/* 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 ();
}
throw failed_constructor();
}
_plugin = _fst->plugin;
-
+
// Plugin::setup_controls ();
}
VSTPlugin::default_value (uint32_t port)
{
return 0;
-}
+}
void
VSTPlugin::set_parameter (uint32_t which, float val)
VSTPlugin::get_parameter (uint32_t which) const
{
return _plugin->getParameter (_plugin, which);
-
+
}
uint32_t
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 */
-
- sys::path user_vst_directory(user_config_directory());
- user_vst_directory /= "vst";
-
- try {
- sys::create_directories (user_vst_directory);
- }
- catch (const sys::filesystem_error& ex)
- {
- error << "Could not create user configuration directory" << endmsg;
- return *root;
- }
-
- sys::path file (user_vst_directory);
-
- file /= "something";
-
/* store information */
XMLNode* chunk_node = new XMLNode (X_("chunk"));
- chunk_node->add_property ("path", file.to_string());
-
+
+ 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");
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) {
_plugin->setParameter (_plugin, param, val);
}
- return 0;
+ /* program number is not knowable */
+
+ _fst->current_program = -1;
+
+ ret = 0;
+
}
- return -1;
+ return ret;
}
int
desc.min_unbound = false;
desc.max_unbound = false;
+ prop.flags = 0;
if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) {
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;
}
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];
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++;
}
/* we already know it can support processReplacing */
_plugin->processReplacing (_plugin, ins, outs, nframes);
-
+
return 0;
}
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 {
plugin->set_info(PluginInfoPtr(new VSTPluginInfo(*this)));
return plugin;
- }
+ }
catch (failed_constructor &err) {
return PluginPtr ((Plugin*) 0);