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_waveform.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2018, 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_waveform.h"
  28. #include "arm_math.h"
  29. #include "utility/dspinst.h"
  30. // uncomment for more accurate but more computationally expensive frequency modulation
  31. //#define IMPROVE_EXPONENTIAL_ACCURACY
  32. void AudioSynthWaveform::update(void)
  33. {
  34. audio_block_t *block;
  35. int16_t *bp, *end;
  36. int32_t val1, val2;
  37. int16_t magnitude15;
  38. uint32_t i, ph, index, index2, scale;
  39. const uint32_t inc = phase_increment;
  40. ph = phase_accumulator + phase_offset;
  41. if (magnitude == 0) {
  42. phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
  43. return;
  44. }
  45. block = allocate();
  46. if (!block) {
  47. phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
  48. return;
  49. }
  50. bp = block->data;
  51. switch(tone_type) {
  52. case WAVEFORM_SINE:
  53. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  54. index = ph >> 24;
  55. val1 = AudioWaveformSine[index];
  56. val2 = AudioWaveformSine[index+1];
  57. scale = (ph >> 8) & 0xFFFF;
  58. val2 *= scale;
  59. val1 *= 0x10000 - scale;
  60. *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
  61. ph += inc;
  62. }
  63. break;
  64. case WAVEFORM_ARBITRARY:
  65. if (!arbdata) {
  66. release(block);
  67. phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
  68. return;
  69. }
  70. // len = 256
  71. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  72. index = ph >> 24;
  73. index2 = index + 1;
  74. if (index2 >= 256) index2 = 0;
  75. val1 = *(arbdata + index);
  76. val2 = *(arbdata + index2);
  77. scale = (ph >> 8) & 0xFFFF;
  78. val2 *= scale;
  79. val1 *= 0x10000 - scale;
  80. *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
  81. ph += inc;
  82. }
  83. break;
  84. case WAVEFORM_SQUARE:
  85. magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
  86. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  87. if (ph & 0x80000000) {
  88. *bp++ = -magnitude15;
  89. } else {
  90. *bp++ = magnitude15;
  91. }
  92. ph += inc;
  93. }
  94. break;
  95. case WAVEFORM_SAWTOOTH:
  96. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  97. *bp++ = signed_multiply_32x16t(magnitude, ph);
  98. ph += inc;
  99. }
  100. break;
  101. case WAVEFORM_SAWTOOTH_REVERSE:
  102. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  103. *bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, ph);
  104. ph += inc;
  105. }
  106. break;
  107. case WAVEFORM_TRIANGLE:
  108. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  109. uint32_t phtop = ph >> 30;
  110. if (phtop == 1 || phtop == 2) {
  111. *bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
  112. } else {
  113. *bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
  114. }
  115. ph += inc;
  116. }
  117. break;
  118. case WAVEFORM_TRIANGLE_VARIABLE:
  119. do {
  120. uint32_t rise = 0xFFFFFFFF / (pulse_width >> 16);
  121. uint32_t fall = 0xFFFFFFFF / (0xFFFF - (pulse_width >> 16));
  122. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  123. if (ph < pulse_width/2) {
  124. uint32_t n = (ph >> 16) * rise;
  125. *bp++ = ((n >> 16) * magnitude) >> 16;
  126. } else if (ph < 0xFFFFFFFF - pulse_width/2) {
  127. uint32_t n = 0x7FFFFFFF - (((ph - pulse_width/2) >> 16) * fall);
  128. *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
  129. } else {
  130. uint32_t n = ((ph + pulse_width/2) >> 16) * rise + 0x80000000;
  131. *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
  132. }
  133. ph += inc;
  134. }
  135. } while (0);
  136. break;
  137. case WAVEFORM_PULSE:
  138. magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
  139. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  140. if (ph < pulse_width) {
  141. *bp++ = magnitude15;
  142. } else {
  143. *bp++ = -magnitude15;
  144. }
  145. ph += inc;
  146. }
  147. break;
  148. case WAVEFORM_SAMPLE_HOLD:
  149. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  150. *bp++ = sample;
  151. uint32_t newph = ph + inc;
  152. if (newph < ph) {
  153. sample = random(magnitude) - (magnitude >> 1);
  154. }
  155. ph = newph;
  156. }
  157. break;
  158. }
  159. phase_accumulator = ph - phase_offset;
  160. if (tone_offset) {
  161. bp = block->data;
  162. end = bp + AUDIO_BLOCK_SAMPLES;
  163. do {
  164. val1 = *bp;
  165. *bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
  166. } while (bp < end);
  167. }
  168. transmit(block, 0);
  169. release(block);
  170. }
  171. //--------------------------------------------------------------------------------
  172. void AudioSynthWaveformModulated::update(void)
  173. {
  174. audio_block_t *block, *moddata, *shapedata;
  175. int16_t *bp, *end;
  176. int32_t val1, val2;
  177. int16_t magnitude15;
  178. uint32_t i, ph, index, index2, scale, priorphase;
  179. const uint32_t inc = phase_increment;
  180. moddata = receiveReadOnly(0);
  181. shapedata = receiveReadOnly(1);
  182. // Pre-compute the phase angle for every output sample of this update
  183. ph = phase_accumulator;
  184. priorphase = phasedata[AUDIO_BLOCK_SAMPLES-1];
  185. if (moddata && modulation_type == 0) {
  186. // Frequency Modulation
  187. bp = moddata->data;
  188. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  189. int32_t n = (*bp++) * modulation_factor; // n is # of octaves to mod
  190. int32_t ipart = n >> 27; // 4 integer bits
  191. n &= 0x7FFFFFF; // 27 fractional bits
  192. #ifdef IMPROVE_EXPONENTIAL_ACCURACY
  193. // exp2 polynomial suggested by Stefan Stenzel on "music-dsp"
  194. // mail list, Wed, 3 Sep 2014 10:08:55 +0200
  195. int32_t x = n << 3;
  196. n = multiply_accumulate_32x32_rshift32_rounded(536870912, x, 1494202713);
  197. int32_t sq = multiply_32x32_rshift32_rounded(x, x);
  198. n = multiply_accumulate_32x32_rshift32_rounded(n, sq, 1934101615);
  199. n = n + (multiply_32x32_rshift32_rounded(sq,
  200. multiply_32x32_rshift32_rounded(x, 1358044250)) << 1);
  201. n = n << 1;
  202. #else
  203. // exp2 algorithm by Laurent de Soras
  204. // https://www.musicdsp.org/en/latest/Other/106-fast-exp2-approximation.html
  205. n = (n + 134217728) << 3;
  206. n = multiply_32x32_rshift32_rounded(n, n);
  207. n = multiply_32x32_rshift32_rounded(n, 715827883) << 3;
  208. n = n + 715827882;
  209. #endif
  210. uint32_t scale = n >> (14 - ipart);
  211. uint64_t phstep = (uint64_t)inc * scale;
  212. uint32_t phstep_msw = phstep >> 32;
  213. if (phstep_msw < 0x7FFE) {
  214. ph += phstep >> 16;
  215. } else {
  216. ph += 0x7FFE0000;
  217. }
  218. phasedata[i] = ph;
  219. }
  220. release(moddata);
  221. } else if (moddata) {
  222. // Phase Modulation
  223. bp = moddata->data;
  224. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  225. // more than +/- 180 deg shift by 32 bit overflow of "n"
  226. uint32_t n = (uint16_t)(*bp++) * modulation_factor;
  227. phasedata[i] = ph + n;
  228. ph += inc;
  229. }
  230. release(moddata);
  231. } else {
  232. // No Modulation Input
  233. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  234. phasedata[i] = ph;
  235. ph += inc;
  236. }
  237. }
  238. phase_accumulator = ph;
  239. // If the amplitude is zero, no output, but phase still increments properly
  240. if (magnitude == 0) {
  241. if (shapedata) release(shapedata);
  242. return;
  243. }
  244. block = allocate();
  245. if (!block) {
  246. if (shapedata) release(shapedata);
  247. return;
  248. }
  249. bp = block->data;
  250. // Now generate the output samples using the pre-computed phase angles
  251. switch(tone_type) {
  252. case WAVEFORM_SINE:
  253. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  254. ph = phasedata[i];
  255. index = ph >> 24;
  256. val1 = AudioWaveformSine[index];
  257. val2 = AudioWaveformSine[index+1];
  258. scale = (ph >> 8) & 0xFFFF;
  259. val2 *= scale;
  260. val1 *= 0x10000 - scale;
  261. *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
  262. }
  263. break;
  264. case WAVEFORM_ARBITRARY:
  265. if (!arbdata) {
  266. release(block);
  267. if (shapedata) release(shapedata);
  268. return;
  269. }
  270. // len = 256
  271. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  272. ph = phasedata[i];
  273. index = ph >> 24;
  274. index2 = index + 1;
  275. if (index2 >= 256) index2 = 0;
  276. val1 = *(arbdata + index);
  277. val2 = *(arbdata + index2);
  278. scale = (ph >> 8) & 0xFFFF;
  279. val2 *= scale;
  280. val1 *= 0x10000 - scale;
  281. *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
  282. }
  283. break;
  284. case WAVEFORM_PULSE:
  285. if (shapedata) {
  286. magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
  287. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  288. uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16;
  289. if (phasedata[i] < width) {
  290. *bp++ = magnitude15;
  291. } else {
  292. *bp++ = -magnitude15;
  293. }
  294. }
  295. break;
  296. } // else fall through to orginary square without shape modulation
  297. case WAVEFORM_SQUARE:
  298. magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
  299. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  300. if (phasedata[i] & 0x80000000) {
  301. *bp++ = -magnitude15;
  302. } else {
  303. *bp++ = magnitude15;
  304. }
  305. }
  306. break;
  307. case WAVEFORM_SAWTOOTH:
  308. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  309. *bp++ = signed_multiply_32x16t(magnitude, phasedata[i]);
  310. }
  311. break;
  312. case WAVEFORM_SAWTOOTH_REVERSE:
  313. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  314. *bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, phasedata[i]);
  315. }
  316. break;
  317. case WAVEFORM_TRIANGLE_VARIABLE:
  318. if (shapedata) {
  319. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  320. uint32_t width = (shapedata->data[i] + 0x8000) & 0xFFFF;
  321. uint32_t rise = 0xFFFFFFFF / width;
  322. uint32_t fall = 0xFFFFFFFF / (0xFFFF - width);
  323. uint32_t halfwidth = width << 15;
  324. uint32_t n;
  325. ph = phasedata[i];
  326. if (ph < halfwidth) {
  327. n = (ph >> 16) * rise;
  328. *bp++ = ((n >> 16) * magnitude) >> 16;
  329. } else if (ph < 0xFFFFFFFF - halfwidth) {
  330. n = 0x7FFFFFFF - (((ph - halfwidth) >> 16) * fall);
  331. *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
  332. } else {
  333. n = ((ph + halfwidth) >> 16) * rise + 0x80000000;
  334. *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
  335. }
  336. ph += inc;
  337. }
  338. break;
  339. } // else fall through to orginary triangle without shape modulation
  340. case WAVEFORM_TRIANGLE:
  341. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  342. ph = phasedata[i];
  343. uint32_t phtop = ph >> 30;
  344. if (phtop == 1 || phtop == 2) {
  345. *bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
  346. } else {
  347. *bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
  348. }
  349. }
  350. break;
  351. case WAVEFORM_SAMPLE_HOLD:
  352. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  353. ph = phasedata[i];
  354. if (ph < priorphase) { // does not work for phase modulation
  355. sample = random(magnitude) - (magnitude >> 1);
  356. }
  357. priorphase = ph;
  358. *bp++ = sample;
  359. }
  360. break;
  361. }
  362. if (tone_offset) {
  363. bp = block->data;
  364. end = bp + AUDIO_BLOCK_SAMPLES;
  365. do {
  366. val1 = *bp;
  367. *bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
  368. } while (bp < end);
  369. }
  370. if (shapedata) release(shapedata);
  371. transmit(block, 0);
  372. release(block);
  373. }