Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

164 lines
3.4KB

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