extensive changes to PresentationInfo API
[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         case RecSafeAutomation:
79                 lower  = 0.0;
80                 upper  = 1.0;
81                 toggled = true;
82                 break;
83         case PluginAutomation:
84         case FadeInAutomation:
85         case FadeOutAutomation:
86         case EnvelopeAutomation:
87                 upper  = 2.0f;
88                 normal = 1.0f;
89                 break;
90         case SoloAutomation:
91         case MuteAutomation:
92                 upper  = 1.0f;
93                 normal = 0.0f;
94                 toggled = true;
95                 break;
96         case MidiCCAutomation:
97         case MidiPgmChangeAutomation:
98         case MidiChannelPressureAutomation:
99                 lower  = 0.0;
100                 normal = 0.0;
101                 upper  = 127.0;
102                 break;
103         case MidiPitchBenderAutomation:
104                 lower  = 0.0;
105                 normal = 8192.0;
106                 upper  = 16383.0;
107                 break;
108         case PhaseAutomation:
109                 toggled = true;
110                 break;
111         case MonitoringAutomation:
112                 enumeration = true;
113                 integer_step = true;
114                 lower = MonitorAuto;
115                 upper = MonitorDisk; /* XXX bump when we add MonitorCue */
116                 break;
117         case SoloIsolateAutomation:
118                 toggled = true;
119                 break;
120         case SoloSafeAutomation:
121                 toggled = true;
122                 break;
123         default:
124                 break;
125         }
126
127         update_steps();
128 }
129
130 ParameterDescriptor::ParameterDescriptor()
131         : Evoral::ParameterDescriptor()
132         , key((uint32_t)-1)
133         , datatype(Variant::NOTHING)
134         , type(NullAutomation)
135         , unit(NONE)
136         , step(0)
137         , smallstep(0)
138         , largestep(0)
139         , integer_step(false)
140         , logarithmic(false)
141         , sr_dependent(false)
142         , min_unbound(0)
143         , max_unbound(0)
144         , enumeration(false)
145 {}
146
147 void
148 ParameterDescriptor::update_steps()
149 {
150         if (unit == ParameterDescriptor::MIDI_NOTE) {
151                 step      = smallstep = 1;  // semitone
152                 largestep = 12;             // octave
153         } else if (type == GainAutomation || type == TrimAutomation) {
154                 /* dB_coeff_step gives a step normalized for [0, max_gain].  This is
155                    like "slider position", so we convert from "slider position" to gain
156                    to have the correct unit here. */
157                 largestep = slider_position_to_gain(dB_coeff_step(upper));
158                 step      = slider_position_to_gain(largestep / 10.0);
159                 smallstep = step;
160         } else {
161                 const float delta = upper - lower;
162
163                 /* 30 happens to be the total number of steps for a fader with default
164                    max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
165                 step      = smallstep = (delta / 300.0f);
166                 largestep = (delta / 30.0f);
167
168                 if (logarithmic) {
169                         /* Steps are linear, but we map them with pow like values (in
170                            internal_to_interface).  Thus, they are applied exponentially,
171                            which means too few steps.  So, divide to get roughly the
172                            desired number of steps (30).  This is not mathematically
173                            precise but seems to be about right for the controls I tried.
174                            If you're reading this, you've probably found a case where that
175                            isn't true, and somebody needs to sit down with a piece of paper
176                            and actually do the math. */
177                         smallstep = smallstep / logf(30.0f);
178                         step      = step      / logf(30.0f);
179                         largestep = largestep / logf(30.0f);
180                 } else if (integer_step) {
181                         smallstep = 1.0;
182                         step      = std::max(1.f, rintf (step));
183                         largestep = std::max(1.f, rintf (largestep));
184                 }
185         }
186 }
187
188 } // namespace ARDOUR