change API for GainControl, VCA and VCAManager
[ardour.git] / libs / ardour / parameter_descriptor.cc
1 /*
2     Copyright (C) 2014 Paul Davis
3     Author: David Robillard
4
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "ardour/amp.h"
21 #include "ardour/dB.h"
22 #include "ardour/parameter_descriptor.h"
23 #include "ardour/rc_configuration.h"
24 #include "ardour/types.h"
25 #include "ardour/utils.h"
26
27 #include "i18n.h"
28
29 namespace ARDOUR {
30
31 ParameterDescriptor::ParameterDescriptor(const Evoral::Parameter& parameter)
32         : Evoral::ParameterDescriptor()
33         , key((uint32_t)-1)
34         , datatype(Variant::NOTHING)
35         , type((AutomationType)parameter.type())
36         , unit(NONE)
37         , step(0)
38         , smallstep(0)
39         , largestep(0)
40         , integer_step(parameter.type() >= MidiCCAutomation &&
41                        parameter.type() <= MidiChannelPressureAutomation)
42         , logarithmic(false)
43         , sr_dependent(false)
44         , min_unbound(0)
45         , max_unbound(0)
46         , enumeration(false)
47 {
48         ScalePoints sp;
49
50         switch((AutomationType)parameter.type()) {
51         case GainAutomation:
52                 upper  = Config->get_max_gain();
53                 normal = 1.0f;
54                 break;
55         case BusSendLevel:
56                 upper = Config->get_max_gain ();
57                 normal = 1.0f;
58                 break;
59         case BusSendEnable:
60                 normal = 1.0f;
61                 toggled = true;
62                 break;
63         case TrimAutomation:
64                 upper  = 10; // +20dB
65                 lower  = .1; // -20dB
66                 normal = 1.0f;
67                 break;
68         case PanAzimuthAutomation:
69                 normal = 0.5f; // there really is no _normal but this works for stereo, sort of
70                 upper  = 1.0f;
71                 break;
72         case PanWidthAutomation:
73                 lower  = -1.0;
74                 upper  = 1.0;
75                 normal = 0.0f;
76                 break;
77         case RecEnableAutomation:
78                 lower  = 0.0;
79                 upper  = 1.0;
80                 toggled = true;
81                 break;
82         case PluginAutomation:
83         case FadeInAutomation:
84         case FadeOutAutomation:
85         case EnvelopeAutomation:
86                 upper  = 2.0f;
87                 normal = 1.0f;
88                 break;
89         case SoloAutomation:
90         case MuteAutomation:
91                 upper  = 1.0f;
92                 normal = 0.0f;
93                 toggled = true;
94                 break;
95         case MidiCCAutomation:
96         case MidiPgmChangeAutomation:
97         case MidiChannelPressureAutomation:
98                 lower  = 0.0;
99                 normal = 0.0;
100                 upper  = 127.0;
101                 break;
102         case MidiPitchBenderAutomation:
103                 lower  = 0.0;
104                 normal = 8192.0;
105                 upper  = 16383.0;
106                 break;
107         case PhaseAutomation:
108                 toggled = true;
109                 break;
110         case MonitoringAutomation:
111                 enumeration = true;
112                 integer_step = true;
113                 lower = MonitorAuto;
114                 upper = MonitorDisk; /* XXX bump when we add MonitorCue */
115                 break;
116         case SoloIsolateAutomation:
117                 toggled = true;
118                 break;
119         case SoloSafeAutomation:
120                 toggled = true;
121                 break;
122         default:
123                 break;
124         }
125
126         update_steps();
127 }
128
129 ParameterDescriptor::ParameterDescriptor()
130         : Evoral::ParameterDescriptor()
131         , key((uint32_t)-1)
132         , datatype(Variant::NOTHING)
133         , type(NullAutomation)
134         , unit(NONE)
135         , step(0)
136         , smallstep(0)
137         , largestep(0)
138         , integer_step(false)
139         , logarithmic(false)
140         , sr_dependent(false)
141         , min_unbound(0)
142         , max_unbound(0)
143         , enumeration(false)
144 {}
145
146 void
147 ParameterDescriptor::update_steps()
148 {
149         if (unit == ParameterDescriptor::MIDI_NOTE) {
150                 step      = smallstep = 1;  // semitone
151                 largestep = 12;             // octave
152         } else if (type == GainAutomation || type == TrimAutomation) {
153                 /* dB_coeff_step gives a step normalized for [0, max_gain].  This is
154                    like "slider position", so we convert from "slider position" to gain
155                    to have the correct unit here. */
156                 largestep = slider_position_to_gain(dB_coeff_step(upper));
157                 step      = slider_position_to_gain(largestep / 10.0);
158                 smallstep = step;
159         } else {
160                 const float delta = upper - lower;
161
162                 /* 30 happens to be the total number of steps for a fader with default
163                    max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
164                 step      = smallstep = (delta / 300.0f);
165                 largestep = (delta / 30.0f);
166
167                 if (logarithmic) {
168                         /* Steps are linear, but we map them with pow like values (in
169                            internal_to_interface).  Thus, they are applied exponentially,
170                            which means too few steps.  So, divide to get roughly the
171                            desired number of steps (30).  This is not mathematically
172                            precise but seems to be about right for the controls I tried.
173                            If you're reading this, you've probably found a case where that
174                            isn't true, and somebody needs to sit down with a piece of paper
175                            and actually do the math. */
176                         smallstep = smallstep / logf(30.0f);
177                         step      = step      / logf(30.0f);
178                         largestep = largestep / logf(30.0f);
179                 } else if (integer_step) {
180                         smallstep = 1.0;
181                         step      = std::max(1.f, rintf (step));
182                         largestep = std::max(1.f, rintf (largestep));
183                 }
184         }
185 }
186
187 } // namespace ARDOUR