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)
82 if (_io->n_outputs().n_total() == 0) {
88 _io->silence (nframes);
92 _io->deliver_output (bufs, start_frame, end_frame, nframes);
93 _io->collect_input (bufs, nframes);
97 PortInsert::get_state(void)
103 PortInsert::state (bool full)
105 XMLNode& node = IOProcessor::state(full);
107 node.add_property ("type", "port");
108 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
109 node.add_property ("bitslot", buf);
115 PortInsert::set_state(const XMLNode& node)
117 XMLNodeList nlist = node.children();
118 XMLNodeIterator niter;
119 XMLPropertyList plist;
120 const XMLProperty *prop;
122 if ((prop = node.property ("type")) == 0) {
123 error << _("XML node describing port insert is missing the `type' field") << endmsg;
127 if (prop->value() != "port") {
128 error << _("non-port insert XML used for port plugin insert") << endmsg;
132 if ((prop = node.property ("bitslot")) == 0) {
133 bitslot = _session.next_insert_id();
135 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
136 _session.mark_insert_id (bitslot);
139 const XMLNode* insert_node = &node;
141 // legacy sessions: search for child IOProcessor node
142 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
143 if ((*niter)->name() == "IOProcessor") {
144 insert_node = *niter;
149 IOProcessor::set_state (*insert_node);
155 PortInsert::signal_latency() const
157 /* because we deliver and collect within the same cycle,
158 all I/O is necessarily delayed by at least frames_per_cycle().
160 if the return port for insert has its own latency, we
161 need to take that into account too.
164 return _session.engine().frames_per_cycle() + _io->input_latency();
168 PortInsert::configure_io (ChanCount in, ChanCount out)
170 /* do not allow configuration to be changed outside the range of
171 the last request config. or something like that.
174 /* this is a bit odd:
176 the number of inputs we are required to handle corresponds
177 to the number of output ports we need.
179 the number of outputs we are required to have corresponds
180 to the number of input ports we need.
183 _io->set_output_maximum (in);
184 _io->set_output_minimum (in);
185 _io->set_input_maximum (out);
186 _io->set_input_minimum (out);
188 if (_io->ensure_io (out, in, false, this) != 0) {
192 return Processor::configure_io (in, out);
196 PortInsert::output_streams() const
198 return _io->n_inputs ();
202 PortInsert::input_streams() const
204 return _io->n_outputs ();
208 PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const