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 : Redirect (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
47 InsertCreated (this); /* EMIT SIGNAL */
50 PortInsert::PortInsert (const PortInsert& other)
51 : Redirect (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
54 InsertCreated (this); /* EMIT SIGNAL */
60 if (_io->add_input_port ("", this)) {
61 error << _("PortInsert: cannot add input port") << endmsg;
62 throw failed_constructor();
65 if (_io->add_output_port ("", this)) {
66 error << _("PortInsert: cannot add output port") << endmsg;
67 throw failed_constructor();
71 PortInsert::PortInsert (Session& s, const XMLNode& node)
72 : Redirect (s, "unnamed port insert", PreFader)
74 if (set_state (node)) {
75 throw failed_constructor();
78 InsertCreated (this); /* EMIT SIGNAL */
81 PortInsert::~PortInsert ()
87 PortInsert::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
89 if (_io->n_outputs().n_total() == 0) {
95 _io->silence (nframes, offset);
99 _io->deliver_output(bufs, start_frame, end_frame, nframes, offset);
101 _io->collect_input(bufs, nframes, offset);
105 PortInsert::get_state(void)
111 PortInsert::state (bool full)
113 XMLNode& node = Redirect::state(full);
115 node.add_property ("type", "port");
116 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
117 node.add_property ("bitslot", buf);
123 PortInsert::set_state(const XMLNode& node)
125 XMLNodeList nlist = node.children();
126 XMLNodeIterator niter;
127 XMLPropertyList plist;
128 const XMLProperty *prop;
130 if ((prop = node.property ("type")) == 0) {
131 error << _("XML node describing insert is missing the `type' field") << endmsg;
135 if (prop->value() != "port") {
136 error << _("non-port insert XML used for port plugin insert") << endmsg;
140 if ((prop = node.property ("bitslot")) == 0) {
141 bitslot = _session.next_insert_id();
143 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
144 _session.mark_insert_id (bitslot);
147 const XMLNode* insert_node = &node;
149 // legacy sessions: search for child Redirect node
150 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
151 if ((*niter)->name() == "Redirect") {
152 insert_node = *niter;
157 Redirect::set_state (*insert_node);
163 PortInsert::latency()
165 /* because we deliver and collect within the same cycle,
166 all I/O is necessarily delayed by at least frames_per_cycle().
168 if the return port for insert has its own latency, we
169 need to take that into account too.
172 return _session.engine().frames_per_cycle() + _io->input_latency();
176 PortInsert::can_support_input_configuration (ChanCount in) const
178 if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
180 /* not configured yet */
182 return true; /* we can support anything the first time we're asked */
186 /* the "input" config for a port insert corresponds to how
187 many output ports it will have.
190 if (_io->output_maximum() == in) {
200 PortInsert::output_for_input_configuration (ChanCount in) const
206 PortInsert::configure_io (ChanCount in, ChanCount out)
208 /* do not allow configuration to be changed outside the range of
209 the last request config. or something like that.
213 /* this is a bit odd:
215 the number of inputs we are required to handle corresponds
216 to the number of output ports we need.
218 the number of outputs we are required to have corresponds
219 to the number of input ports we need.
222 _io->set_output_maximum (in);
223 _io->set_output_minimum (in);
224 _io->set_input_maximum (out);
225 _io->set_input_minimum (out);
227 bool success = (_io->ensure_io (out, in, false, this) == 0);
230 return Insert::configure_io(in, out);
236 PortInsert::output_streams() const
238 return _io->n_inputs ();
242 PortInsert::input_streams() const
244 return _io->n_outputs ();