I have just spent two days tracking down a mysterious bug, only to find something really stupid...
I have made a flac (Free Lossless Audio Codec) decoder from scratch, and it exhibited some weird behaviour. Some songs played completely through without any errors at all. I even compared side by side with the original wav file while playing. Other songs erred all the way through the song. There were no in-betweens. Either the song played correctly all the way, or it didn't play at all. The errors I had when the playroutine failed was of a missing sync problem, indicating a bug that caused the wrong number of bits from a block to be read. The mystery was why and where it happened. I was almost confident my decoding routine was ok, since it was going through the same stages with the songs that worked, than the ones that didn't work.
In pure desperation I tracked down a flac frame that seemed broken, and started to decode the frame manually to see what was supposed to happen. What I found was that the flac was supposed to be decoded using the LPC decoder stage, but my audio player said that it was trying to squeeze the data through the FIXED decoder stage. Finally a hint of what could be the problem. Looking at the bit pattern that chooses which stage to decode in:
001xxx = FIXED (xxx = order)
1xxxxx = LPC (xxxxx - 1 = order)
Looking at my code, i found something like this:
if ((subFrameType & 0x08) == 0x08) {
[frameInfo setCurrentSampleSize:[self sampleSizeForChannel:audioChannel]];
isOK = [self subFrameFixed:audioChannel predictorOrder:(subFrameType & 0x07) fullyDecode:YES];
}
else if ((subFrameType &0x20) == 0x20) {
[frameInfo setCurrentSampleSize:[self sampleSizeForChannel:audioChannel]];
isOK = [self subFrameLPC:audioChannel lpcOrder:((subFrameType & 0x1f) + 1) fullyDecode:YES];
}