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.

290 lines
8.9KB

  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. // Exciter.
  28. #include "elements/dsp/exciter.h"
  29. #include <algorithm>
  30. #include "stmlib/dsp/dsp.h"
  31. #include "stmlib/dsp/units.h"
  32. #include "elements/dsp/dsp.h"
  33. #include "elements/resources.h"
  34. namespace elements {
  35. using namespace std;
  36. using namespace stmlib;
  37. void Exciter::Init() {
  38. set_model(EXCITER_MODEL_MALLET);
  39. set_parameter(0.0f);
  40. set_timbre(0.99f);
  41. lp_.Init();
  42. damp_state_ = 0.0f;
  43. delay_ = 0;
  44. plectrum_delay_ = 0;
  45. particle_state_ = 0.5f;
  46. damping_ = 0.0f;
  47. signature_ = 0.0f;
  48. }
  49. float Exciter::GetPulseAmplitude(float cutoff) {
  50. uint32_t cutoff_index = static_cast<uint32_t>(cutoff * 256.0f);
  51. return lut_approx_svf_gain[cutoff_index];
  52. }
  53. void Exciter::Process(const uint8_t flags, float* out, size_t size) {
  54. damping_ = 0.0f;
  55. (this->*fn_table_[model_])(flags, out, size);
  56. // Apply filters.
  57. if (model_ != EXCITER_MODEL_GRANULAR_SAMPLE_PLAYER &&
  58. model_ != EXCITER_MODEL_SAMPLE_PLAYER) {
  59. uint32_t cutoff_index = static_cast<uint32_t>(timbre_ * 256.0f);
  60. if (model_ == EXCITER_MODEL_NOISE) {
  61. uint32_t resonance_index = static_cast<uint32_t>(parameter_ * 256.0f);
  62. lp_.set_g_r(
  63. lut_approx_svf_g[cutoff_index],
  64. lut_approx_svf_r[resonance_index]);
  65. } else {
  66. lp_.set_g_r_h(
  67. lut_approx_svf_g[cutoff_index],
  68. 2.0f,
  69. lut_approx_svf_h[cutoff_index]);
  70. }
  71. lp_.Process<FILTER_MODE_LOW_PASS>(out, out, size);
  72. }
  73. }
  74. void Exciter::ProcessGranularSamplePlayer(
  75. const uint8_t flags, float* out, size_t size) {
  76. const uint32_t restart_prob = uint32_t(0.01f * 4294967296.0f);
  77. const uint32_t restart_point = uint32_t(parameter_ * 32767.0f) << 17;
  78. const uint32_t phase_increment = static_cast<uint32_t>(
  79. 131072.0f * SemitonesToRatio(72.0f * timbre_ - 60.0f));
  80. const int16_t* base = &smp_noise_sample[static_cast<size_t>(
  81. signature_ * 8192.0f)];
  82. uint32_t phase = phase_;
  83. while (size--) {
  84. uint32_t phase_integral = phase >> 17;
  85. float phase_fractional = static_cast<float>(phase & 0x1ffff) / 131072.0f;
  86. float a = static_cast<float>(base[phase_integral]);
  87. float b = static_cast<float>(base[phase_integral + 1]);
  88. *out++ = (a + (b - a) * phase_fractional) / 32768.0f;
  89. phase += phase_increment;
  90. if (Random::GetWord() < restart_prob) {
  91. phase = restart_point;
  92. }
  93. }
  94. phase_ = phase;
  95. damping_ = 0.0f;
  96. }
  97. void Exciter::ProcessSamplePlayer(
  98. const uint8_t flags, float* out, size_t size) {
  99. float index = (1.0f - parameter_) * 8.0f;
  100. MAKE_INTEGRAL_FRACTIONAL(index);
  101. if (index_integral == 8) {
  102. index_integral = 7;
  103. index_fractional = 1.0f;
  104. }
  105. const uint32_t offset_1 = smp_boundaries[index_integral];
  106. const uint32_t offset_2 = smp_boundaries[index_integral + 1];
  107. const uint32_t length_1 = offset_2 - offset_1 - 1;
  108. const uint32_t length_2 = smp_boundaries[index_integral + 2] - offset_2 - 1;
  109. const uint32_t phase_increment = static_cast<uint32_t>(
  110. 65536.0f * SemitonesToRatio(72.0f * timbre_ - 36.0f + 7.0f));
  111. float damp = damp_state_;
  112. uint32_t phase = phase_;
  113. if (flags & EXCITER_FLAG_RISING_EDGE) {
  114. damp = 0.0f;
  115. phase = 0;
  116. }
  117. if (!(flags & EXCITER_FLAG_GATE)) {
  118. damp = 1.0f - 0.95f * (1.0f - damp);
  119. }
  120. while (size--) {
  121. uint32_t phase_integral = phase >> 16;
  122. float phase_fractional = static_cast<float>(phase & 0xffff) / 65536.0f;
  123. float sample_1 = 0.0f;
  124. float sample_2 = 0.0f;
  125. bool step = false;
  126. if (phase_integral < length_1) {
  127. const int16_t* base = &smp_sample_data[offset_1 + phase_integral];
  128. float a = static_cast<float>(base[0]);
  129. float b = static_cast<float>(base[1]);
  130. sample_1 = a + (b - a) * phase_fractional;
  131. step = true;
  132. }
  133. if (phase_integral < length_2) {
  134. const int16_t* base = &smp_sample_data[offset_2 + phase_integral];
  135. float a = static_cast<float>(base[0]);
  136. float b = static_cast<float>(base[1]);
  137. sample_2 = a + (b - a) * phase_fractional;
  138. step = true;
  139. }
  140. if (step) {
  141. phase += phase_increment;
  142. }
  143. *out++ = (sample_1 + (sample_2 - sample_1) * index_fractional) / 65536.0f;
  144. }
  145. phase_ = phase;
  146. damping_ = damp * (parameter_ >= 0.8f ? parameter_ * 5.0f - 4.0f : 0.0f);
  147. damp_state_ = damp;
  148. }
  149. void Exciter::ProcessMallet(const uint8_t flags, float* out, size_t size) {
  150. fill(&out[0], &out[size], 0.0f);
  151. if (flags & EXCITER_FLAG_RISING_EDGE) {
  152. damp_state_ = 0.0f;
  153. out[0] = GetPulseAmplitude(timbre_);
  154. }
  155. if (!(flags & EXCITER_FLAG_GATE)) {
  156. damp_state_ = 1.0f - 0.95f * (1.0f - damp_state_);
  157. }
  158. damping_ = damp_state_ * (1.0f - parameter_);
  159. }
  160. void Exciter::ProcessPlectrum(
  161. const uint8_t flags,
  162. float* out,
  163. size_t size) {
  164. float amplitude = GetPulseAmplitude(timbre_);
  165. float damp = damp_state_;
  166. float impulse = 0.0f;
  167. if (flags & EXCITER_FLAG_RISING_EDGE) {
  168. impulse = -amplitude * (0.05f + signature_ * 0.2f);
  169. plectrum_delay_ = static_cast<uint32_t>(
  170. 4096.0f * parameter_ * parameter_) + 64;
  171. }
  172. while (size--) {
  173. if (plectrum_delay_) {
  174. --plectrum_delay_;
  175. if (plectrum_delay_ == 0) {
  176. impulse = amplitude;
  177. }
  178. damp = 1.0f - 0.997f * (1.0f - damp);
  179. } else {
  180. damp = 0.9f * damp;
  181. }
  182. *out++ = impulse;
  183. impulse = 0.0f;
  184. }
  185. damping_ = damp * 0.5f;
  186. damp_state_ = damp;
  187. }
  188. void Exciter::ProcessParticles(
  189. const uint8_t flags,
  190. float* out,
  191. size_t size) {
  192. if (flags & EXCITER_FLAG_RISING_EDGE) {
  193. particle_state_ = RandomSample();
  194. particle_state_ = 1.0f - 0.6f * particle_state_ * particle_state_;
  195. delay_ = 0;
  196. particle_range_ = 1.0f;
  197. }
  198. fill(&out[0], &out[size], 0.0f);
  199. if (flags & EXCITER_FLAG_GATE) {
  200. const uint32_t up_probability = uint32_t(0.7f * 4294967296.0f);
  201. const uint32_t down_probability = uint32_t(0.3f * 4294967296.0f);
  202. const float amplitude = GetPulseAmplitude(timbre_);
  203. while (size--) {
  204. if (delay_ == 0) {
  205. float amount = RandomSample();
  206. amount = 1.05f + 0.5f * amount * amount;
  207. if (Random::GetWord() > up_probability) {
  208. particle_state_ *= amount;
  209. if (particle_state_ >= (particle_range_ + 0.25f)) {
  210. particle_state_ = particle_range_ + 0.25f;
  211. }
  212. } else if (Random::GetWord() < down_probability) {
  213. particle_state_ /= amount;
  214. if (particle_state_ <= 0.02f) {
  215. particle_state_ = 0.02f;
  216. }
  217. }
  218. delay_ = static_cast<uint32_t>(particle_state_ * 0.15f * kSampleRate);
  219. float gain = 1.0f - particle_range_;
  220. gain *= gain;
  221. *out = particle_state_ * amplitude * (1.0f - gain);
  222. float decay_factor = 1.0f - parameter_;
  223. particle_range_ *= 1.0f - decay_factor * decay_factor * 0.5f;
  224. } else {
  225. --delay_;
  226. }
  227. ++out;
  228. }
  229. }
  230. }
  231. void Exciter::ProcessFlow(
  232. const uint8_t flags,
  233. float* out,
  234. size_t size) {
  235. float scale = parameter_ * parameter_ * parameter_ * parameter_;
  236. float threshold = 0.0001f + scale * 0.125f;
  237. if (flags & EXCITER_FLAG_RISING_EDGE) {
  238. particle_state_ = 0.5f;
  239. }
  240. while (size--) {
  241. float sample = RandomSample();
  242. if (sample < threshold) {
  243. particle_state_ = -particle_state_;
  244. }
  245. *out++ = particle_state_ + (sample - 0.5f - particle_state_) * scale;
  246. }
  247. }
  248. void Exciter::ProcessNoise(const uint8_t flags, float* out, size_t size) {
  249. while (size--) {
  250. *out++ = RandomSample() - 0.5f;
  251. }
  252. }
  253. /* static */
  254. Exciter::ProcessFn Exciter::fn_table_[] = {
  255. &Exciter::ProcessGranularSamplePlayer,
  256. &Exciter::ProcessSamplePlayer,
  257. &Exciter::ProcessMallet,
  258. &Exciter::ProcessPlectrum,
  259. &Exciter::ProcessParticles,
  260. &Exciter::ProcessFlow,
  261. &Exciter::ProcessNoise
  262. };
  263. } // namespace elements