X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Froute.cc;h=fa4b3ce51d08a72f280bf2acad00e297d96b99bd;hb=4e4c75a34a694a91bac75e763f3f83c512d11b36;hp=154c5fd0a06669381eec5c53775726a044c18232;hpb=f6fdd8dcbf41f864e9f0cc32dabe81fe3533ddfe;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 154c5fd0a0..fa4b3ce51d 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -25,6 +25,7 @@ #include "pbd/xml++.h" #include "pbd/enumwriter.h" #include "pbd/memento_command.h" +#include "pbd/stacktrace.h" #include "evoral/Curve.hpp" @@ -63,13 +64,15 @@ using namespace ARDOUR; using namespace PBD; uint32_t Route::order_key_cnt = 0; -boost::signals2::signal Route::SyncOrderKeys; +PBD::Signal1 Route::SyncOrderKeys; +PBD::Signal0 Route::RemoteControlIDChange; Route::Route (Session& sess, string name, Flag flg, DataType default_type) : SessionObject (sess, name) , AutomatableControls (sess) , _flags (flg) , _solo_control (new SoloControllable (X_("solo"), *this)) + , _mute_control (new MuteControllable (X_("mute"), *this)) , _mute_master (new MuteMaster (sess, name)) , _default_type (default_type) @@ -93,13 +96,14 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) /* now that we have _meter, its safe to connect to this */ - scoped_connect (Metering::Meter, (boost::bind (&Route::meter, this))); + Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this))); } Route::Route (Session& sess, const XMLNode& node, DataType default_type) : SessionObject (sess, "toBeReset") , AutomatableControls (sess) , _solo_control (new SoloControllable (X_("solo"), *this)) + , _mute_control (new MuteControllable (X_("mute"), *this)) , _mute_master (new MuteMaster (sess, "toBeReset")) , _default_type (default_type) { @@ -109,7 +113,7 @@ Route::Route (Session& sess, const XMLNode& node, DataType default_type) /* now that we have _meter, its safe to connect to this */ - scoped_connect (Metering::Meter, (boost::bind (&Route::meter, this))); + Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this))); } void @@ -139,16 +143,19 @@ Route::init () /* add standard controls */ + _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle)); + _mute_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle)); + add_control (_solo_control); - add_control (_mute_master); + add_control (_mute_control); /* input and output objects */ _input.reset (new IO (_session, _name, IO::Input, _default_type)); _output.reset (new IO (_session, _name, IO::Output, _default_type)); - scoped_connect (_input->changed, boost::bind (&Route::input_change_handler, this, _1, _2)); - scoped_connect (_output->changed, boost::bind (&Route::output_change_handler, this, _1, _2)); + _input->changed.connect_same_thread (*this, boost::bind (&Route::input_change_handler, this, _1, _2)); + _output->changed.connect_same_thread (*this, boost::bind (&Route::output_change_handler, this, _1, _2)); /* add amp processor */ @@ -160,8 +167,14 @@ Route::~Route () { DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name)); + /* do this early so that we don't get incoming signals as we are going through destruction + */ + + drop_connections (); + /* don't use clear_processors here, as it depends on the session which may - be half-destroyed by now */ + be half-destroyed by now + */ Glib::RWLock::WriterLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { @@ -172,11 +185,14 @@ Route::~Route () } void -Route::set_remote_control_id (uint32_t id) +Route::set_remote_control_id (uint32_t id, bool notify_class_listeners) { if (id != _remote_control_id) { _remote_control_id = id; RemoteControlIDChanged (); + if (notify_class_listeners) { + RemoteControlIDChange (); + } } } @@ -436,11 +452,7 @@ Route::process_output_buffers (BufferSet& bufs, assert (bufs.count() == (*i)->input_streams()); (*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back()); - bufs.set_count (ChanCount::max(bufs.count(), (*i)->output_streams())); - } - - if (!_processors.empty()) { - bufs.set_count (ChanCount::max (bufs.count(), _processors.back()->output_streams())); + bufs.set_count ((*i)->output_streams()); } } } @@ -792,7 +804,8 @@ Route::add_processor (boost::shared_ptr processor, ProcessorList::ite // XXX: do we want to emit the signal here ? change call order. processor->activate (); } - scoped_connect (processor->ActiveChanged, boost::bind (&Session::update_latency_compensation, &_session, false, false)); + + processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); _output->set_user_latency (0); } @@ -1047,7 +1060,7 @@ Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter return -1; } - scoped_connect ((*i)->ActiveChanged, boost::bind (&Session::update_latency_compensation, &_session, false, false)); + (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); } _output->set_user_latency (0); @@ -2837,14 +2850,60 @@ void Route::SoloControllable::set_value (float 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); + + 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 } float Route::SoloControllable::get_value (void) const { - return route.self_soloed() ? 1.0f : 0.0f; + if (Config->get_solo_control_is_listen_control()) { + return route.listening() ? 1.0f : 0.0f; + } else { + return route.self_soloed() ? 1.0f : 0.0f; + } +} + +Route::MuteControllable::MuteControllable (std::string name, Route& r) + : AutomationControl (r.session(), Evoral::Parameter (MuteAutomation), + boost::shared_ptr(), name) + , route (r) +{ + boost::shared_ptr gl(new AutomationList(Evoral::Parameter(MuteAutomation))); + set_list (gl); +} + +void +Route::MuteControllable::set_value (float 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); + _session.set_mute (rl, bval); +#else + route.set_mute (bval, this); +#endif +} + +float +Route::MuteControllable::get_value (void) const +{ + return route.muted() ? 1.0f : 0.0f; } void @@ -3099,3 +3158,40 @@ Route::get_control (const Evoral::Parameter& param) return c; } + +boost::shared_ptr +Route::nth_plugin (uint32_t n) +{ + Glib::RWLock::ReaderLock lm (_processor_lock); + ProcessorList::iterator i; + + for (i = _processors.begin(); i != _processors.end(); ++i) { + if (boost::dynamic_pointer_cast (*i)) { + if (n-- == 0) { + return *i; + } + } + } + + return boost::shared_ptr (); +} + +boost::shared_ptr +Route::nth_send (uint32_t n) +{ + Glib::RWLock::ReaderLock lm (_processor_lock); + ProcessorList::iterator i; + + for (i = _processors.begin(); i != _processors.end(); ++i) { + cerr << "check " << (*i)->name() << endl; + if (boost::dynamic_pointer_cast (*i)) { + if (n-- == 0) { + return *i; + } + } else { + cerr << "\tnot a send\n"; + } + } + + return boost::shared_ptr (); +}