allow to get custom/product/version independent cach dir
[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 "pbd/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         case MidiNotePressureAutomation:
100                 lower  = 0.0;
101                 normal = 0.0;
102                 upper  = 127.0;
103                 break;
104         case MidiPitchBenderAutomation:
105                 lower  = 0.0;
106                 normal = 8192.0;
107                 upper  = 16383.0;
108                 break;
109         case PhaseAutomation:
110                 toggled = true;
111                 break;
112         case MonitoringAutomation:
113                 enumeration = true;
114                 integer_step = true;
115                 lower = MonitorAuto;
116                 upper = MonitorDisk; /* XXX bump when we add MonitorCue */
117                 break;
118         case SoloIsolateAutomation:
119                 toggled = true;
120                 break;
121         case SoloSafeAutomation:
122                 toggled = true;
123                 break;
124         default:
125                 break;
126         }
127
128         update_steps();
129 }
130
131 ParameterDescriptor::ParameterDescriptor()
132         : Evoral::ParameterDescriptor()
133         , key((uint32_t)-1)
134         , datatype(Variant::NOTHING)
135         , type(NullAutomation)
136         , unit(NONE)
137         , step(0)
138         , smallstep(0)
139         , largestep(0)
140         , integer_step(false)
141         , logarithmic(false)
142         , sr_dependent(false)
143         , min_unbound(0)
144         , max_unbound(0)
145         , enumeration(false)
146 {}
147
148 void
149 ParameterDescriptor::update_steps()
150 {
151         if (unit == ParameterDescriptor::MIDI_NOTE) {
152                 step      = smallstep = 1;  // semitone
153                 largestep = 12;             // octave
154         } else if (type == GainAutomation || type == TrimAutomation) {
155                 /* dB_coeff_step gives a step normalized for [0, max_gain].  This is
156                    like "slider position", so we convert from "slider position" to gain
157                    to have the correct unit here. */
158                 largestep = slider_position_to_gain(dB_coeff_step(upper));
159                 step      = slider_position_to_gain(largestep / 10.0);
160                 smallstep = step;
161         } else {
162                 /* note that LV2Plugin::get_parameter_descriptor ()
163                  * overrides this is lv2:rangeStep is set for a port.
164                  */
165                 const float delta = upper - lower;
166
167                 /* 30 happens to be the total number of steps for a fader with default
168                    max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
169                 step      = smallstep = (delta / 300.0f);
170                 largestep = (delta / 30.0f);
171
172                 if (logarithmic) {
173                         /* Steps are linear, but we map them with pow like values (in
174                            internal_to_interface).  Thus, they are applied exponentially,
175                            which means too few steps.  So, divide to get roughly the
176                            desired number of steps (30).  This is not mathematically
177                            precise but seems to be about right for the controls I tried.
178                            If you're reading this, you've probably found a case where that
179                            isn't true, and somebody needs to sit down with a piece of paper
180                            and actually do the math. */
181                         smallstep = smallstep / logf(30.0f);
182                         step      = step      / logf(30.0f);
183                         largestep = largestep / logf(30.0f);
184                 } else if (integer_step) {
185                         smallstep = 1.0;
186                         step      = std::max(1.f, rintf (step));
187                         largestep = std::max(1.f, rintf (largestep));
188                 }
189         }
190 }
191
192 std::string
193 ParameterDescriptor::midi_note_name (const uint8_t b)
194 {
195         char buf[8];
196         if (b > 127) {
197                 snprintf(buf, sizeof(buf), "%d", b);
198                 return buf;
199         }
200
201         static const char* notes[] = {
202                 S_("Note|C"),
203                 S_("Note|C#"),
204                 S_("Note|D"),
205                 S_("Note|D#"),
206                 S_("Note|E"),
207                 S_("Note|F"),
208                 S_("Note|F#"),
209                 S_("Note|G"),
210                 S_("Note|G#"),
211                 S_("Note|A"),
212                 S_("Note|A#"),
213                 S_("Note|B")
214         };
215
216         /* MIDI note 0 is in octave -1 (in scientific pitch notation) */
217         const int octave = b / 12 - 1;
218         snprintf (buf, sizeof (buf), "%s%d", notes[b % 12], octave);
219         return buf;
220 }
221
222 } // namespace ARDOUR