Browse Source

WAV file parsing to handle extended format headers

dds
PaulStoffregen 10 years ago
parent
commit
febe2e85c4
2 changed files with 36 additions and 22 deletions
  1. +32
    -19
      play_sd_wav.cpp
  2. +4
    -3
      play_sd_wav.h

+ 32
- 19
play_sd_wav.cpp View File

buffer_length = 0; buffer_length = 0;
buffer_offset = 0; buffer_offset = 0;
state_play = STATE_STOP; state_play = STATE_STOP;
data_length = 0;
data_length = 20;
header_offset = 0;
state = STATE_PARSE1; state = STATE_PARSE1;
return true; return true;
} }
//Serial.print(", data_length = "); //Serial.print(", data_length = ");
//Serial.print(data_length); //Serial.print(data_length);
//Serial.print(", space = "); //Serial.print(", space = ");
//Serial.println((AUDIO_BLOCK_SAMPLES - block_offset) * 2);
//Serial.print((AUDIO_BLOCK_SAMPLES - block_offset) * 2);
//Serial.print(", state = "); //Serial.print(", state = ");
//Serial.println(state); //Serial.println(state);
switch (state) { switch (state) {
// parse wav file header, is this really a .wav file? // parse wav file header, is this really a .wav file?
case STATE_PARSE1: case STATE_PARSE1:
len = 20 - data_length;
len = data_length;
if (size < len) len = size; if (size < len) len = size;
memcpy((uint8_t *)header + data_length, p, len);
data_length += len;
memcpy((uint8_t *)header + header_offset, p, len);
header_offset += len;
buffer_offset += len; buffer_offset += len;
buffer_length -= len; buffer_length -= len;
if (data_length < 20) return false;
data_length -= len;
if (data_length > 0) return false;
// parse the header... // parse the header...
if (header[0] == 0x46464952 && header[2] == 0x45564157 if (header[0] == 0x46464952 && header[2] == 0x45564157
&& header[3] == 0x20746D66 && header[4] == 16) {
&& header[3] == 0x20746D66 && header[4] >= 16) {
if (header[4] > sizeof(header)) {
// if such .wav files exist, increasing the
// size of header[] should accomodate them...
//Serial.println("WAVEFORMATEXTENSIBLE too long");
break;
}
//Serial.println("header ok"); //Serial.println("header ok");
state = STATE_PARSE2;
p += len; p += len;
size -= len; size -= len;
data_length = 0;
data_length = header[4];
header_offset = 0;
state = STATE_PARSE2;
goto start; goto start;
} }
//Serial.println("unknown WAV header"); //Serial.println("unknown WAV header");


// check & extract key audio parameters // check & extract key audio parameters
case STATE_PARSE2: case STATE_PARSE2:
len = 16 - data_length;
len = data_length;
if (size < len) len = size; if (size < len) len = size;
memcpy((uint8_t *)header + data_length, p, len);
data_length += len;
memcpy((uint8_t *)header + header_offset, p, len);
header_offset += len;
buffer_offset += len; buffer_offset += len;
buffer_length -= len; buffer_length -= len;
if (data_length < 16) return false;
data_length -= len;
if (data_length > 0) return false;
if (parse_format()) { if (parse_format()) {
//Serial.println("audio format ok"); //Serial.println("audio format ok");
p += len; p += len;
size -= len; size -= len;
data_length = 0;
data_length = 8;
header_offset = 0;
state = STATE_PARSE3; state = STATE_PARSE3;
goto start; goto start;
} }


// find the data chunk // find the data chunk
case STATE_PARSE3: // 10 case STATE_PARSE3: // 10
len = 8 - data_length;
len = data_length;
if (size < len) len = size; if (size < len) len = size;
memcpy((uint8_t *)header + data_length, p, len);
data_length += len;
memcpy((uint8_t *)header + header_offset, p, len);
header_offset += len;
buffer_offset += len; buffer_offset += len;
buffer_length -= len; buffer_length -= len;
if (data_length < 8) return false;
data_length -= len;
if (data_length > 0) return false;
//Serial.print("chunk id = "); //Serial.print("chunk id = ");
//Serial.print(header[0], HEX); //Serial.print(header[0], HEX);
//Serial.print(", length = "); //Serial.print(", length = ");
size -= data_length; size -= data_length;
buffer_offset += data_length; buffer_offset += data_length;
buffer_length -= data_length; buffer_length -= data_length;
data_length = 0;
data_length = 8;
header_offset = 0;
state = STATE_PARSE3; state = STATE_PARSE3;
//Serial.println("consumed unknown chunk"); //Serial.println("consumed unknown chunk");
goto start; goto start;

+ 4
- 3
play_sd_wav.h View File

File wavfile; File wavfile;
bool consume(uint32_t size); bool consume(uint32_t size);
bool parse_format(void); bool parse_format(void);
uint32_t header[5];
uint32_t data_length; // number of bytes remaining in data section
uint32_t header[6]; // temporary storage of wav header data
uint32_t data_length; // number of bytes remaining in current section
uint32_t total_length; // number of audio data bytes in file uint32_t total_length; // number of audio data bytes in file
uint32_t bytes2millis; uint32_t bytes2millis;
audio_block_t *block_left; audio_block_t *block_left;
audio_block_t *block_right; audio_block_t *block_right;
uint16_t block_offset; uint16_t block_offset;
uint8_t buffer[512];
uint8_t buffer[512]; // buffer one block of data
uint16_t buffer_offset; uint16_t buffer_offset;
uint16_t buffer_length; uint16_t buffer_length;
uint8_t header_offset; // number of bytes in header[]
uint8_t state; uint8_t state;
uint8_t state_play; uint8_t state_play;
uint8_t leftover_bytes; uint8_t leftover_bytes;

Loading…
Cancel
Save