No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

play_memory.cpp 6.5KB

hace 10 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 "play_memory.h"
  27. #include "utility/dspinst.h"
  28. void AudioPlayMemory::play(const unsigned int *data)
  29. {
  30. uint32_t format;
  31. playing = 0;
  32. prior = 0;
  33. format = *data++;
  34. next = data;
  35. beginning = data;
  36. length = format & 0xFFFFFF;
  37. playing = format >> 24;
  38. }
  39. void AudioPlayMemory::stop(void)
  40. {
  41. playing = 0;
  42. }
  43. extern "C" {
  44. extern const int16_t ulaw_decode_table[256];
  45. };
  46. void AudioPlayMemory::update(void)
  47. {
  48. audio_block_t *block;
  49. const unsigned int *in;
  50. int16_t *out;
  51. uint32_t tmp32, consumed;
  52. int16_t s0, s1, s2, s3, s4;
  53. int i;
  54. if (!playing) return;
  55. block = allocate();
  56. if (block == NULL) return;
  57. //Serial.write('.');
  58. out = block->data;
  59. in = next;
  60. s0 = prior;
  61. switch (playing) {
  62. case 0x01: // u-law encoded, 44100 Hz
  63. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
  64. tmp32 = *in++;
  65. *out++ = ulaw_decode_table[(tmp32 >> 0) & 255];
  66. *out++ = ulaw_decode_table[(tmp32 >> 8) & 255];
  67. *out++ = ulaw_decode_table[(tmp32 >> 16) & 255];
  68. *out++ = ulaw_decode_table[(tmp32 >> 24) & 255];
  69. }
  70. consumed = AUDIO_BLOCK_SAMPLES;
  71. break;
  72. case 0x81: // 16 bit PCM, 44100 Hz
  73. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 2) {
  74. tmp32 = *in++;
  75. *out++ = (int16_t)(tmp32 & 65535);
  76. *out++ = (int16_t)(tmp32 >> 16);
  77. }
  78. consumed = AUDIO_BLOCK_SAMPLES;
  79. break;
  80. case 0x02: // u-law encoded, 22050 Hz
  81. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
  82. tmp32 = *in++;
  83. s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
  84. s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
  85. s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
  86. s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
  87. *out++ = (s0 + s1) >> 1;
  88. *out++ = s1;
  89. *out++ = (s1 + s2) >> 1;
  90. *out++ = s2;
  91. *out++ = (s2 + s3) >> 1;
  92. *out++ = s3;
  93. *out++ = (s3 + s4) >> 1;
  94. *out++ = s4;
  95. s0 = s4;
  96. }
  97. consumed = AUDIO_BLOCK_SAMPLES/2;
  98. break;
  99. case 0x82: // 16 bits PCM, 22050 Hz
  100. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
  101. tmp32 = *in++;
  102. s1 = (int16_t)(tmp32 & 65535);
  103. s2 = (int16_t)(tmp32 >> 16);
  104. *out++ = (s0 + s1) >> 1;
  105. *out++ = s1;
  106. *out++ = (s1 + s2) >> 1;
  107. *out++ = s2;
  108. s0 = s2;
  109. }
  110. consumed = AUDIO_BLOCK_SAMPLES/2;
  111. break;
  112. case 0x03: // u-law encoded, 11025 Hz
  113. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 16) {
  114. tmp32 = *in++;
  115. s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
  116. s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
  117. s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
  118. s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
  119. *out++ = (s0 * 3 + s1) >> 2;
  120. *out++ = (s0 + s1) >> 1;
  121. *out++ = (s0 + s1 * 3) >> 2;
  122. *out++ = s1;
  123. *out++ = (s1 * 3 + s2) >> 2;
  124. *out++ = (s1 + s2) >> 1;
  125. *out++ = (s1 + s2 * 3) >> 2;
  126. *out++ = s2;
  127. *out++ = (s2 * 3 + s3) >> 2;
  128. *out++ = (s2 + s3) >> 1;
  129. *out++ = (s2 + s3 * 3) >> 2;
  130. *out++ = s3;
  131. *out++ = (s3 * 3 + s4) >> 2;
  132. *out++ = (s3 + s4) >> 1;
  133. *out++ = (s3 + s4 * 3) >> 2;
  134. *out++ = s4;
  135. s0 = s4;
  136. }
  137. consumed = AUDIO_BLOCK_SAMPLES/4;
  138. break;
  139. case 0x83: // 16 bit PCM, 11025 Hz
  140. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
  141. tmp32 = *in++;
  142. s1 = (int16_t)(tmp32 & 65535);
  143. s2 = (int16_t)(tmp32 >> 16);
  144. *out++ = (s0 * 3 + s1) >> 2;
  145. *out++ = (s0 + s1) >> 1;
  146. *out++ = (s0 + s1 * 3) >> 2;
  147. *out++ = s1;
  148. *out++ = (s1 * 3 + s2) >> 2;
  149. *out++ = (s1 + s2) >> 1;
  150. *out++ = (s1 + s2 * 3) >> 2;
  151. *out++ = s2;
  152. s0 = s2;
  153. }
  154. consumed = AUDIO_BLOCK_SAMPLES/4;
  155. break;
  156. default:
  157. release(block);
  158. playing = 0;
  159. return;
  160. }
  161. prior = s0;
  162. next = in;
  163. if (length > consumed) {
  164. length -= consumed;
  165. } else {
  166. playing = 0;
  167. }
  168. transmit(block);
  169. release(block);
  170. }
  171. #define B2M_88200 (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0)
  172. #define B2M_44100 (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT) // 97352592
  173. #define B2M_22050 (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT * 2.0)
  174. #define B2M_11025 (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT * 4.0)
  175. uint32_t AudioPlayMemory::positionMillis(void)
  176. {
  177. uint8_t p;
  178. const uint8_t *n, *b;
  179. uint32_t b2m;
  180. __disable_irq();
  181. p = playing;
  182. n = (const uint8_t *)next;
  183. b = (const uint8_t *)beginning;
  184. __enable_irq();
  185. switch (p) {
  186. case 0x81: // 16 bit PCM, 44100 Hz
  187. b2m = B2M_88200; break;
  188. case 0x01: // u-law encoded, 44100 Hz
  189. case 0x82: // 16 bits PCM, 22050 Hz
  190. b2m = B2M_44100; break;
  191. case 0x02: // u-law encoded, 22050 Hz
  192. case 0x83: // 16 bit PCM, 11025 Hz
  193. b2m = B2M_22050; break;
  194. case 0x03: // u-law encoded, 11025 Hz
  195. b2m = B2M_11025; break;
  196. default:
  197. return 0;
  198. }
  199. if (p == 0) return 0;
  200. return ((uint64_t)(n - b) * b2m) >> 32;
  201. }
  202. uint32_t AudioPlayMemory::lengthMillis(void)
  203. {
  204. uint8_t p;
  205. const uint32_t *b;
  206. uint32_t b2m;
  207. __disable_irq();
  208. p = playing;
  209. b = (const uint32_t *)beginning;
  210. __enable_irq();
  211. switch (p) {
  212. case 0x81: // 16 bit PCM, 44100 Hz
  213. case 0x01: // u-law encoded, 44100 Hz
  214. b2m = B2M_44100; break;
  215. case 0x82: // 16 bits PCM, 22050 Hz
  216. case 0x02: // u-law encoded, 22050 Hz
  217. b2m = B2M_22050; break;
  218. case 0x83: // 16 bit PCM, 11025 Hz
  219. case 0x03: // u-law encoded, 11025 Hz
  220. b2m = B2M_11025; break;
  221. default:
  222. return 0;
  223. }
  224. return ((uint64_t)(*(b - 1) & 0xFFFFFF) * b2m) >> 32;
  225. }