From b3bdfdb34c4fe428c2f17f53a77452438a674ca0 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 6 Apr 2021 12:27:59 +0100 Subject: [PATCH] BufferingAudioReader: Fixed an infinite read bug --- .../juce_BufferingAudioFormatReader.cpp | 15 +++++----- .../format/juce_BufferingAudioFormatReader.h | 29 ++++++++++--------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index 57d476758b..fc2c3207ed 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -75,7 +75,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, for (int j = 0; j < numDestChannels; ++j) { - if (auto dest = (float*) destSamples[j]) + if (auto* dest = (float*) destSamples[j]) { dest += startOffsetInDestBuffer; @@ -95,7 +95,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs) { for (int j = 0; j < numDestChannels; ++j) - if (auto dest = (float*) destSamples[j]) + if (auto* dest = (float*) destSamples[j]) FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); break; @@ -135,14 +135,13 @@ int BufferingAudioReader::useTimeSlice() bool BufferingAudioReader::readNextBufferChunk() { auto pos = nextReadPosition.load(); - auto startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock; - auto endPos = startPos + numBlocks * samplesPerBlock; + auto endPos = pos + numBlocks * samplesPerBlock; OwnedArray newBlocks; for (int i = blocks.size(); --i >= 0;) - if (blocks.getUnchecked(i)->range.intersects (Range (startPos, endPos))) - newBlocks.add (blocks.getUnchecked(i)); + if (blocks.getUnchecked (i)->range.intersects (Range (pos, endPos))) + newBlocks.add (blocks.getUnchecked (i)); if (newBlocks.size() == numBlocks) { @@ -150,7 +149,7 @@ bool BufferingAudioReader::readNextBufferChunk() return false; } - for (auto p = startPos; p < endPos; p += samplesPerBlock) + for (auto p = pos; p < endPos; p += samplesPerBlock) { if (getBlockContaining (p) == nullptr) { @@ -165,7 +164,7 @@ bool BufferingAudioReader::readNextBufferChunk() } for (int i = blocks.size(); --i >= 0;) - newBlocks.removeObject (blocks.getUnchecked(i), false); + newBlocks.removeObject (blocks.getUnchecked (i), false); return true; } diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h index 19403c645a..2b2758da8a 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h @@ -57,23 +57,16 @@ public: /** Sets a number of milliseconds that the reader can block for in its readSamples() method before giving up and returning silence. - A value of less that 0 means "wait forever". - The default timeout is 0. + + A value of less that 0 means "wait forever". The default timeout is 0. */ void setReadTimeout (int timeoutMilliseconds) noexcept; + //============================================================================== bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override; private: - std::unique_ptr source; - TimeSliceThread& thread; - std::atomic nextReadPosition { 0 }; - const int numBlocks; - int timeoutMs = 0; - - enum { samplesPerBlock = 32768 }; - struct BufferedBlock { BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples); @@ -82,13 +75,21 @@ private: AudioBuffer buffer; }; - CriticalSection lock; - OwnedArray blocks; - - BufferedBlock* getBlockContaining (int64 pos) const noexcept; int useTimeSlice() override; + BufferedBlock* getBlockContaining (int64 pos) const noexcept; bool readNextBufferChunk(); + static constexpr int samplesPerBlock = 32768; + + std::unique_ptr source; + TimeSliceThread& thread; + std::atomic nextReadPosition { 0 }; + const int numBlocks; + int timeoutMs = 0; + + CriticalSection lock; + OwnedArray blocks; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader) };