Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

210 rindas
5.8KB

  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2016, Byron Jacquot, SparkFun Electronics
  3. *
  4. * Development of this audio library was funded by PJRC.COM, LLC by sales of
  5. * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
  6. * open source software by purchasing Teensy or other PJRC products.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice, development funding notice, and this permission
  16. * notice shall be included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <Arduino.h>
  27. #include "synth_simple_drum.h"
  28. extern "C" {
  29. extern const int16_t AudioWaveformSine[257];
  30. }
  31. void AudioSynthSimpleDrum::noteOn(void)
  32. {
  33. __disable_irq();
  34. wav_phasor = 0;
  35. wav_phasor2 = 0;
  36. env_lin_current = 0x7fff0000;
  37. __enable_irq();
  38. }
  39. void AudioSynthSimpleDrum::secondMix(float level)
  40. {
  41. // As level goes from 0.0 to 1.0,
  42. // second goes from 0 to 1/2 scale
  43. // first goes from full scale to half scale.
  44. if(level < 0)
  45. {
  46. level = 0;
  47. }
  48. else if(level > 1.0)
  49. {
  50. level = 1.0;
  51. }
  52. __disable_irq();
  53. wav_amplitude2 = level * 0x3fff;
  54. wav_amplitude1 = 0x7fff - wav_amplitude2;
  55. __enable_irq();
  56. }
  57. void AudioSynthSimpleDrum::pitchMod(float depth)
  58. {
  59. int32_t intdepth, calc;
  60. // Validate parameter
  61. if(depth < 0)
  62. {
  63. depth = 0;
  64. }
  65. else if(depth > 1.0)
  66. {
  67. depth = 1.0;
  68. }
  69. // Depth is float, 0.0..1.0
  70. // turn 0.0 to 1.0 into
  71. // 0x0 to 0x3fff;
  72. intdepth = depth * 0x7fff;
  73. // Lets turn it into 2.14, in range between -0.75 and 2.9999, woth 0 at 0.5
  74. // It becomes the scalar for the modulation component of the phasor increment.
  75. if(intdepth < 0x4000)
  76. {
  77. // 0 to 0.5 becomes
  78. // -0x3000 (0xffffCfff) to 0 ()
  79. calc = ((0x4000 - intdepth) * 0x3000 )>> 14;
  80. calc = -calc;
  81. }
  82. else
  83. {
  84. // 0.5 to 1.0 becomes
  85. // 0x00 to 0xbfa0
  86. calc = ((intdepth - 0x4000) * 0xc000)>> 14;
  87. }
  88. // Call result 2.14 format (max of ~3.99...approx 4)
  89. // See note in update().
  90. wav_pitch_mod = calc;
  91. }
  92. void AudioSynthSimpleDrum::update(void)
  93. {
  94. audio_block_t *block_wav;
  95. int16_t *p_wave, *end;
  96. int32_t sin_l, sin_r, interp, mod, mod2, delta;
  97. int32_t interp2;
  98. int32_t index, scale;
  99. bool do_second;
  100. int32_t env_sqr_current; // the square of the linear value - inexpensive quasi exponential decay.
  101. block_wav = allocate();
  102. if (!block_wav) return;
  103. p_wave = (block_wav->data);
  104. end = p_wave + AUDIO_BLOCK_SAMPLES;
  105. // 50 is arbitrary threshold...
  106. // low values of second are inaudible, and we can save CPU cycles
  107. // by not calculating second when it's really quiet.
  108. do_second = (wav_amplitude2 > 50);
  109. while(p_wave < end)
  110. {
  111. // Do envelope first
  112. if(env_lin_current < 0x0000ffff)
  113. {
  114. // If envelope has expired, then stuff zeros into output buffer.
  115. *p_wave = 0;
  116. p_wave++;
  117. }
  118. else
  119. {
  120. env_lin_current -= env_decrement;
  121. env_sqr_current = multiply_16tx16t(env_lin_current, env_lin_current) ;
  122. // do wave second;
  123. wav_phasor += wav_increment;
  124. // modulation changes how we use the increment
  125. // the increment will be scaled by the modulation amount.
  126. //
  127. // Pitch mod is in range [-0.75 .. 3.99999] in 2.14 format
  128. // Current envelope value gets scaled by mod depth.
  129. // Then phasor increment gets scaled by that.
  130. mod = signed_multiply_32x16b((env_sqr_current), (wav_pitch_mod>>1)) >> 13;
  131. mod2 = signed_multiply_32x16b(wav_increment<<3, mod>>1);
  132. wav_phasor += (mod2);
  133. wav_phasor &= 0x7fffffff;
  134. if(do_second)
  135. {
  136. // A perfect fifth uses increment of 1.5 times regular increment
  137. wav_phasor2 += wav_increment;
  138. wav_phasor2 += (wav_increment >> 1);
  139. wav_phasor2 += mod2;
  140. wav_phasor2 += (mod2 >> 1);
  141. wav_phasor2 &= 0x7fffffff;
  142. }
  143. // Phase to Sine lookup * interp:
  144. index = wav_phasor >> 23; // take top valid 8 bits
  145. sin_l = AudioWaveformSine[index];
  146. sin_r = AudioWaveformSine[index+1];
  147. // The fraction of the phasor in time we are between L and R
  148. // is the same as the fraction of the ampliture of that interval we should add
  149. // to L.
  150. delta = sin_r-sin_l;
  151. scale = (wav_phasor >> 7) & 0xfFFF;
  152. delta = (delta * scale)>> 16;
  153. interp = sin_l + delta;
  154. if(do_second)
  155. {
  156. index = wav_phasor2 >> 23; // take top valid 8 bits
  157. sin_l = AudioWaveformSine[index];
  158. sin_r = AudioWaveformSine[index+1];
  159. delta = sin_r-sin_l;
  160. scale = (wav_phasor2 >> 7) & 0xFFFF;
  161. delta = (delta * scale)>> 16;
  162. interp2 = sin_l + delta;
  163. // Then scale and add the two waves
  164. interp2 = (interp2 * wav_amplitude2 ) >> 15;
  165. interp = (interp * wav_amplitude1) >> 15;
  166. interp = interp + interp2;
  167. }
  168. *p_wave = signed_multiply_32x16b(env_sqr_current, interp ) >> 15 ;
  169. p_wave++;
  170. }
  171. }
  172. transmit(block_wav, 0);
  173. release(block_wav);
  174. }