|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
-
-
- #include "play_sd_wav.h"
-
- #define STATE_DIRECT_8BIT_MONO 0
- #define STATE_DIRECT_8BIT_STEREO 1
- #define STATE_DIRECT_16BIT_MONO 2
- #define STATE_DIRECT_16BIT_STEREO 3
- #define STATE_CONVERT_8BIT_MONO 4
- #define STATE_CONVERT_8BIT_STEREO 5
- #define STATE_CONVERT_16BIT_MONO 6
- #define STATE_CONVERT_16BIT_STEREO 7
- #define STATE_PARSE1 8
- #define STATE_PARSE2 9
- #define STATE_PARSE3 10
- #define STATE_PARSE4 11
- #define STATE_STOP 12
-
- void AudioPlaySDcardWAV::begin(void)
- {
- state = STATE_STOP;
- state_play = STATE_STOP;
- data_length = 0;
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
- }
-
-
- bool AudioPlaySDcardWAV::play(const char *filename)
- {
- stop();
- wavfile = SD.open(filename);
- if (!wavfile) return false;
- buffer_remaining = 0;
- state_play = STATE_STOP;
- data_length = 0;
- state = STATE_PARSE1;
- return true;
- }
-
- void AudioPlaySDcardWAV::stop(void)
- {
- __disable_irq();
- if (state != STATE_STOP) {
- audio_block_t *b1 = block_left;
- block_left = NULL;
- audio_block_t *b2 = block_right;
- block_right = NULL;
- state = STATE_STOP;
- __enable_irq();
- if (b1) release(b1);
- if (b2) release(b2);
- wavfile.close();
- } else {
- __enable_irq();
- }
- }
-
- bool AudioPlaySDcardWAV::start(void)
- {
- __disable_irq();
- if (state == STATE_STOP) {
- if (state_play == STATE_STOP) {
- __enable_irq();
- return false;
- }
- state = state_play;
- }
- __enable_irq();
- return true;
- }
-
-
- void AudioPlaySDcardWAV::update(void)
- {
-
- if (state == STATE_STOP) return;
-
-
- block_left = allocate();
- if (block_left == NULL) return;
- if (state < 8 && (state & 1) == 1) {
-
-
- block_right = allocate();
- if (block_right == NULL) {
- release(block_left);
- return;
- }
- } else {
-
-
- block_right = NULL;
- }
- block_offset = 0;
-
-
-
-
- if (buffer_remaining > 0) {
-
- if (consume()) return;
- }
-
-
- if (state != STATE_STOP && wavfile.available()) {
-
- buffer_remaining = wavfile.read(buffer, 512);
- if (consume()) {
-
- return;
- } else {
-
- buffer_remaining = 0;
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
-
-
-
-
- if (state != STATE_STOP) return;
- }
- }
-
- wavfile.close();
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
- state_play = STATE_STOP;
- state = STATE_STOP;
- }
-
-
-
-
-
- bool AudioPlaySDcardWAV::consume(void)
- {
- uint32_t len, size;
- uint8_t lsb, msb;
- const uint8_t *p;
-
- size = buffer_remaining;
- p = buffer + 512 - size;
- start:
- if (size == 0) return false;
-
-
-
-
-
-
- switch (state) {
-
- case STATE_PARSE1:
- len = 20 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 20) return false;
-
- if (header[0] == 0x46464952 && header[2] == 0x45564157
- && header[3] == 0x20746D66 && header[4] == 16) {
-
- state = STATE_PARSE2;
- p += len;
- size -= len;
- data_length = 0;
- goto start;
- }
-
- break;
-
-
- case STATE_PARSE2:
- len = 16 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 16) return false;
- if (parse_format()) {
-
- p += len;
- size -= len;
- data_length = 0;
- state = STATE_PARSE3;
- goto start;
- }
-
- break;
-
-
- case STATE_PARSE3:
- len = 8 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 8) return false;
-
-
-
-
- p += len;
- size -= len;
- data_length = header[1];
- if (header[0] == 0x61746164) {
-
-
-
-
- leftover_bytes = 0;
- state = state_play;
- if (state & 1) {
-
-
- block_right = allocate();
- if (!block_right) return false;
- }
- } else {
- state = STATE_PARSE4;
- }
- goto start;
-
-
- case STATE_PARSE4:
- if (size < data_length) {
- data_length -= size;
- return false;
- }
- p += data_length;
- size -= data_length;
- data_length = 0;
- state = STATE_PARSE3;
- goto start;
-
-
- case STATE_DIRECT_8BIT_MONO:
- return false;
-
-
- case STATE_DIRECT_8BIT_STEREO:
- return false;
-
-
- case STATE_DIRECT_16BIT_MONO:
- if (size > data_length) size = data_length;
- data_length -= size;
- while (1) {
- lsb = *p++;
- msb = *p++;
- size -= 2;
- block_left->data[block_offset++] = (msb << 8) | lsb;
- if (block_offset >= AUDIO_BLOCK_SAMPLES) {
- transmit(block_left, 0);
- transmit(block_left, 1);
-
-
- release(block_left);
- block_left = NULL;
- data_length += size;
- buffer_remaining = size;
- if (block_right) release(block_right);
- return true;
- }
- if (size == 0) {
- if (data_length == 0) break;
- return false;
- }
- }
-
- if (block_offset > 0) {
-
- }
- state = STATE_STOP;
- return false;
-
-
- case STATE_DIRECT_16BIT_STEREO:
- if (size > data_length) size = data_length;
- data_length -= size;
- if (leftover_bytes) {
- block_left->data[block_offset] = header[0];
- goto right16;
- }
- while (1) {
- lsb = *p++;
- msb = *p++;
- size -= 2;
- if (size == 0) {
- if (data_length == 0) break;
- header[0] = (msb << 8) | lsb;
- leftover_bytes = 2;
- return false;
- }
- block_left->data[block_offset] = (msb << 8) | lsb;
- right16:
- lsb = *p++;
- msb = *p++;
- size -= 2;
- block_right->data[block_offset++] = (msb << 8) | lsb;
- if (block_offset >= AUDIO_BLOCK_SAMPLES) {
- transmit(block_left, 0);
- release(block_left);
- block_left = NULL;
- transmit(block_right, 1);
- release(block_right);
- block_right = NULL;
- data_length += size;
- buffer_remaining = size;
- return true;
- }
- if (size == 0) {
- if (data_length == 0) break;
- leftover_bytes = 0;
- return false;
- }
- }
-
- if (block_offset > 0) {
-
- }
- state = STATE_STOP;
- return false;
-
-
- case STATE_CONVERT_8BIT_MONO :
- return false;
-
-
- case STATE_CONVERT_8BIT_STEREO:
- return false;
-
-
- case STATE_CONVERT_16BIT_MONO:
- return false;
-
-
- case STATE_CONVERT_16BIT_STEREO:
- return false;
-
-
-
- case STATE_STOP:
- return false;
-
-
-
-
- }
- state_play = STATE_STOP;
- state = STATE_STOP;
- return false;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bool AudioPlaySDcardWAV::parse_format(void)
- {
- uint8_t num = 0;
- uint16_t format;
- uint16_t channels;
- uint32_t rate;
- uint16_t bits;
-
- format = header[0];
-
-
- if (format != 1) return false;
-
- channels = header[0] >> 16;
-
-
- if (channels == 1) {
- } else if (channels == 2) {
- num = 1;
- } else {
- return false;
- }
-
- bits = header[3] >> 16;
-
-
- if (bits == 8) {
- } else if (bits == 16) {
- num |= 2;
- } else {
- return false;
- }
-
- rate = header[1];
-
-
- if (rate == AUDIO_SAMPLE_RATE) {
- } else if (rate >= 8000 && rate <= 48000) {
- num |= 4;
- } else {
- return false;
- }
-
-
-
-
- state_play = num;
- return true;
- }
-
-
|