diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-07-01 13:36:50 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-07-01 13:36:50 +0000 |
commit | 0d6515a24349be9add8d3919d4c6c4d509bac687 (patch) | |
tree | eca75aee7588424eddd30b558098321acf686c65 /libs | |
parent | 4df4574be472b599e149af2ef161ed505088e71a (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')
-rw-r--r-- | libs/ardour/ardour/buffer_set.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/internal_return.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 7 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 16 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 9 | ||||
-rw-r--r-- | libs/ardour/buffer_set.cc | 71 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 9 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 2 | ||||
-rw-r--r-- | libs/ardour/internal_return.cc | 6 | ||||
-rw-r--r-- | libs/ardour/route.cc | 115 | ||||
-rw-r--r-- | libs/ardour/session.cc | 157 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 8 |
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 (); } |