From 6dac4da98344ed8ce609a4e7d567ef2f9fbb9b31 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 28 Apr 2010 01:29:06 +0000 Subject: more solo/mute architecture work. NOTE: changes to mute points are ignored right now git-svn-id: svn://localhost/ardour2/branches/3.0@7009 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/amp.cc | 2 +- libs/ardour/ardour/delivery.h | 7 --- libs/ardour/ardour/mute_master.h | 13 +++-- libs/ardour/ardour/route.h | 3 +- libs/ardour/delivery.cc | 100 +++++++++++++++++++----------------- libs/ardour/mute_master.cc | 66 ++++++++++++++++++------ libs/ardour/route.cc | 107 ++++++++++++--------------------------- libs/ardour/session.cc | 2 - 8 files changed, 147 insertions(+), 153 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index 35b567688c..14a3324a18 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -81,7 +81,7 @@ Amp::run (BufferSet& bufs, sframes_t /*start_frame*/, sframes_t /*end_frame*/, n } if (_mute_master) { - mute_gain = _mute_master->mute_gain_at (MuteMaster::PreFader); + mute_gain = _mute_master->mute_gain_at (MuteMaster::PreFader); } else { mute_gain = 1.0; } diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 1efa5436ee..bb07b9ab25 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -75,10 +75,6 @@ public: void no_outs_cuz_we_no_monitor(bool); - void set_solo_level (int32_t sl) { _solo_level = sl; } - void set_solo_isolated (bool yn) { _solo_isolated = yn; } - void set_solo_ignored (bool yn) { _solo_ignored = yn; } - void cycle_start (nframes_t); void increment_output_offset (nframes_t); void transport_stopped (sframes_t frame); @@ -113,9 +109,6 @@ public: gain_t _current_gain; nframes_t _output_offset; bool _no_outs_cuz_we_no_monitor; - uint32_t _solo_level; - bool _solo_isolated; - bool _solo_ignored; boost::shared_ptr _mute_master; bool no_panner_reset; boost::shared_ptr _panner; diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h index 610ca20dff..4ddb7075da 100644 --- a/libs/ardour/ardour/mute_master.h +++ b/libs/ardour/ardour/mute_master.h @@ -48,6 +48,8 @@ class MuteMaster : public PBD::Stateful bool muted_by_others() const { return _muted_by_others && (_mute_point != MutePoint (0)); } bool muted() const { return (_self_muted || (_muted_by_others > 0)) && (_mute_point != MutePoint (0)); } bool muted_at (MutePoint mp) const { return (_self_muted || (_muted_by_others > 0)) && (_mute_point & mp); } + bool self_muted_at (MutePoint mp) const { return _self_muted && (_mute_point & mp); } + bool muted_by_others_at (MutePoint mp) const { return (_muted_by_others > 0) && (_mute_point & mp); } bool muted_pre_fader() const { return muted_at (PreFader); } bool muted_post_fader() const { return muted_at (PostFader); } @@ -58,8 +60,8 @@ class MuteMaster : public PBD::Stateful void set_self_muted (bool yn) { _self_muted = yn; } void mod_muted_by_others (int delta); + void clear_muted_by_others (); - void clear_mute (); void mute_at (MutePoint); void unmute_at (MutePoint); @@ -67,15 +69,18 @@ class MuteMaster : public PBD::Stateful void set_mute_points (MutePoint); MutePoint mute_points() const { return _mute_point; } + void set_solo_level (int32_t); + PBD::Signal0 MutePointChanged; XMLNode& get_state(); int set_state(const XMLNode&, int version); private: - MutePoint _mute_point; - bool _self_muted; - uint32_t _muted_by_others; + volatile MutePoint _mute_point; + volatile bool _self_muted; + volatile uint32_t _muted_by_others; + volatile int32_t _solo_level; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index bdb041c7dd..5efb9c111b 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -476,8 +476,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou void placement_range (Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end); void set_self_solo (bool yn); - void set_delivery_solo (); - void markup_solo_ignore (); + void set_mute_master_solo (); }; } // namespace ARDOUR diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 5f857d7941..86a2f99c58 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -55,9 +55,6 @@ Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr mm, const string& , _current_gain (1.0) , _output_offset (0) , _no_outs_cuz_we_no_monitor (false) - , _solo_level (0) - , _solo_isolated (false) - , _solo_ignored (false) , _mute_master (mm) , no_panner_reset (false) { @@ -257,7 +251,6 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra tgain = target_gain (); if (tgain != _current_gain) { - /* target gain has changed */ Amp::apply_gain (bufs, nframes, _current_gain, tgain); @@ -297,11 +290,37 @@ Delivery::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nfra if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) { _output->copy_to_outputs (bufs, DataType::AUDIO, nframes, _output_offset); - } + + bool silent; + + for (uint32_t b = 0; b < bufs.count().n_audio(); ++b) { + + AudioBuffer& ab (bufs.get_audio (b)); + Sample* s = ab.data(); + nframes_t n; + + silent = false; + + for (n = 0; nframes < nframes; ++n) { + if (s[n] != 0) { + break; + } + } + if (n == nframes) { + silent = true; + } + + if (silent) { + cerr << _name << ": Buffer " << b << " is silent\n"; + } + } + } if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) { _output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset); } + + } out: @@ -488,48 +507,35 @@ Delivery::target_gain () gain_t desired_gain = -1.0f; - if (_solo_level || _solo_ignored) { - - desired_gain = 1.0; - - } else { - - if (_role == Listen && _session.monitor_out() && !_session.soloing()) { - - /* nobody is soloed, so control/monitor/listen bus gets its - signal from master out, we should be silent - */ - desired_gain = 0.0; + MuteMaster::MutePoint mp; + + switch (_role) { + case Main: + mp = MuteMaster::Main; + break; + case Listen: + mp = MuteMaster::Listen; + break; + case Send: + case Insert: + case Aux: + /* XXX FIX ME this is wrong, we need per-delivery muting */ + mp = MuteMaster::PreFader; + break; + } - } else { + desired_gain = _mute_master->mute_gain_at (mp); + + if (_role == Listen && _session.monitor_out() && !_session.listening()) { - MuteMaster::MutePoint mp; + /* nobody is soloed, and this delivery is a listen-send to the + control/monitor/listen bus, we should be silent since + it gets its signal from the master out. + */ - switch (_role) { - case Main: - mp = MuteMaster::Main; - break; - case Listen: - mp = MuteMaster::Listen; - break; - case Send: - case Insert: - case Aux: - /* XXX FIX ME this is wrong, we need per-delivery muting */ - mp = MuteMaster::PreFader; - break; - } - - if (!_solo_isolated && _session.soloing()) { - - desired_gain = min (Config->get_solo_mute_gain(), _mute_master->mute_gain_at (mp)); - - } else { - - desired_gain = _mute_master->mute_gain_at (mp); - } - } - } + desired_gain = 0.0; + + } return desired_gain; } diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index b3b3d23724..0182e205d0 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -28,6 +28,7 @@ #include "i18n.h" using namespace ARDOUR; +using namespace std; const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFader| MuteMaster::PostFader| @@ -35,26 +36,18 @@ const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFa MuteMaster::Main); MuteMaster::MuteMaster (Session&, const std::string&) - : _mute_point (MutePoint (0)) + : _mute_point (AllPoints) , _self_muted (false) , _muted_by_others (0) { } -void -MuteMaster::clear_mute () -{ - if (_mute_point != MutePoint (0)) { - _mute_point = MutePoint (0); - MutePointChanged (); // EMIT SIGNAL - } -} - void MuteMaster::mute_at (MutePoint mp) { if ((_mute_point & mp) != mp) { _mute_point = MutePoint (_mute_point | mp); + cerr << "Mute point set, now " << _mute_point << endl; MutePointChanged (); // EMIT SIGNAL } } @@ -64,10 +57,17 @@ MuteMaster::unmute_at (MutePoint mp) { if ((_mute_point & mp) == mp) { _mute_point = MutePoint (_mute_point & ~mp); + cerr << "Mute point unset, now " << _mute_point << endl; MutePointChanged (); // EMIT SIGNAL } } +void +MuteMaster::clear_muted_by_others () +{ + _muted_by_others = 0; +} + void MuteMaster::mod_muted_by_others (int32_t delta) { @@ -82,14 +82,45 @@ MuteMaster::mod_muted_by_others (int32_t delta) } } +void +MuteMaster::set_solo_level (int32_t l) +{ + _solo_level = l; +} + gain_t MuteMaster::mute_gain_at (MutePoint mp) const { - if (muted_at (mp)) { - return Config->get_solo_mute_gain (); - } else { - return 1.0; - } + gain_t gain; + int32_t l = _solo_level; + + if (Config->get_solo_mute_override()) { + if (l == 2) { // self-soloed + gain = 1.0; + } else if (self_muted_at (mp)) { // self-muted + gain = Config->get_solo_mute_gain (); + } else if (l == 1) { // soloed by others + gain = 1.0; + } else if (muted_by_others_at (mp)) { // muted by others + gain = Config->get_solo_mute_gain (); + } else { + gain = 1.0; + } + } else { + if (self_muted_at (mp)) { // self-muted + gain = Config->get_solo_mute_gain (); + } else if (l == 2) { // self-soloed + gain = 1.0; + } else if (muted_by_others_at (mp)) { // muted by others + gain = Config->get_solo_mute_gain (); + } else if (l == 1) { // soloed by others + gain = 1.0; + } else { + gain = 1.0; + } + } + + return gain; } void @@ -98,6 +129,7 @@ MuteMaster::set_mute_points (const std::string& mute_point) MutePoint old = _mute_point; _mute_point = (MutePoint) string_2_enum (mute_point, _mute_point); + cerr << "Mute point set from string, now " << _mute_point << endl; if (old != _mute_point) { MutePointChanged(); /* EMIT SIGNAL */ @@ -109,6 +141,7 @@ MuteMaster::set_mute_points (MutePoint mp) { if (_mute_point != mp) { _mute_point = mp; + cerr << "Mute point set from mp, now " << _mute_point << endl; MutePointChanged (); /* EMIT SIGNAL */ } } @@ -119,7 +152,8 @@ MuteMaster::set_state (const XMLNode& node, int /*version*/) const XMLProperty* prop; if ((prop = node.property ("mute-point")) != 0) { - _mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point); + //_mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point); + cerr << "Mute point set from STATE string, now " << _mute_point << endl; } if ((prop = node.property ("muted")) != 0) { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 239a189a0d..89dbf3fcd2 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -161,8 +161,6 @@ Route::init () _main_outs->panner()->set_bypassed (true); } - markup_solo_ignore (); - /* now that we have _meter, its safe to connect to this */ Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this))); @@ -529,10 +527,8 @@ Route::set_listen (bool yn, void* src) if (_monitor_send) { if (yn != _monitor_send->active()) { if (yn) { - _monitor_send->set_solo_level (1); _monitor_send->activate (); } else { - _monitor_send->set_solo_level (0); _monitor_send->deactivate (); } @@ -580,7 +576,7 @@ Route::set_solo (bool yn, void *src) if (self_soloed() != yn) { set_self_solo (yn); - set_delivery_solo (); + set_mute_master_solo (); solo_changed (true, src); /* EMIT SIGNAL */ _solo_control->Changed (); /* EMIT SIGNAL */ } @@ -609,27 +605,24 @@ Route::mod_solo_by_others (int32_t delta) _soloed_by_others += delta; } - set_delivery_solo (); + set_mute_master_solo (); solo_changed (false, this); } void -Route::set_delivery_solo () +Route::set_mute_master_solo () { - /* tell all delivery processors what the solo situation is, so that they keep - delivering even though Session::soloing() is true and they were not - explicitly soloed. - */ + int32_t level; - Glib::RWLock::ReaderLock rm (_processor_lock); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr d; - - if ((d = boost::dynamic_pointer_cast (*i)) != 0) { - d->set_solo_level (soloed ()); - d->set_solo_isolated (solo_isolated()); - } - } + if (self_soloed()) { + level = 2; + } else if (soloed_by_others()) { + level = 1; + } else { + level = 0; + } + + _mute_master->set_solo_level (level); } void @@ -648,34 +641,30 @@ Route::set_solo_isolated (bool yn, void *src) boost::shared_ptr routes = _session.get_routes (); for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) { + + if ((*i).get() == this || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) { + continue; + } + bool sends_only; - bool does_feed = direct_feeds (*i, &sends_only); + bool does_feed = direct_feeds (*i, &sends_only); // we will recurse anyway, so don't use ::feeds() if (does_feed && !sends_only) { (*i)->set_solo_isolated (yn, (*i)->route_group()); } } - /* XXX should we back-propagate as well? */ - - bool changed = false; + /* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */ if (yn) { - if (_solo_isolated == 0) { - changed = true; - } _solo_isolated++; + _mute_master->clear_muted_by_others (); } else { - changed = (_solo_isolated == 1); if (_solo_isolated > 0) { _solo_isolated--; } } - if (changed) { - set_delivery_solo (); - solo_isolated_changed (src); - } } bool @@ -687,14 +676,12 @@ Route::solo_isolated () const void Route::set_mute_points (MuteMaster::MutePoint mp) { - if (mp != _mute_points) { - _mute_points = mp; - _mute_master->set_mute_points (_mute_points); - mute_points_changed (); /* EMIT SIGNAL */ - - if (_mute_master->muted()) { - mute_changed (this); /* EMIT SIGNAL */ - } + _mute_points = mp; + _mute_master->set_mute_points (MuteMaster::AllPoints); + mute_points_changed (); /* EMIT SIGNAL */ + + if (_mute_master->muted()) { + mute_changed (this); /* EMIT SIGNAL */ } } @@ -735,6 +722,10 @@ Route::mod_muted_by_others (int delta) { bool old = muted (); + if (_solo_isolated) { + return; + } + _mute_master->mod_muted_by_others (delta); if (old != muted()) { @@ -846,12 +837,6 @@ Route::add_processor (boost::shared_ptr processor, ProcessorList::ite if (isend && _session.monitor_out() && (isend->target_id() == _session.monitor_out()->id())) { _monitor_send = isend; - - if (_monitor_send->active()) { - _monitor_send->set_solo_level (1); - } else { - _monitor_send->set_solo_level (0); - } } if (activation_allowed && (processor != _monitor_send)) { @@ -1940,7 +1925,7 @@ Route::_set_state_2X (const XMLNode& node, int version) bool first = true; bool muted = string_is_affirmative (prop->value()); - if(muted){ + if (muted){ string mute_point; @@ -2270,30 +2255,9 @@ Route::set_processor_state (const XMLNode& node) } } - markup_solo_ignore (); - processors_changed (RouteProcessorChange ()); } -void -Route::markup_solo_ignore () -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) { - - /* all delivery processors on master, monitor and auditioner never ever pay attention to solo - */ - - boost::shared_ptr d = boost::dynamic_pointer_cast(*p); - - if (d && (is_master() || is_monitor() || is_hidden())) { - cerr << _name << " Found a delivery unit, mark solo ignored\n"; - d->set_solo_ignored (true); - } - } -} - void Route::curve_reallocate () { @@ -2393,11 +2357,6 @@ Route::listen_via (boost::shared_ptr route, Placement placement, bool /*a if (route == _session.monitor_out()) { _monitor_send = boost::dynamic_pointer_cast(d); - if (_monitor_send->active()) { - _monitor_send->set_solo_level (1); - } else { - _monitor_send->set_solo_level (0); - } } /* already listening via the specified IO: do nothing */ @@ -3029,7 +2988,7 @@ Route::MuteControllable::set_value (float val) float Route::MuteControllable::get_value (void) const { - return route.muted() ? 1.0f : 0.0f; + return route.self_muted() ? 1.0f : 0.0f; } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 3d569d22be..4ba092dd91 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2205,7 +2205,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p if ((*i)->feeds (route, &via_sends_only)) { if (!via_sends_only) { (*i)->mod_solo_by_others (delta); - (*i)->mod_muted_by_others (-delta); in_signal_flow = true; } } @@ -2220,7 +2219,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p if (route->feeds (*i, &via_sends_only)) { (*i)->mod_solo_by_others (delta); - (*i)->mod_muted_by_others (-delta); in_signal_flow = true; } -- cgit v1.2.3