amend 3a5ac7f
[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 namespace ARDOUR {
28
29 ParameterDescriptor::ParameterDescriptor(const Evoral::Parameter& parameter)
30         : Evoral::ParameterDescriptor()
31         , key((uint32_t)-1)
32         , datatype(Variant::NOTHING)
33         , type((AutomationType)parameter.type())
34         , unit(NONE)
35         , step(0)
36         , smallstep(0)
37         , largestep(0)
38         , integer_step(parameter.type() >= MidiCCAutomation &&
39                        parameter.type() <= MidiChannelPressureAutomation)
40         , logarithmic(false)
41         , sr_dependent(false)
42         , min_unbound(0)
43         , max_unbound(0)
44         , enumeration(false)
45 {
46         switch((AutomationType)parameter.type()) {
47         case GainAutomation:
48                 upper  = Config->get_max_gain();
49                 normal = 1.0f;
50                 break;
51         case TrimAutomation:
52                 upper  = 10; // +20dB
53                 lower  = .1; // -20dB
54                 normal = 1.0f;
55                 break;
56         case PanAzimuthAutomation:
57                 normal = 0.5f; // there really is no _normal but this works for stereo, sort of
58                 upper  = 1.0f;
59                 break;
60         case PanWidthAutomation:
61                 lower  = -1.0;
62                 upper  = 1.0;
63                 normal = 0.0f;
64                 break;
65         case RecEnableAutomation:
66                 lower  = 0.0;
67                 upper  = 1.0;
68                 toggled = true;
69                 break;
70         case PluginAutomation:
71         case FadeInAutomation:
72         case FadeOutAutomation:
73         case EnvelopeAutomation:
74                 upper  = 2.0f;
75                 normal = 1.0f;
76                 break;
77         case SoloAutomation:
78         case MuteAutomation:
79                 upper  = 1.0f;
80                 normal = 0.0f;
81                 toggled = true;
82                 break;
83         case MidiCCAutomation:
84         case MidiPgmChangeAutomation:
85         case MidiChannelPressureAutomation:
86                 lower  = 0.0;
87                 normal = 0.0;
88                 upper  = 127.0;
89                 break;
90         case MidiPitchBenderAutomation:
91                 lower  = 0.0;
92                 normal = 8192.0;
93                 upper  = 16383.0;
94                 break;
95         default:
96                 break;
97         }
98
99         update_steps();
100 }
101
102 ParameterDescriptor::ParameterDescriptor()
103         : Evoral::ParameterDescriptor()
104         , key((uint32_t)-1)
105         , datatype(Variant::NOTHING)
106         , unit(NONE)
107         , step(0)
108         , smallstep(0)
109         , largestep(0)
110         , integer_step(false)
111         , logarithmic(false)
112         , sr_dependent(false)
113         , min_unbound(0)
114         , max_unbound(0)
115         , enumeration(false)
116 {}
117
118 void
119 ParameterDescriptor::update_steps()
120 {
121         if (unit == ParameterDescriptor::MIDI_NOTE) {
122                 step      = smallstep = 1;  // semitone
123                 largestep = 12;             // octave
124         } else if (type == GainAutomation || type == TrimAutomation) {
125                 /* dB_coeff_step gives a step normalized for [0, max_gain].  This is
126                    like "slider position", so we convert from "slider position" to gain
127                    to have the correct unit here. */
128                 largestep = slider_position_to_gain(dB_coeff_step(upper));
129                 step      = slider_position_to_gain(largestep / 10.0);
130                 smallstep = step;
131         } else {
132                 const float delta = upper - lower;
133
134                 /* 30 happens to be the total number of steps for a fader with default
135                    max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
136                 step      = smallstep = (delta / 300.0f);
137                 largestep = (delta / 30.0f);
138
139                 if (logarithmic) {
140                         /* Steps are linear, but we map them with pow like values (in
141                            internal_to_interface).  Thus, they are applied exponentially,
142                            which means too few steps.  So, divide to get roughly the
143                            desired number of steps (30).  This is not mathematically
144                            precise but seems to be about right for the controls I tried.
145                            If you're reading this, you've probably found a case where that
146                            isn't true, and somebody needs to sit down with a piece of paper
147                            and actually do the math. */
148                         smallstep = smallstep / logf(30.0f);
149                         step      = step      / logf(30.0f);
150                         largestep = largestep / logf(30.0f);
151                 } else if (integer_step) {
152                         smallstep = 1.0;
153                         step      = std::max(1.0, rint(step));
154                         largestep = std::max(1.0, rint(largestep));
155                 }
156         }
157 }
158
159 } // namespace ARDOUR