summaryrefslogtreecommitdiff
path: root/libs/ardour/route.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/route.cc')
-rw-r--r--libs/ardour/route.cc124
1 files changed, 100 insertions, 24 deletions
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 0b6c3c48ca..c3e5862270 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -37,6 +37,7 @@
#include "ardour/buffer_set.h"
#include "ardour/configuration.h"
#include "ardour/cycle_timer.h"
+#include "ardour/delivery.h"
#include "ardour/dB.h"
#include "ardour/internal_send.h"
#include "ardour/internal_return.h"
@@ -114,6 +115,8 @@ Route::Route (Session& sess, const XMLNode& node, DataType default_type)
void
Route::init ()
{
+ _solo_level = 0;
+ _solo_isolated = false;
_active = true;
processor_max_streams.reset();
_solo_safe = false;
@@ -475,7 +478,7 @@ Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t n
void
Route::set_solo (bool yn, void *src)
{
- if (_solo_safe) {
+ if (_solo_safe || _solo_isolated) {
return;
}
@@ -484,17 +487,52 @@ Route::set_solo (bool yn, void *src)
return;
}
- if (_main_outs->soloed() != yn) {
- _main_outs->mod_solo_level (yn ? 1 : -1);
+ if (soloed() != yn) {
+ mod_solo_level (yn ? 1 : -1);
solo_changed (src); /* EMIT SIGNAL */
_solo_control->Changed (); /* EMIT SIGNAL */
}
}
-bool
-Route::soloed() const
+void
+Route::mod_solo_level (int32_t delta)
{
- return _main_outs->soloed ();
+ if (delta < 0) {
+ if (_solo_level >= (uint32_t) delta) {
+ _solo_level += delta;
+ } else {
+ _solo_level = 0;
+ }
+ } else {
+ _solo_level += delta;
+ }
+
+ /* tell "special" delivery units what the solo situation is
+ */
+
+ switch (Config->get_solo_model()) {
+ case SoloInPlace:
+ /* main outs are used for soloing */
+ _main_outs->set_solo_level (_solo_level);
+ _main_outs->set_solo_isolated (_solo_isolated);
+ if (_control_outs) {
+ /* control outs just keep on playing */
+ _control_outs->set_solo_level (0);
+ _control_outs->set_solo_isolated (true);
+ }
+ break;
+
+ case SoloBus:
+ /* control outs are used for soloing */
+ if (_control_outs) {
+ _control_outs->set_solo_level (_solo_level);
+ _control_outs->set_solo_isolated (_solo_isolated);
+ }
+ /* main outs just keep on playing */
+ _main_outs->set_solo_level (0);
+ _main_outs->set_solo_isolated (true);
+ break;
+ }
}
void
@@ -505,14 +543,39 @@ Route::set_solo_isolated (bool yn, void *src)
return;
}
- _main_outs->set_solo_isolated (yn);
- solo_isolated_changed (src);
+ if (yn != _solo_isolated) {
+ _solo_isolated = yn;
+
+ /* tell "special" delivery units what the solo situation is
+ */
+
+ switch (Config->get_solo_model()) {
+ case SoloInPlace:
+ _main_outs->set_solo_level (_solo_level);
+ _main_outs->set_solo_isolated (_solo_isolated);
+ if (_control_outs) {
+ _main_outs->set_solo_level (1);
+ _main_outs->set_solo_isolated (false);
+ }
+ break;
+ case SoloBus:
+ if (_control_outs) {
+ _control_outs->set_solo_level (_solo_level);
+ _control_outs->set_solo_isolated (_solo_isolated);
+ }
+ _main_outs->set_solo_level (1);
+ _main_outs->set_solo_isolated (false);
+ break;
+ }
+
+ solo_isolated_changed (src);
+ }
}
bool
Route::solo_isolated () const
{
- return _main_outs->solo_isolated();
+ return _solo_isolated;
}
void
@@ -535,6 +598,7 @@ Route::muted() const
return _mute_master->muted ();
}
+#if 0
static void
dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
{
@@ -545,6 +609,7 @@ dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& p
}
cerr << "}" << endl;
}
+#endif
int
Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
@@ -567,7 +632,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, Placement placemen
ProcessorList::iterator p;
p = _processors.end();
--p;
- cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
@@ -621,8 +685,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
loc = iter;
}
- cerr << "Adding " << processor->name() << " @ " << processor << endl;
-
_processors.insert (loc, processor);
// Set up processor list channels. This will set processor->[input|output]_streams(),
@@ -705,9 +767,6 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
try {
if ((prop = node.property ("type")) != 0) {
-
- cerr << _name << " : got processor type " << prop->value() << endl;
-
boost::shared_ptr<Processor> processor;
if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
@@ -757,7 +816,7 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
} else if (prop->value() == "intsend") {
processor.reset (new InternalSend (_session, _mute_master, node));
-
+
} else if (prop->value() == "intreturn") {
if (_intreturn) {
@@ -792,7 +851,6 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
ProcessorList::iterator p;
p = _processors.end();
--p;
- cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
@@ -1213,10 +1271,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
list< pair<ChanCount,ChanCount> > configuration;
uint32_t index = 0;
- cerr << "Processor check with " << _processors.size() << endl;
-
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
- cerr << "Checking out " << (*p)->name() << " type = " << endl;
if ((*p)->can_support_io_configuration(in, out)) {
configuration.push_back(make_pair(in, out));
in = out;
@@ -1538,6 +1593,15 @@ Route::_set_state (const XMLNode& node, bool call_base)
set_processor_state (processor_state);
+ if ((prop = node.property ("solo_level")) != 0) {
+ _solo_level = 0; // needed for mod_solo_level() to work
+ mod_solo_level (atoi (prop->value()));
+ }
+
+ if ((prop = node.property ("solo-isolated")) != 0) {
+ set_solo_isolated (prop->value() == "yes", this);
+ }
+
if ((prop = node.property (X_("phase-invert"))) != 0) {
set_phase_invert (prop->value()=="yes"?true:false);
}
@@ -1667,8 +1731,6 @@ Route::set_processor_state (const XMLNode& node)
XMLNodeConstIterator niter;
ProcessorList::iterator i, o;
- dump_processors ("set processor states", _processors);
-
// Iterate through existing processors, remove those which are not in the state list
for (i = _processors.begin(); i != _processors.end(); ) {
@@ -1841,11 +1903,21 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
{
Glib::RWLock::ReaderLock rm (_processor_lock);
- for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
- boost::shared_ptr<const InternalSend> d = boost::dynamic_pointer_cast<const InternalSend>(*x);
+ for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++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.control_out()) {
+ _control_outs = boost::dynamic_pointer_cast<Delivery>(d);
+ }
+
/* already listening via the specified IO: do nothing */
+
return 0;
}
}
@@ -1894,6 +1966,10 @@ Route::drop_listen (boost::shared_ptr<Route> route)
}
rl.release ();
+
+ if (route == _session.control_out()) {
+ _control_outs.reset ();
+ }
}
void