private bool FindFrameData()
{
if (!MediaFile.SeekBegin())
{
Logger.FATAL("Unable to seek to the beginning of the file");
return false;
}
var firstBytes = new byte[4];
while (true)
{
//1. Read the first 4 bytes
if (!MediaFile.PeekBuffer(firstBytes, 4))
{
Logger.FATAL("Unable to read 4 bytes");
return false;
}
if ((firstBytes[0] != 0xff) || ((firstBytes[1] >> 5) != 7))
{
MediaFile.SeekAhead(1);
continue;
}
//2. Split the flags
byte version = (byte)((firstBytes[1] >> 3) & 0x03);
byte layer = (byte)((firstBytes[1] >> 1) & 0x03);
byte bitRateIndex = (byte)(firstBytes[2] >> 4);
byte sampleRateIndex = (byte)((firstBytes[2] >> 2) & 0x03);
byte paddingBit = (byte)((firstBytes[2] >> 1) & 0x01);
//3. Compute the frame length from the flags
var length = _frameSizes[version, layer, bitRateIndex, sampleRateIndex, paddingBit];
if (length == 0)
{
MediaFile.SeekAhead(1);
continue;
}
//4. Save the cursor value and seek ahead to the next frame
long cursor = MediaFile.Position;
MediaFile.SeekTo(cursor + (long) length);
//5. Try to read 4 bytes again
if (!MediaFile.PeekBuffer(firstBytes, 4))
{
Logger.FATAL("Unable to read 4 bytes");
return false;
}
//6. Is this a frame start?
if ((firstBytes[0] == 0xff) && ((firstBytes[1] >> 5) == 7)) return true;
MediaFile.SeekTo(cursor + 1);
//7. Jack pot!
}
}