|
|
|
|
|
|
|
|
// allocate the audio blocks to transmit |
|
|
// allocate the audio blocks to transmit |
|
|
block_left = allocate(); |
|
|
block_left = allocate(); |
|
|
if (block_left == NULL) return; |
|
|
if (block_left == NULL) return; |
|
|
if (state >= 8 || (state & 1) == 1) { |
|
|
|
|
|
|
|
|
if (state < 8 && (state & 1) == 1) { |
|
|
|
|
|
// if we're playing stereo, allocate another |
|
|
|
|
|
// block for the right channel output |
|
|
block_right = allocate(); |
|
|
block_right = allocate(); |
|
|
if (block_right == NULL) { |
|
|
if (block_right == NULL) { |
|
|
release(block_left); |
|
|
release(block_left); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
// if we're playing mono or just parsing |
|
|
|
|
|
// the WAV file header, no right-side block |
|
|
block_right = NULL; |
|
|
block_right = NULL; |
|
|
} |
|
|
} |
|
|
block_offset = 0; |
|
|
block_offset = 0; |
|
|
|
|
|
|
|
|
if (consume()) return; // it was enough to transmit audio |
|
|
if (consume()) return; // it was enough to transmit audio |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// we only get to this point when buffer[512] is empty |
|
|
if (state != STATE_STOP && wavfile.available()) { |
|
|
if (state != STATE_STOP && wavfile.available()) { |
|
|
// we can read more data from the file... |
|
|
// we can read more data from the file... |
|
|
buffer_remaining = wavfile.read(buffer, 512); |
|
|
buffer_remaining = wavfile.read(buffer, 512); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size = buffer_remaining; |
|
|
size = buffer_remaining; |
|
|
p = buffer + 512 - size; |
|
|
p = buffer + 512 - size; |
|
|
|
|
|
|
|
|
start: |
|
|
start: |
|
|
if (size == 0) return false; |
|
|
if (size == 0) return false; |
|
|
//Serial.print("AudioPlaySDcardWAV write, size = "); |
|
|
//Serial.print("AudioPlaySDcardWAV write, size = "); |
|
|
|
|
|
|
|
|
data_length = header[1]; |
|
|
data_length = header[1]; |
|
|
if (header[0] == 0x61746164) { |
|
|
if (header[0] == 0x61746164) { |
|
|
//Serial.println("found data chunk"); |
|
|
//Serial.println("found data chunk"); |
|
|
|
|
|
// TODO: verify offset in file is an even number |
|
|
|
|
|
// as required by WAV format. abort if odd. Code |
|
|
|
|
|
// below will depend upon this and fail if not even. |
|
|
leftover_bytes = 0; |
|
|
leftover_bytes = 0; |
|
|
state = state_play; |
|
|
state = state_play; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
size = data_length; |
|
|
size = data_length; |
|
|
} |
|
|
} |
|
|
data_length -= size; |
|
|
data_length -= size; |
|
|
if (leftover_bytes > 0) { |
|
|
|
|
|
lsb = header[0]; |
|
|
|
|
|
leftover_bytes = 0; |
|
|
|
|
|
goto do_msb; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (1) { |
|
|
while (1) { |
|
|
lsb = *p++; |
|
|
lsb = *p++; |
|
|
size--; |
|
|
|
|
|
if (size == 0) { |
|
|
|
|
|
if (data_length == 0) break; |
|
|
|
|
|
header[0] = lsb; |
|
|
|
|
|
leftover_bytes = 1; |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
do_msb: |
|
|
|
|
|
msb = *p++; |
|
|
msb = *p++; |
|
|
size--; |
|
|
|
|
|
|
|
|
size -= 2; |
|
|
block_left->data[block_offset++] = (msb << 8) | lsb; |
|
|
block_left->data[block_offset++] = (msb << 8) | lsb; |
|
|
if (block_offset >= AUDIO_BLOCK_SAMPLES) { |
|
|
if (block_offset >= AUDIO_BLOCK_SAMPLES) { |
|
|
transmit(block_left, 0); |
|
|
transmit(block_left, 0); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
if (size == 0) { |
|
|
if (size == 0) { |
|
|
if (data_length == 0) break; |
|
|
if (data_length == 0) break; |
|
|
leftover_bytes = 0; |
|
|
|
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |