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.

284 lines
7.9KB

  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. // Voice.
  28. #ifndef YARNS_VOICE_H_
  29. #define YARNS_VOICE_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/utils/ring_buffer.h"
  32. namespace yarns {
  33. const uint16_t kNumOctaves = 11;
  34. const size_t kAudioBlockSize = 64;
  35. enum TriggerShape {
  36. TRIGGER_SHAPE_SQUARE,
  37. TRIGGER_SHAPE_LINEAR,
  38. TRIGGER_SHAPE_EXPONENTIAL,
  39. TRIGGER_SHAPE_RING,
  40. TRIGGER_SHAPE_STEPS,
  41. TRIGGER_SHAPE_NOISE_BURST
  42. };
  43. enum AudioMode {
  44. AUDIO_MODE_OFF,
  45. AUDIO_MODE_SAW,
  46. AUDIO_MODE_SQUARE,
  47. AUDIO_MODE_TRIANGLE,
  48. AUDIO_MODE_SINE
  49. };
  50. class Oscillator {
  51. public:
  52. Oscillator() { }
  53. ~Oscillator() { }
  54. void Init(int32_t scale, int32_t offset);
  55. void Render(uint8_t mode, int16_t note, bool gate);
  56. inline uint16_t ReadSample() {
  57. return audio_buffer_.ImmediateRead();
  58. }
  59. private:
  60. uint32_t ComputePhaseIncrement(int16_t pitch);
  61. void RenderSilence();
  62. void RenderNoise();
  63. void RenderSine(uint32_t phase_increment);
  64. void RenderSaw(uint32_t phase_increment);
  65. void RenderSquare(uint32_t phase_increment, uint32_t pw, bool integrate);
  66. inline int32_t ThisBlepSample(uint32_t t) {
  67. if (t > 65535) {
  68. t = 65535;
  69. }
  70. return t * t >> 18;
  71. }
  72. inline int32_t NextBlepSample(uint32_t t) {
  73. if (t > 65535) {
  74. t = 65535;
  75. }
  76. t = 65535 - t;
  77. return -static_cast<int32_t>(t * t >> 18);
  78. }
  79. int32_t scale_;
  80. int32_t offset_;
  81. uint32_t phase_;
  82. int32_t next_sample_;
  83. int32_t integrator_state_;
  84. bool high_;
  85. stmlib::RingBuffer<uint16_t, kAudioBlockSize * 2> audio_buffer_;
  86. DISALLOW_COPY_AND_ASSIGN(Oscillator);
  87. };
  88. class Voice {
  89. public:
  90. Voice() { }
  91. ~Voice() { }
  92. void Init();
  93. void ResetAllControllers();
  94. void Calibrate(uint16_t* calibrated_dac_code);
  95. void Refresh();
  96. void NoteOn(int16_t note, uint8_t velocity, uint8_t portamento, bool trigger);
  97. void NoteOff();
  98. void ControlChange(uint8_t controller, uint8_t value);
  99. void PitchBend(uint16_t pitch_bend) {
  100. mod_pitch_bend_ = pitch_bend;
  101. }
  102. void Aftertouch(uint8_t velocity) {
  103. mod_aux_[2] = velocity << 9;
  104. }
  105. inline void set_modulation_rate(uint8_t modulation_rate) {
  106. modulation_rate_ = modulation_rate;
  107. }
  108. inline void set_pitch_bend_range(uint8_t pitch_bend_range) {
  109. pitch_bend_range_ = pitch_bend_range;
  110. }
  111. inline void set_vibrato_range(uint8_t vibrato_range) {
  112. vibrato_range_ = vibrato_range;
  113. }
  114. inline void set_trigger_duration(uint8_t trigger_duration) {
  115. trigger_duration_ = trigger_duration;
  116. }
  117. inline void set_trigger_scale(uint8_t trigger_scale) {
  118. trigger_scale_ = trigger_scale;
  119. }
  120. inline void set_trigger_shape(uint8_t trigger_shape) {
  121. trigger_shape_ = trigger_shape;
  122. }
  123. inline void set_aux_cv(uint8_t aux_cv_source) {
  124. aux_cv_source_ = aux_cv_source;
  125. }
  126. inline void set_aux_cv_2(uint8_t aux_cv_source_2) {
  127. aux_cv_source_2_ = aux_cv_source_2;
  128. }
  129. inline int32_t note() const { return note_; }
  130. inline uint8_t velocity() const { return mod_velocity_; }
  131. inline uint8_t modulation() const { return mod_wheel_; }
  132. inline uint8_t aux_cv() const { return mod_aux_[aux_cv_source_] >> 8; }
  133. inline uint8_t aux_cv_2() const { return mod_aux_[aux_cv_source_2_] >> 8; }
  134. inline uint16_t DacCodeFrom16BitValue(uint16_t value) const {
  135. uint32_t v = static_cast<uint32_t>(value);
  136. uint32_t scale = calibrated_dac_code_[3] - calibrated_dac_code_[8];
  137. return static_cast<uint16_t>(calibrated_dac_code_[3] - (scale * v >> 16));
  138. }
  139. inline uint16_t note_dac_code() const {
  140. return note_dac_code_;
  141. }
  142. inline uint16_t velocity_dac_code() const {
  143. return DacCodeFrom16BitValue(mod_velocity_ << 9);
  144. }
  145. inline uint16_t modulation_dac_code() const {
  146. return DacCodeFrom16BitValue(mod_wheel_ << 9);
  147. }
  148. inline uint16_t aux_cv_dac_code() const {
  149. return DacCodeFrom16BitValue(mod_aux_[aux_cv_source_]);
  150. }
  151. inline uint16_t aux_cv_dac_code_2() const {
  152. return DacCodeFrom16BitValue(mod_aux_[aux_cv_source_2_]);
  153. }
  154. inline bool gate_on() const { return gate_; }
  155. inline bool gate() const { return gate_ && !retrigger_delay_; }
  156. inline bool trigger() const {
  157. return gate_ && trigger_pulse_;
  158. }
  159. uint16_t trigger_dac_code() const;
  160. inline uint16_t calibration_dac_code(uint8_t note) const {
  161. return calibrated_dac_code_[note];
  162. }
  163. inline void set_calibration_dac_code(uint8_t note, uint16_t dac_code) {
  164. calibrated_dac_code_[note] = dac_code;
  165. dirty_ = true;
  166. }
  167. inline void set_audio_mode(uint8_t audio_mode) {
  168. audio_mode_ = audio_mode;
  169. }
  170. inline void set_tuning(int8_t coarse, int8_t fine) {
  171. tuning_ = (static_cast<int32_t>(coarse) << 7) + fine;
  172. }
  173. inline uint8_t audio_mode() {
  174. return audio_mode_;
  175. }
  176. inline void RenderAudio() {
  177. oscillator_.Render(audio_mode_, note_, gate_);
  178. }
  179. inline uint16_t ReadSample() {
  180. return oscillator_.ReadSample();
  181. }
  182. void TapLfo(uint32_t target_phase) {
  183. uint32_t target_increment = target_phase - lfo_pll_previous_target_phase_;
  184. int32_t d_error = target_increment - (lfo_phase_ - lfo_pll_previous_phase_);
  185. int32_t p_error = target_phase - lfo_phase_;
  186. int32_t error = d_error + (p_error >> 1);
  187. lfo_pll_phase_increment_ += error >> 11;
  188. lfo_pll_previous_phase_ = lfo_phase_;
  189. lfo_pll_previous_target_phase_ = target_phase;
  190. }
  191. private:
  192. uint16_t NoteToDacCode(int32_t note) const;
  193. void FillAudioBuffer();
  194. int32_t note_source_;
  195. int32_t note_target_;
  196. int32_t note_portamento_;
  197. int32_t note_;
  198. int32_t tuning_;
  199. bool gate_;
  200. bool dirty_; // Set to true when the calibration settings have changed.
  201. uint16_t note_dac_code_;
  202. uint16_t calibrated_dac_code_[kNumOctaves];
  203. int16_t mod_pitch_bend_;
  204. uint8_t mod_wheel_;
  205. uint16_t mod_aux_[8];
  206. uint8_t mod_velocity_;
  207. uint8_t pitch_bend_range_;
  208. uint8_t modulation_rate_;
  209. uint8_t vibrato_range_;
  210. uint8_t trigger_duration_;
  211. uint8_t trigger_shape_;
  212. bool trigger_scale_;
  213. uint8_t aux_cv_source_;
  214. uint8_t aux_cv_source_2_;
  215. uint32_t lfo_phase_;
  216. uint32_t portamento_phase_;
  217. uint32_t portamento_phase_increment_;
  218. bool portamento_exponential_shape_;
  219. // This counter is used to artificially create a 500µs dip at LOW level when
  220. // the gate is currently HIGH and a new note arrive with a retrigger command.
  221. // This happens with note-stealing; or when sending a MIDI sequence with
  222. // overlapping notes.
  223. uint16_t retrigger_delay_;
  224. uint16_t trigger_pulse_;
  225. uint32_t trigger_phase_increment_;
  226. uint32_t trigger_phase_;
  227. // PLL for clock-synced LFO.
  228. uint32_t lfo_pll_phase_increment_;
  229. uint32_t lfo_pll_previous_target_phase_;
  230. uint32_t lfo_pll_previous_phase_;
  231. uint8_t audio_mode_;
  232. Oscillator oscillator_;
  233. DISALLOW_COPY_AND_ASSIGN(Voice);
  234. };
  235. } // namespace yarns
  236. #endif // YARNS_VOICE_H_