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.

306 lines
7.3KB

  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. // Tidal generator.
  28. #ifndef TIDES_GENERATOR_H_
  29. #define TIDES_GENERATOR_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/algorithms/pattern_predictor.h"
  32. #include "stmlib/utils/ring_buffer.h"
  33. // #define WAVETABLE_HACK
  34. namespace tides {
  35. enum GeneratorRange {
  36. GENERATOR_RANGE_HIGH,
  37. GENERATOR_RANGE_MEDIUM,
  38. GENERATOR_RANGE_LOW
  39. };
  40. enum GeneratorMode {
  41. GENERATOR_MODE_AD,
  42. GENERATOR_MODE_LOOPING,
  43. GENERATOR_MODE_AR,
  44. };
  45. enum ControlBitMask {
  46. CONTROL_FREEZE = 1,
  47. CONTROL_GATE = 2,
  48. CONTROL_CLOCK = 4,
  49. CONTROL_CLOCK_RISING = 8,
  50. CONTROL_GATE_RISING = 16,
  51. CONTROL_GATE_FALLING = 32
  52. };
  53. enum FlagBitMask {
  54. FLAG_END_OF_ATTACK = 1,
  55. FLAG_END_OF_RELEASE = 2
  56. };
  57. struct GeneratorSample {
  58. uint16_t unipolar;
  59. int16_t bipolar;
  60. uint8_t flags;
  61. };
  62. const uint16_t kBlockSize = 16;
  63. struct FrequencyRatio {
  64. uint32_t p;
  65. uint32_t q;
  66. };
  67. class Generator {
  68. public:
  69. Generator() { }
  70. ~Generator() { }
  71. void Init();
  72. void set_range(GeneratorRange range) {
  73. ClearFilterState();
  74. range_ = range;
  75. clock_divider_ =
  76. /* harmonic oscillator is sampled at 24kHz */
  77. feature_mode_ == FEAT_MODE_HARMONIC ? 2 :
  78. range_ == GENERATOR_RANGE_LOW ? 4 : 1;
  79. }
  80. void set_mode(GeneratorMode mode) {
  81. mode_ = mode;
  82. if (mode_ == GENERATOR_MODE_LOOPING) {
  83. running_ = true;
  84. }
  85. }
  86. void set_pitch_high_range(int16_t pitch, int16_t fm) {
  87. if (sync_) {
  88. ComputeFrequencyRatio(pitch);
  89. }
  90. pitch_ = pitch + (12 << 7) + fm;
  91. }
  92. void set_pitch(int16_t pitch, int16_t fm) {
  93. if (sync_) {
  94. ComputeFrequencyRatio(pitch);
  95. }
  96. pitch += (12 << 7) - (60 << 7) * static_cast<int16_t>(range_);
  97. if (range_ == GENERATOR_RANGE_LOW) {
  98. pitch -= (12 << 7); // One extra octave of super LF stuff!
  99. }
  100. pitch_ = pitch + fm;
  101. }
  102. void set_shape(int16_t shape) {
  103. shape_ = shape;
  104. }
  105. void set_slope(int16_t slope) {
  106. #ifndef WAVETABLE_HACK
  107. if (range_ == GENERATOR_RANGE_HIGH &&
  108. feature_mode_ != FEAT_MODE_HARMONIC) {
  109. CONSTRAIN(slope, -32512, 32512);
  110. }
  111. #endif // WAVETABLE_HACK
  112. slope_ = slope;
  113. }
  114. void set_smoothness(int16_t smoothness) {
  115. smoothness_ = smoothness;
  116. }
  117. void set_frequency_ratio(FrequencyRatio ratio) {
  118. frequency_ratio_ = ratio;
  119. }
  120. void set_waveshaper_antialiasing(bool antialiasing) {
  121. antialiasing_ = antialiasing;
  122. }
  123. void set_sync(bool sync) {
  124. if (!sync_ && sync) {
  125. pattern_predictor_.Init();
  126. }
  127. sync_ = sync;
  128. sync_edges_counter_ = 0;
  129. }
  130. void set_pulse_width(uint16_t pw) {
  131. pulse_width_ = pw;
  132. }
  133. inline GeneratorMode mode() const { return mode_; }
  134. inline GeneratorRange range() const { return range_; }
  135. inline bool sync() const { return sync_; }
  136. inline GeneratorSample Process(uint8_t control) {
  137. input_buffer_.Overwrite(control);
  138. return output_buffer_.ImmediateRead();
  139. }
  140. inline bool writable_block() const {
  141. return output_buffer_.writable() >= kBlockSize;
  142. }
  143. inline bool FillBufferSafe() {
  144. if (!writable_block()) {
  145. return false;
  146. } else {
  147. FillBuffer();
  148. return true;
  149. }
  150. }
  151. void FillBuffer();
  152. uint32_t clock_divider() const {
  153. return clock_divider_;
  154. }
  155. enum FeatureMode {
  156. FEAT_MODE_FUNCTION,
  157. FEAT_MODE_HARMONIC,
  158. FEAT_MODE_RANDOM,
  159. };
  160. FeatureMode feature_mode_;
  161. private:
  162. // There are two versions of the rendering code, one optimized for audio, with
  163. // band-limiting.
  164. void FillBufferAudioRate();
  165. void FillBufferControlRate();
  166. void FillBufferWavetable();
  167. template<GeneratorMode mode> void FillBufferHarmonic();
  168. void FillBufferRandom();
  169. int32_t ComputeAntialiasAttenuation(
  170. int16_t pitch,
  171. int16_t slope,
  172. int16_t shape,
  173. int16_t smoothness);
  174. inline void ClearFilterState() {
  175. uni_lp_state_[0] = uni_lp_state_[1] = 0;
  176. bi_lp_state_[0] = bi_lp_state_[1] = 0;
  177. }
  178. int32_t ComputePhaseIncrement(int16_t pitch);
  179. int16_t ComputePitch(int32_t phase_increment);
  180. int32_t ComputeCutoffFrequency(int16_t pitch, int16_t smoothness);
  181. void ComputeFrequencyRatio(int16_t pitch);
  182. stmlib::RingBuffer<uint8_t, kBlockSize * 2> input_buffer_;
  183. stmlib::RingBuffer<GeneratorSample, kBlockSize * 2> output_buffer_;
  184. GeneratorMode mode_;
  185. GeneratorRange range_;
  186. GeneratorSample previous_sample_;
  187. uint32_t clock_divider_;
  188. int16_t pitch_;
  189. int16_t previous_pitch_;
  190. int16_t shape_;
  191. int16_t slope_;
  192. int32_t smoothed_slope_;
  193. int16_t smoothness_;
  194. bool antialiasing_;
  195. uint16_t final_gain_;
  196. uint32_t phase_;
  197. int32_t phase_increment_;
  198. uint32_t sub_phase_;
  199. uint16_t x_;
  200. uint16_t y_;
  201. uint16_t z_;
  202. bool wrap_;
  203. uint16_t pulse_width_;
  204. uint32_t divided_phase_;
  205. uint32_t divider_;
  206. uint32_t divider_counter_;
  207. uint32_t delayed_phase_;
  208. int32_t delayed_phase_increment_;
  209. uint32_t delay_;
  210. uint32_t delay_counter_;
  211. int16_t previous_slope_;
  212. uint32_t delayed_threshold_;
  213. uint16_t current_value_[2];
  214. uint16_t next_value_[2];
  215. bool walk_direction_[2];
  216. uint16_t value_[2];
  217. int16_t old_slope_;
  218. int16_t old_pitch_;
  219. bool sync_;
  220. FrequencyRatio frequency_ratio_;
  221. // Time measurement and clock divider for PLL mode.
  222. uint32_t sync_counter_;
  223. uint32_t sync_edges_counter_;
  224. uint32_t local_osc_phase_;
  225. int32_t local_osc_phase_increment_;
  226. int32_t target_phase_increment_;
  227. uint32_t eor_counter_;
  228. stmlib::PatternPredictor<32, 8> pattern_predictor_;
  229. int64_t uni_lp_state_[2];
  230. int64_t bi_lp_state_[2];
  231. bool running_;
  232. bool previous_freeze_;
  233. bool previous_clock_;
  234. static const FrequencyRatio frequency_ratios_[];
  235. static const int16_t num_frequency_ratios_;
  236. static const uint8_t kNumHarmonics = 16;
  237. static const uint8_t kNumHarmonicsPowers = 12;
  238. uint16_t envelope_[kNumHarmonics];
  239. uint16_t envelope_increment_[kNumHarmonics];
  240. uint8_t harm_permut_[kNumHarmonics];
  241. void RandomizeDelay();
  242. void RandomizeDivider();
  243. void RandomizeHarmonicPhase();
  244. void RandomizeHarmonicDistribution();
  245. DISALLOW_COPY_AND_ASSIGN(Generator);
  246. };
  247. } // namespace tides
  248. #endif // TIDES_GENERATOR_H_