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

@@ -64,7 +64,8 @@ bool AudioPlaySdWav::play(const char *filename)
buffer_length = 0;
buffer_offset = 0;
state_play = STATE_STOP;
data_length = 0;
data_length = 20;
header_offset = 0;
state = STATE_PARSE1;
return true;
}
@@ -186,27 +187,35 @@ start:
//Serial.print(", data_length = ");
//Serial.print(data_length);
//Serial.print(", space = ");
//Serial.println((AUDIO_BLOCK_SAMPLES - block_offset) * 2);
//Serial.print((AUDIO_BLOCK_SAMPLES - block_offset) * 2);
//Serial.print(", state = ");
//Serial.println(state);
switch (state) {
// parse wav file header, is this really a .wav file?
case STATE_PARSE1:
len = 20 - data_length;
len = data_length;
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_length -= len;
if (data_length < 20) return false;
data_length -= len;
if (data_length > 0) return false;
// parse the header...
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");
state = STATE_PARSE2;
p += len;
size -= len;
data_length = 0;
data_length = header[4];
header_offset = 0;
state = STATE_PARSE2;
goto start;
}
//Serial.println("unknown WAV header");
@@ -214,18 +223,20 @@ start:

// check & extract key audio parameters
case STATE_PARSE2:
len = 16 - data_length;
len = data_length;
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_length -= len;
if (data_length < 16) return false;
data_length -= len;
if (data_length > 0) return false;
if (parse_format()) {
//Serial.println("audio format ok");
p += len;
size -= len;
data_length = 0;
data_length = 8;
header_offset = 0;
state = STATE_PARSE3;
goto start;
}
@@ -234,13 +245,14 @@ start:

// find the data chunk
case STATE_PARSE3: // 10
len = 8 - data_length;
len = data_length;
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_length -= len;
if (data_length < 8) return false;
data_length -= len;
if (data_length > 0) return false;
//Serial.print("chunk id = ");
//Serial.print(header[0], HEX);
//Serial.print(", length = ");
@@ -280,7 +292,8 @@ start:
size -= data_length;
buffer_offset += data_length;
buffer_length -= data_length;
data_length = 0;
data_length = 8;
header_offset = 0;
state = STATE_PARSE3;
//Serial.println("consumed unknown chunk");
goto start;

+ 4
- 3
play_sd_wav.h View File

@@ -45,16 +45,17 @@ private:
File wavfile;
bool consume(uint32_t size);
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 bytes2millis;
audio_block_t *block_left;
audio_block_t *block_right;
uint16_t block_offset;
uint8_t buffer[512];
uint8_t buffer[512]; // buffer one block of data
uint16_t buffer_offset;
uint16_t buffer_length;
uint8_t header_offset; // number of bytes in header[]
uint8_t state;
uint8_t state_play;
uint8_t leftover_bytes;

Loading…
Cancel
Save