summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/chan_count.h8
-rw-r--r--libs/ardour/ardour/io.h3
-rw-r--r--libs/ardour/ardour/port_insert.h3
-rw-r--r--libs/ardour/ardour/return.h71
-rw-r--r--libs/ardour/ardour/send.h9
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/io.cc34
-rw-r--r--libs/ardour/port_insert.cc31
-rw-r--r--libs/ardour/return.cc164
-rw-r--r--libs/ardour/send.cc65
-rw-r--r--libs/ardour/session.cc43
-rw-r--r--libs/ardour/wscript1
12 files changed, 334 insertions, 103 deletions
diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h
index c9b543c4ba..ccae3920f6 100644
--- a/libs/ardour/ardour/chan_count.h
+++ b/libs/ardour/ardour/chan_count.h
@@ -106,6 +106,14 @@ public:
return ( (*this > other) || (*this == other) );
}
+ ChanCount operator+(const ChanCount& other) const {
+ ChanCount ret;
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ ret.set(*t, get(*t) + other.get(*t));
+ }
+ return ret;
+ }
+
static ChanCount min(const ChanCount& a, const ChanCount& b) {
ChanCount ret;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 3e36d10be3..fbaf379a30 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -102,7 +102,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
virtual void silence (nframes_t);
- void collect_input (BufferSet& bufs, nframes_t nframes);
+ void collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset=ChanCount::ZERO);
void deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
void just_meter_input (nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
@@ -214,7 +214,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
static sigc::signal<int> ConnectingLegal;
/// raised when the number of input or output ports changes
static sigc::signal<void,ChanCount> PortCountChanged;
- static sigc::signal<int> PortsCreated;
static sigc::signal<void,nframes_t> CycleStart;
static void update_meters();
diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h
index 076e4af9d1..ce21d9f223 100644
--- a/libs/ardour/ardour/port_insert.h
+++ b/libs/ardour/ardour/port_insert.h
@@ -54,9 +54,6 @@ class PortInsert : public IOProcessor
nframes_t signal_latency() const;
- ChanCount output_streams() const;
- ChanCount input_streams() const;
-
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool configure_io (ChanCount in, ChanCount out);
diff --git a/libs/ardour/ardour/return.h b/libs/ardour/ardour/return.h
new file mode 100644
index 0000000000..af55df59ed
--- /dev/null
+++ b/libs/ardour/ardour/return.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2009 Paul Davis
+ Author: Dave Robillard
+
+ 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.
+
+*/
+
+#ifndef __ardour_return_h__
+#define __ardour_return_h__
+
+#include <sigc++/signal.h>
+#include <string>
+
+
+#include "pbd/stateful.h"
+#include "ardour/ardour.h"
+#include "ardour/audioengine.h"
+#include "ardour/io_processor.h"
+
+namespace ARDOUR {
+
+class Return : public IOProcessor
+{
+public:
+ Return (Session&);
+ Return (Session&, const XMLNode&);
+ virtual ~Return ();
+
+ uint32_t bit_slot() const { return _bitslot; }
+
+ void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
+
+ void activate() {}
+ void deactivate () {}
+
+ XMLNode& state(bool full);
+ XMLNode& get_state(void);
+ int set_state(const XMLNode& node);
+
+ uint32_t pans_required() const { return _configured_input.n_audio(); }
+
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool configure_io (ChanCount in, ChanCount out);
+
+ static uint32_t how_many_sends();
+ static void make_unique (XMLNode &, Session &);
+
+private:
+ /* disallow copy construction */
+ Return (const Return&);
+
+ uint32_t _bitslot;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_return_h__ */
+
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index 77bb6d9017..825506f0e2 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -38,10 +38,7 @@ class Send : public IOProcessor
Send (Session&, const XMLNode&);
virtual ~Send ();
- uint32_t bit_slot() const { return bitslot; }
-
- ChanCount output_streams() const;
- ChanCount input_streams () const;
+ uint32_t bit_slot() const { return _bitslot; }
void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
@@ -55,7 +52,6 @@ class Send : public IOProcessor
int set_state(const XMLNode& node);
uint32_t pans_required() const { return _configured_input.n_audio(); }
- void expect_inputs (const ChanCount&);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool configure_io (ChanCount in, ChanCount out);
@@ -68,8 +64,7 @@ class Send : public IOProcessor
Send (const Send&);
bool _metering;
- ChanCount expected_inputs;
- uint32_t bitslot;
+ uint32_t _bitslot;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 1e3855c308..86a2f778dc 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -101,6 +101,7 @@ class Port;
class PortInsert;
class Processor;
class Region;
+class Return;
class Route;
class RouteGroup;
class SMFSource;
@@ -764,8 +765,10 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
}
uint32_t next_send_id();
+ uint32_t next_return_id();
uint32_t next_insert_id();
void mark_send_id (uint32_t);
+ void mark_return_id (uint32_t);
void mark_insert_id (uint32_t);
/* s/w "RAID" management */
@@ -1566,7 +1569,9 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
list<PortInsert *> _port_inserts;
list<PluginInsert *> _plugin_inserts;
list<Send *> _sends;
+ list<Return *> _returns;
boost::dynamic_bitset<uint32_t> send_bitset;
+ boost::dynamic_bitset<uint32_t> return_bitset;
boost::dynamic_bitset<uint32_t> insert_bitset;
uint32_t send_cnt;
uint32_t insert_cnt;
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 3e5b138fb7..c8e2c78cd2 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -74,7 +74,6 @@ sigc::signal<int> IO::ConnectingLegal;
sigc::signal<int> IO::PortsLegal;
sigc::signal<int> IO::PannersLegal;
sigc::signal<void,ChanCount> IO::PortCountChanged;
-sigc::signal<int> IO::PortsCreated;
sigc::signal<void,nframes_t> IO::CycleStart;
Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
@@ -290,24 +289,31 @@ IO::copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes)
}
void
-IO::collect_input (BufferSet& outs, nframes_t nframes)
+IO::collect_input (BufferSet& outs, nframes_t nframes, ChanCount offset)
{
assert(outs.available() >= n_inputs());
- if (n_inputs() == ChanCount::ZERO)
+ if (n_inputs() == ChanCount::ZERO) {
return;
+ }
outs.set_count(n_inputs());
-
+
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
-
+ PortSet::iterator i = _inputs.begin(*t);
BufferSet::iterator o = outs.begin(*t);
- PortSet::iterator e = _inputs.end (*t);
- for (PortSet::iterator i = _inputs.begin(*t); i != e; ++i, ++o) {
+
+ cerr << (*t).to_string() << endl;
+ for (uint32_t off = 0; off < offset.get(*t); ++off, ++o) {
+ if (o == outs.end(*t)) {
+ continue;
+ }
+ }
+
+ for ( ; i != _inputs.end(*t); ++i, ++o) {
Buffer& b (i->get_buffer (nframes));
o->read_from (b, nframes);
}
-
}
}
@@ -795,7 +801,8 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
{
Port* input_port = 0;
bool changed = false;
-
+
+ _configured_inputs = count;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
@@ -867,14 +874,14 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
in = ChanCount::min (_input_maximum, in);
out = ChanCount::min (_output_maximum, out);
+
+ _configured_inputs = in;
+ _configured_outputs = out;
if (in == n_inputs() && out == n_outputs() && !clear) {
return 0;
}
- _configured_inputs = in;
- _configured_outputs = out;
-
{
BLOCK_PROCESS_CALLBACK ();
Glib::Mutex::Lock lm (io_lock);
@@ -1034,6 +1041,8 @@ IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
Port* output_port = 0;
bool changed = false;
bool need_pan_reset = false;
+
+ _configured_outputs = count;
if (n_outputs() != count) {
need_pan_reset = true;
@@ -1708,7 +1717,6 @@ IO::create_ports (const XMLNode& node)
set_deferred_state ();
- PortsCreated();
return 0;
}
diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc
index 606b055dab..73a70861ea 100644
--- a/libs/ardour/port_insert.cc
+++ b/libs/ardour/port_insert.cc
@@ -162,23 +162,7 @@ PortInsert::signal_latency() const
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);*/
+ /* for an insert, processor input corresponds to IO output, and vice versa */
if (_io->ensure_io (out, in, false, this) != 0) {
return false;
@@ -187,21 +171,10 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
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;
}
+
diff --git a/libs/ardour/return.cc b/libs/ardour/return.cc
new file mode 100644
index 0000000000..fdc2b259e1
--- /dev/null
+++ b/libs/ardour/return.cc
@@ -0,0 +1,164 @@
+/*
+ Copyright (C) 2000 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 <algorithm>
+
+#include "pbd/xml++.h"
+
+#include "ardour/return.h"
+#include "ardour/session.h"
+#include "ardour/port.h"
+#include "ardour/audio_port.h"
+#include "ardour/buffer_set.h"
+#include "ardour/meter.h"
+#include "ardour/panner.h"
+#include "ardour/io.h"
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+
+Return::Return (Session& s)
+ : IOProcessor (s, string_compose (_("return %1"), (_bitslot = s.next_return_id()) + 1))
+{
+ ProcessorCreated (this); /* EMIT SIGNAL */
+}
+
+Return::Return (Session& s, const XMLNode& node)
+ : IOProcessor (s, "return")
+{
+ if (set_state (node)) {
+ throw failed_constructor();
+ }
+
+ ProcessorCreated (this); /* EMIT SIGNAL */
+}
+
+Return::~Return ()
+{
+ GoingAway ();
+}
+
+XMLNode&
+Return::get_state(void)
+{
+ return state (true);
+}
+
+XMLNode&
+Return::state(bool full)
+{
+ XMLNode& node = IOProcessor::state(full);
+ char buf[32];
+ node.add_property ("type", "return");
+ snprintf (buf, sizeof (buf), "%" PRIu32, _bitslot);
+ node.add_property ("bitslot", buf);
+
+ return node;
+}
+
+int
+Return::set_state(const XMLNode& node)
+{
+ XMLNodeList nlist = node.children();
+ XMLNodeIterator niter;
+ const XMLProperty* prop;
+
+ if ((prop = node.property ("bitslot")) == 0) {
+ _bitslot = _session.next_return_id();
+ } else {
+ sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
+ _session.mark_return_id (_bitslot);
+ }
+
+ const XMLNode* insert_node = &node;
+
+ /* Return has regular IO automation (gain, pan) */
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ if ((*niter)->name() == "IOProcessor") {
+ insert_node = *niter;
+ } else if ((*niter)->name() == X_("Automation")) {
+ // _io->set_automation_state (*(*niter), Evoral::Parameter(GainAutomation));
+ }
+ }
+
+ IOProcessor::set_state (*insert_node);
+
+ return 0;
+}
+
+void
+Return::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
+{
+ if (active()) {
+ _io->collect_input (bufs, nframes, _configured_input);
+ bufs.set_count(_configured_output);
+ }
+}
+
+bool
+Return::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
+{
+ out = in + _io->n_inputs();
+ return true;
+}
+
+bool
+Return::configure_io (ChanCount in, ChanCount out)
+{
+ if (out != in + _io->n_inputs()) {
+ return false;
+ }
+
+ // Ensure there are enough buffers (since we add some)
+ if (_session.get_scratch_buffers(in).count() < out) {
+ Glib::Mutex::Lock em (_session.engine().process_lock());
+ IO::PortCountChanged(out);
+ }
+
+ Processor::configure_io(in, out);
+
+ return true;
+}
+
+/** Set up the XML description of a return so that its name is unique.
+ * @param state XML return state.
+ * @param session Session.
+ */
+void
+Return::make_unique (XMLNode &state, Session &session)
+{
+ uint32_t const bitslot = session.next_return_id() + 1;
+
+ char buf[32];
+ snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
+ state.property("bitslot")->set_value (buf);
+
+ std::string const name = string_compose (_("return %1"), bitslot);
+
+ state.property("name")->set_value (name);
+
+ XMLNode* io = state.child ("IO");
+ if (io) {
+ io->property("name")->set_value (name);
+ }
+}
+
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 9246db9458..2c28fb5dcd 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -36,7 +36,7 @@ using namespace ARDOUR;
using namespace PBD;
Send::Send (Session& s)
- : IOProcessor (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1))
+ : IOProcessor (s, string_compose (_("send %1"), (_bitslot = s.next_send_id()) + 1))
{
_metering = false;
ProcessorCreated (this); /* EMIT SIGNAL */
@@ -71,7 +71,7 @@ Send::state(bool full)
XMLNode& node = IOProcessor::state(full);
char buf[32];
node.add_property ("type", "send");
- snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
+ snprintf (buf, sizeof (buf), "%" PRIu32, _bitslot);
node.add_property ("bitslot", buf);
return node;
@@ -85,10 +85,10 @@ Send::set_state(const XMLNode& node)
const XMLProperty* prop;
if ((prop = node.property ("bitslot")) == 0) {
- bitslot = _session.next_send_id();
+ _bitslot = _session.next_send_id();
} else {
- sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
- _session.mark_send_id (bitslot);
+ sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
+ _session.mark_send_id (_bitslot);
}
const XMLNode* insert_node = &node;
@@ -113,15 +113,7 @@ Send::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
{
if (active()) {
- // we have to copy the input, because IO::deliver_output may alter the buffers
- // in-place, which a send must never do.
-
- BufferSet& sendbufs = _session.get_mix_buffers(bufs.count());
-
- sendbufs.read_from(bufs, nframes);
- assert(sendbufs.count() == bufs.count());
-
- _io->deliver_output (sendbufs, start_frame, end_frame, nframes);
+ _io->deliver_output (bufs, start_frame, end_frame, nframes);
if (_metering) {
if (_io->effective_gain() == 0) {
@@ -152,26 +144,27 @@ Send::set_metering (bool yn)
}
bool
-Send::can_support_io_configuration (const ChanCount& in, ChanCount& out_is_ignored) const
+Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
- if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
+ if (_io->input_maximum() == ChanCount::INFINITE
+ && _io->output_maximum() == ChanCount::INFINITE) {
- /* not configured yet */
+ /* not configured yet, we can support anything */
- return 1; /* we can support anything the first time we're asked */
+ out = in;
+ return true; /* we can support anything the first time we're asked */
} else {
- /* the "input" config for a port insert corresponds to how
- many output ports it will have.
- */
+ /* for a send, processor input corresponds to IO output */
if (_io->output_maximum() == in) {
- return 1;
+ out = in;
+ return true;
}
}
- return -1;
+ return false;
}
bool
@@ -198,32 +191,6 @@ Send::configure_io (ChanCount in, ChanCount out)
return true;
}
-ChanCount
-Send::output_streams() const
-{
- // this method reflects the idea that from the perspective of the Route's ProcessorList,
- // a send is just a passthrough. that doesn't match what the Send actually does with its
- // data, but since what it does is invisible to the Route, it appears to be a passthrough.
-
- return _configured_input;
-}
-
-ChanCount
-Send::input_streams() const
-{
- return _configured_input;
-}
-
-
-void
-Send::expect_inputs (const ChanCount& expected)
-{
- if (expected != expected_inputs) {
- expected_inputs = expected;
- _io->reset_panner ();
- }
-}
-
/** Set up the XML description of a send so that its name is unique.
* @param state XML send state.
* @param session Session.
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index db66c2dc30..302bf87f64 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -72,6 +72,7 @@
#include "ardour/processor.h"
#include "ardour/recent_sessions.h"
#include "ardour/region_factory.h"
+#include "ardour/return.h"
#include "ardour/route_group.h"
#include "ardour/send.h"
#include "ardour/session.h"
@@ -3666,6 +3667,7 @@ void
Session::add_processor (Processor* processor)
{
Send* send;
+ Return* retrn;
PortInsert* port_insert;
PluginInsert* plugin_insert;
@@ -3675,6 +3677,8 @@ Session::add_processor (Processor* processor)
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
_sends.insert (_sends.begin(), send);
+ } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
+ _returns.insert (_returns.begin(), retrn);
} else {
fatal << _("programming error: unknown type of Insert created!") << endmsg;
/*NOTREACHED*/
@@ -3689,6 +3693,7 @@ void
Session::remove_processor (Processor* processor)
{
Send* send;
+ Return* retrn;
PortInsert* port_insert;
PluginInsert* plugin_insert;
@@ -3706,6 +3711,12 @@ Session::remove_processor (Processor* processor)
send_bitset[send->bit_slot()] = false;
_sends.erase (x);
}
+ } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
+ list<Return*>::iterator x = find (_returns.begin(), _returns.end(), retrn);
+ if (x != _returns.end()) {
+ return_bitset[send->bit_slot()] = false;
+ _returns.erase (x);
+ }
} else {
fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
/*NOTREACHED*/
@@ -3884,6 +3895,26 @@ Session::next_send_id ()
}
}
+uint32_t
+Session::next_return_id ()
+{
+ /* this doesn't really loop forever. just think about it */
+
+ while (true) {
+ for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
+ if (!return_bitset[n]) {
+ return_bitset[n] = true;
+ return n;
+
+ }
+ }
+
+ /* none available, so resize and try again */
+
+ return_bitset.resize (return_bitset.size() + 16, false);
+ }
+}
+
void
Session::mark_send_id (uint32_t id)
{
@@ -3897,6 +3928,18 @@ Session::mark_send_id (uint32_t id)
}
void
+Session::mark_return_id (uint32_t id)
+{
+ if (id >= return_bitset.size()) {
+ return_bitset.resize (id+16, false);
+ }
+ if (return_bitset[id]) {
+ warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
+ }
+ return_bitset[id] = true;
+}
+
+void
Session::mark_insert_id (uint32_t id)
{
if (id >= insert_bitset.size()) {
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index adcf3a5f0b..fc0e8107f9 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -175,6 +175,7 @@ def build(bld):
region.cc
region_factory.cc
resampled_source.cc
+ return.cc
reverse.cc
route.cc
route_group.cc