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.

213 lines
6.7KB

  1. // Copyright 2013 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. // LFO.
  28. #include "peaks/modulations/lfo.h"
  29. #include <cstdio>
  30. #include "stmlib/utils/dsp.h"
  31. #include "stmlib/utils/random.h"
  32. #include "peaks/resources.h"
  33. namespace peaks {
  34. const uint16_t kSlopeBits = 12;
  35. const uint32_t kSyncCounterMaxTime = 8 * 48000;
  36. using namespace stmlib;
  37. void Lfo::Init() {
  38. rate_ = 0;
  39. shape_ = LFO_SHAPE_SQUARE;
  40. parameter_ = 0;
  41. reset_phase_ = 0;
  42. sync_ = false;
  43. previous_parameter_ = 32767;
  44. sync_counter_ = kSyncCounterMaxTime;
  45. level_ = 32767;
  46. pattern_predictor_.Init();
  47. }
  48. const int16_t presets[7][2] = {
  49. { LFO_SHAPE_SINE, 0 },
  50. { LFO_SHAPE_TRIANGLE, 0 },
  51. { LFO_SHAPE_TRIANGLE, 32767 },
  52. { LFO_SHAPE_SQUARE, 0 },
  53. { LFO_SHAPE_STEPS, 0 },
  54. { LFO_SHAPE_NOISE, -32767 },
  55. { LFO_SHAPE_NOISE, 32767 },
  56. };
  57. void Lfo::set_shape_parameter_preset(uint16_t value) {
  58. value = (value >> 8) * 7 >> 8;
  59. set_shape(static_cast<LfoShape>(presets[value][0]));
  60. set_parameter(presets[value][1]);
  61. }
  62. void Lfo::Process(const GateFlags* gate_flags, int16_t* out, size_t size) {
  63. if (!sync_) {
  64. int32_t a = lut_lfo_increments[rate_ >> 8];
  65. int32_t b = lut_lfo_increments[(rate_ >> 8) + 1];
  66. phase_increment_ = a + (((b - a) >> 1) * (rate_ & 0xff) >> 7);
  67. }
  68. while (size--) {
  69. ++sync_counter_;
  70. GateFlags gate_flag = *gate_flags++;
  71. if (gate_flag & GATE_FLAG_RISING) {
  72. bool reset_phase = true;
  73. if (sync_) {
  74. if (sync_counter_ < kSyncCounterMaxTime) {
  75. uint32_t period = 0;
  76. if (gate_flag & GATE_FLAG_FROM_BUTTON) {
  77. period = sync_counter_;
  78. } else if (sync_counter_ < 1920) {
  79. period = (3 * period_ + sync_counter_) >> 2;
  80. reset_phase = false;
  81. } else {
  82. period = pattern_predictor_.Predict(sync_counter_);
  83. }
  84. if (period != period_) {
  85. period_ = period;
  86. phase_increment_ = 0xffffffff / period_;
  87. }
  88. }
  89. sync_counter_ = 0;
  90. }
  91. if (reset_phase) {
  92. phase_ = reset_phase_;
  93. }
  94. }
  95. phase_ += phase_increment_;
  96. int32_t sample = (this->*compute_sample_fn_table_[shape_])();
  97. *out++ = sample * level_ >> 15;
  98. }
  99. }
  100. int16_t Lfo::ComputeSampleSine() {
  101. uint32_t phase = phase_;
  102. int16_t sine = Interpolate1022(wav_sine, phase);
  103. int16_t sample;
  104. if (parameter_ > 0) {
  105. int32_t wf_balance = parameter_;
  106. int32_t wf_gain = 2048 + \
  107. (static_cast<int32_t>(parameter_) * (65535 - 2048) >> 15);
  108. int32_t original = sine;
  109. int32_t folded = Interpolate1022(
  110. wav_fold_sine, original * wf_gain + (1UL << 31));
  111. sample = original + ((folded - original) * wf_balance >> 15);
  112. } else {
  113. int32_t wf_balance = -parameter_;
  114. int32_t original = sine;
  115. phase += 1UL << 30;
  116. int32_t tri = phase < (1UL << 31) ? phase << 1 : ~(phase << 1);
  117. int32_t folded = Interpolate1022(wav_fold_power, tri);
  118. sample = original + ((folded - original) * wf_balance >> 15);
  119. }
  120. return sample;
  121. }
  122. int16_t Lfo::ComputeSampleTriangle() {
  123. if (parameter_ != previous_parameter_) {
  124. uint16_t slope_offset = parameter_ + 32768;
  125. if (slope_offset <= 1) {
  126. decay_factor_ = 32768 << kSlopeBits;
  127. attack_factor_ = 1 << (kSlopeBits - 1);
  128. } else {
  129. decay_factor_ = (32768 << kSlopeBits) / slope_offset;
  130. attack_factor_ = (32768 << kSlopeBits) / (65536 - slope_offset);
  131. }
  132. end_of_attack_ = (static_cast<uint32_t>(slope_offset) << 16);
  133. previous_parameter_ = parameter_;
  134. }
  135. uint32_t phase = phase_;
  136. uint32_t skewed_phase = phase;
  137. if (phase < end_of_attack_) {
  138. skewed_phase = (phase >> kSlopeBits) * decay_factor_;
  139. } else {
  140. skewed_phase = ((phase - end_of_attack_) >> kSlopeBits) * attack_factor_;
  141. skewed_phase += 1L << 31;
  142. }
  143. return skewed_phase < 1UL << 31
  144. ? -32768 + (skewed_phase >> 15)
  145. : 32767 - (skewed_phase >> 15);
  146. }
  147. int16_t Lfo::ComputeSampleSquare() {
  148. uint32_t threshold = static_cast<uint32_t>(parameter_ + 32768) << 16;
  149. if (threshold < (phase_increment_ << 1)) {
  150. threshold = phase_increment_ << 1;
  151. } else if (~threshold < (phase_increment_ << 1)) {
  152. threshold = ~(phase_increment_ << 1);
  153. }
  154. return phase_ < threshold ? 32767 : -32767;
  155. }
  156. int16_t Lfo::ComputeSampleSteps() {
  157. uint16_t quantization_levels = 2 + (((parameter_ + 32768) * 15) >> 16);
  158. uint16_t scale = 65535 / (quantization_levels - 1);
  159. uint32_t phase = phase_;
  160. uint32_t tri_phase = phase;
  161. uint32_t tri = tri_phase < (1UL << 31) ? tri_phase << 1 : ~(tri_phase << 1);
  162. return ((tri >> 16) * quantization_levels >> 16) * scale - 32768;
  163. }
  164. int16_t Lfo::ComputeSampleNoise() {
  165. uint32_t phase = phase_;
  166. if (phase < phase_increment_) {
  167. value_ = next_value_;
  168. next_value_ = Random::GetSample();
  169. }
  170. int16_t sample;
  171. int32_t linear_interpolation = value_ + \
  172. ((next_value_ - value_) * static_cast<int32_t>(phase >> 17) >> 15);
  173. if (parameter_ < 0) {
  174. int32_t balance = parameter_ + 32767;
  175. sample = value_ + ((linear_interpolation - value_) * balance >> 15);
  176. } else {
  177. int16_t raised_cosine = Interpolate824(lut_raised_cosine, phase) >> 1;
  178. int32_t smooth_interpolation = value_ + \
  179. ((next_value_ - value_) * raised_cosine >> 15);
  180. sample = linear_interpolation + \
  181. ((smooth_interpolation - linear_interpolation) * parameter_ >> 15);
  182. }
  183. return sample;
  184. }
  185. /* static */
  186. Lfo::ComputeSampleFn Lfo::compute_sample_fn_table_[] = {
  187. &Lfo::ComputeSampleSine,
  188. &Lfo::ComputeSampleTriangle,
  189. &Lfo::ComputeSampleSquare,
  190. &Lfo::ComputeSampleSteps,
  191. &Lfo::ComputeSampleNoise
  192. };
  193. } // namespace peaks