| @@ -1429,20 +1429,9 @@ struct MP3Stream | |||||
| { | { | ||||
| MP3Stream (InputStream& source) | MP3Stream (InputStream& source) | ||||
| : stream (source, 8192), | : stream (source, 8192), | ||||
| numFrames (0), currentFrameIndex (0), vbrHeaderFound (false), | |||||
| encoderDelay (-1), encoderPadding (-1), | |||||
| headerParsed (false), sideParsed (false), dataParsed (false), | |||||
| needToSyncBitStream (true), isFreeFormat (false), wasFreeFormat (false), | |||||
| sideInfoSize (0), dataSize (0), frameSize (0), lastFrameSize (-1), | |||||
| lastFrameSizeNoPadding (0), bufferSpaceIndex (0), | |||||
| wordPointer (bufferSpace[bufferSpaceIndex] + 512), | |||||
| bitIndex (0), synthBo (1) | |||||
| numFrames (0), currentFrameIndex (0), vbrHeaderFound (false) | |||||
| { | { | ||||
| zerostruct (sideinfo); | |||||
| zeromem (bufferSpace, sizeof (bufferSpace)); | |||||
| zeromem (hybridBlock, sizeof (hybridBlock)); | |||||
| zeromem (hybridBlockIndex, sizeof (hybridBlockIndex)); | |||||
| zeromem (synthBuffers, sizeof (synthBuffers)); | |||||
| reset(); | |||||
| } | } | ||||
| int decodeNextBlock (float* const out0, float* const out1, int& done) | int decodeNextBlock (float* const out0, float* const out1, int& done) | ||||
| @@ -1468,12 +1457,12 @@ struct MP3Stream | |||||
| int size; | int size; | ||||
| wasFreeFormat = false; | wasFreeFormat = false; | ||||
| needToSyncBitStream = true; | needToSyncBitStream = true; | ||||
| size = (int) (wordPointer - (bufferSpace[bufferSpaceIndex] + 512)); | |||||
| size = (int) (bufferPointer - (bufferSpace[bufferSpaceIndex] + 512)); | |||||
| if (size > 2880) | if (size > 2880) | ||||
| { | { | ||||
| size = 0; | size = 0; | ||||
| wordPointer = bufferSpace[bufferSpaceIndex] + 512; | |||||
| bufferPointer = bufferSpace[bufferSpaceIndex] + 512; | |||||
| } | } | ||||
| const int toSkip = (size + nextFrameOffset) - 2880; | const int toSkip = (size + nextFrameOffset) - 2880; | ||||
| @@ -1484,7 +1473,7 @@ struct MP3Stream | |||||
| nextFrameOffset -= toSkip; | nextFrameOffset -= toSkip; | ||||
| } | } | ||||
| stream.read (wordPointer, nextFrameOffset); | |||||
| stream.read (bufferPointer, nextFrameOffset); | |||||
| lastFrameSize += nextFrameOffset; | lastFrameSize += nextFrameOffset; | ||||
| } | } | ||||
| @@ -1499,7 +1488,7 @@ struct MP3Stream | |||||
| sideInfoSize += 2; | sideInfoSize += 2; | ||||
| bufferSpaceIndex = 1 - bufferSpaceIndex; | bufferSpaceIndex = 1 - bufferSpaceIndex; | ||||
| wordPointer = bufferSpace[bufferSpaceIndex] + 512; | |||||
| bufferPointer = bufferSpace[bufferSpaceIndex] + 512; | |||||
| bitIndex = 0; | bitIndex = 0; | ||||
| if (lastFrameSize == -1) | if (lastFrameSize == -1) | ||||
| @@ -1510,7 +1499,7 @@ struct MP3Stream | |||||
| { | { | ||||
| if (frame.layer == 3) | if (frame.layer == 3) | ||||
| { | { | ||||
| stream.read (wordPointer, sideInfoSize); | |||||
| stream.read (bufferPointer, sideInfoSize); | |||||
| if (frame.crc16FollowsHeader) | if (frame.crc16FollowsHeader) | ||||
| getBits (16); | getBits (16); | ||||
| @@ -1534,7 +1523,7 @@ struct MP3Stream | |||||
| if (! dataParsed) | if (! dataParsed) | ||||
| { | { | ||||
| stream.read (wordPointer, dataSize); | |||||
| stream.read (bufferPointer, dataSize); | |||||
| if (out0 != nullptr) | if (out0 != nullptr) | ||||
| { | { | ||||
| @@ -1550,7 +1539,7 @@ struct MP3Stream | |||||
| } | } | ||||
| } | } | ||||
| wordPointer = bufferSpace[bufferSpaceIndex] + 512 + sideInfoSize + dataSize; | |||||
| bufferPointer = bufferSpace[bufferSpaceIndex] + 512 + sideInfoSize + dataSize; | |||||
| dataParsed = true; | dataParsed = true; | ||||
| result = 0; | result = 0; | ||||
| } | } | ||||
| @@ -1588,8 +1577,8 @@ struct MP3Stream | |||||
| frameSize -= toSkip; | frameSize -= toSkip; | ||||
| } | } | ||||
| stream.read (wordPointer, bytes); | |||||
| wordPointer += bytes; | |||||
| stream.read (bufferPointer, bytes); | |||||
| bufferPointer += bytes; | |||||
| } | } | ||||
| lastFrameSize = frameSize; | lastFrameSize = frameSize; | ||||
| @@ -1618,8 +1607,7 @@ struct MP3Stream | |||||
| frameStreamPositions.size() * storedStartPosInterval - 1); | frameStreamPositions.size() * storedStartPosInterval - 1); | ||||
| stream.setPosition (frameStreamPositions.getUnchecked (frameIndex / storedStartPosInterval)); | stream.setPosition (frameStreamPositions.getUnchecked (frameIndex / storedStartPosInterval)); | ||||
| currentFrameIndex = frameIndex; | currentFrameIndex = frameIndex; | ||||
| frameSize = 0; | |||||
| headerParsed = sideParsed = dataParsed = false; | |||||
| reset(); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -1638,7 +1626,7 @@ private: | |||||
| int bufferSpaceIndex; | int bufferSpaceIndex; | ||||
| Layer3SideInfo sideinfo; | Layer3SideInfo sideinfo; | ||||
| uint8 bufferSpace[2][2880 + 1024]; | uint8 bufferSpace[2][2880 + 1024]; | ||||
| uint8* wordPointer; | |||||
| uint8* bufferPointer; | |||||
| int bitIndex, synthBo; | int bitIndex, synthBo; | ||||
| float hybridBlock[2][2][32 * 18]; | float hybridBlock[2][2][32 * 18]; | ||||
| int hybridBlockIndex[2]; | int hybridBlockIndex[2]; | ||||
| @@ -1646,6 +1634,23 @@ private: | |||||
| float hybridIn[2][32][18]; | float hybridIn[2][32][18]; | ||||
| float hybridOut[2][18][32]; | float hybridOut[2][18][32]; | ||||
| void reset() noexcept | |||||
| { | |||||
| headerParsed = sideParsed = dataParsed = isFreeFormat = wasFreeFormat = false; | |||||
| encoderDelay = encoderPadding = lastFrameSize = -1; | |||||
| needToSyncBitStream = true; | |||||
| frameSize = sideInfoSize = dataSize = frameSize = bitIndex = 0; | |||||
| lastFrameSizeNoPadding = bufferSpaceIndex = 0; | |||||
| bufferPointer = bufferSpace[bufferSpaceIndex] + 512; | |||||
| synthBo = 1; | |||||
| zerostruct (sideinfo); | |||||
| zeromem (bufferSpace, sizeof (bufferSpace)); | |||||
| zeromem (hybridBlock, sizeof (hybridBlock)); | |||||
| zeromem (hybridBlockIndex, sizeof (hybridBlockIndex)); | |||||
| zeromem (synthBuffers, sizeof (synthBuffers)); | |||||
| } | |||||
| enum { storedStartPosInterval = 4 }; | enum { storedStartPosInterval = 4 }; | ||||
| Array<int64> frameStreamPositions; | Array<int64> frameStreamPositions; | ||||
| @@ -1673,16 +1678,16 @@ private: | |||||
| && (header & 3) != 2; | && (header & 3) != 2; | ||||
| } | } | ||||
| bool rollBackPointer (int backstep) noexcept | |||||
| bool rollBackBufferPointer (int backstep) noexcept | |||||
| { | { | ||||
| if (lastFrameSize < 0 && backstep > 0) | if (lastFrameSize < 0 && backstep > 0) | ||||
| return false; | return false; | ||||
| const uint8* oldBuffer = bufferSpace[1 - bufferSpaceIndex] + 512; | const uint8* oldBuffer = bufferSpace[1 - bufferSpaceIndex] + 512; | ||||
| wordPointer -= backstep; | |||||
| bufferPointer -= backstep; | |||||
| if (backstep != 0) | if (backstep != 0) | ||||
| memcpy (wordPointer, oldBuffer + lastFrameSize - backstep, (size_t) backstep); | |||||
| memcpy (bufferPointer, oldBuffer + lastFrameSize - backstep, (size_t) backstep); | |||||
| bitIndex = 0; | bitIndex = 0; | ||||
| return true; | return true; | ||||
| @@ -1690,31 +1695,31 @@ private: | |||||
| uint32 getBits (const int numBits) noexcept | uint32 getBits (const int numBits) noexcept | ||||
| { | { | ||||
| if (numBits <= 0 || wordPointer == nullptr) | |||||
| if (numBits <= 0 || bufferPointer == nullptr) | |||||
| return 0; | return 0; | ||||
| const uint32 result = ((((((wordPointer[0] << 8) | wordPointer[1]) << 8) | |||||
| | wordPointer[2]) << bitIndex) & 0xffffff) >> (24 - numBits); | |||||
| const uint32 result = ((((((bufferPointer[0] << 8) | bufferPointer[1]) << 8) | |||||
| | bufferPointer[2]) << bitIndex) & 0xffffff) >> (24 - numBits); | |||||
| bitIndex += numBits; | bitIndex += numBits; | ||||
| wordPointer += (bitIndex >> 3); | |||||
| bufferPointer += (bitIndex >> 3); | |||||
| bitIndex &= 7; | bitIndex &= 7; | ||||
| return result; | return result; | ||||
| } | } | ||||
| uint32 getOneBit() noexcept | uint32 getOneBit() noexcept | ||||
| { | { | ||||
| const uint8 result = *wordPointer << bitIndex; | |||||
| const uint8 result = *bufferPointer << bitIndex; | |||||
| ++bitIndex; | ++bitIndex; | ||||
| wordPointer += (bitIndex >> 3); | |||||
| bufferPointer += (bitIndex >> 3); | |||||
| bitIndex &= 7; | bitIndex &= 7; | ||||
| return result >> 7; | return result >> 7; | ||||
| } | } | ||||
| uint32 getBitsFast (const int numBits) noexcept | uint32 getBitsFast (const int numBits) noexcept | ||||
| { | { | ||||
| const uint32 result = ((((wordPointer[0] << 8) | wordPointer[1]) << bitIndex) & 0xffff) >> (16 - numBits); | |||||
| const uint32 result = ((((bufferPointer[0] << 8) | bufferPointer[1]) << bitIndex) & 0xffff) >> (16 - numBits); | |||||
| bitIndex += numBits; | bitIndex += numBits; | ||||
| wordPointer += (bitIndex >> 3); | |||||
| bufferPointer += (bitIndex >> 3); | |||||
| bitIndex &= 7; | bitIndex &= 7; | ||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -1843,7 +1848,7 @@ private: | |||||
| void decodeLayer3Frame (float* const pcm0, float* const pcm1, int& samplesDone) noexcept | void decodeLayer3Frame (float* const pcm0, float* const pcm1, int& samplesDone) noexcept | ||||
| { | { | ||||
| if (! rollBackPointer ((int) sideinfo.mainDataStart)) | |||||
| if (! rollBackBufferPointer ((int) sideinfo.mainDataStart)) | |||||
| return; | return; | ||||
| const int single = frame.numChannels == 1 ? 0 : frame.single; | const int single = frame.numChannels == 1 ? 0 : frame.single; | ||||
| @@ -1997,7 +2002,6 @@ private: | |||||
| { | { | ||||
| const uint8 n0 = si.allocation[i][0]; | const uint8 n0 = si.allocation[i][0]; | ||||
| const uint8 n1 = si.allocation[i][1]; | const uint8 n1 = si.allocation[i][1]; | ||||
| fraction[0][i] = n0 > 0 ? (float) (((-1 << n0) + getLeq16Bits (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0; | fraction[0][i] = n0 > 0 ? (float) (((-1 << n0) + getLeq16Bits (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0; | ||||
| fraction[1][i] = n1 > 0 ? (float) (((-1 << n1) + getLeq16Bits (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0; | fraction[1][i] = n1 > 0 ? (float) (((-1 << n1) + getLeq16Bits (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0; | ||||
| } | } | ||||
| @@ -3015,6 +3019,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| decodedStart = decodedEnd = 0; | |||||
| const int64 streamPos = stream.currentFrameIndex * 1152; | const int64 streamPos = stream.currentFrameIndex * 1152; | ||||
| int toSkip = startSampleInFile - streamPos; | int toSkip = startSampleInFile - streamPos; | ||||
| jassert (toSkip >= 0); | jassert (toSkip >= 0); | ||||