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.

342 lines
10KB

  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 "synth_waveform.h"
  27. #include "arm_math.h"
  28. #include "utility/dspinst.h"
  29. #ifdef ORIGINAL_AUDIOSYNTHWAVEFORM
  30. /******************************************************************/
  31. // PAH - add ramp-up and ramp-down to the onset of the wave
  32. // the length is specified in samples
  33. void AudioSynthWaveform::set_ramp_length(uint16_t r_length)
  34. {
  35. if(r_length < 0) {
  36. ramp_length = 0;
  37. return;
  38. }
  39. // Don't set the ramp length longer than about 4 milliseconds
  40. if(r_length > 44*4) {
  41. ramp_length = 44*4;
  42. return;
  43. }
  44. ramp_length = r_length;
  45. }
  46. void AudioSynthWaveform::update(void)
  47. {
  48. audio_block_t *block;
  49. uint32_t i, ph, inc, index, scale;
  50. int32_t val1, val2, val3;
  51. //Serial.println("AudioSynthWaveform::update");
  52. if (((magnitude > 0) || ramp_down) && (block = allocate()) != NULL) {
  53. ph = phase;
  54. inc = phase_increment;
  55. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  56. index = ph >> 24;
  57. val1 = wavetable[index];
  58. val2 = wavetable[index+1];
  59. scale = (ph >> 8) & 0xFFFF;
  60. val2 *= scale;
  61. val1 *= 0xFFFF - scale;
  62. val3 = (val1 + val2) >> 16;
  63. // The value of ramp_up is always initialized to RAMP_LENGTH and then is
  64. // decremented each time through here until it reaches zero.
  65. // The value of ramp_up is used to generate a Q15 fraction which varies
  66. // from [0 - 1), and multiplies this by the current sample
  67. if(ramp_up) {
  68. // ramp up to the new magnitude
  69. // ramp_mag is the Q15 representation of the fraction
  70. // Since ramp_up can't be zero, this cannot generate +1
  71. ramp_mag = ((ramp_length-ramp_up)<<15)/ramp_length;
  72. ramp_up--;
  73. block->data[i] = (val3 * ((ramp_mag * magnitude)>>15)) >> 15;
  74. } else if(ramp_down) {
  75. // ramp down to zero from the last magnitude
  76. // The value of ramp_down is always initialized to RAMP_LENGTH and then is
  77. // decremented each time through here until it reaches zero.
  78. // The value of ramp_down is used to generate a Q15 fraction which varies
  79. // from (1 - 0], and multiplies this by the current sample
  80. // avoid RAMP_LENGTH/RAMP_LENGTH because Q15 format
  81. // cannot represent +1
  82. ramp_mag = ((ramp_down - 1)<<15)/ramp_length;
  83. ramp_down--;
  84. block->data[i] = (val3 * ((ramp_mag * last_magnitude)>>15)) >> 15;
  85. } else {
  86. block->data[i] = (val3 * magnitude) >> 15;
  87. }
  88. //Serial.print(block->data[i]);
  89. //Serial.print(", ");
  90. //if ((i % 12) == 11) Serial.println();
  91. ph += inc;
  92. }
  93. //Serial.println();
  94. phase = ph;
  95. transmit(block);
  96. release(block);
  97. } else {
  98. // is this numerical overflow ok?
  99. phase += phase_increment * AUDIO_BLOCK_SAMPLES;
  100. }
  101. }
  102. #else
  103. /******************************************************************/
  104. // PAH - add ramp-up and ramp-down to the onset of the wave
  105. // the length is specified in samples
  106. void AudioSynthWaveform::set_ramp_length(uint16_t r_length)
  107. {
  108. if(r_length < 0) {
  109. ramp_length = 0;
  110. return;
  111. }
  112. // Don't set the ramp length longer than about 4 milliseconds
  113. if(r_length > 44*4) {
  114. ramp_length = 44*4;
  115. return;
  116. }
  117. ramp_length = r_length;
  118. }
  119. boolean AudioSynthWaveform::begin(float t_amp,int t_hi,short type)
  120. {
  121. tone_type = type;
  122. // tone_amp = t_amp;
  123. amplitude(t_amp);
  124. tone_freq = t_hi;
  125. if(t_hi < 1)return false;
  126. if(t_hi >= AUDIO_SAMPLE_RATE_EXACT/2)return false;
  127. tone_phase = 0;
  128. tone_incr = (0x100000000LL*t_hi)/AUDIO_SAMPLE_RATE_EXACT;
  129. if(0) {
  130. Serial.print("AudioSynthWaveform.begin(tone_amp = ");
  131. Serial.print(t_amp);
  132. Serial.print(", tone_hi = ");
  133. Serial.print(t_hi);
  134. Serial.print(", tone_incr = ");
  135. Serial.print(tone_incr,HEX);
  136. // Serial.print(", tone_hi = ");
  137. // Serial.print(t_hi);
  138. Serial.println(")");
  139. }
  140. return(true);
  141. }
  142. void AudioSynthWaveform::update(void)
  143. {
  144. audio_block_t *block;
  145. short *bp;
  146. // temporary for ramp in sine
  147. uint32_t ramp_mag;
  148. // temporaries for TRIANGLE
  149. uint32_t mag;
  150. short tmp_amp;
  151. if(tone_freq == 0)return;
  152. // L E F T C H A N N E L O N L Y
  153. block = allocate();
  154. if(block) {
  155. bp = block->data;
  156. switch(tone_type) {
  157. case TONE_TYPE_SINE:
  158. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  159. // The value of ramp_up is always initialized to RAMP_LENGTH and then is
  160. // decremented each time through here until it reaches zero.
  161. // The value of ramp_up is used to generate a Q15 fraction which varies
  162. // from [0 - 1), and multiplies this by the current sample
  163. if(ramp_up) {
  164. // ramp up to the new magnitude
  165. // ramp_mag is the Q15 representation of the fraction
  166. // Since ramp_up can't be zero, this cannot generate +1
  167. ramp_mag = ((ramp_length-ramp_up)<<15)/ramp_length;
  168. ramp_up--;
  169. // adjust tone_phase to Q15 format and then adjust the result
  170. // of the multiplication
  171. *bp = (short)((arm_sin_q15(tone_phase>>17) * tone_amp) >> 15);
  172. *bp++ = (*bp * ramp_mag)>>15;
  173. }
  174. else if(ramp_down) {
  175. // ramp down to zero from the last magnitude
  176. // The value of ramp_down is always initialized to RAMP_LENGTH and then is
  177. // decremented each time through here until it reaches zero.
  178. // The value of ramp_down is used to generate a Q15 fraction which varies
  179. // from (1 - 0], and multiplies this by the current sample
  180. // avoid RAMP_LENGTH/RAMP_LENGTH because Q15 format
  181. // cannot represent +1
  182. ramp_mag = ((ramp_down - 1)<<15)/ramp_length;
  183. ramp_down--;
  184. // adjust tone_phase to Q15 format and then adjust the result
  185. // of the multiplication
  186. *bp = (short)((arm_sin_q15(tone_phase>>17) * last_tone_amp) >> 15);
  187. *bp++ = (*bp * ramp_mag)>>15;
  188. } else {
  189. // adjust tone_phase to Q15 format and then adjust the result
  190. // of the multiplication
  191. *bp++ = (short)((arm_sin_q15(tone_phase>>17) * tone_amp) >> 15);
  192. }
  193. // phase and incr are both unsigned 32-bit fractions
  194. tone_phase += tone_incr;
  195. }
  196. break;
  197. case TONE_TYPE_SQUARE:
  198. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  199. if(tone_phase & 0x80000000)*bp++ = -tone_amp;
  200. else *bp++ = tone_amp;
  201. // phase and incr are both unsigned 32-bit fractions
  202. tone_phase += tone_incr;
  203. }
  204. break;
  205. case TONE_TYPE_SAWTOOTH:
  206. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  207. *bp = ((short)(tone_phase>>16)*tone_amp) >> 15;
  208. bp++;
  209. // phase and incr are both unsigned 32-bit fractions
  210. tone_phase += tone_incr;
  211. }
  212. break;
  213. case TONE_TYPE_TRIANGLE:
  214. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  215. if(tone_phase & 0x80000000) {
  216. // negative half-cycle
  217. tmp_amp = -tone_amp;
  218. }
  219. else {
  220. // positive half-cycle
  221. tmp_amp = tone_amp;
  222. }
  223. mag = tone_phase << 2;
  224. // Determine which quadrant
  225. if(tone_phase & 0x40000000) {
  226. // negate the magnitude
  227. mag = ~mag + 1;
  228. }
  229. *bp++ = ((short)(mag>>17)*tmp_amp) >> 15;
  230. tone_phase += tone_incr;
  231. }
  232. break;
  233. }
  234. // send the samples to the left channel
  235. transmit(block,0);
  236. release(block);
  237. }
  238. }
  239. #endif
  240. #if 0
  241. void AudioSineWaveMod::frequency(float f)
  242. {
  243. if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return;
  244. phase_increment = (f / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  245. }
  246. void AudioSineWaveMod::update(void)
  247. {
  248. audio_block_t *block, *modinput;
  249. uint32_t i, ph, inc, index, scale;
  250. int32_t val1, val2;
  251. //Serial.println("AudioSineWave::update");
  252. modinput = receiveReadOnly();
  253. ph = phase;
  254. inc = phase_increment;
  255. block = allocate();
  256. if (!block) {
  257. // unable to allocate memory, so we'll send nothing
  258. if (modinput) {
  259. // but if we got modulation data, update the phase
  260. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  261. ph += inc + modinput->data[i] * modulation_factor;
  262. }
  263. release(modinput);
  264. } else {
  265. ph += phase_increment * AUDIO_BLOCK_SAMPLES;
  266. }
  267. phase = ph;
  268. return;
  269. }
  270. if (modinput) {
  271. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  272. index = ph >> 24;
  273. val1 = sine_table[index];
  274. val2 = sine_table[index+1];
  275. scale = (ph >> 8) & 0xFFFF;
  276. val2 *= scale;
  277. val1 *= 0xFFFF - scale;
  278. block->data[i] = (val1 + val2) >> 16;
  279. //Serial.print(block->data[i]);
  280. //Serial.print(", ");
  281. //if ((i % 12) == 11) Serial.println();
  282. ph += inc + modinput->data[i] * modulation_factor;
  283. }
  284. release(modinput);
  285. } else {
  286. ph = phase;
  287. inc = phase_increment;
  288. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  289. index = ph >> 24;
  290. val1 = sine_table[index];
  291. val2 = sine_table[index+1];
  292. scale = (ph >> 8) & 0xFFFF;
  293. val2 *= scale;
  294. val1 *= 0xFFFF - scale;
  295. block->data[i] = (val1 + val2) >> 16;
  296. //Serial.print(block->data[i]);
  297. //Serial.print(", ");
  298. //if ((i % 12) == 11) Serial.println();
  299. ph += inc;
  300. }
  301. }
  302. phase = ph;
  303. transmit(block);
  304. release(block);
  305. }
  306. #endif