in pedalboard/juce_overrides/juce_PatchedMP3AudioFormat.cpp [1809:1977]
int decodeNextBlock(float *out0, float *out1, int &done) {
if (!headerParsed) {
auto nextFrameOffset = scanForNextFrameHeader(false);
if (lastFrameSize == -1 || needToSyncBitStream) {
needToSyncBitStream = false;
readVBRHeader();
if (vbrHeaderFound)
return 1;
}
if (nextFrameOffset > 0) {
wasFreeFormat = false;
needToSyncBitStream = true;
auto size =
(int)(bufferPointer - (bufferSpace[bufferSpaceIndex] + 512));
if (size > 2880) {
size = 0;
bufferPointer = bufferSpace[bufferSpaceIndex] + 512;
}
auto toSkip = (size + nextFrameOffset) - 2880;
if (toSkip > 0) {
stream.skipNextBytes(toSkip);
nextFrameOffset -= toSkip;
}
stream.read(bufferPointer, nextFrameOffset);
lastFrameSize += nextFrameOffset;
}
uint32 nextIntBigEndian = (uint32)stream.readIntBigEndian();
static const uint32 LYRICS_HEADER_START = 0x4c595249;
if (nextFrameOffset < 0) {
if (nextIntBigEndian == LYRICS_HEADER_START) {
// Looks like we've hit a Lyrics3 block; a non-standard MP3 extension.
// Rather than explode, let's just return "we're done" and pretend
// that this file is over:
stream.skipNextBytes(stream.getTotalLength() - stream.getPosition());
return 1;
} else {
return -1;
}
}
const auto successful = frame.decodeHeader(nextIntBigEndian);
if (successful == MP3Frame::ParseSuccessful::no)
return -1;
headerParsed = true;
frameSize = frame.frameSize;
isFreeFormat = (frameSize == 0);
sideInfoSize = frame.lsf != 0 ? ((frame.numChannels == 1) ? 9 : 17)
: ((frame.numChannels == 1) ? 17 : 32);
if (frame.crc16FollowsHeader)
sideInfoSize += 2;
bufferSpaceIndex = 1 - bufferSpaceIndex;
bufferPointer = bufferSpace[bufferSpaceIndex] + 512;
bitIndex = 0;
if (lastFrameSize < 0)
return 1;
}
if (!sideParsed) {
if (frame.layer == 3) {
stream.read(bufferPointer, sideInfoSize);
if (frame.crc16FollowsHeader)
getBits(16);
auto bits = jmax(0, decodeLayer3SideInfo());
dataSize = (bits + 7) / 8;
if (!isFreeFormat)
dataSize = jmin(dataSize, frame.frameSize - sideInfoSize);
} else {
dataSize = frame.frameSize;
sideInfoSize = 0;
}
sideParsed = true;
}
int result = 1;
if (!dataParsed) {
stream.read(bufferPointer, dataSize);
if (out0 != nullptr) {
if (frame.layer < 3 && frame.crc16FollowsHeader)
getBits(16);
switch (frame.layer) {
case 1:
decodeLayer1Frame(out0, out1, done);
break;
case 2:
decodeLayer2Frame(out0, out1, done);
break;
case 3:
decodeLayer3Frame(out0, out1, done);
break;
default:
break;
}
}
bufferPointer =
bufferSpace[bufferSpaceIndex] + 512 + sideInfoSize + dataSize;
dataParsed = true;
result = 0;
// We decoded a frame correctly, so increase the amount of patience
// we have when scanning for the next frame header:
if (maximumScanLength < 0xFFFFFFF) {
maximumScanLength *= 2;
}
}
if (isFreeFormat) {
if (wasFreeFormat) {
frameSize = lastFrameSizeNoPadding + frame.padding;
} else {
auto nextFrameOffset = scanForNextFrameHeader(true);
wasFreeFormat = isFreeFormat;
if (nextFrameOffset < 0) {
lastFrameSize = frameSize;
return result;
}
frameSize = nextFrameOffset + sideInfoSize + dataSize;
lastFrameSizeNoPadding = frameSize - frame.padding;
}
}
if (result == 0)
return result;
int bytes = frameSize - (sideInfoSize + dataSize);
if (bytes > 0) {
auto toSkip = bytes - 512;
if (toSkip > 0) {
stream.skipNextBytes(toSkip);
bytes -= toSkip;
frameSize -= toSkip;
}
stream.read(bufferPointer, bytes);
bufferPointer += bytes;
}
lastFrameSize = frameSize;
wasFreeFormat = isFreeFormat;
frameSize = 0;
headerParsed = sideParsed = dataParsed = false;
return result;
}