#include "play_memory.h" #include "utility/dspinst.h" void AudioPlayMemory::play(const unsigned int *data) { uint32_t format; playing = 0; prior = 0; format = *data++; next = data; length = format & 0xFFFFFF; playing = format >> 24; } void AudioPlayMemory::stop(void) { playing = 0; } extern "C" { extern const int16_t ulaw_decode_table[256]; }; void AudioPlayMemory::update(void) { audio_block_t *block; const unsigned int *in; int16_t *out; uint32_t tmp32, consumed; int16_t s0, s1, s2, s3, s4; int i; if (!playing) return; block = allocate(); if (block == NULL) return; //Serial.write('.'); out = block->data; in = next; s0 = prior; switch (playing) { case 0x01: // u-law encoded, 44100 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) { tmp32 = *in++; *out++ = ulaw_decode_table[(tmp32 >> 0) & 255]; *out++ = ulaw_decode_table[(tmp32 >> 8) & 255]; *out++ = ulaw_decode_table[(tmp32 >> 16) & 255]; *out++ = ulaw_decode_table[(tmp32 >> 24) & 255]; } consumed = 128; break; case 0x81: // 16 bit PCM, 44100 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 2) { tmp32 = *in++; *out++ = (int16_t)(tmp32 & 65535); *out++ = (int16_t)(tmp32 >> 16); } consumed = 128; break; case 0x02: // u-law encoded, 22050 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) { tmp32 = *in++; s1 = ulaw_decode_table[(tmp32 >> 0) & 255]; s2 = ulaw_decode_table[(tmp32 >> 8) & 255]; s3 = ulaw_decode_table[(tmp32 >> 16) & 255]; s4 = ulaw_decode_table[(tmp32 >> 24) & 255]; *out++ = (s0 + s1) >> 1; *out++ = s1; *out++ = (s1 + s2) >> 1; *out++ = s2; *out++ = (s2 + s3) >> 1; *out++ = s3; *out++ = (s3 + s4) >> 1; *out++ = s4; s0 = s4; } consumed = 64; break; case 0x82: // 16 bits PCM, 22050 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) { tmp32 = *in++; s1 = (int16_t)(tmp32 & 65535); s2 = (int16_t)(tmp32 >> 16); *out++ = (s0 + s1) >> 1; *out++ = s1; *out++ = (s1 + s2) >> 1; *out++ = s2; s0 = s2; } consumed = 64; break; case 0x03: // u-law encoded, 11025 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 16) { tmp32 = *in++; s1 = ulaw_decode_table[(tmp32 >> 0) & 255]; s2 = ulaw_decode_table[(tmp32 >> 8) & 255]; s3 = ulaw_decode_table[(tmp32 >> 16) & 255]; s4 = ulaw_decode_table[(tmp32 >> 24) & 255]; *out++ = (s0 * 3 + s1) >> 2; *out++ = (s0 + s1) >> 1; *out++ = (s0 + s1 * 3) >> 2; *out++ = s1; *out++ = (s1 * 3 + s2) >> 2; *out++ = (s1 + s2) >> 1; *out++ = (s1 + s2 * 3) >> 2; *out++ = s2; *out++ = (s2 * 3 + s3) >> 2; *out++ = (s2 + s3) >> 1; *out++ = (s2 + s3 * 3) >> 2; *out++ = s3; *out++ = (s3 * 3 + s4) >> 2; *out++ = (s3 + s4) >> 1; *out++ = (s3 + s4 * 3) >> 2; *out++ = s4; s0 = s4; } consumed = 32; break; case 0x83: // 16 bit PCM, 11025 Hz for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) { tmp32 = *in++; s1 = (int16_t)(tmp32 & 65535); s2 = (int16_t)(tmp32 >> 16); *out++ = (s0 * 3 + s1) >> 2; *out++ = (s0 + s1) >> 1; *out++ = (s0 + s1 * 3) >> 2; *out++ = s1; *out++ = (s1 * 3 + s2) >> 2; *out++ = (s1 + s2) >> 1; *out++ = (s1 + s2 * 3) >> 2; *out++ = s2; s0 = s2; } consumed = 32; break; default: release(block); playing = 0; return; } prior = s0; next = in; if (length > consumed) { length -= consumed; } else { playing = 0; } transmit(block); release(block); }