summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-07-01 13:36:50 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-07-01 13:36:50 +0000
commit0d6515a24349be9add8d3919d4c6c4d509bac687 (patch)
treeeca75aee7588424eddd30b558098321acf686c65 /libs/ardour
parent4df4574be472b599e149af2ef161ed505088e71a (diff)
separate solo & listen. some minor fixes and additional related fixes still to come
git-svn-id: svn://localhost/ardour2/branches/3.0@5298 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/buffer_set.h1
-rw-r--r--libs/ardour/ardour/internal_return.h2
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h4
-rw-r--r--libs/ardour/ardour/route.h7
-rw-r--r--libs/ardour/ardour/session.h16
-rw-r--r--libs/ardour/ardour/types.h9
-rw-r--r--libs/ardour/buffer_set.cc71
-rw-r--r--libs/ardour/enums.cc9
-rw-r--r--libs/ardour/globals.cc2
-rw-r--r--libs/ardour/internal_return.cc6
-rw-r--r--libs/ardour/route.cc115
-rw-r--r--libs/ardour/session.cc157
-rw-r--r--libs/ardour/session_state.cc8
13 files changed, 275 insertions, 132 deletions
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index ecd4e4ab72..664c22c583 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -59,6 +59,7 @@ public:
void attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset = 0);
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity);
+ void ensure_buffers(const ChanCount& chns, size_t buffer_capacity);
const ChanCount& available() const { return _available; }
ChanCount& available() { return _available; }
diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h
index a23b17adf8..c057d45cc8 100644
--- a/libs/ardour/ardour/internal_return.h
+++ b/libs/ardour/ardour/internal_return.h
@@ -34,7 +34,7 @@ class InternalReturn : public Return
InternalReturn (Session&);
InternalReturn (Session&, const XMLNode&);
- bool visible() const { return false; }
+ bool visible() const { return true; }
XMLNode& state(bool full);
XMLNode& get_state(void);
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 20b9c85f0e..5217ea6aa7 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -77,7 +77,9 @@ CONFIG_VARIABLE (bool, mute_affects_post_fader, "mute-affects-post-fader", true)
CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", true)
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
-CONFIG_VARIABLE (SoloModel, solo_model, "solo-model", SoloInPlace)
+CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
+
+CONFIG_VARIABLE (bool, solo_control_is_listen_control, "solo-control-is-listen-control", false)
CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true)
CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false)
CONFIG_VARIABLE (bool, all_safe, "all-safe", false)
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index d346a22342..40a11cdae1 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -124,6 +124,7 @@ class Route : public SessionObject, public AutomatableControls
void set_mute (bool yn, void* src);
bool muted () const;
+
/* controls use set_solo() to modify this route's solo state
*/
@@ -132,6 +133,9 @@ class Route : public SessionObject, public AutomatableControls
void set_solo_isolated (bool yn, void *src);
bool solo_isolated() const;
+
+ void set_listen (bool yn, void* src);
+ bool listening () const;
void set_phase_invert (bool yn);
bool phase_invert() const;
@@ -229,6 +233,7 @@ class Route : public SessionObject, public AutomatableControls
sigc::signal<void> active_changed;
sigc::signal<void> phase_invert_changed;
sigc::signal<void> denormal_protection_changed;
+ sigc::signal<void,void*> listen_changed;
sigc::signal<void,void*> solo_changed;
sigc::signal<void,void*> solo_safe_changed;
sigc::signal<void,void*> solo_isolated_changed;
@@ -262,7 +267,7 @@ class Route : public SessionObject, public AutomatableControls
sigc::signal<void,void*> SelectedChanged;
- int listen_via (boost::shared_ptr<Route>, const std::string& name);
+ int listen_via (boost::shared_ptr<Route>, bool);
void drop_listen (boost::shared_ptr<Route>);
bool feeds (boost::shared_ptr<Route>);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 39822de678..2be7e418dc 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -723,9 +723,11 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
/* session-wide solo/mute/rec-enable */
bool soloing() const { return _non_soloed_outs_muted; }
-
+ bool listening() const { return _listen_cnt > 0; }
+
void set_all_solo (bool);
void set_all_mute (bool);
+ void set_all_listen (bool);
sigc::signal<void,bool> SoloActive;
sigc::signal<void> SoloChanged;
@@ -1031,6 +1033,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
float _meter_hold;
float _meter_falloff;
bool _non_soloed_outs_muted;
+ uint32_t _listen_cnt;
void set_worst_io_latencies ();
void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
@@ -1451,16 +1454,15 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
/* mixer stuff */
- bool solo_update_disabled;
+ bool solo_update_disabled;
+ void route_listen_changed (void *src, boost::weak_ptr<Route>);
void route_mute_changed (void *src);
void route_solo_changed (void *src, boost::weak_ptr<Route>);
- void catch_up_on_solo ();
- void catch_up_on_solo_mute_override ();
- void solo_model_changed ();
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
- void modify_solo_mute (bool, bool);
- void strip_portname_for_solo (std::string& portname);
+
+ void listen_position_changed ();
+ void solo_control_mode_changed ();
/* REGION MANAGEMENT */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 3067928161..809eb5b2b2 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -330,10 +330,9 @@ namespace ARDOUR {
AddHigher
};
- enum SoloModel {
- SoloInPlace,
- SoloAFL,
- SoloPFL
+ enum ListenPosition {
+ AfterFaderListen,
+ PreFaderListen
};
enum AutoConnectOption {
@@ -455,7 +454,7 @@ 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::RemoteModel& sf);
-std::istream& operator>>(std::istream& o, ARDOUR::SoloModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::ListenPosition& sf);
std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf);
std::istream& operator>>(std::istream& o, ARDOUR::CrossfadeModel& sf);
std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf);
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index 7e6ddd68dd..589c13ce41 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -130,6 +130,7 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
}
_available.set(type, num_buffers);
+ _count.set (type, num_buffers);
}
#ifdef HAVE_SLV2
@@ -149,6 +150,76 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
assert(bufs[0]->capacity() >= buffer_capacity);
}
+/** Ensure that the number of buffers of each type @a type matches @a chns
+ * and each buffer is of size at least @a buffer_capacity
+ */
+void
+BufferSet::ensure_buffers(const ChanCount& chns, size_t buffer_capacity)
+{
+ if (chns == ChanCount::ZERO) {
+ return;
+ }
+
+ // If we're a mirror just make sure we're ok
+ if (_is_mirror) {
+ assert(_count >= chns);
+ return;
+ }
+
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+
+ // The vector of buffers of this type
+ BufferVec& bufs = _buffers[*t];
+
+ uint32_t nbufs = chns.get (*t);
+
+ if (nbufs == 0) {
+ // Nuke it
+ for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
+ delete (*i);
+ }
+ bufs.clear();
+ continue;
+ }
+
+ // If there's not enough or they're too small, just nuke the whole thing and
+ // rebuild it (so I'm lazy..)
+ if (bufs.size() < nbufs
+ || (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
+
+ // Nuke it
+ for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
+ delete (*i);
+ }
+ bufs.clear();
+
+ // Rebuild it
+ for (size_t i = 0; i < nbufs; ++i) {
+ bufs.push_back(Buffer::create(*t, buffer_capacity));
+ }
+
+ _available.set (*t, nbufs);
+ }
+
+#ifdef HAVE_SLV2
+ // Ensure enough low level MIDI format buffers are available for conversion
+ // in both directions (input & output, out-of-place)
+ if (*t == DataType::MIDI && _lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2 + 1) {
+ while (_lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2) {
+ _lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
+ }
+ }
+#endif
+
+ // Post-conditions
+ assert(bufs[0]->type() == *t);
+ assert(bufs.size() == _available.get(*t));
+ assert(bufs[0]->capacity() >= buffer_capacity);
+ }
+
+ assert (available() == chns);
+}
+
/** Get the capacity (size) of the available buffers of the given type.
*
* All buffers of a certain type always have the same capacity.
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index 32a1420bc4..efe72ddb4b 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -64,7 +64,7 @@ setup_enum_writer ()
DenormalModel _DenormalModel;
CrossfadeModel _CrossfadeModel;
LayerModel _LayerModel;
- SoloModel _SoloModel;
+ ListenPosition _ListenPosition;
SampleFormat _SampleFormat;
CDMarkerFormat _CDMarkerFormat;
HeaderFormat _HeaderFormat;
@@ -229,10 +229,9 @@ setup_enum_writer ()
REGISTER_ENUM (AddHigher);
REGISTER (_LayerModel);
- REGISTER_ENUM (SoloInPlace);
- REGISTER_ENUM (SoloAFL);
- REGISTER_ENUM (SoloPFL);
- REGISTER (_SoloModel);
+ REGISTER_ENUM (AfterFaderListen);
+ REGISTER_ENUM (PreFaderListen);
+ REGISTER (_ListenPosition);
REGISTER_ENUM (AutoConnectPhysical);
REGISTER_ENUM (AutoConnectMaster);
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 0ce024c31e..26e2baca26 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -604,7 +604,7 @@ std::istream& operator>>(std::istream& o, AutoConnectOption& var) { return int_t
std::istream& operator>>(std::istream& o, MonitorModel& var) { return int_to_type<MonitorModel> (o, var); }
std::istream& operator>>(std::istream& o, RemoteModel& var) { return int_to_type<RemoteModel> (o, var); }
std::istream& operator>>(std::istream& o, EditMode& var) { return int_to_type<EditMode> (o, var); }
-std::istream& operator>>(std::istream& o, SoloModel& var) { return int_to_type<SoloModel> (o, var); }
+std::istream& operator>>(std::istream& o, ListenPosition& var) { return int_to_type<ListenPosition> (o, var); }
std::istream& operator>>(std::istream& o, LayerModel& var) { return int_to_type<LayerModel> (o, var); }
std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_type<CrossfadeModel> (o, var); }
std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type<SlaveSource> (o, var); }
diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc
index 0a45228c67..f3ab1dd901 100644
--- a/libs/ardour/internal_return.cc
+++ b/libs/ardour/internal_return.cc
@@ -60,7 +60,7 @@ bool
InternalReturn::configure_io (ChanCount in, ChanCount out)
{
IOProcessor::configure_io (in, out);
- allocate_buffers (_session.get_block_size());
+ allocate_buffers (_session.engine().frames_per_cycle());
return true;
}
@@ -73,8 +73,8 @@ InternalReturn::set_block_size (nframes_t nframes)
void
InternalReturn::allocate_buffers (nframes_t nframes)
{
- buffers.ensure_buffers (DataType::AUDIO, _configured_input.n_audio(), nframes);
- buffers.ensure_buffers (DataType::MIDI, _configured_input.n_midi(), nframes);
+ buffers.ensure_buffers (_configured_input, nframes);
+ buffers.set_count (_configured_input);
}
BufferSet*
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 575cad8e0b..a6af898f38 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -454,14 +454,26 @@ Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
}
bufs.set_count (_input->n_ports());
-
- for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+
+ if (is_control() && _session.listening()) {
- BufferSet::iterator o = bufs.begin(*t);
- PortSet& ports (_input->ports());
+ /* control/monitor bus ignores input ports when something is
+ feeding the listen "stream". data will "arrive" into the
+ route from the intreturn processor element.
+ */
+
+ bufs.silence (nframes, 0);
- for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
- o->read_from (i->get_buffer(nframes), nframes);
+ } else {
+
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+
+ BufferSet::iterator o = bufs.begin(*t);
+ PortSet& ports (_input->ports());
+
+ for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
+ o->read_from (i->get_buffer(nframes), nframes);
+ }
}
}
@@ -475,6 +487,32 @@ Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t n
}
void
+Route::set_listen (bool yn, void* src)
+{
+ if (_control_outs) {
+ if (yn != _control_outs->active()) {
+ if (yn) {
+ _control_outs->activate ();
+ } else {
+ _control_outs->deactivate ();
+ }
+
+ listen_changed (src); /* EMIT SIGNAL */
+ }
+ }
+}
+
+bool
+Route::listening () const
+{
+ if (_control_outs) {
+ return _control_outs->active ();
+ } else {
+ return false;
+ }
+}
+
+void
Route::set_solo (bool yn, void *src)
{
if (_solo_safe || _solo_isolated) {
@@ -506,33 +544,11 @@ Route::mod_solo_level (int32_t delta)
_solo_level += delta;
}
- /* tell "special" delivery units what the solo situation is
+ /* tell main outs 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 SoloAFL:
- case SoloPFL:
- /* 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;
- }
+ _main_outs->set_solo_level (_solo_level);
+ _main_outs->set_solo_isolated (_solo_isolated);
}
void
@@ -546,28 +562,11 @@ Route::set_solo_isolated (bool yn, void *src)
if (yn != _solo_isolated) {
_solo_isolated = yn;
- /* tell "special" delivery units what the solo situation is
+ /* tell main outs 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 SoloAFL:
- case SoloPFL:
- 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;
- }
+ _main_outs->set_solo_level (_solo_level);
+ _main_outs->set_solo_isolated (_solo_isolated);
solo_isolated_changed (src);
}
@@ -711,7 +710,9 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
}
// XXX: do we want to emit the signal here ? change call order.
- processor->activate ();
+ if (!boost::dynamic_pointer_cast<InternalSend>(processor)) {
+ processor->activate ();
+ }
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
_output->set_user_latency (0);
@@ -1862,7 +1863,8 @@ Route::get_return_buffer () const
boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
if (d) {
- return d->get_buffers ();
+ BufferSet* bs = d->get_buffers ();
+ return bs;
}
}
@@ -1884,7 +1886,7 @@ Route::release_return_buffer () const
}
int
-Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
+Route::listen_via (boost::shared_ptr<Route> route, bool active)
{
vector<string> ports;
vector<string>::const_iterator i;
@@ -1893,6 +1895,7 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
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);
if (d && d->target_route() == route) {
@@ -1921,6 +1924,10 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
return -1;
}
+ if (route == _session.control_out()) {
+ _control_outs = listener;
+ }
+
add_processor (listener, PreFader);
return 0;
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 24a40f4c31..e470c2623e 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -46,6 +46,7 @@
#include "ardour/analyser.h"
#include "ardour/audio_buffer.h"
#include "ardour/audio_diskstream.h"
+#include "ardour/audio_port.h"
#include "ardour/audio_track.h"
#include "ardour/audioengine.h"
#include "ardour/audiofilesource.h"
@@ -269,16 +270,6 @@ Session::Session (AudioEngine &eng,
RouteList rl;
int control_id = 1;
- if (control_out_channels) {
- ChanCount count(DataType::AUDIO, control_out_channels);
- shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
- r->input()->ensure_io (count, false, this);
- r->output()->ensure_io (count, false, this);
- r->set_remote_control_id (control_id++);
-
- rl.push_back (r);
- }
-
if (master_out_channels) {
ChanCount count(DataType::AUDIO, master_out_channels);
shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
@@ -292,6 +283,16 @@ Session::Session (AudioEngine &eng,
output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
}
+ if (control_out_channels) {
+ ChanCount count(DataType::AUDIO, control_out_channels);
+ shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
+ r->input()->ensure_io (count, false, this);
+ r->output()->ensure_io (count, false, this);
+ r->set_remote_control_id (control_id++);
+
+ rl.push_back (r);
+ }
+
if (!rl.empty()) {
add_routes (rl, false);
}
@@ -680,11 +681,46 @@ Session::when_engine_running ()
if (_control_out) {
- uint32_t limit = _control_out->n_outputs().n_total();
+ /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
+ are undefined, at best.
+ */
+
+ /* control out listens to master bus (but ignores it
+ under some conditions)
+ */
+
+ uint32_t limit = _control_out->n_inputs().n_audio();
+ if (_master_out) {
+ for (uint32_t n = 0; n < limit; ++n) {
+ AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
+ AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
+
+ if (o) {
+ string connect_to = o->name();
+ if (_control_out->input()->connect (p, connect_to, this)) {
+ error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
+ << endmsg;
+ break;
+ }
+ }
+ }
+ }
+
+ /* connect control out to physical outs, but use ones after the master
+ if possible
+ */
+
+ /* XXX this logic is wrong for mixed port types */
+
+ uint32_t shift = _master_out->n_outputs().n_audio();
+ uint32_t mod = _master_out->n_outputs().n_audio();
+ limit = _control_out->n_outputs().n_audio();
+
for (uint32_t n = 0; n < limit; ++n) {
+
Port* p = _control_out->output()->nth (n);
- string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
+ string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
if (!connect_to.empty()) {
if (_control_out->output()->connect (p, connect_to, this)) {
@@ -764,7 +800,7 @@ Session::hookup_io ()
continue;
}
- (*x)->listen_via (_control_out, X_("listen"));
+ (*x)->listen_via (_control_out, false);
}
}
@@ -780,9 +816,13 @@ Session::hookup_io ()
graph_reordered ();
- /* update mixer solo state */
+ /* update the full solo state, which can't be
+ correctly determined on a per-route basis, but
+ needs the global overview that only the session
+ has.
+ */
- catch_up_on_solo();
+ update_route_solo_state ();
}
void
@@ -2069,6 +2109,7 @@ Session::add_routes (RouteList& new_routes, bool save)
boost::weak_ptr<Route> wpr (*x);
+ (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
(*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
(*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
(*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
@@ -2090,7 +2131,8 @@ Session::add_routes (RouteList& new_routes, bool save)
if ((*x)->is_control() || (*x)->is_master()) {
continue;
}
- (*x)->listen_via (_control_out, "control");
+ cerr << "Add listen via control outs\n";
+ (*x)->listen_via (_control_out, false);
}
resort_routes ();
@@ -2139,7 +2181,7 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, boost::shared_ptr<Ro
continue;
}
- (*i)->listen_via (dest, "aux");
+ (*i)->listen_via (dest, true);
}
}
@@ -2254,6 +2296,22 @@ Session::route_mute_changed (void* src)
}
void
+Session::route_listen_changed (void* src, boost::weak_ptr<Route> wpr)
+{
+ boost::shared_ptr<Route> route = wpr.lock();
+ if (!route) {
+ error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
+ return;
+ }
+
+ if (route->listening()) {
+ _listen_cnt++;
+ } else if (_listen_cnt > 0) {
+ _listen_cnt--;
+ }
+}
+
+void
Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
{
if (solo_update_disabled) {
@@ -2329,34 +2387,6 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
}
}
-void
-Session::catch_up_on_solo ()
-{
- /* this is called after set_state() to catch the full solo
- state, which can't be correctly determined on a per-route
- basis, but needs the global overview that only the session
- has.
- */
- update_route_solo_state();
-}
-
-void
-Session::catch_up_on_solo_mute_override ()
-{
- if (Config->get_solo_model() != SoloInPlace) {
- return;
- }
-
- /* this is called whenever the param solo-mute-override is
- changed.
- */
- shared_ptr<RouteList> r = routes.reader ();
-
- for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- // (*i)->catch_up_on_solo_mute_override ();
- }
-}
-
shared_ptr<Route>
Session::route_by_name (string name)
{
@@ -3492,6 +3522,20 @@ Session::set_all_solo (bool yn)
}
void
+Session::set_all_listen (bool yn)
+{
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (!(*i)->is_hidden()) {
+ (*i)->set_listen (yn, this);
+ }
+ }
+
+ set_dirty();
+}
+
+void
Session::set_all_mute (bool yn)
{
shared_ptr<RouteList> r = routes.reader ();
@@ -4257,19 +4301,16 @@ Session::update_have_rec_enabled_diskstream ()
}
void
-Session::solo_model_changed ()
+Session::listen_position_changed ()
{
Placement p;
- switch (Config->get_solo_model()) {
- case SoloInPlace:
- return;
-
- case SoloAFL:
+ switch (Config->get_listen_position()) {
+ case AfterFaderListen:
p = PostFader;
break;
- case SoloPFL:
+ case PreFaderListen:
p = PreFader;
break;
}
@@ -4282,6 +4323,18 @@ Session::solo_model_changed ()
}
void
+Session::solo_control_mode_changed ()
+{
+ /* cancel all solo or all listen when solo control mode changes */
+
+ if (Config->get_solo_control_is_listen_control()) {
+ set_all_solo (false);
+ } else {
+ set_all_listen (false);
+ }
+}
+
+void
Session::route_group_changed ()
{
RouteGroupChanged (); /* EMIT SIGNAL */
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 32e31580af..c05dda60cd 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -152,6 +152,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_non_soloed_outs_muted = false;
+ _listen_cnt = 0;
g_atomic_int_set (&processing_prohibited, 0);
_transport_speed = 0;
_last_transport_speed = 0;
@@ -3152,10 +3153,13 @@ Session::config_changed (std::string p, bool ours)
}
} else if (p == "solo-mute-override") {
// catch_up_on_solo_mute_override ();
- } else if (p == "solo-model") {
- solo_model_changed ();
+ } else if (p == "listen-position") {
+ listen_position_changed ();
+ } else if (p == "solo-control-is-listen-control") {
+ solo_control_mode_changed ();
}
+
set_dirty ();
}