PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

synth_sine.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
  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_sine.h"
  28. #include "utility/dspinst.h"
  29. // data_waveforms.c
  30. extern "C" {
  31. extern const int16_t AudioWaveformSine[257];
  32. }
  33. void AudioSynthWaveformSine::update(void)
  34. {
  35. audio_block_t *block;
  36. uint32_t i, ph, inc, index, scale;
  37. int32_t val1, val2;
  38. if (magnitude) {
  39. block = allocate();
  40. if (block) {
  41. ph = phase_accumulator;
  42. inc = phase_increment;
  43. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  44. index = ph >> 24;
  45. val1 = AudioWaveformSine[index];
  46. val2 = AudioWaveformSine[index+1];
  47. scale = (ph >> 8) & 0xFFFF;
  48. val2 *= scale;
  49. val1 *= 0x10000 - scale;
  50. #if defined(__ARM_ARCH_7EM__)
  51. block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
  52. #elif defined(KINETISL)
  53. block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16;
  54. #endif
  55. ph += inc;
  56. }
  57. phase_accumulator = ph;
  58. transmit(block);
  59. release(block);
  60. return;
  61. }
  62. }
  63. phase_accumulator += phase_increment * AUDIO_BLOCK_SAMPLES;
  64. }
  65. #if defined(__ARM_ARCH_7EM__)
  66. // High accuracy 11th order Taylor Series Approximation
  67. // input is 0 to 0xFFFFFFFF, representing 0 to 360 degree phase
  68. // output is 32 bit signed integer, top 25 bits should be very good
  69. static int32_t taylor(uint32_t ph)
  70. {
  71. int32_t angle, sum, p1, p2, p3, p5, p7, p9, p11;
  72. if (ph >= 0xC0000000 || ph < 0x40000000) { // ph: 0.32
  73. angle = (int32_t)ph; // valid from -90 to +90 degrees
  74. } else {
  75. angle = (int32_t)(0x80000000u - ph); // angle: 2.30
  76. }
  77. p1 = multiply_32x32_rshift32_rounded(angle, 1686629713) << 2; // p1: 2.30
  78. p2 = multiply_32x32_rshift32_rounded(p1, p1) << 1; // p2: 3.29
  79. p3 = multiply_32x32_rshift32_rounded(p2, p1) << 2; // p3: 3.29
  80. sum = multiply_subtract_32x32_rshift32_rounded(p1, p3, 1431655765); // sum: 2.30
  81. p5 = multiply_32x32_rshift32_rounded(p3, p2); // p5: 6.26
  82. sum = multiply_accumulate_32x32_rshift32_rounded(sum, p5, 572662306);
  83. p7 = multiply_32x32_rshift32_rounded(p5, p2); // p7: 9.23
  84. sum = multiply_subtract_32x32_rshift32_rounded(sum, p7, 109078534);
  85. p9 = multiply_32x32_rshift32_rounded(p7, p2); // p9: 12.20
  86. sum = multiply_accumulate_32x32_rshift32_rounded(sum, p9, 12119837);
  87. p11 = multiply_32x32_rshift32_rounded(p9, p2); // p11: 15.17
  88. sum = multiply_subtract_32x32_rshift32_rounded(sum, p11, 881443);
  89. return sum <<= 1; // return: 1.31
  90. }
  91. #endif
  92. void AudioSynthWaveformSineHires::update(void)
  93. {
  94. #if defined(__ARM_ARCH_7EM__)
  95. audio_block_t *msw, *lsw;
  96. uint32_t i, ph, inc;
  97. int32_t val;
  98. if (magnitude) {
  99. msw = allocate();
  100. lsw = allocate();
  101. if (msw && lsw) {
  102. ph = phase_accumulator;
  103. inc = phase_increment;
  104. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  105. val = taylor(ph);
  106. msw->data[i] = val >> 16;
  107. lsw->data[i] = val & 0xFFFF;
  108. ph += inc;
  109. }
  110. phase_accumulator = ph;
  111. transmit(msw, 0);
  112. release(msw);
  113. transmit(lsw, 1);
  114. release(lsw);
  115. return;
  116. } else {
  117. if (msw) release(msw);
  118. if (lsw) release(lsw);
  119. }
  120. }
  121. phase_accumulator += phase_increment * AUDIO_BLOCK_SAMPLES;
  122. #endif
  123. }
  124. #if defined(__ARM_ARCH_7EM__)
  125. void AudioSynthWaveformSineModulated::update(void)
  126. {
  127. audio_block_t *block, *modinput;
  128. uint32_t i, ph, inc, index, scale;
  129. int32_t val1, val2;
  130. int16_t mod;
  131. modinput = receiveReadOnly();
  132. ph = phase_accumulator;
  133. inc = phase_increment;
  134. block = allocate();
  135. if (!block) {
  136. // unable to allocate memory, so we'll send nothing
  137. if (modinput) {
  138. // but if we got modulation data, update the phase
  139. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  140. mod = modinput->data[i];
  141. ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
  142. }
  143. release(modinput);
  144. } else {
  145. ph += phase_increment * AUDIO_BLOCK_SAMPLES;
  146. }
  147. phase_accumulator = ph;
  148. return;
  149. }
  150. if (modinput) {
  151. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  152. index = ph >> 24;
  153. val1 = AudioWaveformSine[index];
  154. val2 = AudioWaveformSine[index+1];
  155. scale = (ph >> 8) & 0xFFFF;
  156. val2 *= scale;
  157. val1 *= 0x10000 - scale;
  158. //block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16;
  159. block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
  160. // -32768 = no phase increment
  161. // 32767 = double phase increment
  162. mod = modinput->data[i];
  163. ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
  164. //ph += inc + (((int64_t)inc * (mod << 16)) >> 31);
  165. }
  166. release(modinput);
  167. } else {
  168. ph = phase_accumulator;
  169. inc = phase_increment;
  170. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  171. index = ph >> 24;
  172. val1 = AudioWaveformSine[index];
  173. val2 = AudioWaveformSine[index+1];
  174. scale = (ph >> 8) & 0xFFFF;
  175. val2 *= scale;
  176. val1 *= 0x10000 - scale;
  177. block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
  178. ph += inc;
  179. }
  180. }
  181. phase_accumulator = ph;
  182. transmit(block);
  183. release(block);
  184. }
  185. #elif defined(KINETISL)
  186. void AudioSynthWaveformSineModulated::update(void)
  187. {
  188. audio_block_t *block;
  189. block = receiveReadOnly();
  190. if (block) release(block);
  191. }
  192. #endif