along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
#include <string>
#include <ardour/port.h>
#include <ardour/route.h>
#include <ardour/ladspa_plugin.h>
+
+#ifdef HAVE_SLV2
+#include <ardour/lv2_plugin.h>
+#endif
+
+#ifdef VST_SUPPORT
#include <ardour/vst_plugin.h>
+#endif
+
+#ifdef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
+
#include <ardour/audioengine.h>
#include <ardour/session.h>
+#include <ardour/types.h>
#include "i18n.h"
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
-Insert::Insert(Session& s, Placement p)
- : Redirect (s, s.next_insert_name(), p)
-{
-}
-
-
-Insert::Insert(Session& s, Placement p, int imin, int imax, int omin, int omax)
- : Redirect (s, s.next_insert_name(), p, imin, imax, omin, omax)
+Insert::Insert(Session& s, string name, Placement p)
+ : Redirect (s, name, p)
{
}
-Insert::Insert(Session& s, string name, Placement p)
- : Redirect (s, name, p)
+Insert::Insert(Session& s, string name, Placement p, int imin, int imax, int omin, int omax)
+ : Redirect (s, name, p, imin, imax, omin, omax)
{
}
const string PluginInsert::port_automation_node_name = "PortAutomation";
-PluginInsert::PluginInsert (Session& s, Plugin& plug, Placement placement)
- : Insert (s, plug.name(), placement)
+PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placement placement)
+ : Insert (s, plug->name(), placement)
{
/* the first is the master */
- _plugins.push_back(&plug);
+ _plugins.push_back (plug);
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
init ();
- save_state (_("initial state"));
-
- {
- LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__);
+ if (_plugins[0]->fixed_io()) {
+ Glib::Mutex::Lock em (_session.engine().process_lock());
IO::MoreOutputs (output_streams ());
}
set_automatable ();
- save_state (_("initial state"));
-
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
- {
- LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__);
+ if (_plugins[0]->fixed_io()) {
+ Glib::Mutex::Lock em (_session.engine().process_lock());
IO::MoreOutputs (output_streams());
}
}
PluginInsert::PluginInsert (const PluginInsert& other)
- : Insert (other._session, other.plugin().name(), other.placement())
+ : Insert (other._session, other.plugin()->name(), other.placement())
{
uint32_t count = other._plugins.size();
/* make as many copies as requested */
for (uint32_t n = 0; n < count; ++n) {
- _plugins.push_back (plugin_factory (other.plugin()));
+ _plugins.push_back (plugin_factory (other.plugin (n)));
}
init ();
- save_state (_("initial state"));
-
RedirectCreated (this); /* EMIT SIGNAL */
}
uint32_t diff = num - _plugins.size();
for (uint32_t n = 0; n < diff; ++n) {
- _plugins.push_back (plugin_factory (*_plugins[0]));
+ _plugins.push_back (plugin_factory (_plugins[0]));
if (require_state) {
/* XXX do something */
} else if (num < _plugins.size()) {
uint32_t diff = _plugins.size() - num;
for (uint32_t n= 0; n < diff; ++n) {
- Plugin * plug = _plugins.back();
_plugins.pop_back();
- delete plug;
}
}
PluginInsert::~PluginInsert ()
{
- GoingAway (this); /* EMIT SIGNAL */
-
- while (!_plugins.empty()) {
- Plugin* p = _plugins.back();
- _plugins.pop_back();
- delete p;
- }
+ GoingAway (); /* EMIT SIGNAL */
}
void
PluginInsert::automation_list_creation_callback (uint32_t which, AutomationList& alist)
{
- alist.automation_state_changed.connect (sigc::bind (mem_fun (*this, &PluginInsert::auto_state_changed), (which)));
+ alist.automation_state_changed.connect (sigc::bind (mem_fun (*this, &PluginInsert::auto_state_changed), (which)));
}
void
uint32_t
PluginInsert::output_streams() const
{
- return _plugins[0]->get_info().n_outputs * _plugins.size();
+ int32_t out = _plugins[0]->get_info()->n_outputs;
+
+ if (out < 0) {
+ return _plugins[0]->output_streams ();
+ } else {
+ return out * _plugins.size();
+ }
}
uint32_t
PluginInsert::input_streams() const
{
- return _plugins[0]->get_info().n_inputs * _plugins.size();
+ int32_t in = _plugins[0]->get_info()->n_inputs;
+ if (in < 0) {
+ return _plugins[0]->input_streams ();
+ } else {
+ return in * _plugins.size();
+ }
}
uint32_t
PluginInsert::natural_output_streams() const
{
- return _plugins[0]->get_info().n_outputs;
+ return _plugins[0]->get_info()->n_outputs;
}
uint32_t
PluginInsert::natural_input_streams() const
{
- return _plugins[0]->get_info().n_inputs;
+ return _plugins[0]->get_info()->n_inputs;
}
bool
a specific "instrument" flag, for example.
*/
- return _plugins[0]->get_info().n_inputs == 0;
+ return _plugins[0]->get_info()->n_inputs == 0;
}
void
void
PluginInsert::parameter_changed (uint32_t which, float val)
{
- vector<Plugin*>::iterator i = _plugins.begin();
+ vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin();
/* don't set the first plugin, just all the slaves */
}
void
-PluginInsert::set_block_size (jack_nframes_t nframes)
+PluginInsert::set_block_size (nframes_t nframes)
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->set_block_size (nframes);
}
}
void
PluginInsert::activate ()
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->activate ();
}
}
void
PluginInsert::deactivate ()
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->deactivate ();
}
}
void
-PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now)
+PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now)
{
int32_t in_index = 0;
int32_t out_index = 0;
}
}
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->connect_and_run (bufs, nbufs, in_index, out_index, nframes, offset);
}
}
void
-PluginInsert::automation_snapshot (jack_nframes_t now)
+PluginInsert::automation_snapshot (nframes_t now)
{
map<uint32_t,AutomationList*>::iterator li;
-
+
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
- AutomationList& alist (*((*li).second));
- if (alist.automation_write ()) {
+ AutomationList *alist = ((*li).second);
+ if (alist != 0 && alist->automation_write ()) {
float val = _plugins[0]->get_parameter ((*li).first);
- alist.rt_add (now, val);
+ alist->rt_add (now, val);
last_automation_snapshot = now;
}
}
}
void
-PluginInsert::transport_stopped (jack_nframes_t now)
+PluginInsert::transport_stopped (nframes_t now)
{
map<uint32_t,AutomationList*>::iterator li;
}
void
-PluginInsert::silence (jack_nframes_t nframes, jack_nframes_t offset)
+PluginInsert::silence (nframes_t nframes, nframes_t offset)
{
int32_t in_index = 0;
int32_t out_index = 0;
uint32_t n;
if (active()) {
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- n = (*i) -> get_info().n_inputs;
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ n = (*i) -> get_info()->n_inputs;
(*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, offset);
}
}
}
void
-PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset)
+PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
{
if (active()) {
connect_and_run (bufs, nbufs, nframes, offset, false);
}
} else {
- uint32_t in = _plugins[0]->get_info().n_inputs;
- uint32_t out = _plugins[0]->get_info().n_outputs;
-
- if (out > in) {
+ uint32_t in = _plugins[0]->get_info()->n_inputs;
+ uint32_t out = _plugins[0]->get_info()->n_outputs;
- /* not active, but something has make up for any channel count increase */
+ if (in < 0 || out < 0) {
- for (uint32_t n = out - in; n < out; ++n) {
- memcpy (bufs[n], bufs[in - 1], sizeof (Sample) * nframes);
+ } else {
+
+ if (out > in) {
+
+ /* not active, but something has make up for any channel count increase */
+
+ for (uint32_t n = out - in; n < out; ++n) {
+ memcpy (bufs[n], bufs[in - 1], sizeof (Sample) * nframes);
+ }
}
}
}
}
void
-PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset)
+PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
{
ControlEvent next_event (0, 0.0f);
- jack_nframes_t now = _session.transport_frame ();
- jack_nframes_t end = now + nframes;
+ nframes_t now = _session.transport_frame ();
+ nframes_t end = now + nframes;
- TentativeLockMonitor lm (_automation_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (_automation_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
connect_and_run (bufs, nbufs, nframes, offset, false);
while (nframes) {
- jack_nframes_t cnt = min (((jack_nframes_t) floor (next_event.when) - now), nframes);
+ nframes_t cnt = min (((nframes_t) ceil (next_event.when) - now), nframes);
connect_and_run (bufs, nbufs, cnt, offset, true, now);
if (s != al.automation_state()) {
al.set_automation_state (s);
- last_automation_snapshot = 0;
_session.set_dirty ();
}
}
switch (al.automation_state()) {
case Write:
- case Touch:
al.set_automation_state (Off);
break;
+ case Touch:
+ al.set_automation_state (Play);
+ break;
default:
break;
}
}
}
-Plugin*
-PluginInsert::plugin_factory (Plugin& other)
+boost::shared_ptr<Plugin>
+PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
{
- LadspaPlugin* lp;
+ boost::shared_ptr<LadspaPlugin> lp;
+#ifdef HAVE_SLV2
+ boost::shared_ptr<LV2Plugin> lv2p;
+#endif
#ifdef VST_SUPPORT
- VSTPlugin* vp;
+ boost::shared_ptr<VSTPlugin> vp;
+#endif
+#ifdef HAVE_AUDIOUNITS
+ boost::shared_ptr<AUPlugin> ap;
#endif
- if ((lp = dynamic_cast<LadspaPlugin*> (&other)) != 0) {
- return new LadspaPlugin (*lp);
+ if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
+#ifdef HAVE_SLV2
+ } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
+#endif
#ifdef VST_SUPPORT
- } else if ((vp = dynamic_cast<VSTPlugin*> (&other)) != 0) {
- return new VSTPlugin (*vp);
+ } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new VSTPlugin (*vp));
+#endif
+#ifdef HAVE_AUDIOUNITS
+ } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
#endif
}
X_("unknown plugin type in PluginInsert::plugin_factory"))
<< endmsg;
/*NOTREACHED*/
- return 0;
+ return boost::shared_ptr<Plugin> ((Plugin*) 0);
}
int32_t
PluginInsert::compute_output_streams (int32_t cnt) const
{
- return _plugins[0]->get_info().n_outputs * cnt;
+ int32_t outputs;
+
+ if ((outputs = _plugins[0]->get_info()->n_outputs) < 0) {
+ // have to ask the plugin itself, because it has flexible I/O
+ return _plugins[0]->compute_output_streams (cnt);
+ }
+
+ return outputs * cnt;
}
int32_t
int32_t
PluginInsert::can_support_input_configuration (int32_t in) const
{
- int32_t outputs = _plugins[0]->get_info().n_outputs;
- int32_t inputs = _plugins[0]->get_info().n_inputs;
+ int32_t outputs = _plugins[0]->get_info()->n_outputs;
+ int32_t inputs = _plugins[0]->get_info()->n_inputs;
+
+ if (outputs < 0 || inputs < 0) {
+ /* have to ask the plugin because its got reconfigurable I/O
+ */
+ return _plugins[0]->can_support_input_configuration (in);
+ }
if (inputs == 0) {
node->add_child_nocopy (Redirect::state (full));
node->add_property ("type", _plugins[0]->state_node_name());
- snprintf(buf, sizeof(buf), "%s", _plugins[0]->name());
- node->add_property("id", string(buf));
- if (_plugins[0]->state_node_name() == "ladspa") {
- char buf[32];
- snprintf (buf, 31, "%d", _plugins[0]->get_info().unique_id);
- node->add_property("unique-id", string(buf));
- }
+ node->add_property("unique-id", _plugins[0]->unique_id());
node->add_property("count", string_compose("%1", _plugins.size()));
node->add_child_nocopy (_plugins[0]->get_state());
+ /* add controllables */
+
+ XMLNode* control_node = new XMLNode (X_("controls"));
+
+ for (uint32_t x = 0; x < _plugins[0]->parameter_count(); ++x) {
+ Controllable* c = _plugins[0]->get_nth_control (x, true);
+ if (c) {
+ XMLNode& controllable_state (c->get_state());
+ controllable_state.add_property ("parameter", to_string (x, std::dec));
+ control_node->add_child_nocopy (controllable_state);
+ }
+ }
+ node->add_child_nocopy (*control_node);
+
/* add port automation state */
XMLNode *autonode = new XMLNode(port_automation_node_name);
set<uint32_t> automatable = _plugins[0]->automatable();
XMLNode* child = new XMLNode("port");
snprintf(buf, sizeof(buf), "%" PRIu32, *x);
child->add_property("number", string(buf));
-
- if (full) {
- snprintf(buf, sizeof(buf), "0x%x", automation_list (*x).automation_state ());
- } else {
- snprintf(buf, sizeof(buf), "0x%x", ARDOUR::Off);
- }
- child->add_property("auto", string(buf));
-
+
+ child->add_child_nocopy (automation_list (*x).state (full));
autonode->add_child_nocopy (*child);
}
XMLNodeIterator niter;
XMLPropertyList plist;
const XMLProperty *prop;
- long unique = 0;
- PluginInfo::Type type;
+ ARDOUR::PluginType type;
if ((prop = node.property ("type")) == 0) {
error << _("XML node describing insert is missing the `type' field") << endmsg;
}
if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
- type = PluginInfo::LADSPA;
+ type = ARDOUR::LADSPA;
+ } else if (prop->value() == X_("lv2")) {
+ type = ARDOUR::LV2;
} else if (prop->value() == X_("vst")) {
- type = PluginInfo::VST;
+ type = ARDOUR::VST;
+ } else if (prop->value() == X_("audiounit")) {
+ type = ARDOUR::AudioUnit;
} else {
error << string_compose (_("unknown plugin type %1 in plugin insert state"),
prop->value())
}
prop = node.property ("unique-id");
- if (prop != 0) {
- unique = atol(prop->value().c_str());
- }
+ if (prop == 0) {
+#ifdef VST_SUPPORT
+ /* older sessions contain VST plugins with only an "id" field.
+ */
+
+ if (type == ARDOUR::VST) {
+ if (prop = node.property ("id")) {
+ }
+ }
+#endif
+ /* recheck */
- if ((prop = node.property ("id")) == 0) {
- error << _("XML node describing insert is missing the `id' field") << endmsg;
- return -1;
+ if (prop == 0) {
+ error << _("Plugin has no unique ID field") << endmsg;
+ return -1;
+ }
}
- Plugin* plugin;
+ boost::shared_ptr<Plugin> plugin;
- if (unique != 0) {
- plugin = find_plugin (_session, "", unique, type);
- } else {
- plugin = find_plugin (_session, prop->value(), 0, type);
- }
+ plugin = find_plugin (_session, prop->value(), type);
if (plugin == 0) {
error << string_compose(_("Found a reference to a plugin (\"%1\") that is unknown.\n"
_plugins.push_back (plugin);
for (uint32_t n=1; n < count; ++n) {
- _plugins.push_back (plugin_factory (*plugin));
+ _plugins.push_back (plugin_factory (plugin));
}
}
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == plugin->state_node_name()) {
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->set_state (**niter);
}
break;
}
}
+ if (niter == nlist.end()) {
+ error << string_compose(_("XML node describing a plugin insert is missing the `%1' information"), plugin->state_node_name()) << endmsg;
+ return -1;
+ }
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == Redirect::state_node_name) {
Redirect::set_state (**niter);
return -1;
}
- if (niter == nlist.end()) {
- error << string_compose(_("XML node describing a plugin insert is missing the `%1' information"), plugin->state_node_name()) << endmsg;
- return -1;
- }
+ /* look for controllables node */
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ if ((*niter)->name() != X_("controls")) {
+ continue;
+ }
+
+ XMLNodeList grandchildren ((*niter)->children());
+ XMLProperty* prop;
+ XMLNodeIterator gciter;
+ uint32_t param;
+
+ for (gciter = grandchildren.begin(); gciter != grandchildren.end(); ++gciter) {
+ if ((prop = (*gciter)->property (X_("parameter"))) != 0) {
+ param = atoi (prop->value());
+ /* force creation of controllable for this parameter */
+ _plugins[0]->make_nth_control (param, **gciter);
+ }
+ }
+
+ break;
+ }
+
/* look for port automation node */
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- if ((*niter)->name() == port_automation_node_name) {
- XMLNodeList cnodes;
- XMLProperty *cprop;
- XMLNodeConstIterator iter;
- XMLNode *child;
- const char *port;
- uint32_t port_id;
-
- cnodes = (*niter)->children ("port");
-
- for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
-
- child = *iter;
-
- if ((cprop = child->property("number")) != 0) {
- port = cprop->value().c_str();
- } else {
- warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
- continue;
- }
- sscanf (port, "%" PRIu32, &port_id);
+ if ((*niter)->name() != port_automation_node_name) {
+ continue;
+ }
- if (port_id >= _plugins[0]->parameter_count()) {
- warning << _("PluginInsert: Auto: port id out of range") << endmsg;
- continue;
- }
-
+ XMLNodeList cnodes;
+ XMLProperty *cprop;
+ XMLNodeConstIterator iter;
+ XMLNode *child;
+ const char *port;
+ uint32_t port_id;
+
+ cnodes = (*niter)->children ("port");
+
+ for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
+
+ child = *iter;
+
+ if ((cprop = child->property("number")) != 0) {
+ port = cprop->value().c_str();
+ } else {
+ warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
+ continue;
+ }
+
+ sscanf (port, "%" PRIu32, &port_id);
+
+ if (port_id >= _plugins[0]->parameter_count()) {
+ warning << _("PluginInsert: Auto: port id out of range") << endmsg;
+ continue;
+ }
+
+ if (!child->children().empty()) {
+ automation_list (port_id).set_state (*child->children().front());
+ } else {
if ((cprop = child->property("auto")) != 0) {
+
+ /* old school */
+
int x;
sscanf (cprop->value().c_str(), "0x%x", &x);
automation_list (port_id).set_automation_state (AutoState (x));
+
+ } else {
+
+ /* missing */
+
+ automation_list (port_id).set_automation_state (Off);
}
}
-
- break;
+
}
+
+ /* done */
+
+ break;
}
if (niter == nlist.end()) {
}
// The name of the PluginInsert comes from the plugin, nothing else
- set_name(plugin->get_info().name,this);
+ set_name(plugin->get_info()->name,this);
return 0;
}
return _plugins[0]->describe_parameter (what);
}
-void
-PluginInsert::reset_midi_control (MIDI::Port* port, bool on)
-{
- _plugins[0]->reset_midi_control (port, on);
-}
-
-void
-PluginInsert::send_all_midi_feedback ()
-{
- _plugins[0]->send_all_midi_feedback();
-}
-
-jack_nframes_t
+nframes_t
PluginInsert::latency()
{
return _plugins[0]->latency ();
}
-void
-PluginInsert::store_state (PluginInsertState& state) const
-{
- Redirect::store_state (state);
- _plugins[0]->store_state (state.plugin_state);
-}
-
-Change
-PluginInsert::restore_state (StateManager::State& state)
-{
- PluginInsertState* pistate = dynamic_cast<PluginInsertState*> (&state);
-
- Redirect::restore_state (state);
-
- _plugins[0]->restore_state (pistate->plugin_state);
-
- return Change (0);
-}
-
-StateManager::State*
-PluginInsert::state_factory (std::string why) const
+ARDOUR::PluginType
+PluginInsert::type ()
{
- PluginInsertState* state = new PluginInsertState (why);
-
- store_state (*state);
+ boost::shared_ptr<LadspaPlugin> lp;
+#ifdef VST_SUPPORT
+ boost::shared_ptr<VSTPlugin> vp;
+#endif
+#ifdef HAVE_AUDIOUNITS
+ boost::shared_ptr<AUPlugin> ap;
+#endif
+
+ PluginPtr other = plugin ();
- return state;
+ if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
+ return ARDOUR::LADSPA;
+#ifdef VST_SUPPORT
+ } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
+ return ARDOUR::VST;
+#endif
+#ifdef HAVE_AUDIOUNITS
+ } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
+ return ARDOUR::AudioUnit;
+#endif
+ } else {
+ /* NOT REACHED */
+ return (ARDOUR::PluginType) 0;
+ }
}
/***************************************************************
***************************************************************/
PortInsert::PortInsert (Session& s, Placement p)
- : Insert (s, p, 1, -1, 1, -1)
+ : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
{
init ();
- save_state (_("initial state"));
RedirectCreated (this); /* EMIT SIGNAL */
+
}
PortInsert::PortInsert (const PortInsert& other)
- : Insert (other._session, other.placement(), 1, -1, 1, -1)
+ : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
{
init ();
- save_state (_("initial state"));
RedirectCreated (this); /* EMIT SIGNAL */
}
PortInsert::PortInsert (Session& s, const XMLNode& node)
: Insert (s, "will change", PreFader)
{
+ bitslot = 0xffffffff;
if (set_state (node)) {
throw failed_constructor();
}
PortInsert::~PortInsert ()
{
- GoingAway (this);
+ GoingAway ();
}
void
-PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset)
+PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
{
if (n_outputs() == 0) {
return;
for (o = _outputs.begin(), n = 0; o != _outputs.end(); ++o, ++n) {
memcpy ((*o)->get_buffer (nframes) + offset, bufs[min(nbufs,n)], sizeof (Sample) * nframes);
+ (*o)->mark_silence (false);
}
/* collect input */
PortInsert::state (bool full)
{
XMLNode *node = new XMLNode("Insert");
-
+ char buf[32];
node->add_child_nocopy (Redirect::state(full));
- node->add_property("type", "port");
+ node->add_property ("type", "port");
+ snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
+ node->add_property ("bitslot", buf);
return *node;
}
return -1;
}
+ if ((prop = node.property ("bitslot")) == 0) {
+ bitslot = _session.next_insert_id();
+ } else {
+ uint32_t old_bitslot = bitslot;
+ sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
+
+ if (old_bitslot != bitslot) {
+ _session.mark_insert_id (bitslot);
+ }
+ }
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == Redirect::state_node_name) {
Redirect::set_state (**niter);
return 0;
}
-jack_nframes_t
+nframes_t
PortInsert::latency()
{
/* because we deliver and collect within the same cycle,
{
return n_outputs ();
}
+