summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-02-20 00:55:32 +0000
committerCarl Hetherington <carl@carlh.net>2011-02-20 00:55:32 +0000
commit13232d03f3e5f8a5d7d19392c26c27ce0327250c (patch)
tree8c7b3b49174595d75b9ca8e13d12d10aa7a3a318 /libs
parentc77d116703647a72cd7d01c6735fa610a88171dd (diff)
Modify route _processor list set up so that the logic for placing `invisible' processors (e.g. internal returns etc.) is in one place. Add option to get pre-fade listen from before or after pre-fade processors (#3781).
git-svn-id: svn://localhost/ardour2/branches/3.0@8903 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h1
-rw-r--r--libs/ardour/ardour/route.h41
-rw-r--r--libs/ardour/ardour/types.h9
-rw-r--r--libs/ardour/enums.cc21
-rw-r--r--libs/ardour/monitor_processor.cc5
-rw-r--r--libs/ardour/route.cc396
-rw-r--r--libs/ardour/session.cc30
-rw-r--r--libs/ardour/session_state.cc2
8 files changed, 304 insertions, 201 deletions
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 92647947a2..e1030bafa0 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -84,6 +84,7 @@ CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", t
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
+CONFIG_VARIABLE (PFLPosition, pfl_position, "pfl-position", PFLFromAfterProcessors)
CONFIG_VARIABLE (bool, use_monitor_bus, "use-monitor-bus", false)
CONFIG_VARIABLE (bool, solo_control_is_listen_control, "solo-control-is-listen-control", false)
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index e17dc775d1..defcc2c5c2 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -155,7 +155,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
bool solo_safe() const;
void set_listen (bool yn, void* src);
- bool listening () const;
+ bool listening_via_monitor () const;
void set_phase_invert (uint32_t, bool yn);
void set_phase_invert (boost::dynamic_bitset<>);
@@ -220,7 +220,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void add_internal_return ();
BufferSet* get_return_buffer () const;
void release_return_buffer () const;
- void put_monitor_send_at (Placement);
+ void listen_position_changed ();
boost::shared_ptr<CapturingProcessor> add_export_point(/* Add some argument for placement later */);
/** A record of the stream configuration at some point in the processor list.
@@ -294,7 +294,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
PBD::Signal1<void,void*> SelectedChanged;
- int listen_via (boost::shared_ptr<Route>, Placement p, bool active, bool aux);
+ int listen_via_monitor ();
+ int listen_via (boost::shared_ptr<Route>, Placement p);
void drop_listen (boost::shared_ptr<Route>);
/**
@@ -508,6 +509,40 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void set_processor_positions ();
void update_port_latencies (const PortSet& ports, const PortSet& feeders, bool playback, framecnt_t) const;
+
+ void setup_invisible_processors ();
+
+ boost::shared_ptr<CapturingProcessor> _capturing_processor;
+
+ /** A handy class to keep processor state while we attempt a reconfiguration
+ * that may fail.
+ */
+ class ProcessorState {
+ public:
+ ProcessorState (Route* r)
+ : _route (r)
+ , _processors (r->_processors)
+ , _processor_max_streams (r->processor_max_streams)
+ { }
+
+ void restore () {
+ _route->_processors = _processors;
+ _route->processor_max_streams = _processor_max_streams;
+ }
+
+ private:
+ /* this should perhaps be a shared_ptr, but ProcessorStates will
+ not hang around long enough for it to matter.
+ */
+ Route* _route;
+ ProcessorList _processors;
+ ChanCount _processor_max_streams;
+ };
+
+ friend class ProcessorState;
+
+ /* no copy construction */
+ Route (Route const &);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 744c06f552..b03ba6b232 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -346,6 +346,13 @@ namespace ARDOUR {
ExternalMonitoring
};
+ enum PFLPosition {
+ /** PFL signals come from before pre-fader processors */
+ PFLFromBeforeProcessors,
+ /** PFL signals come pre-fader but after pre-fader processors */
+ PFLFromAfterProcessors
+ };
+
enum DenormalModel {
DenormalNone,
DenormalFTZ,
@@ -557,6 +564,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf);
std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf);
std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf);
std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::PFLPosition& sf);
std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf);
std::istream& operator>>(std::istream& o, ARDOUR::ListenPosition& sf);
std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf);
@@ -576,6 +584,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoConnectOption& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::EditMode& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::MonitorModel& sf);
+std::ostream& operator<<(std::ostream& o, const ARDOUR::PFLPosition& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::RemoteModel& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::ListenPosition& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::LayerModel& sf);
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index 976cd99f9f..5219b51458 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -65,6 +65,7 @@ setup_enum_writer ()
RegionPoint _RegionPoint;
Placement _Placement;
MonitorModel _MonitorModel;
+ PFLPosition _PFLPosition;
RemoteModel _RemoteModel;
DenormalModel _DenormalModel;
CrossfadeModel _CrossfadeModel;
@@ -219,6 +220,10 @@ setup_enum_writer ()
REGISTER_ENUM (ExternalMonitoring);
REGISTER (_MonitorModel);
+ REGISTER_ENUM (PFLFromBeforeProcessors);
+ REGISTER_ENUM (PFLFromAfterProcessors);
+ REGISTER (_PFLPosition);
+
REGISTER_ENUM (DenormalNone);
REGISTER_ENUM (DenormalFTZ);
REGISTER_ENUM (DenormalDAZ);
@@ -603,6 +608,7 @@ std::ostream& operator<<(std::ostream& o, const AutoConnectOption& var)
std::string s = enum_2_string (var);
return o << s;
}
+
std::istream& operator>>(std::istream& o, MonitorModel& var)
{
std::string s;
@@ -616,6 +622,21 @@ std::ostream& operator<<(std::ostream& o, const MonitorModel& var)
std::string s = enum_2_string (var);
return o << s;
}
+
+std::istream& operator>>(std::istream& o, PFLPosition& var)
+{
+ std::string s;
+ o >> s;
+ var = (PFLPosition) string_2_enum (s, var);
+ return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const PFLPosition& var)
+{
+ std::string s = enum_2_string (var);
+ return o << s;
+}
+
std::istream& operator>>(std::istream& o, RemoteModel& var)
{
std::string s;
diff --git a/libs/ardour/monitor_processor.cc b/libs/ardour/monitor_processor.cc
index 4f204031ac..be4431b98a 100644
--- a/libs/ardour/monitor_processor.cc
+++ b/libs/ardour/monitor_processor.cc
@@ -275,7 +275,7 @@ MonitorProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /
target_gain = 0.0;
}
}
-
+
if (target_gain != _channels[chn]->current_gain || target_gain != 1.0f) {
Amp::apply_gain (*b, nframes, _channels[chn]->current_gain, target_gain);
@@ -334,7 +334,8 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out)
bool
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
- return in == out;
+ out = in;
+ return true;
}
void
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index a980b3f446..56fc090576 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -144,37 +144,27 @@ Route::init ()
_amp.reset (new Amp (_session));
add_processor (_amp, PostFader);
- /* add standard processors: meter, main outs, monitor out */
+ /* create standard processors: meter, main outs, monitor out;
+ they will be added to _processors by setup_invisible_processors ()
+ */
_meter.reset (new PeakMeter (_session));
_meter->set_display_to_user (false);
-
- add_processor (_meter, PostFader);
+ _meter->activate ();
_main_outs.reset (new Delivery (_session, _output, _pannable, _mute_master, _name, Delivery::Main));
-
- add_processor (_main_outs, PostFader);
+ _main_outs->activate ();
if (is_monitor()) {
/* where we listen to tracks */
_intreturn.reset (new InternalReturn (_session));
- add_processor (_intreturn, PreFader);
-
- ProcessorList::iterator i;
-
- for (i = _processors.begin(); i != _processors.end(); ++i) {
- if (*i == _intreturn) {
- ++i;
- break;
- }
- }
+ _intreturn->activate ();
/* the thing that provides proper control over a control/monitor/listen bus
(such as per-channel cut, dim, solo, invert, etc).
- It always goes right after the internal return;
*/
_monitor_control.reset (new MonitorProcessor (_session));
- add_processor (_monitor_control, i);
+ _monitor_control->activate ();
/* no panning on the monitor main outs */
@@ -191,6 +181,12 @@ Route::init ()
Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
+ {
+ /* run a configure so that the invisible processors get set up */
+ Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ configure_processors (0);
+ }
+
return 0;
}
@@ -505,7 +501,7 @@ Route::process_output_buffers (BufferSet& bufs,
if (boost::dynamic_pointer_cast<UnknownProcessor> (*i)) {
break;
}
-
+
if (bufs.count() != (*i)->input_streams()) {
cerr << _name << " bufs = " << bufs.count()
<< " input for " << (*i)->name() << " = " << (*i)->input_streams()
@@ -600,7 +596,7 @@ Route::set_listen (bool yn, void* src)
}
bool
-Route::listening () const
+Route::listening_via_monitor () const
{
if (_monitor_send) {
return _monitor_send->active ();
@@ -862,13 +858,14 @@ Route::add_processor (boost::shared_ptr<Processor> processor, Placement placemen
/** Add a processor to the route.
- * @a iter must point to an iterator in _processors and the new
- * processor will be inserted immediately before this location. Otherwise,
- * @a position is used.
+ * @param iter an iterator in _processors; the new processor will be inserted immediately before this location.
*/
int
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err, bool activation_allowed)
{
+ assert (processor != _meter);
+ assert (processor != _main_outs);
+
ChanCount old_pms = processor_max_streams;
if (!_session.engine().connected() || !processor) {
@@ -877,14 +874,15 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
{
Glib::RWLock::WriterLock lm (_processor_lock);
+ ProcessorState pstate (this);
boost::shared_ptr<PluginInsert> pi;
boost::shared_ptr<PortInsert> porti;
ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
- if (processor == _amp || processor == _meter || processor == _main_outs) {
- // Ensure only one of these are in the list at any time
+ if (processor == _amp) {
+ // Ensure only one amp is in the list at any time
if (loc != _processors.end()) {
if (iter == loc) { // Already in place, do nothing
return 0;
@@ -911,9 +909,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) {
- ProcessorList::iterator ploc = loc;
- --ploc;
- _processors.erase(ploc);
+ pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ...
cerr << "configure failed\n";
return -1;
@@ -929,15 +925,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
}
- /* is this the monitor send ? if so, make sure we keep track of it */
-
- boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (processor);
-
- if (isend && _session.monitor_out() && (isend->target_id() == _session.monitor_out()->id())) {
- _monitor_send = isend;
- }
-
- if (activation_allowed && (processor != _monitor_send)) {
+ if (activation_allowed) {
processor->activate ();
}
@@ -1033,8 +1021,8 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
if (before) {
loc = find(_processors.begin(), _processors.end(), before);
} else {
- /* nothing specified - at end but before main outs */
- loc = find (_processors.begin(), _processors.end(), _main_outs);
+ /* nothing specified - at end */
+ loc = _processors.end ();
}
ChanCount old_pms = processor_max_streams;
@@ -1049,29 +1037,18 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
{
Glib::RWLock::WriterLock lm (_processor_lock);
-
- ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
+ ProcessorState pstate (this);
for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
- // Ensure meter only appears in the list once
if (*i == _meter) {
- ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
- if (m != _processors.end()) {
- _processors.erase(m);
- }
+ continue;
}
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
pi->set_count (1);
-
- ChanCount m = max (pi->input_streams(), pi->output_streams());
-
- if (m > potential_max_streams) {
- potential_max_streams = m;
- }
}
ProcessorList::iterator inserted = _processors.insert (loc, *i);
@@ -1083,7 +1060,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) {
- _processors.erase (inserted);
+ pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ...
return -1;
}
@@ -1327,6 +1304,8 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
{
Glib::RWLock::WriterLock lm (_processor_lock);
+ ProcessorState pstate (this);
+
ProcessorList::iterator i;
bool removed = false;
@@ -1373,8 +1352,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) {
- /* get back to where we where */
- _processors.insert (i, processor);
+ pstate.restore ();
/* we know this will work, because it worked before :) */
configure_processors_unlocked (0);
return -1;
@@ -1415,11 +1393,11 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
{
Glib::RWLock::WriterLock lm (_processor_lock);
+ ProcessorState pstate (this);
+
ProcessorList::iterator i;
boost::shared_ptr<Processor> processor;
- ProcessorList as_we_were = _processors;
-
for (i = _processors.begin(); i != _processors.end(); ) {
processor = *i;
@@ -1464,8 +1442,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) {
- /* get back to where we where */
- _processors = as_we_were;
+ pstate.restore ();
/* we know this will work, because it worked before :) */
configure_processors_unlocked (0);
return -1;
@@ -1508,6 +1485,7 @@ Route::configure_processors (ProcessorStreams* err)
Glib::RWLock::WriterLock lm (_processor_lock);
return configure_processors_unlocked (err);
}
+
return 0;
}
@@ -1577,6 +1555,9 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
return 0;
}
+ /* put invisible processors where they should be */
+ setup_invisible_processors ();
+
_in_configure_processors = true;
list<pair<ChanCount, ChanCount> > configuration = try_configure_processors_unlocked (input_streams (), err);
@@ -1706,10 +1687,10 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
{
Glib::RWLock::WriterLock lm (_processor_lock);
- ChanCount old_pms = processor_max_streams;
+ ProcessorState pstate (this);
+
ProcessorList::iterator oiter;
ProcessorList::const_iterator niter;
- ProcessorList as_it_was_before = _processors;
ProcessorList as_it_will_be;
oiter = _processors.begin();
@@ -1767,8 +1748,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (err)) {
- _processors = as_it_was_before;
- processor_max_streams = old_pms;
+ pstate.restore ();
return -1;
}
}
@@ -2348,24 +2328,20 @@ Route::set_processor_state (const XMLNode& node)
new_order.push_back (_amp);
} else if (prop->value() == "meter") {
_meter->set_state (**niter, Stateful::current_state_version);
- new_order.push_back (_meter);
} else if (prop->value() == "main-outs") {
_main_outs->set_state (**niter, Stateful::current_state_version);
- new_order.push_back (_main_outs);
} else if (prop->value() == "intreturn") {
if (!_intreturn) {
_intreturn.reset (new InternalReturn (_session));
must_configure = true;
}
_intreturn->set_state (**niter, Stateful::current_state_version);
- new_order.push_back (_intreturn);
} else if (is_monitor() && prop->value() == "monitor") {
if (!_monitor_control) {
_monitor_control.reset (new MonitorProcessor (_session));
must_configure = true;
}
_monitor_control->set_state (**niter, Stateful::current_state_version);
- new_order.push_back (_monitor_control);
} else {
ProcessorList::iterator o;
@@ -2412,7 +2388,11 @@ Route::set_processor_state (const XMLNode& node)
/* This processor could not be configured. Turn it into a UnknownProcessor */
processor.reset (new UnknownProcessor (_session, **niter));
}
-
+
+ /* it doesn't matter if invisible processors are added here, as they
+ will be sorted out by setup_invisible_processors () shortly.
+ */
+
new_order.push_back (processor);
must_configure = true;
}
@@ -2516,78 +2496,58 @@ Route::release_return_buffer () const
}
}
+/** Add a monitor send, if we don't already have one */
int
-Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
+Route::listen_via_monitor ()
{
- vector<string> ports;
- vector<string>::const_iterator i;
+ /* master never sends to control outs */
+ assert (!is_master ());
+
+ /* make sure we have one */
+ if (!_monitor_send) {
+ _monitor_send.reset (new InternalSend (_session, _pannable, _mute_master, _session.monitor_out(), Delivery::Listen));
+ _monitor_send->activate ();
+ _monitor_send->set_display_to_user (false);
+ }
+
+ /* set it up */
+ Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ configure_processors (0);
+
+ return 0;
+}
+/** Add an internal send to a route.
+ * @param route route to send to.
+ * @param placement placement for the send.
+ */
+int
+Route::listen_via (boost::shared_ptr<Route> route, Placement placement)
+{
+ assert (route != _session.monitor_out ());
+
{
Glib::RWLock::ReaderLock rm (_processor_lock);
for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
- boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
+ boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend> (*x);
if (d && d->target_route() == route) {
-
- /* if the target is the control outs, then make sure
- we take note of which i-send is doing that.
- */
-
- if (route == _session.monitor_out()) {
- _monitor_send = boost::dynamic_pointer_cast<Delivery>(d);
- }
-
/* already listening via the specified IO: do nothing */
-
return 0;
}
}
}
- boost::shared_ptr<InternalSend> listener;
-
try {
-
- if (is_master()) {
-
- if (route == _session.monitor_out()) {
- /* master never sends to control outs */
- return 0;
- } else {
- listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
- }
-
- } else {
- listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
- }
+ boost::shared_ptr<InternalSend> listener (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux));
+ add_processor (listener, placement);
} catch (failed_constructor& err) {
return -1;
}
- if (route == _session.monitor_out()) {
- _monitor_send = listener;
- }
-
-
- if (aux) {
-
- add_processor (listener, placement);
-
- } else {
-
- if (placement == PostFader) {
- /* put it *really* at the end, not just after the panner (main outs)
- */
- add_processor (listener, _processors.end());
- } else {
- add_processor (listener, PreFader);
- }
-
- }
-
return 0;
}
@@ -2971,29 +2931,21 @@ Route::set_meter_point (MeterPoint p, bool force)
return;
}
+ _meter_point = p;
+
bool meter_was_visible_to_user = _meter->display_to_user ();
{
Glib::RWLock::WriterLock lm (_processor_lock);
- if (p != MeterCustom) {
- // Move meter in the processors list to reflect the new position
- ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
- _processors.erase(loc);
- switch (p) {
- case MeterInput:
- loc = _processors.begin();
- break;
- case MeterPreFader:
- loc = find (_processors.begin(), _processors.end(), _amp);
- break;
- case MeterPostFader:
- loc = _processors.end();
- break;
- default:
- break;
- }
+ if (_meter_point != MeterCustom) {
+
+ _meter->set_display_to_user (false);
+
+ setup_invisible_processors ();
+ ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
+
ChanCount m_in;
if (loc == _processors.begin()) {
@@ -3006,16 +2958,12 @@ Route::set_meter_point (MeterPoint p, bool force)
_meter->reflect_inputs (m_in);
- _processors.insert (loc, _meter);
-
/* we do not need to reconfigure the processors, because the meter
(a) is always ready to handle processor_max_streams
(b) is always an N-in/N-out processor, and thus moving
it doesn't require any changes to the other processors.
*/
- _meter->set_display_to_user (false);
-
} else {
// just make it visible and let the user move it
@@ -3024,7 +2972,6 @@ Route::set_meter_point (MeterPoint p, bool force)
}
}
- _meter_point = p;
meter_change (); /* EMIT SIGNAL */
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
@@ -3033,37 +2980,17 @@ Route::set_meter_point (MeterPoint p, bool force)
}
void
-Route::put_monitor_send_at (Placement p)
+Route::listen_position_changed ()
{
- if (!_monitor_send) {
- return;
- }
-
{
Glib::RWLock::WriterLock lm (_processor_lock);
- ProcessorList as_it_was (_processors);
- ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _monitor_send);
- _processors.erase(loc);
-
- switch (p) {
- case PreFader:
- loc = find(_processors.begin(), _processors.end(), _amp);
- if (loc != _processors.begin()) {
- --loc;
- }
- break;
- case PostFader:
- loc = _processors.end();
- break;
- }
-
- _processors.insert (loc, _monitor_send);
+ ProcessorState pstate (this);
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors_unlocked (0)) {
- _processors = as_it_was;
+ pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ...
return;
}
@@ -3077,16 +3004,19 @@ Route::put_monitor_send_at (Placement p)
boost::shared_ptr<CapturingProcessor>
Route::add_export_point()
{
- // Check if it exists already
- boost::shared_ptr<CapturingProcessor> processor;
- if ((processor = boost::dynamic_pointer_cast<CapturingProcessor> (*_processors.begin()))) {
- return processor;
- }
+ if (!_capturing_processor) {
+
+ _capturing_processor.reset (new CapturingProcessor (_session));
+ _capturing_processor->activate ();
- // ...else add it
- processor.reset (new CapturingProcessor (_session));
- add_processor (processor, _processors.begin());
- return processor;
+ {
+ Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ configure_processors (0);
+ }
+
+ }
+
+ return _capturing_processor;
}
framecnt_t
@@ -3196,7 +3126,7 @@ double
Route::SoloControllable::get_value (void) const
{
if (Config->get_solo_control_is_listen_control()) {
- return route.listening() ? 1.0f : 0.0f;
+ return route.listening_via_monitor() ? 1.0f : 0.0f;
} else {
return route.self_soloed() ? 1.0f : 0.0f;
}
@@ -3699,3 +3629,125 @@ Route::update_port_latencies (const PortSet& operands, const PortSet& feeders, b
}
#endif
}
+
+
+/** Put the invisible processors in the right place in _processors.
+ * Must be called with a writer lock on _processor_lock held.
+ */
+void
+Route::setup_invisible_processors ()
+{
+#ifdef NDEBUG
+ Glib::RWLock::WriterLock lm (_processor_lock, Glib::TryLock);
+ assert (!lm.locked ());
+#endif
+
+ /* we'll build this new list here and then use it */
+
+ ProcessorList new_processors;
+
+ /* find visible processors */
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ if ((*i)->display_to_user ()) {
+ new_processors.push_back (*i);
+ }
+ }
+
+ /* find the amp */
+
+ ProcessorList::iterator amp = new_processors.begin ();
+ while (amp != new_processors.end() && boost::dynamic_pointer_cast<Amp> (*amp) == 0) {
+ ++amp;
+ }
+
+ assert (amp != _processors.end ());
+
+ /* and the processor after the amp */
+
+ ProcessorList::iterator after_amp = amp;
+ ++after_amp;
+
+ /* METER */
+
+ if (_meter) {
+ switch (_meter_point) {
+ case MeterInput:
+ assert (!_meter->display_to_user ());
+ new_processors.push_front (_meter);
+ break;
+ case MeterPreFader:
+ assert (!_meter->display_to_user ());
+ new_processors.insert (amp, _meter);
+ break;
+ case MeterPostFader:
+ assert (!_meter->display_to_user ());
+ new_processors.insert (after_amp, _meter);
+ break;
+ case MeterCustom:
+ /* the meter is visible, so we don't touch it here */
+ break;
+ }
+ }
+
+
+ /* MAIN OUTS */
+
+ if (_main_outs) {
+ assert (!_main_outs->display_to_user ());
+ new_processors.push_back (_main_outs);
+ }
+
+ /* MONITOR SEND */
+
+ if (_monitor_send && !is_monitor ()) {
+ assert (!_monitor_send->display_to_user ());
+ switch (Config->get_listen_position ()) {
+ case PreFaderListen:
+ switch (Config->get_pfl_position ()) {
+ case PFLFromBeforeProcessors:
+ new_processors.push_front (_monitor_send);
+ break;
+ case PFLFromAfterProcessors:
+ new_processors.insert (amp, _monitor_send);
+ break;
+ }
+ break;
+ case AfterFaderListen:
+ new_processors.insert (after_amp, _monitor_send);
+ break;
+ }
+ }
+
+ /* MONITOR CONTROL */
+
+ if (_monitor_control && is_monitor ()) {
+ assert (!_monitor_control->display_to_user ());
+ new_processors.push_front (_monitor_control);
+ }
+
+ /* INTERNAL RETURN */
+
+ /* doing this here means that any monitor control will come just after
+ the return.
+ */
+
+ if (_intreturn) {
+ assert (!_intreturn->display_to_user ());
+ new_processors.push_front (_intreturn);
+ }
+
+ /* EXPORT PROCESSOR */
+
+ if (_capturing_processor) {
+ assert (!_capturing_processor->display_to_user ());
+ new_processors.push_front (_capturing_processor);
+ }
+
+ _processors = new_processors;
+
+ DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: setup_invisible_processors\n", _name));
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));
+ }
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 39f6fc4ff7..e09513b07d 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -727,10 +727,8 @@ Session::hookup_io ()
/* relax */
} else {
-
- (*x)->listen_via (_monitor_out,
- (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
- false, false);
+
+ (*x)->listen_via_monitor ();
}
}
}
@@ -2000,9 +1998,7 @@ Session::add_routes (RouteList& new_routes, bool save)
} else if ((*x)->is_master()) {
/* relax */
} else {
- (*x)->listen_via (_monitor_out,
- (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
- false, false);
+ (*x)->listen_via_monitor ();
}
}
@@ -2091,7 +2087,7 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::
continue;
}
- (*i)->listen_via (dest, p, true, true);
+ (*i)->listen_via (dest, p);
}
graph_reordered ();
@@ -2207,7 +2203,7 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
return;
}
- if (route->listening()) {
+ if (route->listening_via_monitor ()) {
if (Config->get_exclusive_solo()) {
/* new listen: disable all other listen */
@@ -2363,7 +2359,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
something_soloed = true;
}
- if (!(*i)->is_hidden() && (*i)->listening()) {
+ if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
if (Config->get_solo_control_is_listen_control()) {
listeners++;
} else {
@@ -3892,22 +3888,10 @@ Session::update_have_rec_enabled_track ()
void
Session::listen_position_changed ()
{
- Placement p;
-
- switch (Config->get_listen_position()) {
- case AfterFaderListen:
- p = PostFader;
- break;
-
- case PreFaderListen:
- p = PreFader;
- break;
- }
-
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- (*i)->put_monitor_send_at (p);
+ (*i)->listen_position_changed ();
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index b925e9416e..a8e8abf804 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -3476,7 +3476,7 @@ Session::config_changed (std::string p, bool ours)
}
} else if (p == "solo-mute-override") {
// catch_up_on_solo_mute_override ();
- } else if (p == "listen-position") {
+ } else if (p == "listen-position" || p == "pfl-position") {
listen_position_changed ();
} else if (p == "solo-control-is-listen-control") {
solo_control_mode_changed ();