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.

271 lines
9.1KB

  1. // Copyright 2014 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Modal synthesis voice.
  28. #include "elements/dsp/voice.h"
  29. #include "stmlib/dsp/dsp.h"
  30. #include "stmlib/dsp/units.h"
  31. #include <algorithm>
  32. namespace elements {
  33. using namespace std;
  34. using namespace stmlib;
  35. void Voice::Init() {
  36. envelope_.Init();
  37. bow_.Init();
  38. blow_.Init();
  39. strike_.Init();
  40. diffuser_.Init(diffuser_buffer_);
  41. ResetResonator();
  42. bow_.set_model(EXCITER_MODEL_FLOW);
  43. bow_.set_parameter(0.7f);
  44. bow_.set_timbre(0.5f);
  45. blow_.set_model(EXCITER_MODEL_GRANULAR_SAMPLE_PLAYER);
  46. envelope_.set_adsr(0.5f, 0.5f, 0.5f, 0.5f);
  47. previous_gate_ = false;
  48. strength_ = 0.0f;
  49. exciter_level_ = 0.0f;
  50. envelope_value_ = 0.0f;
  51. chord_index_ = 0.0f;
  52. resonator_model_ = RESONATOR_MODEL_MODAL;
  53. }
  54. void Voice::ResetResonator() {
  55. resonator_.Init();
  56. for (size_t i = 0; i < kNumStrings; ++i) {
  57. string_[i].Init(true);
  58. }
  59. dc_blocker_.Init(1.0f - 10.0f / kSampleRate);
  60. resonator_.set_resolution(52); // Runs with 56 extremely tightly.
  61. }
  62. float chords[11][5] = {
  63. { 0.0f, -12.0f, 0.0f, 0.01f, 12.0f },
  64. { 0.0f, -12.0f, 3.0f, 7.0f, 10.0f },
  65. { 0.0f, -12.0f, 3.0f, 7.0f, 12.0f },
  66. { 0.0f, -12.0f, 3.0f, 7.0f, 14.0f },
  67. { 0.0f, -12.0f, 3.0f, 7.0f, 17.0f },
  68. { 0.0f, -12.0f, 7.0f, 12.0f, 19.0f },
  69. { 0.0f, -12.0f, 4.0f, 7.0f, 17.0f },
  70. { 0.0f, -12.0f, 4.0f, 7.0f, 14.0f },
  71. { 0.0f, -12.0f, 4.0f, 7.0f, 12.0f },
  72. { 0.0f, -12.0f, 4.0f, 7.0f, 11.0f },
  73. { 0.0f, -12.0f, 5.0f, 7.0f, 12.0f },
  74. };
  75. void Voice::Process(
  76. const Patch& patch,
  77. float frequency,
  78. float strength,
  79. const bool gate_in,
  80. const float* blow_in,
  81. const float* strike_in,
  82. float* raw,
  83. float* center,
  84. float* sides,
  85. size_t size) {
  86. uint8_t flags = GetGateFlags(gate_in);
  87. // Compute the envelope.
  88. float envelope_gain = 1.0f;
  89. if (patch.exciter_envelope_shape < 0.4f) {
  90. float a = patch.exciter_envelope_shape * 0.75f + 0.15f;
  91. float dr = a * 1.8f;
  92. envelope_.set_adsr(a, dr, 0.0f, dr);
  93. envelope_gain = 5.0f - patch.exciter_envelope_shape * 10.0f;
  94. } else if (patch.exciter_envelope_shape < 0.6f) {
  95. float s = (patch.exciter_envelope_shape - 0.4f) * 5.0f;
  96. envelope_.set_adsr(0.45f, 0.81f, s, 0.81f);
  97. } else {
  98. float a = (1.0f - patch.exciter_envelope_shape) * 0.75f + 0.15f;
  99. float dr = a * 1.8f;
  100. envelope_.set_adsr(a, dr, 1.0f, dr);
  101. }
  102. float envelope_value = envelope_.Process(flags) * envelope_gain;
  103. float envelope_increment = (envelope_value - envelope_value_) / size;
  104. // Configure and evaluate exciters.
  105. float brightness_factor = 0.4f + 0.6f * patch.resonator_brightness;
  106. bow_.set_timbre(patch.exciter_bow_timbre * brightness_factor);
  107. blow_.set_parameter(patch.exciter_blow_meta);
  108. blow_.set_timbre(patch.exciter_blow_timbre);
  109. blow_.set_signature(patch.exciter_signature);
  110. float strike_meta = patch.exciter_strike_meta;
  111. strike_.set_meta(
  112. strike_meta <= 0.4f ? strike_meta * 0.625f : strike_meta * 1.25f - 0.25f,
  113. EXCITER_MODEL_SAMPLE_PLAYER,
  114. EXCITER_MODEL_PARTICLES);
  115. strike_.set_timbre(patch.exciter_strike_timbre);
  116. strike_.set_signature(patch.exciter_signature);
  117. bow_.Process(flags, bow_buffer_, size);
  118. float blow_level, tube_level;
  119. blow_level = patch.exciter_blow_level * 1.5f;
  120. tube_level = blow_level > 1.0f ? (blow_level - 1.0f) * 2.0f : 0.0f;
  121. blow_level = blow_level < 1.0f ? blow_level * 0.4f : 0.4f;
  122. blow_.Process(flags, blow_buffer_, size);
  123. tube_.Process(
  124. frequency,
  125. envelope_value,
  126. patch.resonator_damping,
  127. tube_level,
  128. blow_buffer_,
  129. tube_level * 0.5f,
  130. size);
  131. for (size_t i = 0; i < size; ++i) {
  132. blow_buffer_[i] = blow_buffer_[i] * blow_level + blow_in[i];
  133. }
  134. diffuser_.Process(blow_buffer_, size);
  135. strike_.Process(flags, strike_buffer_, size);
  136. // The Strike exciter is implemented in such a way that raising the level
  137. // beyond a certain point doesn't change the exciter amplitude, but instead,
  138. // increasingly mixes the raw exciter signal into the resonator output.
  139. float strike_level, strike_bleed;
  140. strike_level = patch.exciter_strike_level * 1.25f;
  141. strike_bleed = strike_level > 1.0f ? (strike_level - 1.0f) * 2.0f : 0.0f;
  142. strike_level = strike_level < 1.0f ? strike_level : 1.0f;
  143. strike_level *= 1.5f;
  144. // The strength parameter is very sensitive to zipper noise.
  145. strength *= 256.0f;
  146. float strength_increment = (strength - strength_) / size;
  147. // Sum all sources of excitation.
  148. for (size_t i = 0; i < size; ++i) {
  149. strength_ += strength_increment;
  150. envelope_value_ += envelope_increment;
  151. float input_sample = 0.0f;
  152. float e = envelope_value_;
  153. float strength_lut = strength_;
  154. MAKE_INTEGRAL_FRACTIONAL(strength_lut);
  155. float accent = lut_accent_gain_coarse[strength_lut_integral] *
  156. lut_accent_gain_fine[
  157. static_cast<int32_t>(256.0f * strength_lut_fractional)];
  158. bow_strength_buffer_[i] = e * patch.exciter_bow_level;
  159. strike_buffer_[i] *= accent;
  160. e *= accent;
  161. input_sample += bow_buffer_[i] * bow_strength_buffer_[i] * 0.125f * accent;
  162. input_sample += blow_buffer_[i] * e;
  163. input_sample += strike_buffer_[i] * strike_level;
  164. input_sample += strike_in[i];
  165. raw[i] = input_sample * 0.5f;
  166. }
  167. // Update meter for exciter.
  168. for (size_t i = 0; i < size; ++i) {
  169. float error = raw[i] * raw[i] - exciter_level_;
  170. exciter_level_ += error * (error > 0.0f ? 0.5f : 0.001f);
  171. }
  172. // Some exciters can cause palm mutes on release.
  173. float damping = patch.resonator_damping;
  174. damping -= strike_.damping() * strike_level * 0.125f;
  175. damping -= (1.0f - bow_strength_buffer_[0]) * \
  176. patch.exciter_bow_level * 0.0625f;
  177. if (damping <= 0.0f) {
  178. damping = 0.0f;
  179. }
  180. // Configure resonator.
  181. if (resonator_model_ == RESONATOR_MODEL_MODAL) {
  182. resonator_.set_frequency(frequency);
  183. resonator_.set_geometry(patch.resonator_geometry);
  184. resonator_.set_brightness(patch.resonator_brightness);
  185. resonator_.set_position(patch.resonator_position);
  186. resonator_.set_damping(damping);
  187. resonator_.set_modulation_frequency(patch.resonator_modulation_frequency);
  188. resonator_.set_modulation_offset(patch.resonator_modulation_offset);
  189. // Process through resonator.
  190. resonator_.Process(bow_strength_buffer_, raw, center, sides, size);
  191. } else {
  192. size_t num_notes = resonator_model_ == RESONATOR_MODEL_STRING
  193. ? 1
  194. : kNumStrings;
  195. float normalization = 1.0f / static_cast<float>(num_notes);
  196. dc_blocker_.Process(raw, size);
  197. for (size_t i = 0; i < size; ++i) {
  198. raw[i] *= normalization;
  199. }
  200. float chord = patch.resonator_geometry * 10.0f;
  201. float hysteresis = chord > chord_index_ ? -0.1f : 0.1f;
  202. int chord_index = static_cast<int>(chord + hysteresis + 0.5f);
  203. CONSTRAIN(chord_index, 0, 10);
  204. chord_index_ = static_cast<float>(chord_index);
  205. fill(&center[0], &center[size], 0.0f);
  206. fill(&sides[0], &sides[size], 0.0f);
  207. for (size_t i = 0; i < num_notes; ++i) {
  208. float transpose = chords[chord_index][i];
  209. string_[i].set_frequency(frequency * SemitonesToRatio(transpose));
  210. string_[i].set_brightness(patch.resonator_brightness);
  211. string_[i].set_position(patch.resonator_position);
  212. string_[i].set_damping(damping);
  213. if (num_notes == 1) {
  214. string_[i].set_dispersion(patch.resonator_geometry);
  215. } else {
  216. float b = patch.resonator_brightness;
  217. string_[i].set_dispersion(b < 0.5f ? 0.0f : (b - 0.5f) * -0.4f);
  218. }
  219. string_[i].Process(raw, center, sides, size);
  220. }
  221. for (size_t i = 0; i < size; ++i) {
  222. float left = center[i];
  223. float right = sides[i];
  224. center[i] = left - right;
  225. sides[i] = left + right;
  226. }
  227. }
  228. // This is where the raw mallet signal bleeds through the exciter output.
  229. for (size_t i = 0; i < size; ++i) {
  230. center[i] += strike_bleed * strike_buffer_[i];
  231. }
  232. }
  233. } // namespace elements