diff options
author | David Robillard <d@drobilla.net> | 2007-06-20 03:39:19 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-06-20 03:39:19 +0000 |
commit | 05184ed52ffcdcad3c071d4c99287f832f42b74b (patch) | |
tree | 567c1e66d0e7fb88ca772e006c6cfbbab7a39133 /libs/ardour/port_insert.cc | |
parent | 8ae580427987b4eefc102f3e801c1b76fdc74d48 (diff) |
Split PortInsert and PluginInsert into their own files.
git-svn-id: svn://localhost/ardour2/trunk@2026 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/port_insert.cc')
-rw-r--r-- | libs/ardour/port_insert.cc | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc new file mode 100644 index 0000000000..25234dbf77 --- /dev/null +++ b/libs/ardour/port_insert.cc @@ -0,0 +1,242 @@ +/* + Copyright (C) 2000,2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <string> + +#include <sigc++/bind.h> + +#include <pbd/failed_constructor.h> +#include <pbd/xml++.h> + +#include <ardour/port_insert.h> +#include <ardour/plugin.h> +#include <ardour/port.h> +#include <ardour/route.h> +#include <ardour/buffer_set.h> + +#include <ardour/audioengine.h> +#include <ardour/session.h> +#include <ardour/types.h> + +#include "i18n.h" + +using namespace std; +using namespace ARDOUR; +using namespace PBD; + +PortInsert::PortInsert (Session& s, Placement p) + : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1) +{ + init (); + RedirectCreated (this); /* EMIT SIGNAL */ +} + +PortInsert::PortInsert (const PortInsert& other) + : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1) +{ + init (); + RedirectCreated (this); /* EMIT SIGNAL */ +} + +void +PortInsert::init () +{ + if (add_input_port ("", this)) { + error << _("PortInsert: cannot add input port") << endmsg; + throw failed_constructor(); + } + + if (add_output_port ("", this)) { + error << _("PortInsert: cannot add output port") << endmsg; + throw failed_constructor(); + } +} + +PortInsert::PortInsert (Session& s, const XMLNode& node) + : Insert (s, "will change", PreFader) +{ + if (set_state (node)) { + throw failed_constructor(); + } + + RedirectCreated (this); /* EMIT SIGNAL */ +} + +PortInsert::~PortInsert () +{ + GoingAway (); +} + +void +PortInsert::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) +{ + if (n_outputs().get(_default_type) == 0) { + return; + } + + if (!active()) { + /* deliver silence */ + silence (nframes, offset); + return; + } + + deliver_output(bufs, start_frame, end_frame, nframes, offset); + + collect_input(bufs, nframes, offset); +} + +XMLNode& +PortInsert::get_state(void) +{ + return state (true); +} + +XMLNode& +PortInsert::state (bool full) +{ + XMLNode *node = new XMLNode("Insert"); + char buf[32]; + node->add_child_nocopy (Redirect::state(full)); + node->add_property ("type", "port"); + snprintf (buf, sizeof (buf), "%" PRIu32, bitslot); + node->add_property ("bitslot", buf); + + return *node; +} + +int +PortInsert::set_state(const XMLNode& node) +{ + XMLNodeList nlist = node.children(); + XMLNodeIterator niter; + XMLPropertyList plist; + const XMLProperty *prop; + + if ((prop = node.property ("type")) == 0) { + error << _("XML node describing insert is missing the `type' field") << endmsg; + return -1; + } + + if (prop->value() != "port") { + error << _("non-port insert XML used for port plugin insert") << endmsg; + return -1; + } + + if ((prop = node.property ("bitslot")) == 0) { + bitslot = _session.next_insert_id(); + } else { + sscanf (prop->value().c_str(), "%" PRIu32, &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); + break; + } + } + + if (niter == nlist.end()) { + error << _("XML node describing insert is missing a Redirect node") << endmsg; + return -1; + } + + return 0; +} + +ARDOUR::nframes_t +PortInsert::latency() +{ + /* because we deliver and collect within the same cycle, + all I/O is necessarily delayed by at least frames_per_cycle(). + + if the return port for insert has its own latency, we + need to take that into account too. + */ + + return _session.engine().frames_per_cycle() + input_latency(); +} + +bool +PortInsert::can_support_input_configuration (ChanCount in) const +{ + if (input_maximum() == ChanCount::INFINITE && output_maximum() == ChanCount::INFINITE) { + + /* not configured yet */ + + return true; /* we can support anything the first time we're asked */ + + } else { + + /* the "input" config for a port insert corresponds to how + many output ports it will have. + */ + + if (output_maximum() == in) { + + return true; + } + } + + return false; +} + +ChanCount +PortInsert::output_for_input_configuration (ChanCount in) const +{ + return in; +} + +bool +PortInsert::configure_io (ChanCount in, ChanCount out) +{ + /* do not allow configuration to be changed outside the range of + the last request config. or something like that. + */ + + + /* this is a bit odd: + + the number of inputs we are required to handle corresponds + to the number of output ports we need. + + the number of outputs we are required to have corresponds + to the number of input ports we need. + */ + + set_output_maximum (in); + set_output_minimum (in); + set_input_maximum (out); + set_input_minimum (out); + + return (ensure_io (out, in, false, this) == 0); +} + +ChanCount +PortInsert::output_streams() const +{ + return n_inputs (); +} + +ChanCount +PortInsert::input_streams() const +{ + return n_outputs (); +} + |