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