You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

622 lines
38KB

  1. /* Copyright 2013-2019 Matt Tytel
  2. *
  3. * vital is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * vital is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with vital. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "synth_parameters.h"
  17. #include "compressor.h"
  18. #include "distortion.h"
  19. #include "digital_svf.h"
  20. #include "synth_constants.h"
  21. #include "random_lfo.h"
  22. #include "synth_lfo.h"
  23. #include "synth_oscillator.h"
  24. #include "synth_strings.h"
  25. #include "voice_handler.h"
  26. #include "wavetable.h"
  27. #include "utils.h"
  28. #include <cfloat>
  29. namespace vital {
  30. bool compareValueDetails(const ValueDetails* a, const ValueDetails* b) {
  31. if (a->version_added != b->version_added)
  32. return a->version_added < b->version_added;
  33. return a->name.compare(b->name) < 0;
  34. }
  35. using namespace constants;
  36. static const std::string kIdDelimiter = "_";
  37. static const std::string kEnvIdPrefix = "env";
  38. static const std::string kLfoIdPrefix = "lfo";
  39. static const std::string kRandomIdPrefix = "random";
  40. static const std::string kOscIdPrefix = "osc";
  41. static const std::string kFilterIdPrefix = "filter";
  42. static const std::string kModulationIdPrefix = "modulation";
  43. static const std::string kNameDelimiter = " ";
  44. static const std::string kEnvNamePrefix = "Envelope";
  45. static const std::string kLfoNamePrefix = "LFO";
  46. static const std::string kRandomNamePrefix = "Random LFO";
  47. static const std::string kOscNamePrefix = "Oscillator";
  48. static const std::string kFilterNamePrefix = "Filter";
  49. static const std::string kModulationNamePrefix = "Modulation";
  50. const ValueDetails ValueDetailsLookup::parameter_list[] = {
  51. { "bypass", 0x000702, 0.0, 1.0, 0.0, 0.0, 60.0,
  52. ValueDetails::kIndexed, false, "", "Bypass", nullptr },
  53. { "beats_per_minute", 0x000000, 0.333333333, 5.0, 2.0, 0.0, 60.0,
  54. ValueDetails::kLinear, false, "", "Beats Per Minute", nullptr },
  55. { "delay_dry_wet", 0x000000, 0.0, 1.0, 0.3334, 0.0, 100.0,
  56. ValueDetails::kLinear, false, "%", "Delay Mix", nullptr },
  57. { "delay_feedback", 0x000000, -1.0, 1.0, 0.5, 0.0, 100.0,
  58. ValueDetails::kLinear, false, "%", "Delay Feedback", nullptr },
  59. { "delay_frequency", 0x000000, -2.0, 9.0, 2.0, 0.0, 1.0,
  60. ValueDetails::kExponential, true, " secs", "Delay Frequency", nullptr },
  61. { "delay_aux_frequency", 0x000507, -2.0, 9.0, 2.0, 0.0, 1.0,
  62. ValueDetails::kExponential, true, " secs", "Delay Frequency 2", nullptr },
  63. { "delay_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  64. ValueDetails::kIndexed, false, "", "Delay Switch", strings::kOffOnNames },
  65. { "delay_style", 0x000000, 0.0, 3.0, 0.0, 0.0, 1.0,
  66. ValueDetails::kIndexed, false, "", "Delay Style", strings::kDelayStyleNames },
  67. { "delay_filter_cutoff", 0x000000, 8.0, 136.0, 60.0, 0.0, 1.0,
  68. ValueDetails::kLinear, false, "", "Delay Filter Cutoff", nullptr },
  69. { "delay_filter_spread", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  70. ValueDetails::kLinear, false, "", "Delay Filter Spread", nullptr },
  71. { "delay_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
  72. ValueDetails::kIndexed, false, "", "Delay Sync", strings::kFrequencySyncNames },
  73. { "delay_tempo", 0x000000, 4.0, 12.0, 9.0, 0.0, 1.0,
  74. ValueDetails::kIndexed, false, "", "Delay Tempo", strings::kSyncedFrequencyNames },
  75. { "delay_aux_sync", 0x000507, 0.0, 3.0, 1.0, 0.0, 1.0,
  76. ValueDetails::kIndexed, false, "", "Delay Sync 2", strings::kFrequencySyncNames },
  77. { "delay_aux_tempo", 0x000507, 4.0, 12.0, 9.0, 0.0, 1.0,
  78. ValueDetails::kIndexed, false, "", "Delay Tempo 2", strings::kSyncedFrequencyNames },
  79. { "distortion_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  80. ValueDetails::kIndexed, false, "", "Distortion Switch", strings::kOffOnNames },
  81. { "distortion_type", 0x000000, 0.0, 5.0, 0.0, 0.0, 1.0,
  82. ValueDetails::kIndexed, false, "", "Distortion Type", strings::kDistortionTypeNames },
  83. { "distortion_drive", 0x000000, Distortion::kMinDrive, Distortion::kMaxDrive, 0.0, 0.0, 1.0,
  84. ValueDetails::kLinear, false, " dB", "Distortion Drive", nullptr },
  85. { "distortion_mix", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  86. ValueDetails::kLinear, false, "", "Distortion Mix", nullptr },
  87. { "distortion_filter_order", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
  88. ValueDetails::kIndexed, false, "", "Distortion Filter Order", strings::kDistortionFilterOrderNames },
  89. { "distortion_filter_cutoff", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
  90. ValueDetails::kLinear, false, " semitones", "Distortion Filter Cutoff", nullptr },
  91. { "distortion_filter_resonance", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  92. ValueDetails::kLinear, false, "%", "Distortion Filter Resonance", nullptr },
  93. { "distortion_filter_blend", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
  94. ValueDetails::kLinear, false, "", "Distortion Filter Blend", nullptr },
  95. { "legato", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  96. ValueDetails::kIndexed, false, "", "Legato", strings::kOffOnNames },
  97. { "macro_control_1", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  98. ValueDetails::kLinear, false, "", "Macro 1", nullptr },
  99. { "macro_control_2", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  100. ValueDetails::kLinear, false, "", "Macro 2", nullptr },
  101. { "macro_control_3", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  102. ValueDetails::kLinear, false, "", "Macro 3", nullptr },
  103. { "macro_control_4", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  104. ValueDetails::kLinear, false, "", "Macro 4", nullptr },
  105. { "pitch_bend_range", 0x000000, 0.0, 48.0, 2.0, 0.0, 1.0,
  106. ValueDetails::kIndexed, false, " semitones", "Pitch Bend Range", nullptr },
  107. { "polyphony", 0x000000, 1.0, kMaxPolyphony - 1, 8.0, 0.0, 1.0,
  108. ValueDetails::kIndexed, false, " voices", "Polyphony", nullptr },
  109. { "voice_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  110. ValueDetails::kLinear, false, " cents", "Voice Tune", nullptr },
  111. { "voice_transpose", 0x000604, -48.0, 48.0, 0.0, 0.0, 1.0,
  112. ValueDetails::kIndexed, false, "", "Voice Transpose", nullptr },
  113. { "voice_amplitude", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  114. ValueDetails::kLinear, false, "", "Voice Amplitude", nullptr },
  115. { "stereo_routing", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
  116. ValueDetails::kLinear, false, "%", "Stereo Routing", nullptr },
  117. { "stereo_mode", 0x000605, 0.0, 1.0, 0.0, 0.0, 1.0,
  118. ValueDetails::kIndexed, false, "", "Stereo Mode", strings::kStereoModeNames },
  119. { "portamento_time", 0x000000, -10.0, 4.0, -10.0, 0.0, 1.0,
  120. ValueDetails::kExponential, false, " secs", "Portamento Time", nullptr },
  121. { "portamento_slope", 0x000000, -8.0, 8.0, 0.0, 0.0, 1.0,
  122. ValueDetails::kLinear, false, "", "Portamento Slope", nullptr },
  123. { "portamento_force", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  124. ValueDetails::kIndexed, false, "", "Portamento Force", strings::kOffOnNames },
  125. { "portamento_scale", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  126. ValueDetails::kIndexed, false, "", "Portamento Scale", strings::kOffOnNames },
  127. { "reverb_pre_low_cutoff", 0x000000, 0.0, 128.0, 0.0, 0.0, 1.0,
  128. ValueDetails::kLinear, false, " semitones", "Reverb Pre Low Cutoff", nullptr },
  129. { "reverb_pre_high_cutoff", 0x000000, 0.0, 128.0, 110.0, 0.0, 1.0,
  130. ValueDetails::kLinear, false, " semitones", "Reverb Pre High Cutoff", nullptr },
  131. { "reverb_low_shelf_cutoff", 0x000000, 0.0, 128.0, 0.0, 0.0, 1.0,
  132. ValueDetails::kLinear, false, " semitones", "Reverb Low Cutoff", nullptr },
  133. { "reverb_low_shelf_gain", 0x000000, -6.0, 0.0, 0.0, 0.0, 1.0,
  134. ValueDetails::kLinear, false, " dB", "Reverb Low Gain", nullptr },
  135. { "reverb_high_shelf_cutoff", 0x000000, 0.0, 128.0, 90.0, 0.0, 1.0,
  136. ValueDetails::kLinear, false, " semitones", "Reverb High Cutoff", nullptr },
  137. { "reverb_high_shelf_gain", 0x000000, -6.0, 0.0, -1.0, 0.0, 1.0,
  138. ValueDetails::kLinear, false, " dB", "Reverb High Gain", nullptr },
  139. { "reverb_dry_wet", 0x000000, 0.0, 1.0, 0.25, 0.0, 100.0,
  140. ValueDetails::kLinear, false, "%", "Reverb Mix", nullptr },
  141. { "reverb_delay", 0x000609, 0.0, 0.3, 0.0, 0.0, 1.0,
  142. ValueDetails::kLinear, false, " secs", "Reverb Delay", nullptr },
  143. { "reverb_decay_time", 0x000000, -6.0, 6.0, 0.0, 0.0, 1.0,
  144. ValueDetails::kExponential, false, " secs", "Reverb Decay Time", nullptr },
  145. { "reverb_size", 0x000506, 0.0, 1.0, 0.5, 0.0, 100.0,
  146. ValueDetails::kLinear, false, "%", "Reverb Size", nullptr },
  147. { "reverb_chorus_amount", 0x000000, 0.0, 1.0, 0.223607, 0.0, 100.0,
  148. ValueDetails::kQuadratic, false, "%", "Reverb Chorus Amount", nullptr },
  149. { "reverb_chorus_frequency", 0x000000, -8.0, 3.0, -2.0, 0.0, 1.0,
  150. ValueDetails::kExponential, false, " Hz", "Reverb Chorus Frequency", nullptr },
  151. { "reverb_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  152. ValueDetails::kIndexed, false, "", "Reverb Switch", strings::kOffOnNames },
  153. { "sub_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  154. ValueDetails::kIndexed, false, "", "Sub Switch", strings::kOffOnNames },
  155. { "sub_direct_out", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  156. ValueDetails::kIndexed, false, "", "Sub Direct Out", nullptr },
  157. { "sub_transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
  158. ValueDetails::kIndexed, false, "", "Sub Transpose", nullptr },
  159. { "sub_transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
  160. ValueDetails::kIndexed, false, "", "Sub Transpose Quantize", nullptr },
  161. { "sub_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  162. ValueDetails::kLinear, false, "", "Sub Tune", nullptr },
  163. { "sub_level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
  164. ValueDetails::kQuadratic, false, "", "Sub Level", nullptr },
  165. { "sub_pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  166. ValueDetails::kLinear, false, "%", "Sub Pan", nullptr },
  167. { "sub_waveform", 0x000000, 0.0, PredefinedWaveFrames::kNumShapes - 1, 2.0, 0.0, 1.0,
  168. ValueDetails::kIndexed, false, "", "Sub Osc Waveform", nullptr },
  169. { "sample_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  170. ValueDetails::kIndexed, false, "", "Sample Switch", strings::kOffOnNames },
  171. { "sample_random_phase", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  172. ValueDetails::kIndexed, false, "", "Sample Random Phase", strings::kOffOnNames },
  173. { "sample_keytrack", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  174. ValueDetails::kIndexed, false, "", "Sample Keytrack", strings::kOffOnNames },
  175. { "sample_loop", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  176. ValueDetails::kIndexed, false, "", "Sample Loop", strings::kOffOnNames },
  177. { "sample_bounce", 0x000603, 0.0, 1.0, 0.0, 0.0, 1.0,
  178. ValueDetails::kIndexed, false, "", "Sample Bounce", strings::kOffOnNames },
  179. { "sample_transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
  180. ValueDetails::kIndexed, false, "", "Sample Transpose", nullptr },
  181. { "sample_transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
  182. ValueDetails::kIndexed, false, "", "Sample Transpose Quantize", nullptr },
  183. { "sample_tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  184. ValueDetails::kLinear, false, "", "Sample Tune", nullptr },
  185. { "sample_level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
  186. ValueDetails::kQuadratic, false, "", "Sample Level", nullptr },
  187. { "sample_destination", 0x000500, 0.0, constants::kNumSourceDestinations + constants::kNumEffects, 3.0, 0.0, 1.0,
  188. ValueDetails::kIndexed, false, "", "Sample Destination", strings::kDestinationNames },
  189. { "sample_pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  190. ValueDetails::kLinear, false, "%", "Sample Pan", nullptr },
  191. { "velocity_track", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  192. ValueDetails::kLinear, false, "%", "Velocity Track", nullptr },
  193. { "volume", 0x000000, 0.0, 7399.4404, 5473.0404, -80, 1.0,
  194. ValueDetails::kSquareRoot, false, "dB", "Volume", nullptr },
  195. { "phaser_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  196. ValueDetails::kIndexed, false, "", "Phaser Switch", strings::kOffOnNames },
  197. { "phaser_dry_wet", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
  198. ValueDetails::kLinear, false, "%", "Phaser Mix", nullptr },
  199. { "phaser_feedback", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  200. ValueDetails::kLinear, false, "%", "Phaser Feedback", nullptr },
  201. { "phaser_frequency", 0x000000, -5.0, 2.0, -3.0, 0.0, 1.0,
  202. ValueDetails::kExponential, true, " secs", "Phaser Frequency", nullptr },
  203. { "phaser_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
  204. ValueDetails::kIndexed, false, "", "Phaser Sync",strings::kFrequencySyncNames },
  205. { "phaser_tempo", 0x000000, 0.0, 10.0, 3.0, 0.0, 1.0,
  206. ValueDetails::kIndexed, false, "", "Phaser Tempo", strings::kSyncedFrequencyNames },
  207. { "phaser_center", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
  208. ValueDetails::kLinear, false, " semitones", "Phaser Center", nullptr },
  209. { "phaser_blend", 0x000509, 0.0, 2.0, 1.0, 0.0, 1.0,
  210. ValueDetails::kLinear, false, "", "Phaser Blend", nullptr },
  211. { "phaser_mod_depth", 0x000000, 0.0, 48.0, 24.0, 0.0, 1.0,
  212. ValueDetails::kLinear, false, " semitones", "Phaser Mod Depth", nullptr },
  213. { "phaser_phase_offset", 0x000000, 0, 1.0, 0.33333333, 0.0, kDegreesPerCycle,
  214. ValueDetails::kLinear, false, "", "Phaser Phase Offset", nullptr },
  215. { "flanger_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  216. ValueDetails::kIndexed, false, "", "Flanger Switch", strings::kOffOnNames },
  217. { "flanger_dry_wet", 0x000000, 0.0, 0.5, 0.5, 0.0, 200.0,
  218. ValueDetails::kLinear, false, "%", "Flanger Mix", nullptr },
  219. { "flanger_feedback", 0x000000, -1.0, 1.0, 0.5, 0.0, 100.0,
  220. ValueDetails::kLinear, false, "%", "Flanger Feedback", nullptr },
  221. { "flanger_frequency", 0x000000, -5.0, 2.0, 2.0, 0.0, 1.0,
  222. ValueDetails::kExponential, true, " secs", "Flanger Frequency", nullptr },
  223. { "flanger_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
  224. ValueDetails::kIndexed, false, "", "Flanger Sync", strings::kFrequencySyncNames },
  225. { "flanger_tempo", 0x000000, 0.0, 10.0, 4.0, 0.0, 1.0,
  226. ValueDetails::kIndexed, false, "", "Flanger Tempo", strings::kSyncedFrequencyNames },
  227. { "flanger_center", 0x000505, 8.0, 136.0, 64.0, 0.0, 1.0,
  228. ValueDetails::kLinear, false, " semitones", "Flanger Center", nullptr },
  229. { "flanger_mod_depth", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  230. ValueDetails::kLinear, false, "%", "Flanger Mod Depth", nullptr },
  231. { "flanger_phase_offset", 0x000000, 0, 1.0, 0.33333333, 0.0, kDegreesPerCycle,
  232. ValueDetails::kLinear, false, "", "Flanger Phase Offset", nullptr },
  233. { "chorus_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  234. ValueDetails::kIndexed, false, "", "Chorus Switch", strings::kOffOnNames },
  235. { "chorus_dry_wet", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  236. ValueDetails::kLinear, false, "%", "Chorus Mix", nullptr },
  237. { "chorus_feedback", 0x000000, -0.95, 0.95, 0.4, 0.0, 100.0,
  238. ValueDetails::kLinear, false, "%", "Chorus Feedback", nullptr },
  239. { "chorus_cutoff", 0x000000, 8.0, 136.0, 60.0, 0.0, 1.0,
  240. ValueDetails::kLinear, false, "", "Chorus Filter Cutoff", nullptr },
  241. { "chorus_spread", 0x000607, 0.0, 1.0, 1.0, 0.0, 1.0,
  242. ValueDetails::kLinear, false, "", "Chorus Filter Spread", nullptr },
  243. { "chorus_voices", 0x000508, 1.0, 4.0, 4.0, 0.0, 4.0,
  244. ValueDetails::kIndexed, false, "", "Chorus Voices", nullptr },
  245. { "chorus_frequency", 0x000000, -6.0, 3.0, -3.0, 0.0, 1.0,
  246. ValueDetails::kExponential, true, " secs", "Chorus Frequency", nullptr },
  247. { "chorus_sync", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
  248. ValueDetails::kIndexed, false, "", "Chorus Sync", strings::kFrequencySyncNames },
  249. { "chorus_tempo", 0x000000, 0.0, 10.0, 4.0, 0.0, 1.0,
  250. ValueDetails::kIndexed, false, "", "Chorus Tempo", strings::kSyncedFrequencyNames },
  251. { "chorus_mod_depth", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  252. ValueDetails::kLinear, false, "%", "Chorus Mod Depth", nullptr },
  253. { "chorus_delay_1", 0x000000, -10.0, -5.64386, -9.0, 0.0, 1000.0,
  254. ValueDetails::kExponential, false, "ms", "Chorus Delay 1", nullptr },
  255. { "chorus_delay_2", 0x000000, -10.0, -5.64386, -7.0, 0.0, 1000.0,
  256. ValueDetails::kExponential, false, " ms", "Chorus Delay 2", nullptr },
  257. { "compressor_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  258. ValueDetails::kIndexed, false, "", "Compressor Switch", strings::kOffOnNames },
  259. { "compressor_low_upper_threshold", 0x000000, -80.0, 0.0, -28.0, 0.0, 1.0,
  260. ValueDetails::kLinear, false, " dB", "Low Upper Threshold", nullptr },
  261. { "compressor_band_upper_threshold", 0x000000, -80.0, 0.0, -25.0, 0.0, 1.0,
  262. ValueDetails::kLinear, false, " dB", "Band Upper Threshold", nullptr },
  263. { "compressor_high_upper_threshold", 0x000000, -80.0, 0.0, -30.0, 0.0, 1.0,
  264. ValueDetails::kLinear, false, " dB", "High Upper Threshold", nullptr },
  265. { "compressor_low_lower_threshold", 0x000000, -80.0, 0.0, -35.0, 0.0, 1.0,
  266. ValueDetails::kLinear, false, " dB", "Low Lower Threshold", nullptr },
  267. { "compressor_band_lower_threshold", 0x000000, -80.0, 0.0, -36.0, 0.0, 1.0,
  268. ValueDetails::kLinear, false, " dB", "Band Lower Threshold", nullptr },
  269. { "compressor_high_lower_threshold", 0x000000, -80.0, 0.0, -35.0, 0.0, 1.0,
  270. ValueDetails::kLinear, false, " dB", "High Lower Threshold", nullptr },
  271. { "compressor_low_upper_ratio", 0x000000, 0.0, 1.0, 0.9, 0.0, 1.0,
  272. ValueDetails::kLinear, false, "", "Low Upper Ratio", nullptr },
  273. { "compressor_band_upper_ratio", 0x000000, 0.0, 1.0, 0.857, 0.0, 1.0,
  274. ValueDetails::kLinear, false, "", "Band Upper Ratio", nullptr },
  275. { "compressor_high_upper_ratio", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  276. ValueDetails::kLinear, false, "", "High Upper Ratio", nullptr },
  277. { "compressor_low_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
  278. ValueDetails::kLinear, false, "", "Low Lower Ratio", nullptr },
  279. { "compressor_band_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
  280. ValueDetails::kLinear, false, "", "Band Lower Ratio", nullptr },
  281. { "compressor_high_lower_ratio", 0x000000, -1.0, 1.0, 0.8, 0.0, 1.0,
  282. ValueDetails::kLinear, false, "", "High Lower Ratio", nullptr },
  283. { "compressor_low_gain", 0x000000, -30.0, 30.0, 16.3, 0.0, 1.0,
  284. ValueDetails::kLinear, false, " dB", "Compressor Low Gain", nullptr },
  285. { "compressor_band_gain", 0x000000, -30.0, 30.0, 11.7, 0.0, 1.0,
  286. ValueDetails::kLinear, false, " dB", "Compressor Band Gain", nullptr },
  287. { "compressor_high_gain", 0x000000, -30.0, 30.0, 16.3, 0.0, 1.0,
  288. ValueDetails::kLinear, false, " dB", "Compressor High Gain", nullptr },
  289. { "compressor_attack", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  290. ValueDetails::kLinear, false, "%", "Compressor Attack", nullptr },
  291. { "compressor_release", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  292. ValueDetails::kLinear, false, "%", "Compressor Release", nullptr },
  293. { "compressor_enabled_bands", 0x000000, 0.0, vital::MultibandCompressor::kNumBandOptions - 1, 0.0, 0.0, 1.0,
  294. ValueDetails::kIndexed, false, "", "Compressor Enabled Bands", strings::kCompressorBandNames },
  295. { "compressor_mix", 0x000602, 0.0, 1.0, 1.0, 0.0, 1.0,
  296. ValueDetails::kLinear, false, "", "Compressor Mix", nullptr },
  297. { "compressor_low_band_unused", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  298. ValueDetails::kIndexed, false, "", "Compressor Unused", nullptr },
  299. { "eq_on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  300. ValueDetails::kIndexed, false, "", "EQ Switch", strings::kOffOnNames },
  301. { "eq_low_mode", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  302. ValueDetails::kIndexed, false, "", "EQ Low Mode", strings::kEqLowModeNames },
  303. { "eq_low_cutoff", 0x000000, 8.0, 136.0, 40.0, 0.0, 1.0,
  304. ValueDetails::kLinear, false, " semitones", "EQ Low Cutoff", nullptr },
  305. { "eq_low_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
  306. ValueDetails::kLinear, false, " dB", "EQ Low Gain", nullptr },
  307. { "eq_low_resonance", 0x000000, 0.0, 1.0, 0.3163, 0.0, 100.0,
  308. ValueDetails::kQuadratic, false, "%", "EQ Low Resonance", nullptr },
  309. { "eq_band_mode", 0x000506, 0.0, 1.0, 0.0, 0.0, 1.0,
  310. ValueDetails::kIndexed, false, "", "EQ Band Mode", strings::kEqBandModeNames },
  311. { "eq_band_cutoff", 0x000000, 8.0, 136.0, 80.0, 0.0, 1.0,
  312. ValueDetails::kLinear, false, " semitones", "EQ Band Cutoff", nullptr },
  313. { "eq_band_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
  314. ValueDetails::kLinear, false, " dB", "EQ Band Gain", nullptr },
  315. { "eq_band_resonance", 0x000000, 0.0, 1.0, 0.4473, 0.0, 100.0,
  316. ValueDetails::kQuadratic, false, "", "EQ Band Resonance", nullptr },
  317. { "eq_high_mode", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  318. ValueDetails::kIndexed, false, "", "EQ High Mode", strings::kEqHighModeNames },
  319. { "eq_high_cutoff", 0x000000, 8.0, 136.0, 100.0, 0.0, 1.0,
  320. ValueDetails::kLinear, false, " semitones", "EQ High Cutoff", nullptr },
  321. { "eq_high_gain", 0x000000, DigitalSvf::kMinGain, DigitalSvf::kMaxGain, 0.0, 0.0, 1.0,
  322. ValueDetails::kLinear, false, " dB", "EQ High Gain", nullptr },
  323. { "eq_high_resonance", 0x000000, 0.0, 1.0, 0.3163, 0.0, 100.0,
  324. ValueDetails::kQuadratic, false, "", "EQ High Resonance", nullptr },
  325. { "effect_chain_order", 0x000000, 0.0, vital::utils::factorial(vital::kNumEffects) - 1, 0.0, 0.0, 1.0,
  326. ValueDetails::kIndexed, false, "", "Effect Chain Order", nullptr },
  327. { "voice_priority", 0x000000, 0.0, VoiceHandler::kNumVoicePriorities - 1, VoiceHandler::kRoundRobin, 0.0, 1.0,
  328. ValueDetails::kIndexed, false, "", "Voice Priority", strings::kVoicePriorityNames },
  329. { "voice_override", 0x000700, 0.0, VoiceHandler::kNumVoiceOverrides - 1, VoiceHandler::kKill, 0.0, 1.0,
  330. ValueDetails::kIndexed, false, "", "Voice Override", strings::kVoiceOverrideNames },
  331. { "oversampling", 0x000000, 0.0, 3.0, 1.0, 0.0, 1.0,
  332. ValueDetails::kIndexed, false, "", "Oversampling", strings::kOversamplingNames },
  333. { "pitch_wheel", 0x000400, -1.0, 1.0, 0.0, 0.0, 1.0,
  334. ValueDetails::kLinear, false, "", "Pitch Wheel", nullptr },
  335. { "mod_wheel", 0x000400, 0.0, 1.0, 0.0, 0.0, 1.0,
  336. ValueDetails::kLinear, false, "", "Mod Wheel", nullptr },
  337. { "mpe_enabled", 0x000501, 0.0, 1.0, 0.0, 0.0, 1.0,
  338. ValueDetails::kIndexed, false, "", "MPE Enabled", strings::kOffOnNames },
  339. { "view_spectrogram", 0x000803, 0.0, 2.0, 0.0, 0.0, 1.0,
  340. ValueDetails::kIndexed, false, "", "View Spectrogram", strings::kOffOnNames },
  341. };
  342. const ValueDetails ValueDetailsLookup::env_parameter_list[] = {
  343. { "delay", 0x000503, 0.0, 1.4142135624, 0.0, 0.0, 1.0,
  344. ValueDetails::kQuartic, false, " secs", "Delay", nullptr },
  345. { "attack", 0x000000, 0.0, 2.37842, 0.1495, 0.0, 1.0,
  346. ValueDetails::kQuartic, false, " secs", "Attack", nullptr },
  347. { "hold", 0x000504, 0.0, 1.4142135624, 0.0, 0.0, 1.0,
  348. ValueDetails::kQuartic, false, " secs", "Hold", nullptr },
  349. { "decay", 0x000000, 0.0, 2.37842, 1.0, 0.0, 1.0,
  350. ValueDetails::kQuartic, false, " secs", "Decay", nullptr },
  351. { "release", 0x000000, 0.0, 2.37842, 0.5476, 0.0, 1.0,
  352. ValueDetails::kQuartic, false, " secs", "Release", nullptr },
  353. { "attack_power", 0x000000, -20.0, 20.0, 0.0f, 0.0, 1.0,
  354. ValueDetails::kLinear, false, "", "Attack Power", nullptr },
  355. { "decay_power", 0x000000, -20.0, 20.0, -2.0f, 0.0, 1.0,
  356. ValueDetails::kLinear, false, "", "Decay Power", nullptr },
  357. { "release_power", 0x000000, -20.0, 20.0, -2.0f, 0.0, 1.0,
  358. ValueDetails::kLinear, false, "", "Release Power", nullptr },
  359. { "sustain", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  360. ValueDetails::kLinear, false, "", "Sustain", nullptr },
  361. };
  362. const ValueDetails ValueDetailsLookup::lfo_parameter_list[] = {
  363. { "phase", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  364. ValueDetails::kLinear, false, "", "Phase", nullptr },
  365. { "sync_type", 0x000000, 0.0, SynthLfo::kNumSyncTypes - 1, 0.0, 0.0, 1.0,
  366. ValueDetails::kIndexed, false, "", "Sync Type", strings::kSyncNames },
  367. { "frequency", 0x000000, -7.0, 9.0, 1.0, 0.0, 1.0,
  368. ValueDetails::kExponential, true, " secs", "Frequency", nullptr },
  369. { "sync", 0x000000, 0.0, SynthLfo::kNumSyncOptions - 1, 1.0, 0.0, 1.0,
  370. ValueDetails::kIndexed, false, "", "Sync", strings::kFrequencySyncNames },
  371. { "tempo", 0x000000, 0.0, 12.0, 7.0, 0.0, 1.0,
  372. ValueDetails::kIndexed, false, "", "Tempo", strings::kSyncedFrequencyNames },
  373. { "fade_time", 0x000000, 0.0, 8.0, 0.0, 0.0, 1.0,
  374. ValueDetails::kLinear, false, " secs", "Fade In", nullptr },
  375. { "smooth_mode", 0x000801, 0.0, 1.0, 1.0, 0.0, 1.0,
  376. ValueDetails::kIndexed, false, "", "Smooth Mode", strings::kOffOnNames },
  377. { "smooth_time", 0x000801, -10.0, 4.0, -7.5, 0.0, 1.0,
  378. ValueDetails::kExponential, false, " secs", "Smooth Time", nullptr },
  379. { "delay_time", 0x000000, 0.0, 4.0, 0.0, 0.0, 1.0,
  380. ValueDetails::kLinear, false, " secs", "Delay", nullptr },
  381. { "stereo", 0x000406, -0.5, 0.5, 0.0, 0.0, 1.0,
  382. ValueDetails::kLinear, false, "", "Stereo", nullptr },
  383. { "keytrack_transpose", 0x000704, -60.0, 36.0, -12.0, 0.0, 1.0,
  384. ValueDetails::kIndexed, false, "", "Transpose", nullptr },
  385. { "keytrack_tune", 0x000704, -1.0, 1.0, 0.0, 0.0, 100.0,
  386. ValueDetails::kLinear, false, "", "Tune", nullptr },
  387. };
  388. const ValueDetails ValueDetailsLookup::random_lfo_parameter_list[] = {
  389. { "style", 0x000401, 0.0, RandomLfo::kNumStyles - 1, 0.0, 0.0, 1.0,
  390. ValueDetails::kIndexed, false, "", "Style", strings::kRandomNames },
  391. { "frequency", 0x000401, -7.0, 9.0, 1.0, 0.0, 1.0,
  392. ValueDetails::kExponential, true, " secs", "Frequency", nullptr },
  393. { "sync", 0x000401, 0.0, SynthLfo::kNumSyncOptions - 1, 1.0, 0.0, 1.0,
  394. ValueDetails::kIndexed, false, "", "Sync", strings::kFrequencySyncNames },
  395. { "tempo", 0x000401, 0.0, 12.0, 8.0, 0.0, 1.0,
  396. ValueDetails::kIndexed, false, "", "Tempo", strings::kSyncedFrequencyNames },
  397. { "stereo", 0x000401, 0.0, 1.0, 0.0, 0.0, 1.0,
  398. ValueDetails::kIndexed, false, "", "Stereo", strings::kOffOnNames },
  399. { "sync_type", 0x000600, 0.0, 1.0, 0.0, 0.0, 1.0,
  400. ValueDetails::kIndexed, false, "", "Sync Type", strings::kOffOnNames },
  401. { "keytrack_transpose", 0x000704, -60.0, 36.0, -12.0, 0.0, 1.0,
  402. ValueDetails::kIndexed, false, "", "Transpose", nullptr },
  403. { "keytrack_tune", 0x000704, -1.0, 1.0, 0.0, 0.0, 100.0,
  404. ValueDetails::kLinear, false, "", "Tune", nullptr },
  405. };
  406. const ValueDetails ValueDetailsLookup::filter_parameter_list[] = {
  407. { "mix", 0x000000, 0.0f, 1.0f, 1.0f, 0.0, 100.0,
  408. ValueDetails::kLinear, false, "%", "Mix", nullptr },
  409. { "cutoff", 0x000000, 8.0, 136.0, 60.0, -60.0, 1.0,
  410. ValueDetails::kLinear, false, " semitones", "Cutoff", nullptr },
  411. { "resonance", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  412. ValueDetails::kLinear, false, "%", "Resonance", nullptr },
  413. { "drive", 0x000000, 0.0, 20.0, 0.0, 0.0, 1.0,
  414. ValueDetails::kLinear, false, "dB", "Drive", nullptr },
  415. { "blend", 0x000000, 0.0, 2.0, 0.0, 0.0, 1.0,
  416. ValueDetails::kLinear, false, "", "Blend", nullptr },
  417. { "style", 0x000000, 0.0, 9.0, 0.0, 0.0, 1.0,
  418. ValueDetails::kIndexed, false, "", "Style", strings::kFilterStyleNames },
  419. { "model", 0x000000, 0.0, kNumFilterModels - 1.0, 0.0, 0.0, 1.0,
  420. ValueDetails::kIndexed, false, "", "Model", strings::kFilterModelNames },
  421. { "on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  422. ValueDetails::kIndexed, false, "", "Switch", strings::kOffOnNames },
  423. { "blend_transpose", 0x000000, 0.0, 84.0, 42.0, 0.0, 1.0,
  424. ValueDetails::kLinear, false, " semitones", "Comb Blend Offset", nullptr },
  425. { "keytrack", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  426. ValueDetails::kLinear, false, "%", "Key Track", nullptr },
  427. { "formant_x", 0x000000, 0.0, 1.0, 0.5, 0.0, 1.0,
  428. ValueDetails::kLinear, false, "", "Formant X", nullptr },
  429. { "formant_y", 0x000000, 0.0, 1.0, 0.5, 0.0, 1.0,
  430. ValueDetails::kLinear, false, "", "Formant Y", nullptr },
  431. { "formant_transpose", 0x000000, -12.0, 12.0, 0.0, 0.0, 1.0,
  432. ValueDetails::kLinear, false, "", "Formant Transpose", nullptr },
  433. { "formant_resonance", 0x000000, 0.3, 1.0, 0.85, 0.0, 100.0,
  434. ValueDetails::kLinear, false, "%", "Formant Resonance", nullptr },
  435. { "formant_spread", 0x000707, -1.0, 1.0, 0.0, 0.0, 100.0,
  436. ValueDetails::kLinear, false, "%", "Formant Spread", nullptr },
  437. { "osc1_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  438. ValueDetails::kIndexed, false, "", "OSC 1 Input", strings::kOffOnNames },
  439. { "osc2_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  440. ValueDetails::kIndexed, false, "", "OSC 2 Input", strings::kOffOnNames },
  441. { "osc3_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  442. ValueDetails::kIndexed, false, "", "OSC 3 Input", strings::kOffOnNames },
  443. { "sample_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  444. ValueDetails::kIndexed, false, "", "SAMPLE Input", strings::kOffOnNames },
  445. { "filter_input", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  446. ValueDetails::kIndexed, false, "", "FILTER Input", strings::kOffOnNames },
  447. };
  448. const ValueDetails ValueDetailsLookup::osc_parameter_list[] = {
  449. { "on", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  450. ValueDetails::kIndexed, false, "", "Switch", strings::kOffOnNames },
  451. { "transpose", 0x000000, -48.0, 48.0, 0.0, 0.0, 1.0,
  452. ValueDetails::kIndexed, false, "", "Transpose", nullptr },
  453. { "transpose_quantize", 0x000000, 0.0, 8191.0, 0.0, 0.0, 1.0,
  454. ValueDetails::kIndexed, false, "", "Transpose Quantize", nullptr },
  455. { "tune", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  456. ValueDetails::kLinear, false, "", "Tune", nullptr },
  457. { "pan", 0x000000, -1.0, 1.0, 0.0, 0.0, 100.0,
  458. ValueDetails::kLinear, false, "%", "Pan", nullptr },
  459. { "stack_style", 0x000000, 0.0, SynthOscillator::kNumUnisonStackTypes - 1, 0.0, 0.0, 1.0,
  460. ValueDetails::kIndexed, false, "", "Stack Style", strings::kUnisonStackNames },
  461. { "unison_detune", 0x000000, 0.0, 10.0, 4.472135955, 0.0, 1.0,
  462. ValueDetails::kQuadratic, false, "%", "Unison Detune", nullptr },
  463. { "unison_voices", 0x000000, 1.0, 16.0, 1.0, 0.0, 1.0,
  464. ValueDetails::kIndexed, false, "v", "Unison Voices", nullptr },
  465. { "unison_blend", 0x000000, 0.0, 1.0, 0.8, 0.0, 100.0,
  466. ValueDetails::kLinear, false, "%", "Blend", nullptr },
  467. { "detune_power", 0x000000, -5.0, 5.0, 1.5, 0.0, 1.0,
  468. ValueDetails::kLinear, false, "", "Detune Power", nullptr },
  469. { "detune_range", 0x000000, 0.0, 48.0, 2.0, 0.0, 1.0,
  470. ValueDetails::kLinear, false, "", "Detune Range", nullptr },
  471. { "level", 0x000000, 0.0, 1.0, 0.70710678119, 0.0, 1.0,
  472. ValueDetails::kQuadratic, false, "", "Level", nullptr },
  473. { "midi_track", 0x000000, 0.0, 1.0, 1.0, 0.0, 1.0,
  474. ValueDetails::kIndexed, false, "", "Midi Track", strings::kOffOnNames },
  475. { "smooth_interpolation", 0x000000, 0.0, 1.0, 0.0, 0.0, 1.0,
  476. ValueDetails::kIndexed, false, "", "Smooth Interpolation", strings::kOffOnNames },
  477. { "spectral_unison", 0x000500, 0.0, 1.0, 1.0, 0.0, 1.0,
  478. ValueDetails::kIndexed, false, "", "Spectral Unison", strings::kOffOnNames },
  479. { "wave_frame", 0x000000, 0.0, kNumOscillatorWaveFrames - 1, 0.0, 0.0, 1.0,
  480. ValueDetails::kLinear, false, "", "Wave Frame", nullptr },
  481. { "frame_spread", 0x000000, -kNumOscillatorWaveFrames / 2, kNumOscillatorWaveFrames / 2, 0.0, 0.0, 1.0,
  482. ValueDetails::kLinear, false, "", "Unison Frame Spread", nullptr },
  483. { "stereo_spread", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
  484. ValueDetails::kLinear, false, "%", "Stereo Spread", nullptr },
  485. { "phase", 0x000000, 0.0, 1.0, 0.5, 0.0, 360.0,
  486. ValueDetails::kLinear, false, "", "Phase", nullptr },
  487. { "distortion_phase", 0x000000, 0.0, 1.0, 0.5, 0.0, 360.0,
  488. ValueDetails::kLinear, false, "", "Distortion Phase", nullptr },
  489. { "random_phase", 0x000000, 0.0, 1.0, 1.0, 0.0, 100.0,
  490. ValueDetails::kLinear, false, "%", "Phase Randomization", nullptr },
  491. { "distortion_type", 0x000000, 0.0, SynthOscillator::kNumDistortionTypes - 1, 0.0, 0.0, 1.0,
  492. ValueDetails::kIndexed, false, "", "Distortion Type", strings::kPhaseDistortionNames },
  493. { "distortion_amount", 0x000000, 0.0, 1.0, 0.5, 0.0, 100.0,
  494. ValueDetails::kLinear, false, "%", "Distortion Amount", nullptr },
  495. { "distortion_spread", 0x000000, -0.5, 0.5, 0.0, 0.0, 200.0,
  496. ValueDetails::kLinear, false, "%", "Distortion Spread", nullptr },
  497. { "spectral_morph_type", 0x000407, 0.0, SynthOscillator::kNumSpectralMorphTypes - 1, 0.0, 0.0, 1.0,
  498. ValueDetails::kIndexed, false, "", "Frequency Morph Type", strings::kSpectralMorphNames },
  499. { "spectral_morph_amount", 0x000407, 0.0, 1.0, 0.5, 0.0, 100.0,
  500. ValueDetails::kLinear, false, "%", "Frequency Morph Amount", nullptr },
  501. { "spectral_morph_spread", 0x000407, -0.5, 0.5, 0.0, 0.0, 200.0,
  502. ValueDetails::kLinear, false, "%", "Frequency Morph Spread", nullptr },
  503. { "destination", 0x000500, 0.0, constants::kNumSourceDestinations + constants::kNumEffects, 0.0, 0.0, 1.0,
  504. ValueDetails::kIndexed, false, "", "Destination", strings::kDestinationNames },
  505. { "view_2d", 0x000402, 0.0, 2.0, 1.0, 0.0, 1.0,
  506. ValueDetails::kIndexed, false, "", "View 2D", strings::kOffOnNames },
  507. };
  508. const ValueDetails ValueDetailsLookup::mod_parameter_list[] = {
  509. { "amount", 0x000000, -1.0, 1.0, 0.0, 0.0, 1.0,
  510. ValueDetails::kLinear, false, "", "Amount", nullptr },
  511. { "power", 0x000000, -10.0, 10.0, 0.0, 0.0, 1.0,
  512. ValueDetails::kLinear, false, "", "Power", nullptr },
  513. { "bipolar", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
  514. ValueDetails::kIndexed, false, "", "Bipolar", strings::kOffOnNames },
  515. { "stereo", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
  516. ValueDetails::kIndexed, false, "", "Stereo", strings::kOffOnNames },
  517. { "bypass", 0x000000, 0.0, 1.0f, 0.0, 0.0, 1.0,
  518. ValueDetails::kIndexed, false, "", "Bypass", strings::kOffOnNames }
  519. };
  520. ValueDetailsLookup::ValueDetailsLookup() {
  521. static constexpr int kNumOscillatorsOld = 2;
  522. static constexpr int kNewOscillatorVersion = 0x000500;
  523. static constexpr int kOldMaxModulations = 32;
  524. static constexpr int kNewModulationVersion = 0x000601;
  525. int num_parameters = sizeof(parameter_list) / sizeof(ValueDetails);
  526. for (int i = 0; i < num_parameters; ++i) {
  527. details_lookup_[parameter_list[i].name] = parameter_list[i];
  528. details_list_.push_back(&parameter_list[i]);
  529. VITAL_ASSERT(parameter_list[i].default_value <= parameter_list[i].max);
  530. VITAL_ASSERT(parameter_list[i].default_value >= parameter_list[i].min);
  531. }
  532. int num_env_parameters = sizeof(env_parameter_list) / sizeof(ValueDetails);
  533. for (int env = 0; env < kNumEnvelopes; ++env)
  534. addParameterGroup(env_parameter_list, num_env_parameters, env, kEnvIdPrefix, kEnvNamePrefix);
  535. int num_lfo_parameters = sizeof(lfo_parameter_list) / sizeof(ValueDetails);
  536. for (int lfo = 0; lfo < kNumLfos; ++lfo)
  537. addParameterGroup(lfo_parameter_list, num_lfo_parameters, lfo, kLfoIdPrefix, kLfoNamePrefix);
  538. int num_random_lfo_parameters = sizeof(random_lfo_parameter_list) / sizeof(ValueDetails);
  539. for (int lfo = 0; lfo < kNumRandomLfos; ++lfo)
  540. addParameterGroup(random_lfo_parameter_list, num_random_lfo_parameters, lfo, kRandomIdPrefix, kRandomNamePrefix);
  541. int num_osc_parameters = sizeof(osc_parameter_list) / sizeof(ValueDetails);
  542. for (int osc = 0; osc < kNumOscillatorsOld; ++osc)
  543. addParameterGroup(osc_parameter_list, num_osc_parameters, osc, kOscIdPrefix, kOscNamePrefix);
  544. for (int osc = kNumOscillatorsOld; osc < kNumOscillators; ++osc) {
  545. addParameterGroup(osc_parameter_list, num_osc_parameters, osc, kOscIdPrefix,
  546. kOscNamePrefix, kNewOscillatorVersion);
  547. }
  548. int num_filter_parameters = sizeof(filter_parameter_list) / sizeof(ValueDetails);
  549. for (int filter = 0; filter < kNumFilters; ++filter)
  550. addParameterGroup(filter_parameter_list, num_filter_parameters, filter, kFilterIdPrefix, kFilterNamePrefix);
  551. addParameterGroup(filter_parameter_list, num_filter_parameters, "fx", kFilterIdPrefix, kFilterNamePrefix);
  552. int num_mod_parameters = sizeof(mod_parameter_list) / sizeof(ValueDetails);
  553. for (int modulation = 0; modulation < kOldMaxModulations; ++modulation) {
  554. addParameterGroup(mod_parameter_list, num_mod_parameters, modulation,
  555. kModulationIdPrefix, kModulationNamePrefix);
  556. }
  557. for (int modulation = kOldMaxModulations; modulation < kMaxModulationConnections; ++modulation) {
  558. addParameterGroup(mod_parameter_list, num_mod_parameters, modulation,
  559. kModulationIdPrefix, kModulationNamePrefix, kNewModulationVersion);
  560. }
  561. details_lookup_["osc_1_on"].default_value = 1.0f;
  562. details_lookup_["osc_2_destination"].default_value = 1.0f;
  563. details_lookup_["osc_3_destination"].default_value = 3.0f;
  564. details_lookup_["filter_1_osc1_input"].default_value = 1.0f;
  565. details_lookup_["filter_2_osc2_input"].default_value = 1.0f;
  566. std::sort(details_list_.begin(), details_list_.end(), compareValueDetails);
  567. }
  568. void ValueDetailsLookup::addParameterGroup(const ValueDetails* list, int num_parameters, int index,
  569. std::string id_prefix, std::string name_prefix, int version) {
  570. std::string string_num = std::to_string(index + 1);
  571. addParameterGroup(list, num_parameters, string_num, id_prefix, name_prefix, version);
  572. }
  573. void ValueDetailsLookup::addParameterGroup(const ValueDetails* list, int num_parameters, std::string id,
  574. std::string id_prefix, std::string name_prefix, int version) {
  575. std::string id_start = id_prefix + kIdDelimiter + id + kIdDelimiter;
  576. std::string name_start = name_prefix + kNameDelimiter + id + kNameDelimiter;
  577. for (int i = 0; i < num_parameters; ++i) {
  578. ValueDetails details = list[i];
  579. if (version > details.version_added)
  580. details.version_added = version;
  581. details.name = id_start + details.name;
  582. details.local_description = details.display_name;
  583. details.display_name = name_start + details.display_name;
  584. details_lookup_[details.name] = details;
  585. details_list_.push_back(&details_lookup_[details.name]);
  586. }
  587. }
  588. ValueDetailsLookup Parameters::lookup_;
  589. } // namespace vital