1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-18 00:54:19 +00:00

BufferingAudioReader: Fixed an infinite read bug

This commit is contained in:
ed 2021-04-06 12:27:59 +01:00
parent 0aeee97b91
commit b3bdfdb34c
2 changed files with 22 additions and 22 deletions

View file

@ -75,7 +75,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
for (int j = 0; j < numDestChannels; ++j) for (int j = 0; j < numDestChannels; ++j)
{ {
if (auto dest = (float*) destSamples[j]) if (auto* dest = (float*) destSamples[j])
{ {
dest += startOffsetInDestBuffer; dest += startOffsetInDestBuffer;
@ -95,7 +95,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs) if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs)
{ {
for (int j = 0; j < numDestChannels; ++j) for (int j = 0; j < numDestChannels; ++j)
if (auto dest = (float*) destSamples[j]) if (auto* dest = (float*) destSamples[j])
FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples);
break; break;
@ -135,14 +135,13 @@ int BufferingAudioReader::useTimeSlice()
bool BufferingAudioReader::readNextBufferChunk() bool BufferingAudioReader::readNextBufferChunk()
{ {
auto pos = nextReadPosition.load(); auto pos = nextReadPosition.load();
auto startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock; auto endPos = pos + numBlocks * samplesPerBlock;
auto endPos = startPos + numBlocks * samplesPerBlock;
OwnedArray<BufferedBlock> newBlocks; OwnedArray<BufferedBlock> newBlocks;
for (int i = blocks.size(); --i >= 0;) for (int i = blocks.size(); --i >= 0;)
if (blocks.getUnchecked(i)->range.intersects (Range<int64> (startPos, endPos))) if (blocks.getUnchecked (i)->range.intersects (Range<int64> (pos, endPos)))
newBlocks.add (blocks.getUnchecked(i)); newBlocks.add (blocks.getUnchecked (i));
if (newBlocks.size() == numBlocks) if (newBlocks.size() == numBlocks)
{ {
@ -150,7 +149,7 @@ bool BufferingAudioReader::readNextBufferChunk()
return false; return false;
} }
for (auto p = startPos; p < endPos; p += samplesPerBlock) for (auto p = pos; p < endPos; p += samplesPerBlock)
{ {
if (getBlockContaining (p) == nullptr) if (getBlockContaining (p) == nullptr)
{ {
@ -165,7 +164,7 @@ bool BufferingAudioReader::readNextBufferChunk()
} }
for (int i = blocks.size(); --i >= 0;) for (int i = blocks.size(); --i >= 0;)
newBlocks.removeObject (blocks.getUnchecked(i), false); newBlocks.removeObject (blocks.getUnchecked (i), false);
return true; return true;
} }

View file

@ -57,23 +57,16 @@ public:
/** Sets a number of milliseconds that the reader can block for in its readSamples() /** Sets a number of milliseconds that the reader can block for in its readSamples()
method before giving up and returning silence. 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; void setReadTimeout (int timeoutMilliseconds) noexcept;
//==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override; int64 startSampleInFile, int numSamples) override;
private: private:
std::unique_ptr<AudioFormatReader> source;
TimeSliceThread& thread;
std::atomic<int64> nextReadPosition { 0 };
const int numBlocks;
int timeoutMs = 0;
enum { samplesPerBlock = 32768 };
struct BufferedBlock struct BufferedBlock
{ {
BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples); BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples);
@ -82,13 +75,21 @@ private:
AudioBuffer<float> buffer; AudioBuffer<float> buffer;
}; };
int useTimeSlice() override;
BufferedBlock* getBlockContaining (int64 pos) const noexcept;
bool readNextBufferChunk();
static constexpr int samplesPerBlock = 32768;
std::unique_ptr<AudioFormatReader> source;
TimeSliceThread& thread;
std::atomic<int64> nextReadPosition { 0 };
const int numBlocks;
int timeoutMs = 0;
CriticalSection lock; CriticalSection lock;
OwnedArray<BufferedBlock> blocks; OwnedArray<BufferedBlock> blocks;
BufferedBlock* getBlockContaining (int64 pos) const noexcept;
int useTimeSlice() override;
bool readNextBufferChunk();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader)
}; };