fix mute & solo behaviour mostly ; remove some verbose debugging output
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Jun 2009 13:59:06 +0000 (13:59 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Jun 2009 13:59:06 +0000 (13:59 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5153 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/mute_master.h
libs/ardour/audio_diskstream.cc
libs/ardour/delivery.cc
libs/ardour/enums.cc
libs/ardour/io.cc
libs/ardour/mute_master.cc
libs/ardour/panner.cc
libs/ardour/route.cc
libs/ardour/session.cc
libs/ardour/session_command.cc

index d55de0c856d912055cdb31058b39a5661e75a0e7..eb64181d892b68f2ee941ec1c15dabfb715ca1df 100644 (file)
@@ -47,7 +47,7 @@ class MuteMaster : public AutomationControl
        bool muted_main () const      { return _mute_point & Main; }
 
        bool muted_at (MutePoint mp) const { return _mute_point & mp; }
-       bool muted() const { return _mute_point != MutePoint (0) && get_value() != 0.0; }
+       bool muted() const { return _mute_point != MutePoint (0); }
        
        gain_t mute_gain_at (MutePoint) const;
 
index 9a562acf9e40d2bebcfdc5d225954ef496c22ad9..9ff030678a39a2cff38ae3dd6eefa161219c924c 100644 (file)
@@ -160,8 +160,6 @@ AudioDiskstream::free_working_buffers()
 void
 AudioDiskstream::non_realtime_input_change ()
 {
-       cerr << "AD::NRIC ... " << name() << endl;
-
        {
                Glib::Mutex::Lock lm (state_lock);
 
@@ -2065,8 +2063,6 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force)
        boost::shared_ptr<ChannelList> c = channels.reader();
        uint32_t n;
 
-       cerr << _name << " RWS!!!\n";
-
        if (!recordable()) {
                return;
        }
index 75b026618b6d1a27c5115881572ed73e5d05c33f..4d79aad2b97f6808d522a325a8ee5d55699dc191 100644 (file)
@@ -148,6 +148,9 @@ Delivery::run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_fr
                return;
        }
 
+       PortSet& ports (_output->ports());
+       output_buffers().attach_buffers (ports, nframes, _output_offset);
+
        // this Delivery processor is not a derived type, and thus we assume
        // we really can modify the buffers passed in (it is almost certainly
        // the main output stage of a Route). Contrast with Send::run_in_place()
@@ -156,15 +159,31 @@ Delivery::run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_fr
        gain_t tgain = target_gain ();
        
        if (tgain != _current_gain) {
+               
+               /* target gain has changed */
+
                Amp::apply_gain (bufs, nframes, _current_gain, tgain);
                _current_gain = tgain;
+
+       } else if (tgain == 0.0) {
+
+               /* we were quiet last time, and we're still supposed to be quiet.
+                  Silence the outputs, and make sure the buffers are quiet too,
+               */
+
+               _output->silence (nframes);
+               Amp::apply_simple_gain (bufs, nframes, 0.0);
+               
+               return;
+
+       } else if (tgain != 1.0) {
+
+               /* target gain has not changed, but is not unity */
+               Amp::apply_simple_gain (bufs, nframes, tgain);
        }
 
        // Attach output buffers to port buffers
 
-       PortSet& ports (_output->ports());
-       output_buffers().attach_buffers (ports, nframes, _output_offset);
-
        if (_panner && _panner->npanners() && !_panner->bypassed()) {
 
                // Use the panner to distribute audio to output port buffers
@@ -229,7 +248,6 @@ Delivery::set_state (const XMLNode& node)
        XMLNode* pan_node = node.child (X_("Panner"));
        
        if (pan_node) {
-               cerr << _name << " reset pan state from XML\n";
                _panner->set_state (*pan_node);
        } 
 
@@ -241,16 +259,11 @@ Delivery::set_state (const XMLNode& node)
 void
 Delivery::reset_panner ()
 {
-       cerr << _name << " reset panner - plegal ? " << panners_legal << endl;
-
        if (panners_legal) {
                if (!no_panner_reset) {
-                       cerr << "\treset panner with " << _output->name() << " = " << _output->n_ports()
-                            << " vs. " << pans_required () << endl;
                        _panner->reset (_output->n_ports().n_audio(), pans_required());
                }
        } else {
-               cerr << "\tdefer pan reset till later\n";
                panner_legal_c.disconnect ();
                panner_legal_c = PannersLegal.connect (mem_fun (*this, &Delivery::panners_became_legal));
        }
@@ -259,8 +272,6 @@ Delivery::reset_panner ()
 int
 Delivery::panners_became_legal ()
 {
-       cerr << _name << " panners now legal, outputs @ " << _output << " on " << _output->name()
-            << " = " << _output->n_ports() << " vs. " << pans_required() << endl;
        _panner->reset (_output->n_ports().n_audio(), pans_required());
        _panner->load (); // automation
        panner_legal_c.disconnect ();
@@ -345,51 +356,36 @@ Delivery::target_gain ()
        gain_t desired_gain;
        MuteMaster::MutePoint mp;
 
+       switch (_role) {
+       case Main:
+               mp = MuteMaster::Main;
+               break;
+       case Listen:
+               mp = MuteMaster::Listen;
+               break;
+       case Send:
+       case Insert:
+               if (_placement == PreFader) {
+                       mp = MuteMaster::PreFader;
+               } else {
+                       mp = MuteMaster::PostFader;
+               }
+               break;
+       }
+
        if (_solo_level) {
                desired_gain = 1.0;
        } else {
                if (_solo_isolated) {
 
-                       switch (_role) {
-                       case Main:
-                               mp = MuteMaster::Main;
-                               break;
-                       case Listen:
-                               mp = MuteMaster::Listen;
-                               break;
-                       case Send:
-                       case Insert:
-                               if (_placement == PreFader) {
-                                       mp = MuteMaster::PreFader;
-                               } else {
-                                       mp = MuteMaster::PostFader;
-                               }
-                               break;
-                       }
-
                        desired_gain = _mute_master->mute_gain_at (mp);
-               } else if (_session.soloing()) {
 
-                       switch (_role) {
-                       case Main:
-                               mp = MuteMaster::Main;
-                               break;
-                       case Listen:
-                               mp = MuteMaster::Listen;
-                               break;
-                       case Send:
-                       case Insert:
-                               if (_placement == PreFader) {
-                                       mp = MuteMaster::PreFader;
-                               } else {
-                                       mp = MuteMaster::PostFader;
-                               }
-                               break;
-                       }
+               } else if (_session.soloing()) {
 
                        desired_gain = min (Config->get_solo_mute_gain(), _mute_master->mute_gain_at (mp));
+
                } else {
-                       desired_gain = 1.0;
+                       desired_gain = _mute_master->mute_gain_at (mp);
                }
        }
 
index 60d2b5177ed303ae6087b203297a2a6cbb057470..1d0f811aeaa0897a59d91ff071bb13cabafeeab8 100644 (file)
@@ -29,6 +29,7 @@
 #include "ardour/io.h"
 #include "ardour/location.h"
 #include "ardour/midi_track.h"
+#include "ardour/mute_master.h"
 #include "ardour/panner.h"
 #include "ardour/route_group.h"
 #include "ardour/session.h"
@@ -106,6 +107,7 @@ setup_enum_writer ()
        ExportProfileManager::TimeFormat _ExportProfileManager_TimeFormat;
        Delivery::Role _Delivery_Role;
        IO::Direction _IO_Direction;
+       MuteMaster::MutePoint _MuteMaster_MutePoint;
 
 #define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
 #define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@@ -503,6 +505,12 @@ setup_enum_writer ()
        REGISTER_CLASS_ENUM (Delivery, Main);
        REGISTER_BITS (_Delivery_Role);
 
+       REGISTER_CLASS_ENUM (MuteMaster, PreFader);
+       REGISTER_CLASS_ENUM (MuteMaster, PostFader);
+       REGISTER_CLASS_ENUM (MuteMaster, Listen);
+       REGISTER_CLASS_ENUM (MuteMaster, Main);
+       REGISTER (_MuteMaster_MutePoint);
+
        REGISTER_CLASS_ENUM (IO, Input);
        REGISTER_CLASS_ENUM (IO, Output);
        REGISTER (_IO_Direction);
index 4a762c8eb73237cb48c121b9d4b3381a27df742b..014c0056779332adb44304fb362e953fcbb3fa66 100644 (file)
@@ -83,7 +83,6 @@ IO::IO (Session& s, const string& name, Direction dir, DataType default_type)
        _active = true;
        pending_state_node = 0;
        setup_bundles ();
-       cerr << "+++ IO created with name = " << _name << endl;
 }
 
 IO::IO (Session& s, const XMLNode& node, DataType dt)
@@ -95,9 +94,7 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
        pending_state_node = 0;
 
        set_state (node);
-
        setup_bundles ();
-       cerr << "+++ IO created from XML with name = " << _name << endl;
 }
 
 IO::~IO ()
@@ -429,11 +426,7 @@ IO::ensure_ports (ChanCount count, bool clear, bool lockit, void* src)
 {
        bool changed = false;
 
-       cerr << "Ensure that IO " << _name << '/' << (_direction == Input ? "input" : "output") 
-            << " has " << count << endl;
-
        if (count == n_ports() && !clear) {
-               cerr << "\talready has " << n_ports() << endl;
                return 0;
        }
 
@@ -451,8 +444,6 @@ IO::ensure_ports (ChanCount count, bool clear, bool lockit, void* src)
                _session.set_dirty ();
        }
 
-       cerr << "\t@" << this << "  established with " << n_ports() << endl;
-       
        return 0;
 }
 
@@ -743,8 +734,6 @@ IO::create_ports (const XMLNode& node)
        
        get_port_counts (node, n, c);
        
-       cerr << _name << " got " << n << " from XML node" << endl;
-
        if (ensure_ports (n, true, true, this)) {
                error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
                return -1;
index ca64fb01a591ae318fbe4df28a59ab3a2d520874..bbf1036dd4f4398ada42dbf25eb84273ca90f234 100644 (file)
@@ -17,6 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 */
+#include <iostream>
 
 #include "ardour/mute_master.h"
 #include "ardour/rc_configuration.h"
@@ -68,7 +69,7 @@ MuteMaster::mute (bool yn)
        /* convenience wrapper around AutomationControl method */
 
        if (yn) {
-               set_value (1.0f);
+               set_value ((float) 0xffff);
        } else {
                set_value (0.0f);
        }
@@ -87,7 +88,11 @@ MuteMaster::mute_gain_at (MutePoint mp) const
 void
 MuteMaster::set_value (float f)
 {
-       mute_at ((MutePoint) ((int) rint (f)));
+       MutePoint old = _mute_point;
+       _mute_point = (MutePoint) (rint (f));
+       if (old != _mute_point) {
+               MutePointChanged (); // EMIT SIGNAL
+       }
 }
 
 float
index 3b700631cbb20294a31e443e571387e8e0b69fb4..bd6d05a0b4feb435f55df50428b129ba50bd0328 100644 (file)
@@ -830,8 +830,6 @@ Panner::reset (uint32_t nouts, uint32_t npans)
        bool changed = false;
        bool do_not_and_did_not_need_panning = ((nouts < 2) && (outputs.size() < 2));
 
-       cerr << "panner " << _name << " reset to " << nouts << " / " << npans << endl;
-
        /* if new and old config don't need panning, or if 
           the config hasn't changed, we're done.
        */
index edd38eb80cbf7bf8effb11ebdf6b968ee72b04cd..dd0c8579ffe8b236f036b6b8d3fe95e74c537fc9 100644 (file)
@@ -1660,8 +1660,6 @@ Route::set_processor_state (const XMLNode& node)
                        has_meter_processor = true;
                }
 
-               cerr << _name << " setting up proc state for " << prop->value() << endl;
-
                o = i;
 
                if (prop->value() != "meter" && prop->value() != "amp" && prop->value() != "main-outs") {
@@ -1682,8 +1680,6 @@ Route::set_processor_state (const XMLNode& node)
                // create it and move it to the correct location
                if (o == _processors.end()) {
 
-                       cerr << "\tproc not in list\n";
-
                        if (add_processor_from_xml (**niter, i)) {
                                --i; // move iterator to the newly inserted processor
                        } else {
@@ -1694,8 +1690,6 @@ Route::set_processor_state (const XMLNode& node)
                // ensure it is at the location provided in the XML state
                } else {
 
-                       cerr << "\tproc in wrong place in list\n";
-                       
                        if (i != o) {
                                boost::shared_ptr<Processor> tmp = (*o);
                                _processors.erase (o); // remove the old copy
@@ -1703,7 +1697,6 @@ Route::set_processor_state (const XMLNode& node)
                                --i; // move iterator to the correct processor
                        }
 
-                       cerr << "\tnow reset proc " << (*i)->name() << endl;
                        (*i)->set_state (**niter);
                }
        }
index 9800b9a8c33ea433b2df367c4815d22a76c17fae..54bada345ad58cda90b153489cb22f550bd4be19 100644 (file)
@@ -2218,6 +2218,8 @@ Session::route_mute_changed (void* src)
 void
 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
 {
+       cerr << "RSC sud = " << solo_update_disabled << endl;
+
        if (solo_update_disabled) {
                // We know already
                return;
@@ -2240,7 +2242,10 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
                delta = -1;
        }
 
+       cerr << "\tshift solo level by " << delta << endl;
+
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+
                if ((*i)->feeds (route->input())) {
                        /* do it */
                        
@@ -2250,12 +2255,18 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
                }
        }
 
-       /* now figure out if anything is soloed */
+       /* make sure master is never muted by solo */
+
+       if (_master_out->main_outs()->solo_level() == 0) {
+               _master_out->main_outs()->mod_solo_level (1);
+       }
+
+       /* now figure out if anything that matters is soloed */
 
        bool something_soloed = false;
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if ((*i)->soloed()) {
+               if (!(*i)->is_master() && !(*i)->is_hidden() && (*i)->soloed()) {
                        something_soloed = true;
                        break;
                }
index 828daf37bb93d509a24c9208c7bc197ca8696aec..4af18fcd12948c4b8274493813de07226fb5ff7b 100644 (file)
@@ -105,6 +105,8 @@ Session::memento_command_factory(XMLNode *n)
     } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name() || obj_T == typeid(MidiTrack).name()) { 
                if (boost::shared_ptr<Route> r = route_by_id(id)) {
                        return new MementoCommand<Route>(*r, before, after);
+               } else {
+                       error << string_compose (X_("Route %1 not found in session"), id) << endmsg;
                }
     } else if (obj_T == typeid (Evoral::Curve).name() || obj_T == typeid (AutomationList).name()) {
                std::map<PBD::ID, AutomationList*>::iterator i = automation_lists.find(id);