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.

356 lines
11KB

  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 140415 - change sin to use Paul's interpolation which is much
  105. // faster than arm's sin function
  106. // PAH 140316 - fix calculation of sample (amplitude error)
  107. // PAH 140314 - change t_hi from int to float
  108. // PAH - add ramp-up and ramp-down to the onset of the wave
  109. // the length is specified in samples
  110. void AudioSynthWaveform::set_ramp_length(int16_t r_length)
  111. {
  112. if(r_length < 0) {
  113. ramp_length = 0;
  114. return;
  115. }
  116. // Don't set the ramp length longer than about 4 milliseconds
  117. if(r_length > 44*4) {
  118. ramp_length = 44*4;
  119. return;
  120. }
  121. ramp_length = r_length;
  122. }
  123. boolean AudioSynthWaveform::begin(float t_amp,float t_hi,short type)
  124. {
  125. tone_type = type;
  126. amplitude(t_amp);
  127. tone_freq = t_hi > 0.0;
  128. if(t_hi <= 0.0)return false;
  129. if(t_hi >= AUDIO_SAMPLE_RATE_EXACT/2)return false;
  130. tone_phase = 0;
  131. frequency(t_hi);
  132. if(0) {
  133. Serial.print("AudioSynthWaveform.begin(tone_amp = ");
  134. Serial.print(t_amp);
  135. Serial.print(", tone_hi = ");
  136. Serial.print(t_hi);
  137. Serial.print(", tone_incr = ");
  138. Serial.print(tone_incr,HEX);
  139. // Serial.print(", tone_hi = ");
  140. // Serial.print(t_hi);
  141. Serial.println(")");
  142. }
  143. return(true);
  144. }
  145. // PAH - 140313 fixed a problem with ramping
  146. void AudioSynthWaveform::update(void)
  147. {
  148. audio_block_t *block;
  149. short *bp;
  150. // temporary for ramp in sine
  151. uint32_t ramp_mag;
  152. int32_t val1, val2, val3;
  153. uint32_t index, scale;
  154. // temporaries for TRIANGLE
  155. uint32_t mag;
  156. short tmp_amp;
  157. if(tone_freq == 0)return;
  158. // L E F T C H A N N E L O N L Y
  159. block = allocate();
  160. if(block) {
  161. bp = block->data;
  162. switch(tone_type) {
  163. case TONE_TYPE_SINE:
  164. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  165. // Calculate interpolated sin
  166. index = tone_phase >> 23;
  167. val1 = AudioWaveformSine[index];
  168. val2 = AudioWaveformSine[index+1];
  169. scale = (tone_phase >> 7) & 0xFFFF;
  170. val2 *= scale;
  171. val1 *= 0xFFFF - scale;
  172. val3 = (val1 + val2) >> 16;
  173. // The value of ramp_up is always initialized to RAMP_LENGTH and then is
  174. // decremented each time through here until it reaches zero.
  175. // The value of ramp_up is used to generate a Q15 fraction which varies
  176. // from [0 - 1), and multiplies this by the current sample
  177. if(ramp_up) {
  178. // ramp up to the new magnitude
  179. // ramp_mag is the Q15 representation of the fraction
  180. // Since ramp_up can't be zero, this cannot generate +1
  181. ramp_mag = ((ramp_length-ramp_up)<<15)/ramp_length;
  182. ramp_up--;
  183. // adjust tone_phase to Q15 format and then adjust the result
  184. // of the multiplication
  185. // calculate the sample
  186. tmp_amp = (short)((val3 * tone_amp) >> 15);
  187. *bp++ = (tmp_amp * ramp_mag)>>15;
  188. }
  189. else if(ramp_down) {
  190. // ramp down to zero from the last magnitude
  191. // The value of ramp_down is always initialized to RAMP_LENGTH and then is
  192. // decremented each time through here until it reaches zero.
  193. // The value of ramp_down is used to generate a Q15 fraction which varies
  194. // from [0 - 1), and multiplies this by the current sample
  195. // avoid RAMP_LENGTH/RAMP_LENGTH because Q15 format
  196. // cannot represent +1
  197. ramp_mag = ((ramp_down - 1)<<15)/ramp_length;
  198. ramp_down--;
  199. tmp_amp = (short)((val3 * last_tone_amp) >> 15);
  200. *bp++ = (tmp_amp * ramp_mag)>>15;
  201. } else {
  202. *bp++ = (short)((val3 * tone_amp) >> 15);
  203. }
  204. // phase and incr are both unsigned 32-bit fractions
  205. tone_phase += tone_incr;
  206. // If tone_phase has overflowed, truncate the top bit
  207. if(tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
  208. }
  209. break;
  210. case TONE_TYPE_SQUARE:
  211. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  212. if(tone_phase & 0x40000000)*bp++ = -tone_amp;
  213. else *bp++ = tone_amp;
  214. // phase and incr are both unsigned 32-bit fractions
  215. tone_phase += tone_incr;
  216. }
  217. break;
  218. case TONE_TYPE_SAWTOOTH:
  219. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  220. *bp++ = ((short)(tone_phase>>15)*tone_amp) >> 15;
  221. // phase and incr are both unsigned 32-bit fractions
  222. tone_phase += tone_incr;
  223. }
  224. break;
  225. case TONE_TYPE_TRIANGLE:
  226. for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
  227. if(tone_phase & 0x80000000) {
  228. // negative half-cycle
  229. tmp_amp = -tone_amp;
  230. }
  231. else {
  232. // positive half-cycle
  233. tmp_amp = tone_amp;
  234. }
  235. mag = tone_phase << 2;
  236. // Determine which quadrant
  237. if(tone_phase & 0x40000000) {
  238. // negate the magnitude
  239. mag = ~mag + 1;
  240. }
  241. *bp++ = ((short)(mag>>17)*tmp_amp) >> 15;
  242. tone_phase += 2*tone_incr;
  243. }
  244. break;
  245. }
  246. // send the samples to the left channel
  247. transmit(block,0);
  248. release(block);
  249. }
  250. }
  251. #endif
  252. #if 0
  253. void AudioSineWaveMod::frequency(float f)
  254. {
  255. if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return;
  256. phase_increment = (f / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  257. }
  258. void AudioSineWaveMod::update(void)
  259. {
  260. audio_block_t *block, *modinput;
  261. uint32_t i, ph, inc, index, scale;
  262. int32_t val1, val2;
  263. //Serial.println("AudioSineWave::update");
  264. modinput = receiveReadOnly();
  265. ph = phase;
  266. inc = phase_increment;
  267. block = allocate();
  268. if (!block) {
  269. // unable to allocate memory, so we'll send nothing
  270. if (modinput) {
  271. // but if we got modulation data, update the phase
  272. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  273. ph += inc + modinput->data[i] * modulation_factor;
  274. }
  275. release(modinput);
  276. } else {
  277. ph += phase_increment * AUDIO_BLOCK_SAMPLES;
  278. }
  279. phase = ph;
  280. return;
  281. }
  282. if (modinput) {
  283. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  284. index = ph >> 24;
  285. val1 = sine_table[index];
  286. val2 = sine_table[index+1];
  287. scale = (ph >> 8) & 0xFFFF;
  288. val2 *= scale;
  289. val1 *= 0xFFFF - scale;
  290. block->data[i] = (val1 + val2) >> 16;
  291. //Serial.print(block->data[i]);
  292. //Serial.print(", ");
  293. //if ((i % 12) == 11) Serial.println();
  294. ph += inc + modinput->data[i] * modulation_factor;
  295. }
  296. release(modinput);
  297. } else {
  298. ph = phase;
  299. inc = phase_increment;
  300. for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
  301. index = ph >> 24;
  302. val1 = sine_table[index];
  303. val2 = sine_table[index+1];
  304. scale = (ph >> 8) & 0xFFFF;
  305. val2 *= scale;
  306. val1 *= 0xFFFF - scale;
  307. block->data[i] = (val1 + val2) >> 16;
  308. //Serial.print(block->data[i]);
  309. //Serial.print(", ");
  310. //if ((i % 12) == 11) Serial.println();
  311. ph += inc;
  312. }
  313. }
  314. phase = ph;
  315. transmit(block);
  316. release(block);
  317. }
  318. #endif