From 17853bc472f3a097df53443b43cd859be356eea0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 4 Mar 2016 11:42:43 -0500 Subject: [PATCH] ensure that GainControl::get_value() never returns > Config->get_max_gain() --- libs/ardour/ardour/gain_control.h | 1 + libs/ardour/gain_control.cc | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h index f833163383..c44a76dd04 100644 --- a/libs/ardour/ardour/gain_control.h +++ b/libs/ardour/ardour/gain_control.h @@ -93,6 +93,7 @@ class LIBARDOUR_API GainControl : public AutomationControl { PBD::ScopedConnectionList masters_connections; std::string _masters_state_string (); + gain_t get_value_locked () const; gain_t get_master_gain_locked () const; void master_going_away (boost::weak_ptr); void recompute_masters_ratios (double val); diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc index 52752dcdda..b9c381c406 100644 --- a/libs/ardour/gain_control.cc +++ b/libs/ardour/gain_control.cc @@ -43,10 +43,10 @@ GainControl::GainControl (Session& session, const Evoral::Parameter ¶m, boos range_db = accurate_coefficient_to_dB (_desc.upper) - lower_db; } -double -GainControl::get_value () const -{ - Glib::Threads::RWLock::ReaderLock lm (master_lock); +gain_t +GainControl::get_value_locked () const { + + /* read or write masters lock must be held */ if (_masters.empty()) { return AutomationControl::get_value(); @@ -59,7 +59,14 @@ GainControl::get_value () const g *= mr->second.master()->get_value () * mr->second.ratio(); } - return g; + return min (Config->get_max_gain(), g); +} + +double +GainControl::get_value () const +{ + Glib::Threads::RWLock::ReaderLock lm (master_lock); + return get_value_locked (); } void @@ -164,19 +171,20 @@ GainControl::get_master_gain_locked () const void GainControl::add_master (boost::shared_ptr vca) { - gain_t old_master_val; + gain_t current_value; std::pair res; { Glib::Threads::RWLock::WriterLock lm (master_lock); - old_master_val = get_master_gain_locked (); + current_value = get_value_locked (); /* ratio will be recomputed below */ res = _masters.insert (make_pair (vca->number(), MasterRecord (vca->control(), 0.0))); if (res.second) { - recompute_masters_ratios (old_master_val); + + recompute_masters_ratios (current_value); /* note that we bind @param m as a weak_ptr, thus avoiding holding a reference to the control in the binding @@ -210,15 +218,15 @@ GainControl::master_going_away (boost::weak_ptr wv) void GainControl::remove_master (boost::shared_ptr vca) { - gain_t old_master_val; + gain_t current_value; Masters::size_type erased = 0; { Glib::Threads::RWLock::WriterLock lm (master_lock); - old_master_val = get_master_gain_locked (); + current_value = get_value_locked (); erased = _masters.erase (vca->number()); if (erased) { - recompute_masters_ratios (old_master_val); + recompute_masters_ratios (current_value); } } -- 2.30.2