2 Copyright (C) 2006-2016 Paul Davis
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "pbd/convert.h"
22 #include "pbd/strsplit.h"
24 #include "ardour/dB.h"
25 #include "ardour/gain_control.h"
26 #include "ardour/session.h"
27 #include "ardour/vca.h"
28 #include "ardour/vca_manager.h"
32 using namespace ARDOUR;
35 GainControl::GainControl (Session& session, const Evoral::Parameter ¶m, boost::shared_ptr<AutomationList> al)
36 : SlavableAutomationControl (session, param, ParameterDescriptor(param),
37 al ? al : boost::shared_ptr<AutomationList> (new AutomationList (param)),
38 param.type() == GainAutomation ? X_("gaincontrol") : X_("trimcontrol"),
39 Controllable::GainLike)
41 alist()->reset_default (1.0);
43 lower_db = accurate_coefficient_to_dB (_desc.lower);
44 range_db = accurate_coefficient_to_dB (_desc.upper) - lower_db;
48 GainControl::internal_to_interface (double v) const
50 if (_desc.type == GainAutomation) {
51 return gain_to_slider_position (v);
53 return (accurate_coefficient_to_dB (v) - lower_db) / range_db;
58 GainControl::interface_to_internal (double v) const
60 if (_desc.type == GainAutomation) {
61 return slider_position_to_gain (v);
63 return dB_to_coefficient (lower_db + v * range_db);
68 GainControl::internal_to_user (double v) const
70 return accurate_coefficient_to_dB (v);
74 GainControl::user_to_internal (double u) const
76 return dB_to_coefficient (u);
80 GainControl::get_user_string () const
82 char theBuf[32]; sprintf( theBuf, _("%3.1f dB"), accurate_coefficient_to_dB (get_value()));
83 return std::string(theBuf);
87 GainControl::inc_gain (gain_t factor)
89 /* To be used ONLY when doing group-relative gain adjustment, from
90 * ControlGroup::set_group_values().
93 const float desired_gain = user_double();
95 if (fabsf (desired_gain) < GAIN_COEFF_SMALL) {
96 // really?! what's the idea here?
97 actually_set_value (0.000001f + (0.000001f * factor), Controllable::ForGroup);
99 actually_set_value (desired_gain + (desired_gain * factor), Controllable::ForGroup);
104 GainControl::recompute_masters_ratios (double val)
106 /* Master WRITE lock must be held */
108 /* V' is the new gain value for this
110 Mv(n) is the return value of ::get_value() for the n-th master
111 Mr(n) is the return value of ::ratio() for the n-th master record
113 the slave should return V' on the next call to ::get_value().
115 but the value is determined by the masters, so we know:
117 V' = (Mv(1) * Mr(1)) * (Mv(2) * Mr(2)) * ... * (Mv(n) * Mr(n))
121 Mr(1) * Mr(2) * ... * (Mr(n) = V' / (Mv(1) * Mv(2) * ... * Mv(n))
123 if we make all ratios equal (i.e. each master contributes the same
124 fraction of its own gain level to make the final slave gain), then we
127 pow (Mr(n), n) = V' / (Mv(1) * Mv(2) * ... * Mv(n))
131 Mr(n) = pow ((V' / (Mv(1) * Mv(2) * ... * Mv(n))), 1/n)
133 Mr(n) is the new ratio number for the slaves
136 const double nmasters = _masters.size();
137 double masters_total_gain_coefficient = 1.0;
139 for (Masters::iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
140 masters_total_gain_coefficient *= mr->second.master()->get_value();
143 const double new_universal_ratio = pow ((val / masters_total_gain_coefficient), (1.0/nmasters));
145 for (Masters::iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
146 mr->second.reset_ratio (new_universal_ratio);