Files
ardour/libs/ardour/port_insert.cc
Carl Hetherington 9a3734a6bd Make DnD copy processors using their XML representations. Remove unused
copy constructors from the Processor hierarchy, and declare them private
to explicitly disallow copy construction.


git-svn-id: svn://localhost/ardour2/branches/3.0@4556 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-02-14 19:45:30 +00:00

214 lines
4.8 KiB
C++

/*
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)
: IOProcessor (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
{
init ();
ProcessorCreated (this); /* EMIT SIGNAL */
}
void
PortInsert::init ()
{
if (_io->add_input_port ("", this)) {
error << _("PortInsert: cannot add input port") << endmsg;
throw failed_constructor();
}
if (_io->add_output_port ("", this)) {
error << _("PortInsert: cannot add output port") << endmsg;
throw failed_constructor();
}
}
PortInsert::PortInsert (Session& s, const XMLNode& node)
: IOProcessor (s, "unnamed port insert", PreFader)
{
if (set_state (node)) {
throw failed_constructor();
}
ProcessorCreated (this); /* EMIT SIGNAL */
}
PortInsert::~PortInsert ()
{
GoingAway ();
}
void
PortInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
{
if (_io->n_outputs().n_total() == 0) {
return;
}
if (!active()) {
/* deliver silence */
_io->silence (nframes, offset);
return;
}
_io->deliver_output(bufs, start_frame, end_frame, nframes, offset);
_io->collect_input(bufs, nframes, offset);
}
XMLNode&
PortInsert::get_state(void)
{
return state (true);
}
XMLNode&
PortInsert::state (bool full)
{
XMLNode& node = IOProcessor::state(full);
char buf[32];
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 port 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);
}
const XMLNode* insert_node = &node;
// legacy sessions: search for child IOProcessor node
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == "IOProcessor") {
insert_node = *niter;
break;
}
}
IOProcessor::set_state (*insert_node);
return 0;
}
ARDOUR::nframes_t
PortInsert::signal_latency() const
{
/* 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() + _io->input_latency();
}
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.
*/
_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (out);
_io->set_input_minimum (out);
if (_io->ensure_io (out, in, false, this) != 0) {
return false;
}
return Processor::configure_io (in, out);
}
ChanCount
PortInsert::output_streams() const
{
return _io->n_inputs ();
}
ChanCount
PortInsert::input_streams() const
{
return _io->n_outputs ();
}
bool
PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
out = in;
return true;
}