View Full Version : Bug in Audio/play_sd_wav.cpp

06-27-2016, 06:20 PM
I've posted issue #187 (https://github.com/PaulStoffregen/Audio/issues) on the Audio github: "Bug in Audio/play_sd_wav.cpp - some WAV files play with stereo left/right channels reversed ".
I'm still pondering how to fix it but perhaps someone who's more awake/alert than I am can figure it out.
The basic problem is that the parsing code in play_sd_wav.cpp assumes that left+right sample pairs in the WAV file are on a 4-byte boundary. This is always true of simple WAV files which only have the standard header followed by the data chunk. But if there's a LIST header before the data chunk and that LIST header is not a multiple of 4 bytes, the left-right sample pairs aren't on a 4-byte boundary anymore and the left and right channels are reversed in all blocks following the first. This also causes another problem that the right channel sample isn't paired with its associated left channel sample but if the basic problem of the offset is fixed this will also go away.
All four demo files SDTEST 1,2,3 and 4 have a LIST chunk. SDTEST4.WAV happens to have a LIST chunk which is a multiple of 4 bytes and it plays correctly. The other three have problematic LIST headers but SDTEST3.WAV demonstrates the problem most clearly. Play it on a PC and at 9 seconds into the recording a guitar starts playing in the left channel. Play this on a Teensy and the guitar is in the right channel.


06-27-2016, 10:12 PM
If I'm reading it correctly, it appears that the leftover_bytes variable is intended to handle this problem but somehow or other it is not working.


06-27-2016, 11:48 PM
I think I have found and fixed it. If it's going to be set at all, leftover_bytes will be non-zero when consume() is called at the beginning of a new SD buffer. But while that buffer is being processed, the audio buffer will fill up and consume() will return. When it is called again, leftover_bytes will still be non-zero even though the problem at the beginning of the buffer has been handled and the pointer to the data is currently correct.
The fix is to clear leftover_bytes, once it has been detected as being non-zero, just before the "goto right16;"

//PAH fix problem with left+right channels being swapped
leftover_bytes = 0;
goto right16;

I've tried a pull request but I'm not sure that it worked.