Vital
Loading...
Searching...
No Matches
synth_parameters.cpp
Go to the documentation of this file.
1/*
2Summary:
3The Parameters and ValueDetailsLookup classes centralize all parameter definitions for Vital. They define the behavior, ranges, and displayed names/units of every parameter (e.g., oscillators, filters, LFOs, envelopes). The code organizes parameters into groups (for envelopes, LFOs, oscillators, filters, and more) and ensures compatibility across versions. This system allows for easy retrieval of parameter metadata throughout the synthesizer’s code and UI layers.
4 */
5
6#include "synth_parameters.h"
7
8#include "compressor.h"
9#include "distortion.h"
10#include "digital_svf.h"
11#include "synth_constants.h"
12#include "random_lfo.h"
13#include "synth_lfo.h"
14#include "synth_oscillator.h"
15#include "synth_strings.h"
16#include "voice_handler.h"
17#include "wavetable.h"
18#include "utils.h"
19
20#include <cfloat>
21
22namespace vital {
23
35 if (a->version_added != b->version_added)
36 return a->version_added < b->version_added;
37
38 return a->name.compare(b->name) < 0;
39 }
40
41 using namespace constants;
42
43 // Various string and ID prefix constants used to name and organize parameter groups.
44 static const std::string kIdDelimiter = "_";
45 static const std::string kEnvIdPrefix = "env";
46 static const std::string kLfoIdPrefix = "lfo";
47 static const std::string kRandomIdPrefix = "random";
48 static const std::string kOscIdPrefix = "osc";
49 static const std::string kFilterIdPrefix = "filter";
50 static const std::string kModulationIdPrefix = "modulation";
51 static const std::string kNameDelimiter = " ";
52 static const std::string kEnvNamePrefix = "Envelope";
53 static const std::string kLfoNamePrefix = "LFO";
54 static const std::string kRandomNamePrefix = "Random LFO";
55 static const std::string kOscNamePrefix = "Oscillator";
56 static const std::string kFilterNamePrefix = "Filter";
57 static const std::string kModulationNamePrefix = "Modulation";
58
59 const ValueDetails ValueDetailsLookup::parameter_list[] = {
60 { "bypass", 0x000702, 0.0, 1.0, 0.0, 0.0, 60.0,
61 ValueDetails::kIndexed, false, "", "Bypass", nullptr },
62 { "beats_per_minute", 0x000000, 0.333333333, 5.0, 2.0, 0.0, 60.0,
63 ValueDetails::kLinear, false, "", "Beats Per Minute", nullptr },
64 { "delay_dry_wet", 0x000000, 0.0, 1.0, 0.3334, 0.0, 100.0,
65 ValueDetails::kLinear, false, "%", "Delay Mix", nullptr },
66 { "delay_feedback", 0x000000, -1.0, 1.0, 0.5, 0.0, 100.0,
67 ValueDetails::kLinear, false, "%", "Delay Feedback", nullptr },
68 { "delay_frequency", 0x000000, -2.0, 9.0, 2.0, 0.0, 1.0,
69 ValueDetails::kExponential, true, " secs", "Delay Frequency", nullptr },
70 { "delay_aux_frequency", 0x000507, -2.0, 9.0, 2.0, 0.0, 1.0,
71 ValueDetails::kExponential, true, " secs", "Delay Frequency 2", nullptr },
72 { "delay_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
73 ValueDetails::kIndexed, false, "", "Delay Switch", strings::kOffOnNames },
74 { "delay_style", 0x000000, 0.0, 3.0, 0.0, 0.0, 1.0,
75 ValueDetails::kIndexed, false, "", "Delay Style", strings::kDelayStyleNames },
76 { "delay_filter_cutoff", 0x000000, 8.0, 136.0, 60.0, 0.0, 1.0,
77 ValueDetails::kLinear, false, "", "Delay Filter Cutoff", nullptr },
78 { "delay_filter_spread", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
79 ValueDetails::kLinear, false, "", "Delay Filter Spread", nullptr },
80 { "delay_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
81 ValueDetails::kIndexed, false, "", "Delay Sync", strings::kFrequencySyncNames },
82 { "delay_tempo", 0x000000, 4.0, 12.0, 9.0, 0.0, 1.0,
83 ValueDetails::kIndexed, false, "", "Delay Tempo", strings::kSyncedFrequencyNames },
84 { "delay_aux_sync", 0x000507, 0.0, 3.0, 1.0, 0.0, 1.0,
85 ValueDetails::kIndexed, false, "", "Delay Sync 2", strings::kFrequencySyncNames },
86 { "delay_aux_tempo", 0x000507, 4.0, 12.0, 9.0, 0.0, 1.0,
87 ValueDetails::kIndexed, false, "", "Delay Tempo 2", strings::kSyncedFrequencyNames },
88 { "distortion_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
89 ValueDetails::kIndexed, false, "", "Distortion Switch", strings::kOffOnNames },
90 { "distortion_type", 0x000000, 0.0, 5.0, 0.0, 0.0, 1.0,
91 ValueDetails::kIndexed, false, "", "Distortion Type", strings::kDistortionTypeNames },
92 { "distortion_drive", 0x000000, Distortion::kMinDrive, Distortion::kMaxDrive, 0.0, 0.0, 1.0,
93 ValueDetails::kLinear, false, " dB", "Distortion Drive", nullptr },
94 { "distortion_mix", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
95 ValueDetails::kLinear, false, "", "Distortion Mix", nullptr },
96 { "distortion_filter_order", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
97 ValueDetails::kIndexed, false, "", "Distortion Filter Order", strings::kDistortionFilterOrderNames },
98 { "distortion_filter_cutoff", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
99 ValueDetails::kLinear, false, " semitones", "Distortion Filter Cutoff", nullptr },
100 { "distortion_filter_resonance", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
101 ValueDetails::kLinear, false, "%", "Distortion Filter Resonance", nullptr },
102 { "distortion_filter_blend", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
103 ValueDetails::kLinear, false, "", "Distortion Filter Blend", nullptr },
104 { "legato", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
105 ValueDetails::kIndexed, false, "", "Legato", strings::kOffOnNames },
106 { "macro_control_1", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
107 ValueDetails::kLinear, false, "", "Macro 1", nullptr },
108 { "macro_control_2", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
109 ValueDetails::kLinear, false, "", "Macro 2", nullptr },
110 { "macro_control_3", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
111 ValueDetails::kLinear, false, "", "Macro 3", nullptr },
112 { "macro_control_4", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
113 ValueDetails::kLinear, false, "", "Macro 4", nullptr },
114 { "pitch_bend_range", 0x000000, 0.0, 48.0, 2.0, 0.0, 1.0,
115 ValueDetails::kIndexed, false, " semitones", "Pitch Bend Range", nullptr },
116 { "polyphony", 0x000000, 1.0, kMaxPolyphony - 1, 8.0, 0.0, 1.0,
117 ValueDetails::kIndexed, false, " voices", "Polyphony", nullptr },
118 { "voice_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
119 ValueDetails::kLinear, false, " cents", "Voice Tune", nullptr },
120 { "voice_transpose", 0x000604, -48.0, 48.0, 0.0, 0.0, 1.0,
121 ValueDetails::kIndexed, false, "", "Voice Transpose", nullptr },
122 { "voice_amplitude", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
123 ValueDetails::kLinear, false, "", "Voice Amplitude", nullptr },
124 { "stereo_routing", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
125 ValueDetails::kLinear, false, "%", "Stereo Routing", nullptr },
126 { "stereo_mode", 0x000605, 0.0, 1.0, 0.0, 0.0, 1.0,
127 ValueDetails::kIndexed, false, "", "Stereo Mode", strings::kStereoModeNames },
128 { "portamento_time", 0x000000, -10.0, 4.0, -10.0, 0.0, 1.0,
129 ValueDetails::kExponential, false, " secs", "Portamento Time", nullptr },
130 { "portamento_slope", 0x000000, -8.0, 8.0, 0.0, 0.0, 1.0,
131 ValueDetails::kLinear, false, "", "Portamento Slope", nullptr },
132 { "portamento_force", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
133 ValueDetails::kIndexed, false, "", "Portamento Force", strings::kOffOnNames },
134 { "portamento_scale", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
135 ValueDetails::kIndexed, false, "", "Portamento Scale", strings::kOffOnNames },
136 { "reverb_pre_low_cutoff", 0x000000, 0.0, 128.0, 0.0, 0.0, 1.0,
137 ValueDetails::kLinear, false, " semitones", "Reverb Pre Low Cutoff", nullptr },
138 { "reverb_pre_high_cutoff", 0x000000, 0.0, 128.0, 110.0, 0.0, 1.0,
139 ValueDetails::kLinear, false, " semitones", "Reverb Pre High Cutoff", nullptr },
140 { "reverb_low_shelf_cutoff", 0x000000, 0.0, 128.0, 0.0, 0.0, 1.0,
141 ValueDetails::kLinear, false, " semitones", "Reverb Low Cutoff", nullptr },
142 { "reverb_low_shelf_gain", 0x000000, -6.0, 0.0, 0.0, 0.0, 1.0,
143 ValueDetails::kLinear, false, " dB", "Reverb Low Gain", nullptr },
144 { "reverb_high_shelf_cutoff", 0x000000, 0.0, 128.0, 90.0, 0.0, 1.0,
145 ValueDetails::kLinear, false, " semitones", "Reverb High Cutoff", nullptr },
146 { "reverb_high_shelf_gain", 0x000000, -6.0, 0.0, -1.0, 0.0, 1.0,
147 ValueDetails::kLinear, false, " dB", "Reverb High Gain", nullptr },
148 { "reverb_dry_wet", 0x000000, 0.0, 1.0, 0.25, 0.0, 100.0,
149 ValueDetails::kLinear, false, "%", "Reverb Mix", nullptr },
150 { "reverb_delay", 0x000609, 0.0, 0.3, 0.0, 0.0, 1.0,
151 ValueDetails::kLinear, false, " secs", "Reverb Delay", nullptr },
152 { "reverb_decay_time", 0x000000, -6.0, 6.0, 0.0, 0.0, 1.0,
153 ValueDetails::kExponential, false, " secs", "Reverb Decay Time", nullptr },
154 { "reverb_size", 0x000506, 0.0, 1.0, 0.5, 0.0, 100.0,
155 ValueDetails::kLinear, false, "%", "Reverb Size", nullptr },
156 { "reverb_chorus_amount", 0x000000, 0.0, 1.0, 0.223607, 0.0, 100.0,
157 ValueDetails::kQuadratic, false, "%", "Reverb Chorus Amount", nullptr },
158 { "reverb_chorus_frequency", 0x000000, -8.0, 3.0, -2.0, 0.0, 1.0,
159 ValueDetails::kExponential, false, " Hz", "Reverb Chorus Frequency", nullptr },
160 { "reverb_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
161 ValueDetails::kIndexed, false, "", "Reverb Switch", strings::kOffOnNames },
162 { "sub_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
163 ValueDetails::kIndexed, false, "", "Sub Switch", strings::kOffOnNames },
164 { "sub_direct_out", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
165 ValueDetails::kIndexed, false, "", "Sub Direct Out", nullptr },
166 { "sub_transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
167 ValueDetails::kIndexed, false, "", "Sub Transpose", nullptr },
168 { "sub_transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
169 ValueDetails::kIndexed, false, "", "Sub Transpose Quantize", nullptr },
170 { "sub_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
171 ValueDetails::kLinear, false, "", "Sub Tune", nullptr },
172 { "sub_level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
173 ValueDetails::kQuadratic, false, "", "Sub Level", nullptr },
174 { "sub_pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
175 ValueDetails::kLinear, false, "%", "Sub Pan", nullptr },
176 { "sub_waveform", 0x000000, 0.0, PredefinedWaveFrames::kNumShapes - 1, 2.0, 0.0, 1.0,
177 ValueDetails::kIndexed, false, "", "Sub Osc Waveform", nullptr },
178 { "sample_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
179 ValueDetails::kIndexed, false, "", "Sample Switch", strings::kOffOnNames },
180 { "sample_random_phase", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
181 ValueDetails::kIndexed, false, "", "Sample Random Phase", strings::kOffOnNames },
182 { "sample_keytrack", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
183 ValueDetails::kIndexed, false, "", "Sample Keytrack", strings::kOffOnNames },
184 { "sample_loop", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
185 ValueDetails::kIndexed, false, "", "Sample Loop", strings::kOffOnNames },
186 { "sample_bounce", 0x000603, 0.0, 1.0, 0.0, 0.0, 1.0,
187 ValueDetails::kIndexed, false, "", "Sample Bounce", strings::kOffOnNames },
188 { "sample_transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
189 ValueDetails::kIndexed, false, "", "Sample Transpose", nullptr },
190 { "sample_transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
191 ValueDetails::kIndexed, false, "", "Sample Transpose Quantize", nullptr },
192 { "sample_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
193 ValueDetails::kLinear, false, "", "Sample Tune", nullptr },
194 { "sample_level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
195 ValueDetails::kQuadratic, false, "", "Sample Level", nullptr },
196 { "sample_destination", 0x000500, 0.0, constants::kNumSourceDestinations + constants::kNumEffects, 3.0, 0.0, 1.0,
197 ValueDetails::kIndexed, false, "", "Sample Destination", strings::kDestinationNames },
198 { "sample_pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
199 ValueDetails::kLinear, false, "%", "Sample Pan", nullptr },
200 { "velocity_track", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
201 ValueDetails::kLinear, false, "%", "Velocity Track", nullptr },
202 { "volume", 0x000000, 0.0, 7399.4404, 5473.0404, -80, 1.0,
203 ValueDetails::kSquareRoot, false, "dB", "Volume", nullptr },
204 { "phaser_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
205 ValueDetails::kIndexed, false, "", "Phaser Switch", strings::kOffOnNames },
206 { "phaser_dry_wet", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
207 ValueDetails::kLinear, false, "%", "Phaser Mix", nullptr },
208 { "phaser_feedback", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
209 ValueDetails::kLinear, false, "%", "Phaser Feedback", nullptr },
210 { "phaser_frequency", 0x000000, -5.0, 2.0, -3.0, 0.0, 1.0,
211 ValueDetails::kExponential, true, " secs", "Phaser Frequency", nullptr },
212 { "phaser_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
213 ValueDetails::kIndexed, false, "", "Phaser Sync",strings::kFrequencySyncNames },
214 { "phaser_tempo", 0x000000, 0.0, 10.0, 3.0, 0.0, 1.0,
215 ValueDetails::kIndexed, false, "", "Phaser Tempo", strings::kSyncedFrequencyNames },
216 { "phaser_center", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
217 ValueDetails::kLinear, false, " semitones", "Phaser Center", nullptr },
218 { "phaser_blend", 0x000509, 0.0, 2.0, 1.0, 0.0, 1.0,
219 ValueDetails::kLinear, false, "", "Phaser Blend", nullptr },
220 { "phaser_mod_depth", 0x000000, 0.0, 48.0, 24.0, 0.0, 1.0,
221 ValueDetails::kLinear, false, " semitones", "Phaser Mod Depth", nullptr },
222 { "phaser_phase_offset", 0x000000, 0, 1.0, 0.33333333, 0.0, kDegreesPerCycle,
223 ValueDetails::kLinear, false, "", "Phaser Phase Offset", nullptr },
224 { "flanger_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
225 ValueDetails::kIndexed, false, "", "Flanger Switch", strings::kOffOnNames },
226 { "flanger_dry_wet", 0x000000, 0.0, 0.5, 0.5, 0.0, 200.0,
227 ValueDetails::kLinear, false, "%", "Flanger Mix", nullptr },
228 { "flanger_feedback", 0x000000, -1.0, 1.0, 0.5, 0.0, 100.0,
229 ValueDetails::kLinear, false, "%", "Flanger Feedback", nullptr },
230 { "flanger_frequency", 0x000000, -5.0, 2.0, 2.0, 0.0, 1.0,
231 ValueDetails::kExponential, true, " secs", "Flanger Frequency", nullptr },
232 { "flanger_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
233 ValueDetails::kIndexed, false, "", "Flanger Sync", strings::kFrequencySyncNames },
234 { "flanger_tempo", 0x000000, 0.0, 10.0, 4.0, 0.0, 1.0,
235 ValueDetails::kIndexed, false, "", "Flanger Tempo", strings::kSyncedFrequencyNames },
236 { "flanger_center", 0x000505, 8.0, 136.0, 64.0, 0.0, 1.0,
237 ValueDetails::kLinear, false, " semitones", "Flanger Center", nullptr },
238 { "flanger_mod_depth", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
239 ValueDetails::kLinear, false, "%", "Flanger Mod Depth", nullptr },
240 { "flanger_phase_offset", 0x000000, 0, 1.0, 0.33333333, 0.0, kDegreesPerCycle,
241 ValueDetails::kLinear, false, "", "Flanger Phase Offset", nullptr },
242 { "chorus_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
243 ValueDetails::kIndexed, false, "", "Chorus Switch", strings::kOffOnNames },
244 { "chorus_dry_wet", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
245 ValueDetails::kLinear, false, "%", "Chorus Mix", nullptr },
246 { "chorus_feedback", 0x000000, -0.95, 0.95, 0.4, 0.0, 100.0,
247 ValueDetails::kLinear, false, "%", "Chorus Feedback", nullptr },
248 { "chorus_cutoff", 0x000000, 8.0, 136.0, 60.0, 0.0, 1.0,
249 ValueDetails::kLinear, false, "", "Chorus Filter Cutoff", nullptr },
250 { "chorus_spread", 0x000607, 0.0, 1.0, 1.0, 0.0, 1.0,
251 ValueDetails::kLinear, false, "", "Chorus Filter Spread", nullptr },
252 { "chorus_voices", 0x000508, 1.0, 4.0, 4.0, 0.0, 4.0,
253 ValueDetails::kIndexed, false, "", "Chorus Voices", nullptr },
254 { "chorus_frequency", 0x000000, -6.0, 3.0, -3.0, 0.0, 1.0,
255 ValueDetails::kExponential, true, " secs", "Chorus Frequency", nullptr },
256 { "chorus_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
257 ValueDetails::kIndexed, false, "", "Chorus Sync", strings::kFrequencySyncNames },
258 { "chorus_tempo", 0x000000, 0.0, 10.0, 4.0, 0.0, 1.0,
259 ValueDetails::kIndexed, false, "", "Chorus Tempo", strings::kSyncedFrequencyNames },
260 { "chorus_mod_depth", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
261 ValueDetails::kLinear, false, "%", "Chorus Mod Depth", nullptr },
262 { "chorus_delay_1", 0x000000, -10.0, -5.64386, -9.0, 0.0, 1000.0,
263 ValueDetails::kExponential, false, "ms", "Chorus Delay 1", nullptr },
264 { "chorus_delay_2", 0x000000, -10.0, -5.64386, -7.0, 0.0, 1000.0,
265 ValueDetails::kExponential, false, " ms", "Chorus Delay 2", nullptr },
266 { "compressor_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
267 ValueDetails::kIndexed, false, "", "Compressor Switch", strings::kOffOnNames },
268 { "compressor_low_upper_threshold", 0x000000, -80.0, 0.0, -28.0, 0.0, 1.0,
269 ValueDetails::kLinear, false, " dB", "Low Upper Threshold", nullptr },
270 { "compressor_band_upper_threshold", 0x000000, -80.0, 0.0, -25.0, 0.0, 1.0,
271 ValueDetails::kLinear, false, " dB", "Band Upper Threshold", nullptr },
272 { "compressor_high_upper_threshold", 0x000000, -80.0, 0.0, -30.0, 0.0, 1.0,
273 ValueDetails::kLinear, false, " dB", "High Upper Threshold", nullptr },
274 { "compressor_low_lower_threshold", 0x000000, -80.0, 0.0, -35.0, 0.0, 1.0,
275 ValueDetails::kLinear, false, " dB", "Low Lower Threshold", nullptr },
276 { "compressor_band_lower_threshold", 0x000000, -80.0, 0.0, -36.0, 0.0, 1.0,
277 ValueDetails::kLinear, false, " dB", "Band Lower Threshold", nullptr },
278 { "compressor_high_lower_threshold", 0x000000, -80.0, 0.0, -35.0, 0.0, 1.0,
279 ValueDetails::kLinear, false, " dB", "High Lower Threshold", nullptr },
280 { "compressor_low_upper_ratio", 0x000000, 0.0, 1.0, 0.9, 0.0, 1.0,
281 ValueDetails::kLinear, false, "", "Low Upper Ratio", nullptr },
282 { "compressor_band_upper_ratio", 0x000000, 0.0, 1.0, 0.857, 0.0, 1.0,
283 ValueDetails::kLinear, false, "", "Band Upper Ratio", nullptr },
284 { "compressor_high_upper_ratio", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
285 ValueDetails::kLinear, false, "", "High Upper Ratio", nullptr },
286 { "compressor_low_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
287 ValueDetails::kLinear, false, "", "Low Lower Ratio", nullptr },
288 { "compressor_band_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
289 ValueDetails::kLinear, false, "", "Band Lower Ratio", nullptr },
290 { "compressor_high_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
291 ValueDetails::kLinear, false, "", "High Lower Ratio", nullptr },
292 { "compressor_low_gain", 0x000000, -30.0, 30.0, 16.3, 0.0, 1.0,
293 ValueDetails::kLinear, false, " dB", "Compressor Low Gain", nullptr },
294 { "compressor_band_gain", 0x000000, -30.0, 30.0, 11.7, 0.0, 1.0,
295 ValueDetails::kLinear, false, " dB", "Compressor Band Gain", nullptr },
296 { "compressor_high_gain", 0x000000, -30.0, 30.0, 16.3, 0.0, 1.0,
297 ValueDetails::kLinear, false, " dB", "Compressor High Gain", nullptr },
298 { "compressor_attack", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
299 ValueDetails::kLinear, false, "%", "Compressor Attack", nullptr },
300 { "compressor_release", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
301 ValueDetails::kLinear, false, "%", "Compressor Release", nullptr },
302 { "compressor_enabled_bands", 0x000000, 0.0, vital::MultibandCompressor::kNumBandOptions - 1, 0.0, 0.0, 1.0,
303 ValueDetails::kIndexed, false, "", "Compressor Enabled Bands", strings::kCompressorBandNames },
304 { "compressor_mix", 0x000602, 0.0, 1.0, 1.0, 0.0, 1.0,
305 ValueDetails::kLinear, false, "", "Compressor Mix", nullptr },
306 { "compressor_low_band_unused", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
307 ValueDetails::kIndexed, false, "", "Compressor Unused", nullptr },
308 { "eq_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
309 ValueDetails::kIndexed, false, "", "EQ Switch", strings::kOffOnNames },
310 { "eq_low_mode", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
311 ValueDetails::kIndexed, false, "", "EQ Low Mode", strings::kEqLowModeNames },
312 { "eq_low_cutoff", 0x000000, 8.0, 136.0, 40.0, 0.0, 1.0,
313 ValueDetails::kLinear, false, " semitones", "EQ Low Cutoff", nullptr },
314 { "eq_low_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
315 ValueDetails::kLinear, false, " dB", "EQ Low Gain", nullptr },
316 { "eq_low_resonance", 0x000000, 0.0, 1.0, 0.3163, 0.0, 100.0,
317 ValueDetails::kQuadratic, false, "%", "EQ Low Resonance", nullptr },
318 { "eq_band_mode", 0x000506, 0.0, 1.0, 0.0, 0.0, 1.0,
319 ValueDetails::kIndexed, false, "", "EQ Band Mode", strings::kEqBandModeNames },
320 { "eq_band_cutoff", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
321 ValueDetails::kLinear, false, " semitones", "EQ Band Cutoff", nullptr },
322 { "eq_band_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
323 ValueDetails::kLinear, false, " dB", "EQ Band Gain", nullptr },
324 { "eq_band_resonance", 0x000000, 0.0, 1.0, 0.4473, 0.0, 100.0,
325 ValueDetails::kQuadratic, false, "", "EQ Band Resonance", nullptr },
326 { "eq_high_mode", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
327 ValueDetails::kIndexed, false, "", "EQ High Mode", strings::kEqHighModeNames },
328 { "eq_high_cutoff", 0x000000, 8.0, 136.0, 100.0, 0.0, 1.0,
329 ValueDetails::kLinear, false, " semitones", "EQ High Cutoff", nullptr },
330 { "eq_high_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
331 ValueDetails::kLinear, false, " dB", "EQ High Gain", nullptr },
332 { "eq_high_resonance", 0x000000, 0.0, 1.0, 0.3163, 0.0, 100.0,
333 ValueDetails::kQuadratic, false, "", "EQ High Resonance", nullptr },
334 { "effect_chain_order", 0x000000, 0.0, vital::utils::factorial(vital::kNumEffects) - 1, 0.0, 0.0, 1.0,
335 ValueDetails::kIndexed, false, "", "Effect Chain Order", nullptr },
336 { "voice_priority", 0x000000, 0.0, VoiceHandler::kNumVoicePriorities - 1, VoiceHandler::kRoundRobin, 0.0, 1.0,
337 ValueDetails::kIndexed, false, "", "Voice Priority", strings::kVoicePriorityNames },
338 { "voice_override", 0x000700, 0.0, VoiceHandler::kNumVoiceOverrides - 1, VoiceHandler::kKill, 0.0, 1.0,
339 ValueDetails::kIndexed, false, "", "Voice Override", strings::kVoiceOverrideNames },
340 { "oversampling", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
341 ValueDetails::kIndexed, false, "", "Oversampling", strings::kOversamplingNames },
342 { "pitch_wheel", 0x000400, -1.0, 1.0, 0.0, 0.0, 1.0,
343 ValueDetails::kLinear, false, "", "Pitch Wheel", nullptr },
344 { "mod_wheel", 0x000400, 0.0, 1.0, 0.0, 0.0, 1.0,
345 ValueDetails::kLinear, false, "", "Mod Wheel", nullptr },
346 { "mpe_enabled", 0x000501, 0.0, 1.0, 0.0, 0.0, 1.0,
347 ValueDetails::kIndexed, false, "", "MPE Enabled", strings::kOffOnNames },
348 { "view_spectrogram", 0x000803, 0.0, 2.0, 0.0, 0.0, 1.0,
349 ValueDetails::kIndexed, false, "", "View Spectrogram", strings::kOffOnNames },
350 };
351
352 const ValueDetails ValueDetailsLookup::env_parameter_list[] = {
353 { "delay", 0x000503, 0.0, 1.4142135624, 0.0, 0.0, 1.0,
354 ValueDetails::kQuartic, false, " secs", "Delay", nullptr },
355 { "attack", 0x000000, 0.0, 2.37842, 0.1495, 0.0, 1.0,
356 ValueDetails::kQuartic, false, " secs", "Attack", nullptr },
357 { "hold", 0x000504, 0.0, 1.4142135624, 0.0, 0.0, 1.0,
358 ValueDetails::kQuartic, false, " secs", "Hold", nullptr },
359 { "decay", 0x000000, 0.0, 2.37842, 1.0, 0.0, 1.0,
360 ValueDetails::kQuartic, false, " secs", "Decay", nullptr },
361 { "release", 0x000000, 0.0, 2.37842, 0.5476, 0.0, 1.0,
362 ValueDetails::kQuartic, false, " secs", "Release", nullptr },
363 { "attack_power", 0x000000, -20.0, 20.0, 0.0f, 0.0, 1.0,
364 ValueDetails::kLinear, false, "", "Attack Power", nullptr },
365 { "decay_power", 0x000000, -20.0, 20.0, -2.0f, 0.0, 1.0,
366 ValueDetails::kLinear, false, "", "Decay Power", nullptr },
367 { "release_power", 0x000000, -20.0, 20.0, -2.0f, 0.0, 1.0,
368 ValueDetails::kLinear, false, "", "Release Power", nullptr },
369 { "sustain", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
370 ValueDetails::kLinear, false, "", "Sustain", nullptr },
371 };
372
373 const ValueDetails ValueDetailsLookup::lfo_parameter_list[] = {
374 { "phase", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
375 ValueDetails::kLinear, false, "", "Phase", nullptr },
376 { "sync_type", 0x000000, 0.0, SynthLfo::kNumSyncTypes - 1, 0.0, 0.0, 1.0,
377 ValueDetails::kIndexed, false, "", "Sync Type", strings::kSyncNames },
378 { "frequency", 0x000000, -7.0, 9.0, 1.0, 0.0, 1.0,
379 ValueDetails::kExponential, true, " secs", "Frequency", nullptr },
380 { "sync", 0x000000, 0.0, SynthLfo::kNumSyncOptions - 1, 1.0, 0.0, 1.0,
382 { "tempo", 0x000000, 0.0, 12.0, 7.0, 0.0, 1.0,
384 { "fade_time", 0x000000, 0.0, 8.0, 0.0, 0.0, 1.0,
385 ValueDetails::kLinear, false, " secs", "Fade In", nullptr },
386 { "smooth_mode", 0x000801, 0.0, 1.0, 1.0, 0.0, 1.0,
387 ValueDetails::kIndexed, false, "", "Smooth Mode", strings::kOffOnNames },
388 { "smooth_time", 0x000801, -10.0, 4.0, -7.5, 0.0, 1.0,
389 ValueDetails::kExponential, false, " secs", "Smooth Time", nullptr },
390 { "delay_time", 0x000000, 0.0, 4.0, 0.0, 0.0, 1.0,
391 ValueDetails::kLinear, false, " secs", "Delay", nullptr },
392 { "stereo", 0x000406, -0.5, 0.5, 0.0, 0.0, 1.0,
393 ValueDetails::kLinear, false, "", "Stereo", nullptr },
394 { "keytrack_transpose", 0x000704, -60.0, 36.0, -12.0, 0.0, 1.0,
395 ValueDetails::kIndexed, false, "", "Transpose", nullptr },
396 { "keytrack_tune", 0x000704, -1.0, 1.0, 0.0, 0.0, 100.0,
397 ValueDetails::kLinear, false, "", "Tune", nullptr },
398 };
399
400 const ValueDetails ValueDetailsLookup::random_lfo_parameter_list[] = {
401 { "style", 0x000401, 0.0, RandomLfo::kNumStyles - 1, 0.0, 0.0, 1.0,
402 ValueDetails::kIndexed, false, "", "Style", strings::kRandomNames },
403 { "frequency", 0x000401, -7.0, 9.0, 1.0, 0.0, 1.0,
404 ValueDetails::kExponential, true, " secs", "Frequency", nullptr },
405 { "sync", 0x000401, 0.0, SynthLfo::kNumSyncOptions - 1, 1.0, 0.0, 1.0,
407 { "tempo", 0x000401, 0.0, 12.0, 8.0, 0.0, 1.0,
409 { "stereo", 0x000401, 0.0, 1.0, 0.0, 0.0, 1.0,
410 ValueDetails::kIndexed, false, "", "Stereo", strings::kOffOnNames },
411 { "sync_type", 0x000600, 0.0, 1.0, 0.0, 0.0, 1.0,
412 ValueDetails::kIndexed, false, "", "Sync Type", strings::kOffOnNames },
413 { "keytrack_transpose", 0x000704, -60.0, 36.0, -12.0, 0.0, 1.0,
414 ValueDetails::kIndexed, false, "", "Transpose", nullptr },
415 { "keytrack_tune", 0x000704, -1.0, 1.0, 0.0, 0.0, 100.0,
416 ValueDetails::kLinear, false, "", "Tune", nullptr },
417 };
418
419 const ValueDetails ValueDetailsLookup::filter_parameter_list[] = {
420 { "mix", 0x000000, 0.0f, 1.0f, 1.0f, 0.0, 100.0,
421 ValueDetails::kLinear, false, "%", "Mix", nullptr },
422 { "cutoff", 0x000000, 8.0, 136.0, 60.0, -60.0, 1.0,
423 ValueDetails::kLinear, false, " semitones", "Cutoff", nullptr },
424 { "resonance", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
425 ValueDetails::kLinear, false, "%", "Resonance", nullptr },
426 { "drive", 0x000000, 0.0, 20.0, 0.0, 0.0, 1.0,
427 ValueDetails::kLinear, false, "dB", "Drive", nullptr },
428 { "blend", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
429 ValueDetails::kLinear, false, "", "Blend", nullptr },
430 { "style", 0x000000, 0.0, 9.0, 0.0, 0.0, 1.0,
432 { "model", 0x000000, 0.0, kNumFilterModels - 1.0, 0.0, 0.0, 1.0,
434 { "on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
435 ValueDetails::kIndexed, false, "", "Switch", strings::kOffOnNames },
436 { "blend_transpose", 0x000000, 0.0, 84.0, 42.0, 0.0, 1.0,
437 ValueDetails::kLinear, false, " semitones", "Comb Blend Offset", nullptr },
438 { "keytrack", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
439 ValueDetails::kLinear, false, "%", "Key Track", nullptr },
440 { "formant_x", 0x000000, 0.0, 1.0, 0.5, 0.0, 1.0,
441 ValueDetails::kLinear, false, "", "Formant X", nullptr },
442 { "formant_y", 0x000000, 0.0, 1.0, 0.5, 0.0, 1.0,
443 ValueDetails::kLinear, false, "", "Formant Y", nullptr },
444 { "formant_transpose", 0x000000, -12.0, 12.0, 0.0, 0.0, 1.0,
445 ValueDetails::kLinear, false, "", "Formant Transpose", nullptr },
446 { "formant_resonance", 0x000000, 0.3, 1.0, 0.85, 0.0, 100.0,
447 ValueDetails::kLinear, false, "%", "Formant Resonance", nullptr },
448 { "formant_spread", 0x000707, -1.0, 1.0, 0.0, 0.0, 100.0,
449 ValueDetails::kLinear, false, "%", "Formant Spread", nullptr },
450 { "osc1_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
451 ValueDetails::kIndexed, false, "", "OSC 1 Input", strings::kOffOnNames },
452 { "osc2_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
453 ValueDetails::kIndexed, false, "", "OSC 2 Input", strings::kOffOnNames },
454 { "osc3_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
455 ValueDetails::kIndexed, false, "", "OSC 3 Input", strings::kOffOnNames },
456 { "sample_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
457 ValueDetails::kIndexed, false, "", "SAMPLE Input", strings::kOffOnNames },
458 { "filter_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
459 ValueDetails::kIndexed, false, "", "FILTER Input", strings::kOffOnNames },
460 };
461
462 const ValueDetails ValueDetailsLookup::osc_parameter_list[] = {
463 { "on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
464 ValueDetails::kIndexed, false, "", "Switch", strings::kOffOnNames },
465 { "transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
466 ValueDetails::kIndexed, false, "", "Transpose", nullptr },
467 { "transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
468 ValueDetails::kIndexed, false, "", "Transpose Quantize", nullptr },
469 { "tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
470 ValueDetails::kLinear, false, "", "Tune", nullptr },
471 { "pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
472 ValueDetails::kLinear, false, "%", "Pan", nullptr },
473 { "stack_style", 0x000000, 0.0, SynthOscillator::kNumUnisonStackTypes - 1, 0.0, 0.0, 1.0,
474 ValueDetails::kIndexed, false, "", "Stack Style", strings::kUnisonStackNames },
475 { "unison_detune", 0x000000, 0.0, 10.0, 4.472135955, 0.0, 1.0,
476 ValueDetails::kQuadratic, false, "%", "Unison Detune", nullptr },
477 { "unison_voices", 0x000000, 1.0, 16.0, 1.0, 0.0, 1.0,
478 ValueDetails::kIndexed, false, "v", "Unison Voices", nullptr },
479 { "unison_blend", 0x000000, 0.0, 1.0, 0.8, 0.0, 100.0,
480 ValueDetails::kLinear, false, "%", "Blend", nullptr },
481 { "detune_power", 0x000000, -5.0, 5.0, 1.5, 0.0, 1.0,
482 ValueDetails::kLinear, false, "", "Detune Power", nullptr },
483 { "detune_range", 0x000000, 0.0, 48.0, 2.0, 0.0, 1.0,
484 ValueDetails::kLinear, false, "", "Detune Range", nullptr },
485 { "level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
486 ValueDetails::kQuadratic, false, "", "Level", nullptr },
487 { "midi_track", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
488 ValueDetails::kIndexed, false, "", "Midi Track", strings::kOffOnNames },
489 { "smooth_interpolation", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
490 ValueDetails::kIndexed, false, "", "Smooth Interpolation", strings::kOffOnNames },
491 { "spectral_unison", 0x000500, 0.0, 1.0, 1.0, 0.0, 1.0,
492 ValueDetails::kIndexed, false, "", "Spectral Unison", strings::kOffOnNames },
493 { "wave_frame", 0x000000, 0.0, kNumOscillatorWaveFrames - 1, 0.0, 0.0, 1.0,
494 ValueDetails::kLinear, false, "", "Wave Frame", nullptr },
495 { "frame_spread", 0x000000, -kNumOscillatorWaveFrames / 2, kNumOscillatorWaveFrames / 2, 0.0, 0.0, 1.0,
496 ValueDetails::kLinear, false, "", "Unison Frame Spread", nullptr },
497 { "stereo_spread", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
498 ValueDetails::kLinear, false, "%", "Stereo Spread", nullptr },
499 { "phase", 0x000000, 0.0, 1.0, 0.5, 0.0, 360.0,
500 ValueDetails::kLinear, false, "", "Phase", nullptr },
501 { "distortion_phase", 0x000000, 0.0, 1.0, 0.5, 0.0, 360.0,
502 ValueDetails::kLinear, false, "", "Distortion Phase", nullptr },
503 { "random_phase", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
504 ValueDetails::kLinear, false, "%", "Phase Randomization", nullptr },
505 { "distortion_type", 0x000000, 0.0, SynthOscillator::kNumDistortionTypes - 1, 0.0, 0.0, 1.0,
506 ValueDetails::kIndexed, false, "", "Distortion Type", strings::kPhaseDistortionNames },
507 { "distortion_amount", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
508 ValueDetails::kLinear, false, "%", "Distortion Amount", nullptr },
509 { "distortion_spread", 0x000000, -0.5, 0.5, 0.0, 0.0, 200.0,
510 ValueDetails::kLinear, false, "%", "Distortion Spread", nullptr },
511 { "spectral_morph_type", 0x000407, 0.0, SynthOscillator::kNumSpectralMorphTypes - 1, 0.0, 0.0, 1.0,
512 ValueDetails::kIndexed, false, "", "Frequency Morph Type", strings::kSpectralMorphNames },
513 { "spectral_morph_amount", 0x000407, 0.0, 1.0, 0.5, 0.0, 100.0,
514 ValueDetails::kLinear, false, "%", "Frequency Morph Amount", nullptr },
515 { "spectral_morph_spread", 0x000407, -0.5, 0.5, 0.0, 0.0, 200.0,
516 ValueDetails::kLinear, false, "%", "Frequency Morph Spread", nullptr },
517 { "destination", 0x000500, 0.0, constants::kNumSourceDestinations + constants::kNumEffects, 0.0, 0.0, 1.0,
518 ValueDetails::kIndexed, false, "", "Destination", strings::kDestinationNames },
519 { "view_2d", 0x000402, 0.0, 2.0, 1.0, 0.0, 1.0,
520 ValueDetails::kIndexed, false, "", "View 2D", strings::kOffOnNames },
521 };
522
523 const ValueDetails ValueDetailsLookup::mod_parameter_list[] = {
524 { "amount", 0x000000, -1.0, 1.0, 0.0, 0.0, 1.0,
525 ValueDetails::kLinear, false, "", "Amount", nullptr },
526 { "power", 0x000000, -10.0, 10.0, 0.0, 0.0, 1.0,
527 ValueDetails::kLinear, false, "", "Power", nullptr },
528 { "bipolar", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
529 ValueDetails::kIndexed, false, "", "Bipolar", strings::kOffOnNames },
530 { "stereo", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
531 ValueDetails::kIndexed, false, "", "Stereo", strings::kOffOnNames },
532 { "bypass", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
533 ValueDetails::kIndexed, false, "", "Bypass", strings::kOffOnNames }
534 };
535
536 // The constructor of ValueDetailsLookup populates the global parameter map and list.
538 static constexpr int kNumOscillatorsOld = 2;
539 static constexpr int kNewOscillatorVersion = 0x000500;
540 static constexpr int kOldMaxModulations = 32;
541 static constexpr int kNewModulationVersion = 0x000601;
542
543 // Load base parameters.
544 int num_parameters = sizeof(parameter_list) / sizeof(ValueDetails);
545 for (int i = 0; i < num_parameters; ++i) {
546 details_lookup_[parameter_list[i].name] = parameter_list[i];
547 details_list_.push_back(&parameter_list[i]);
548
549 VITAL_ASSERT(parameter_list[i].default_value <= parameter_list[i].max);
550 VITAL_ASSERT(parameter_list[i].default_value >= parameter_list[i].min);
551 }
552
553 // Add envelope groups (one for each envelope).
554 int num_env_parameters = sizeof(env_parameter_list) / sizeof(ValueDetails);
555 for (int env = 0; env < kNumEnvelopes; ++env)
556 addParameterGroup(env_parameter_list, num_env_parameters, env, kEnvIdPrefix, kEnvNamePrefix);
557
558 // Add LFO parameter groups.
559 int num_lfo_parameters = sizeof(lfo_parameter_list) / sizeof(ValueDetails);
560 for (int lfo = 0; lfo < kNumLfos; ++lfo)
561 addParameterGroup(lfo_parameter_list, num_lfo_parameters, lfo, kLfoIdPrefix, kLfoNamePrefix);
562
563 // Add Random LFO parameter groups.
564 int num_random_lfo_parameters = sizeof(random_lfo_parameter_list) / sizeof(ValueDetails);
565 for (int lfo = 0; lfo < kNumRandomLfos; ++lfo)
566 addParameterGroup(random_lfo_parameter_list, num_random_lfo_parameters, lfo, kRandomIdPrefix, kRandomNamePrefix);
567
568 // Add Oscillator parameter groups.
569 int num_osc_parameters = sizeof(osc_parameter_list) / sizeof(ValueDetails);
570 for (int osc = 0; osc < kNumOscillatorsOld; ++osc)
571 addParameterGroup(osc_parameter_list, num_osc_parameters, osc, kOscIdPrefix, kOscNamePrefix);
572 for (int osc = kNumOscillatorsOld; osc < kNumOscillators; ++osc) {
573 // Newer oscillators added in a later version.
574 addParameterGroup(osc_parameter_list, num_osc_parameters, osc, kOscIdPrefix,
575 kOscNamePrefix, kNewOscillatorVersion);
576 }
577
578 // Add Filter parameter groups, including FX filter.
579 int num_filter_parameters = sizeof(filter_parameter_list) / sizeof(ValueDetails);
580 for (int filter = 0; filter < kNumFilters; ++filter)
581 addParameterGroup(filter_parameter_list, num_filter_parameters, filter, kFilterIdPrefix, kFilterNamePrefix);
582
583 addParameterGroup(filter_parameter_list, num_filter_parameters, "fx", kFilterIdPrefix, kFilterNamePrefix);
584
585 // Add Modulation parameter groups.
586 int num_mod_parameters = sizeof(mod_parameter_list) / sizeof(ValueDetails);
587 for (int modulation = 0; modulation < kOldMaxModulations; ++modulation) {
588 addParameterGroup(mod_parameter_list, num_mod_parameters, modulation,
589 kModulationIdPrefix, kModulationNamePrefix);
590 }
591 for (int modulation = kOldMaxModulations; modulation < kMaxModulationConnections; ++modulation) {
592 // Newer modulation slots added in a newer version.
593 addParameterGroup(mod_parameter_list, num_mod_parameters, modulation,
594 kModulationIdPrefix, kModulationNamePrefix, kNewModulationVersion);
595 }
596
597 // Override some defaults.
598 details_lookup_["osc_1_on"].default_value = 1.0f;
599 details_lookup_["osc_2_destination"].default_value = 1.0f;
600 details_lookup_["osc_3_destination"].default_value = 3.0f;
601 details_lookup_["filter_1_osc1_input"].default_value = 1.0f;
602 details_lookup_["filter_2_osc2_input"].default_value = 1.0f;
603
604 // Sort the final parameter list by version and name.
605 std::sort(details_list_.begin(), details_list_.end(), compareValueDetails);
606 }
607
608 void ValueDetailsLookup::addParameterGroup(const ValueDetails* list, int num_parameters, int index,
609 std::string id_prefix, std::string name_prefix, int version) {
610 std::string string_num = std::to_string(index + 1);
611 addParameterGroup(list, num_parameters, string_num, id_prefix, name_prefix, version);
612 }
613
614 void ValueDetailsLookup::addParameterGroup(const ValueDetails* list, int num_parameters, std::string id,
615 std::string id_prefix, std::string name_prefix, int version) {
616 std::string id_start = id_prefix + kIdDelimiter + id + kIdDelimiter;
617 std::string name_start = name_prefix + kNameDelimiter + id + kNameDelimiter;
618
619 // Clone and prefix each parameter in the group with the provided identifiers and names.
620 for (int i = 0; i < num_parameters; ++i) {
621 ValueDetails details = list[i];
622 if (version > details.version_added)
623 details.version_added = version;
624
625 details.name = id_start + details.name;
626 details.local_description = details.display_name;
627 details.display_name = name_start + details.display_name;
628 details_lookup_[details.name] = details;
629 details_list_.push_back(&details_lookup_[details.name]);
630 }
631 }
632
633 // Static instance of the global lookup.
635
636} // namespace vital
static constexpr mono_float kMaxGain
Maximum gain in dB for shelf or gain-based operations.
Definition digital_svf.h:37
static constexpr mono_float kMinGain
Minimum gain in dB for shelf or gain-based operations.
Definition digital_svf.h:42
static constexpr mono_float kMinDrive
Minimum allowed drive in decibels.
Definition distortion.h:26
static constexpr mono_float kMaxDrive
Maximum allowed drive in decibels.
Definition distortion.h:21
@ kNumBandOptions
Definition compressor.h:221
static ValueDetailsLookup lookup_
Definition synth_parameters.h:228
@ kNumShapes
Definition wave_frame.h:153
@ kNumStyles
Definition random_lfo.h:77
@ kNumSyncTypes
Definition synth_lfo.h:79
@ kNumSyncOptions
Definition synth_lfo.h:98
@ kNumDistortionTypes
Definition synth_oscillator.h:159
@ kNumSpectralMorphTypes
Definition synth_oscillator.h:139
@ kNumUnisonStackTypes
Definition synth_oscillator.h:177
Maintains a lookup table for all parameters defined in Vital.
Definition synth_parameters.h:63
static const ValueDetails parameter_list[]
Definition synth_parameters.h:173
static const ValueDetails osc_parameter_list[]
Definition synth_parameters.h:178
static const ValueDetails random_lfo_parameter_list[]
Definition synth_parameters.h:176
static const ValueDetails env_parameter_list[]
Definition synth_parameters.h:174
static const ValueDetails filter_parameter_list[]
Definition synth_parameters.h:177
ValueDetailsLookup()
Constructs a ValueDetailsLookup and initializes its parameter tables.
Definition synth_parameters.cpp:537
static const ValueDetails mod_parameter_list[]
Definition synth_parameters.h:179
static const ValueDetails lfo_parameter_list[]
Definition synth_parameters.h:175
void addParameterGroup(const ValueDetails *list, int num_parameters, int index, std::string id_prefix, std::string name_prefix, int version=-1)
Adds a group of parameters, each with prefixed names and display names.
Definition synth_parameters.cpp:608
@ kNumVoiceOverrides
Definition voice_handler.h:403
@ kKill
Immediately kill an existing voice to free one.
Definition voice_handler.h:401
@ kRoundRobin
Definition voice_handler.h:415
@ kNumVoicePriorities
Definition voice_handler.h:416
#define VITAL_ASSERT(x)
Definition common.h:11
const std::string kFilterModelNames[]
Names of different filter models (analog, dirty, ladder, etc.).
Definition synth_strings.h:197
const std::string kPhaseDistortionNames[]
Names of different phase distortion modes.
Definition synth_strings.h:429
const std::string kSyncedFrequencyNames[]
Names for synced LFO frequencies (Freeze, 32/1, 16/1, etc.).
Definition synth_strings.h:241
const std::string kRandomNames[]
Full names for different random generator modes.
Definition synth_strings.h:316
const std::string kEqHighModeNames[]
Names for EQ high band modes.
Definition synth_strings.h:360
const std::string kOversamplingNames[]
Names for oversampling rates.
Definition synth_strings.h:37
const std::string kVoicePriorityNames[]
Voice allocation priority modes (e.g., newest, oldest note).
Definition synth_strings.h:339
const std::string kUnisonStackNames[]
Names for different unison voice stacking modes.
Definition synth_strings.h:97
const std::string kFilterStyleNames[]
Filter style names for visualizing different filter slopes and blends.
Definition synth_strings.h:115
const std::string kFrequencySyncNames[]
Names for frequency synchronization modes (time, tempo, keytrack, etc.).
Definition synth_strings.h:149
const std::string kEqLowModeNames[]
Names for EQ low band modes.
Definition synth_strings.h:378
const std::string kDistortionFilterOrderNames[]
Filter order names for distortion section (pre, post, none).
Definition synth_strings.h:187
const std::string kVoiceOverrideNames[]
Behavior of what happens when voice limit is exceeded (kill or steal).
Definition synth_strings.h:351
const std::string kCompressorBandNames[]
Full names for compressor band modes.
Definition synth_strings.h:59
const std::string kDestinationNames[vital::constants::kNumSourceDestinations+vital::constants::kNumEffects]
Names of possible audio routing destinations (filters, effects).
Definition synth_strings.h:387
const std::string kDelayStyleNames[]
Names for delay line styles (mono, stereo, ping-pong, etc.).
Definition synth_strings.h:48
const std::string kOffOnNames[]
Off/On state names.
Definition synth_strings.h:18
const std::string kSyncNames[]
Full names for different sync/re-triggering modes of modulators.
Definition synth_strings.h:292
const std::string kEqBandModeNames[]
Names for EQ band modes (Shelf or Notch).
Definition synth_strings.h:369
const std::string kStereoModeNames[vital::StereoEncoder::kNumStereoModes]
Names for stereo routing modes.
Definition synth_strings.h:261
const std::string kDistortionTypeNames[]
More descriptive names for various distortion types.
Definition synth_strings.h:174
const std::string kSpectralMorphNames[]
Names for spectral morphing modes in the wavetable.
Definition synth_strings.h:449
@ kNumEffects
Definition synth_constants.h:187
@ kNumFilterModels
Definition synth_constants.h:203
@ kNumSourceDestinations
Definition synth_constants.h:121
constexpr int factorial(int value)
Computes the factorial of a given integer at compile time.
Definition utils.h:38
Contains classes and functions used within the Vital synthesizer framework.
constexpr int kNumOscillators
Number of oscillators available in Vital.
Definition synth_constants.h:16
constexpr int kNumFilters
Number of filter slots in Vital.
Definition synth_constants.h:31
constexpr int kNumRandomLfos
Number of random LFO sources (random modulation generators).
Definition synth_constants.h:25
constexpr int kDegreesPerCycle
Degrees in a full rotation (for LFO phases).
Definition common.h:49
constexpr int kMaxPolyphony
The maximum number of voices allocated for polyphony (includes an extra for handling transitions).
Definition synth_constants.h:40
constexpr int kNumEnvelopes
Number of envelope generators in Vital.
Definition synth_constants.h:22
constexpr int kNumOscillatorWaveFrames
Number of wave frames in each oscillator’s wavetable.
Definition synth_constants.h:19
constexpr int kNumLfos
Number of LFO sources available in the Vital synthesizer.
Definition synth_constants.h:13
constexpr int kMaxModulationConnections
Maximum number of modulation connections allowed.
Definition synth_constants.h:49
bool compareValueDetails(const ValueDetails *a, const ValueDetails *b)
Comparison function for sorting parameters by version and name.
Definition synth_parameters.cpp:34
Holds metadata about a single parameter (control) in the Vital synthesizer.
Definition synth_parameters.h:23
@ kQuartic
Parameter value transformed by a quartic curve.
Definition synth_parameters.h:33
@ kSquareRoot
Parameter value transformed by a square root function.
Definition synth_parameters.h:34
@ kLinear
Parameter scales linearly between min and max.
Definition synth_parameters.h:30
@ kExponential
Parameter value transformed by an exponential function.
Definition synth_parameters.h:35
@ kIndexed
Parameter steps through discrete indexed values.
Definition synth_parameters.h:29
@ kQuadratic
Parameter value transformed by a quadratic curve.
Definition synth_parameters.h:31
std::string display_name
Human-readable name for display in UI.
Definition synth_parameters.h:48
std::string local_description
Local description or additional metadata.
Definition synth_parameters.h:50
int version_added
Version code when the parameter was introduced or changed.
Definition synth_parameters.h:39
std::string name
Unique parameter name/identifier.
Definition synth_parameters.h:38
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...
Declares classes and data structures to handle polyphonic voices in Vital, including voice assignment...