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 : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
47 RedirectCreated (this); /* EMIT SIGNAL */
50 PortInsert::PortInsert (const PortInsert& other)
51 : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
54 RedirectCreated (this); /* EMIT SIGNAL */
60 if (add_input_port ("", this)) {
61 error << _("PortInsert: cannot add input port") << endmsg;
62 throw failed_constructor();
65 if (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 : Insert (s, "will change", PreFader)
74 if (set_state (node)) {
75 throw failed_constructor();
78 RedirectCreated (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 (n_outputs().get(_default_type) == 0) {
95 silence (nframes, offset);
99 deliver_output(bufs, start_frame, end_frame, nframes, offset);
101 collect_input(bufs, nframes, offset);
105 PortInsert::get_state(void)
111 PortInsert::state (bool full)
113 XMLNode *node = new XMLNode("Insert");
115 node->add_child_nocopy (Redirect::state(full));
116 node->add_property ("type", "port");
117 snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
118 node->add_property ("bitslot", buf);
124 PortInsert::set_state(const XMLNode& node)
126 XMLNodeList nlist = node.children();
127 XMLNodeIterator niter;
128 XMLPropertyList plist;
129 const XMLProperty *prop;
131 if ((prop = node.property ("type")) == 0) {
132 error << _("XML node describing insert is missing the `type' field") << endmsg;
136 if (prop->value() != "port") {
137 error << _("non-port insert XML used for port plugin insert") << endmsg;
141 if ((prop = node.property ("bitslot")) == 0) {
142 bitslot = _session.next_insert_id();
144 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
145 _session.mark_insert_id (bitslot);
148 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
149 if ((*niter)->name() == Redirect::state_node_name) {
150 Redirect::set_state (**niter);
155 if (niter == nlist.end()) {
156 error << _("XML node describing insert is missing a Redirect node") << endmsg;
164 PortInsert::latency()
166 /* because we deliver and collect within the same cycle,
167 all I/O is necessarily delayed by at least frames_per_cycle().
169 if the return port for insert has its own latency, we
170 need to take that into account too.
173 return _session.engine().frames_per_cycle() + input_latency();
177 PortInsert::can_support_input_configuration (ChanCount in) const
179 if (input_maximum() == ChanCount::INFINITE && output_maximum() == ChanCount::INFINITE) {
181 /* not configured yet */
183 return true; /* we can support anything the first time we're asked */
187 /* the "input" config for a port insert corresponds to how
188 many output ports it will have.
191 if (output_maximum() == in) {
201 PortInsert::output_for_input_configuration (ChanCount in) const
207 PortInsert::configure_io (ChanCount in, ChanCount out)
209 /* do not allow configuration to be changed outside the range of
210 the last request config. or something like that.
214 /* this is a bit odd:
216 the number of inputs we are required to handle corresponds
217 to the number of output ports we need.
219 the number of outputs we are required to have corresponds
220 to the number of input ports we need.
223 set_output_maximum (in);
224 set_output_minimum (in);
225 set_input_maximum (out);
226 set_input_minimum (out);
228 return (ensure_io (out, in, false, this) == 0);
232 PortInsert::output_streams() const
238 PortInsert::input_streams() const