2 Copyright (C) 2000,2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sigc++/bind.h>
24 #include <pbd/failed_constructor.h>
25 #include <pbd/xml++.h>
27 #include <ardour/port_insert.h>
28 #include <ardour/plugin.h>
29 #include <ardour/port.h>
30 #include <ardour/route.h>
31 #include <ardour/buffer_set.h>
33 #include <ardour/audioengine.h>
34 #include <ardour/session.h>
35 #include <ardour/types.h>
40 using namespace ARDOUR;
43 PortInsert::PortInsert (Session& s, Placement p)
44 : IOProcessor (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
47 ProcessorCreated (this); /* EMIT SIGNAL */
53 if (_io->add_input_port ("", this)) {
54 error << _("PortInsert: cannot add input port") << endmsg;
55 throw failed_constructor();
58 if (_io->add_output_port ("", this)) {
59 error << _("PortInsert: cannot add output port") << endmsg;
60 throw failed_constructor();
64 PortInsert::PortInsert (Session& s, const XMLNode& node)
65 : IOProcessor (s, "unnamed port insert", PreFader)
67 if (set_state (node)) {
68 throw failed_constructor();
71 ProcessorCreated (this); /* EMIT SIGNAL */
74 PortInsert::~PortInsert ()
80 PortInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
82 if (_io->n_outputs().n_total() == 0) {
88 _io->silence (nframes, offset);
92 _io->deliver_output(bufs, start_frame, end_frame, nframes, offset);
94 _io->collect_input(bufs, nframes, offset);
98 PortInsert::get_state(void)
104 PortInsert::state (bool full)
106 XMLNode& node = IOProcessor::state(full);
108 node.add_property ("type", "port");
109 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
110 node.add_property ("bitslot", buf);
116 PortInsert::set_state(const XMLNode& node)
118 XMLNodeList nlist = node.children();
119 XMLNodeIterator niter;
120 XMLPropertyList plist;
121 const XMLProperty *prop;
123 if ((prop = node.property ("type")) == 0) {
124 error << _("XML node describing port insert is missing the `type' field") << endmsg;
128 if (prop->value() != "port") {
129 error << _("non-port insert XML used for port plugin insert") << endmsg;
133 if ((prop = node.property ("bitslot")) == 0) {
134 bitslot = _session.next_insert_id();
136 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
137 _session.mark_insert_id (bitslot);
140 const XMLNode* insert_node = &node;
142 // legacy sessions: search for child IOProcessor node
143 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
144 if ((*niter)->name() == "IOProcessor") {
145 insert_node = *niter;
150 IOProcessor::set_state (*insert_node);
156 PortInsert::signal_latency() const
158 /* because we deliver and collect within the same cycle,
159 all I/O is necessarily delayed by at least frames_per_cycle().
161 if the return port for insert has its own latency, we
162 need to take that into account too.
165 return _session.engine().frames_per_cycle() + _io->input_latency();
169 PortInsert::configure_io (ChanCount in, ChanCount out)
171 /* do not allow configuration to be changed outside the range of
172 the last request config. or something like that.
175 /* this is a bit odd:
177 the number of inputs we are required to handle corresponds
178 to the number of output ports we need.
180 the number of outputs we are required to have corresponds
181 to the number of input ports we need.
184 _io->set_output_maximum (in);
185 _io->set_output_minimum (in);
186 _io->set_input_maximum (out);
187 _io->set_input_minimum (out);
189 if (_io->ensure_io (out, in, false, this) != 0) {
193 return Processor::configure_io (in, out);
197 PortInsert::output_streams() const
199 return _io->n_inputs ();
203 PortInsert::input_streams() const
205 return _io->n_outputs ();
209 PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const