diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 9b2ed47c76..4f6d18e4af 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "pbd/fastlog.h" @@ -65,7 +66,7 @@ class Pannable; class CapturingProcessor; class InternalSend; -class Route : public SessionObject, public Automatable, public RouteGroupMember, public GraphNode +class Route : public SessionObject, public Automatable, public RouteGroupMember, public GraphNode, public boost::enable_shared_from_this { public: @@ -337,20 +338,24 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, boost::shared_ptr get_control (const Evoral::Parameter& param); - struct SoloControllable : public AutomationControl { - SoloControllable (std::string name, Route&); + class SoloControllable : public AutomationControl { + public: + SoloControllable (std::string name, boost::shared_ptr); void set_value (double); - double get_value (void) const; + double get_value () const; - Route& route; + private: + boost::weak_ptr _route; }; struct MuteControllable : public AutomationControl { - MuteControllable (std::string name, Route&); + public: + MuteControllable (std::string name, boost::shared_ptr); void set_value (double); - double get_value (void) const; + double get_value () const; - Route& route; + private: + boost::weak_ptr _route; }; boost::shared_ptr solo_control() const { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 57e56185b9..f8c61353b7 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -97,8 +97,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _recordable (true) , _silent (false) , _declickable (false) - , _solo_control (new SoloControllable (X_("solo"), *this)) - , _mute_control (new MuteControllable (X_("mute"), *this)) , _mute_master (new MuteMaster (sess, name)) , _have_internal_generator (false) , _solo_safe (false) @@ -115,6 +113,9 @@ Route::init () { /* add standard controls */ + _solo_control.reset (new SoloControllable (X_("solo"), shared_from_this ())); + _mute_control.reset (new MuteControllable (X_("mute"), shared_from_this ())); + _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle)); _mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle)); @@ -3096,10 +3097,10 @@ Route::automation_snapshot (framepos_t now, bool force) } } -Route::SoloControllable::SoloControllable (std::string name, Route& r) - : AutomationControl (r.session(), Evoral::Parameter (SoloAutomation), +Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr r) + : AutomationControl (r->session(), Evoral::Parameter (SoloAutomation), boost::shared_ptr(), name) - , route (r) + , _route (r) { boost::shared_ptr gl(new AutomationList(Evoral::Parameter(SoloAutomation))); set_list (gl); @@ -3109,36 +3110,42 @@ void Route::SoloControllable::set_value (double val) { bool bval = ((val >= 0.5f) ? true: false); -# if 0 - this is how it should be done boost::shared_ptr rl (new RouteList); - rl->push_back (route); + + boost::shared_ptr r = _route.lock (); + if (!r) { + return; + } + + rl->push_back (r); if (Config->get_solo_control_is_listen_control()) { _session.set_listen (rl, bval); } else { _session.set_solo (rl, bval); } -#else - route.set_solo (bval, this); -#endif } double -Route::SoloControllable::get_value (void) const +Route::SoloControllable::get_value () const { + boost::shared_ptr r = _route.lock (); + if (!r) { + return 0; + } + if (Config->get_solo_control_is_listen_control()) { - return route.listening_via_monitor() ? 1.0f : 0.0f; + return r->listening_via_monitor() ? 1.0f : 0.0f; } else { - return route.self_soloed() ? 1.0f : 0.0f; + return r->self_soloed() ? 1.0f : 0.0f; } } -Route::MuteControllable::MuteControllable (std::string name, Route& r) - : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation), +Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr r) + : AutomationControl (r->session(), Evoral::Parameter (MuteAutomation), boost::shared_ptr(), name) - , route (r) + , _route (r) { boost::shared_ptr gl(new AutomationList(Evoral::Parameter(MuteAutomation))); set_list (gl); @@ -3148,19 +3155,20 @@ void Route::MuteControllable::set_value (double val) { bool bval = ((val >= 0.5f) ? true: false); -# if 0 - this is how it should be done boost::shared_ptr rl (new RouteList); - rl->push_back (route); + + boost::shared_ptr r = _route.lock (); + if (!r) { + return; + } + + rl->push_back (r); _session.set_mute (rl, bval); -#else - route.set_mute (bval, this); -#endif } double -Route::MuteControllable::get_value (void) const +Route::MuteControllable::get_value () const { return route.muted() ? 1.0f : 0.0f; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index e09513b07d..734fad2d1b 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -671,7 +671,6 @@ Session::hookup_io () _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting); - if (!auditioner) { /* we delay creating the auditioner till now because @@ -679,13 +678,12 @@ Session::hookup_io () */ try { - Auditioner* a = new Auditioner (*this); + boost::shared_ptr a (new Auditioner (*this)); if (a->init()) { - delete a; - throw failed_constructor(); + throw failed_constructor (); } a->use_new_diskstream (); - auditioner.reset (a); + auditioner = a; } catch (failed_constructor& err) { @@ -1486,20 +1484,17 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m boost::shared_ptr track; try { - MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode); + track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode)); - if (mt->init ()) { - delete mt; + if (track->init ()) { goto failed; } - mt->use_new_diskstream(); + track->use_new_diskstream(); #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (mt, "Track"); + boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); #endif - track = boost::shared_ptr(mt); - { Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) { @@ -1657,20 +1652,17 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod boost::shared_ptr track; try { - AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode); + track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode)); - if (at->init ()) { - delete at; + if (track->init ()) { goto failed; } - at->use_new_diskstream(); + track->use_new_diskstream(); #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (at, "Track"); + boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); #endif - track = boost::shared_ptr(at); - { Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); @@ -1779,18 +1771,15 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r } try { - Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO); + boost::shared_ptr bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO)); - if (rt->init ()) { - delete rt; + if (bus->init ()) { goto failure; } #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (rt, "Route"); + boost_debug_shared_ptr_mark_interesting (bus.get(), "Route"); #endif - boost::shared_ptr bus (rt); - { Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); @@ -2222,6 +2211,8 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr wpr) _listen_cnt--; } + + update_route_solo_state (); } void Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr wpr) diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index a8e8abf804..3dd1b5c5eb 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -580,15 +580,13 @@ Session::create (const string& mix_template, BusProfile* bus_profile) ChanCount count(DataType::AUDIO, bus_profile->master_out_channels); if (bus_profile->master_out_channels) { - Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO); - if (rt->init ()) { - delete rt; + boost::shared_ptr r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO)); + if (r->init ()) { return -1; } #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (rt, "Route"); + boost_debug_shared_ptr_mark_interesting (rt.get(), "Route"); #endif - boost::shared_ptr r (rt); { Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); r->input()->ensure_io (count, false, this); @@ -599,15 +597,13 @@ Session::create (const string& mix_template, BusProfile* bus_profile) rl.push_back (r); if (Config->get_use_monitor_bus()) { - Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO); - if (rt->init ()) { - delete rt; + boost::shared_ptr r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO)); + if (r->init ()) { return -1; } #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS boost_debug_shared_ptr_mark_interesting (rt, "Route"); #endif - boost::shared_ptr r (rt); { Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); r->input()->ensure_io (count, false, this); @@ -1502,40 +1498,35 @@ Session::XMLRouteFactory (const XMLNode& node, int version) if (ds_child) { - Track* track; + boost::shared_ptr track; if (type == DataType::AUDIO) { - track = new AudioTrack (*this, X_("toBeResetFroXML")); - + track.reset (new AudioTrack (*this, X_("toBeResetFroXML"))); } else { - track = new MidiTrack (*this, X_("toBeResetFroXML")); + track.reset (new MidiTrack (*this, X_("toBeResetFroXML"))); } if (track->init()) { - delete track; return ret; } if (track->set_state (node, version)) { - delete track; return ret; } #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (track, "Track"); + boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); #endif - ret.reset (track); + ret = track; } else { - Route* rt = new Route (*this, X_("toBeResetFroXML")); + boost::shared_ptr r (new Route (*this, X_("toBeResetFroXML"))); - if (rt->init () == 0 && rt->set_state (node, version) == 0) { + if (r->init () == 0 && r->set_state (node, version) == 0) { #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (rt, "Route"); + boost_debug_shared_ptr_mark_interesting (r.get(), "Route"); #endif - ret.reset (rt); - } else { - delete rt; + ret = r; } } @@ -1577,42 +1568,37 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version) return boost::shared_ptr (); } - Track* track; - + boost::shared_ptr track; + if (type == DataType::AUDIO) { - track = new AudioTrack (*this, X_("toBeResetFroXML")); - + track.reset (new AudioTrack (*this, X_("toBeResetFroXML"))); } else { - track = new MidiTrack (*this, X_("toBeResetFroXML")); + track.reset (new MidiTrack (*this, X_("toBeResetFroXML"))); } if (track->init()) { - delete track; return ret; } if (track->set_state (node, version)) { - delete track; return ret; } track->set_diskstream (*i); #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - boost_debug_shared_ptr_mark_interesting (track, "Track"); + boost_debug_shared_ptr_mark_interesting (track.get(), "Track"); #endif - ret.reset (track); + ret = track; } else { - Route* rt = new Route (*this, X_("toBeResetFroXML")); + boost::shared_ptr r (new Route (*this, X_("toBeResetFroXML"))); - if (rt->init () == 0 && rt->set_state (node, version) == 0) { + if (r->init () == 0 && r->set_state (node, version) == 0) { #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS boost_debug_shared_ptr_mark_interesting (rt, "Route"); #endif - ret.reset (rt); - } else { - delete rt; + ret = r; } }