您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

166 行
3.4KB

  1. #include "Audio.h"
  2. #include "arm_math.h"
  3. #include "utility/dspinst.h"
  4. void AudioPlayMemory::play(const unsigned int *data)
  5. {
  6. uint32_t format;
  7. playing = 0;
  8. prior = 0;
  9. format = *data++;
  10. next = data;
  11. length = format & 0xFFFFFF;
  12. playing = format >> 24;
  13. }
  14. void AudioPlayMemory::stop(void)
  15. {
  16. playing = 0;
  17. }
  18. extern "C" {
  19. extern const int16_t ulaw_decode_table[256];
  20. };
  21. void AudioPlayMemory::update(void)
  22. {
  23. audio_block_t *block;
  24. const unsigned int *in;
  25. int16_t *out;
  26. uint32_t tmp32, consumed;
  27. int16_t s0, s1, s2, s3, s4;
  28. int i;
  29. if (!playing) return;
  30. block = allocate();
  31. if (block == NULL) return;
  32. //Serial.write('.');
  33. out = block->data;
  34. in = next;
  35. s0 = prior;
  36. switch (playing) {
  37. case 0x01: // u-law encoded, 44100 Hz
  38. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
  39. tmp32 = *in++;
  40. *out++ = ulaw_decode_table[(tmp32 >> 0) & 255];
  41. *out++ = ulaw_decode_table[(tmp32 >> 8) & 255];
  42. *out++ = ulaw_decode_table[(tmp32 >> 16) & 255];
  43. *out++ = ulaw_decode_table[(tmp32 >> 24) & 255];
  44. }
  45. consumed = 128;
  46. break;
  47. case 0x81: // 16 bit PCM, 44100 Hz
  48. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 2) {
  49. tmp32 = *in++;
  50. *out++ = (int16_t)(tmp32 & 65535);
  51. *out++ = (int16_t)(tmp32 >> 16);
  52. }
  53. consumed = 128;
  54. break;
  55. case 0x02: // u-law encoded, 22050 Hz
  56. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
  57. tmp32 = *in++;
  58. s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
  59. s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
  60. s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
  61. s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
  62. *out++ = (s0 + s1) >> 1;
  63. *out++ = s1;
  64. *out++ = (s1 + s2) >> 1;
  65. *out++ = s2;
  66. *out++ = (s2 + s3) >> 1;
  67. *out++ = s3;
  68. *out++ = (s3 + s4) >> 1;
  69. *out++ = s4;
  70. s0 = s4;
  71. }
  72. consumed = 64;
  73. break;
  74. case 0x82: // 16 bits PCM, 22050 Hz
  75. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
  76. tmp32 = *in++;
  77. s1 = (int16_t)(tmp32 & 65535);
  78. s2 = (int16_t)(tmp32 >> 16);
  79. *out++ = (s0 + s1) >> 1;
  80. *out++ = s1;
  81. *out++ = (s1 + s2) >> 1;
  82. *out++ = s2;
  83. s0 = s2;
  84. }
  85. consumed = 64;
  86. break;
  87. case 0x03: // u-law encoded, 11025 Hz
  88. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 16) {
  89. tmp32 = *in++;
  90. s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
  91. s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
  92. s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
  93. s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
  94. *out++ = (s0 * 3 + s1) >> 2;
  95. *out++ = (s0 + s1) >> 1;
  96. *out++ = (s0 + s1 * 3) >> 2;
  97. *out++ = s1;
  98. *out++ = (s1 * 3 + s2) >> 2;
  99. *out++ = (s1 + s2) >> 1;
  100. *out++ = (s1 + s2 * 3) >> 2;
  101. *out++ = s2;
  102. *out++ = (s2 * 3 + s3) >> 2;
  103. *out++ = (s2 + s3) >> 1;
  104. *out++ = (s2 + s3 * 3) >> 2;
  105. *out++ = s3;
  106. *out++ = (s3 * 3 + s4) >> 2;
  107. *out++ = (s3 + s4) >> 1;
  108. *out++ = (s3 + s4 * 3) >> 2;
  109. *out++ = s4;
  110. s0 = s4;
  111. }
  112. consumed = 32;
  113. break;
  114. case 0x83: // 16 bit PCM, 11025 Hz
  115. for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
  116. tmp32 = *in++;
  117. s1 = (int16_t)(tmp32 & 65535);
  118. s2 = (int16_t)(tmp32 >> 16);
  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. s0 = s2;
  128. }
  129. consumed = 32;
  130. break;
  131. default:
  132. release(block);
  133. playing = 0;
  134. return;
  135. }
  136. prior = s0;
  137. next = in;
  138. if (length > consumed) {
  139. length -= consumed;
  140. } else {
  141. playing = 0;
  142. }
  143. transmit(block);
  144. release(block);
  145. }