fix initial AFL/PFL state after session-load
[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         , type(NullAutomation)
107         , unit(NONE)
108         , step(0)
109         , smallstep(0)
110         , largestep(0)
111         , integer_step(false)
112         , logarithmic(false)
113         , sr_dependent(false)
114         , min_unbound(0)
115         , max_unbound(0)
116         , enumeration(false)
117 {}
118
119 void
120 ParameterDescriptor::update_steps()
121 {
122         if (unit == ParameterDescriptor::MIDI_NOTE) {
123                 step      = smallstep = 1;  // semitone
124                 largestep = 12;             // octave
125         } else if (type == GainAutomation || type == TrimAutomation) {
126                 /* dB_coeff_step gives a step normalized for [0, max_gain].  This is
127                    like "slider position", so we convert from "slider position" to gain
128                    to have the correct unit here. */
129                 largestep = slider_position_to_gain(dB_coeff_step(upper));
130                 step      = slider_position_to_gain(largestep / 10.0);
131                 smallstep = step;
132         } else {
133                 const float delta = upper - lower;
134
135                 /* 30 happens to be the total number of steps for a fader with default
136                    max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
137                 step      = smallstep = (delta / 300.0f);
138                 largestep = (delta / 30.0f);
139
140                 if (logarithmic) {
141                         /* Steps are linear, but we map them with pow like values (in
142                            internal_to_interface).  Thus, they are applied exponentially,
143                            which means too few steps.  So, divide to get roughly the
144                            desired number of steps (30).  This is not mathematically
145                            precise but seems to be about right for the controls I tried.
146                            If you're reading this, you've probably found a case where that
147                            isn't true, and somebody needs to sit down with a piece of paper
148                            and actually do the math. */
149                         smallstep = smallstep / logf(30.0f);
150                         step      = step      / logf(30.0f);
151                         largestep = largestep / logf(30.0f);
152                 } else if (integer_step) {
153                         smallstep = 1.0;
154                         step      = std::max(1.0, rint(step));
155                         largestep = std::max(1.0, rint(largestep));
156                 }
157         }
158 }
159
160 } // namespace ARDOUR