diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index b4bc157437..cb4d068579 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -49,9 +49,15 @@ BufferingAudioReader::~BufferingAudioReader() thread.removeTimeSliceClient (this); } +void BufferingAudioReader::setReadTimeout (int timeoutMilliseconds) noexcept +{ + timeoutMs = timeoutMilliseconds; +} + bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) { + const uint32 startTime = Time::getMillisecondCounter(); clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, startSampleInFile, numSamples, lengthInSamples); @@ -84,11 +90,19 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, } else { - for (int j = 0; j < numDestChannels; ++j) - if (float* dest = (float*) destSamples[j]) - FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); + if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + timeoutMs) + { + for (int j = 0; j < numDestChannels; ++j) + if (float* dest = (float*) destSamples[j]) + FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); - break; + break; + } + else + { + ScopedUnlock ul (lock); + Thread::yield(); + } } } diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h index 5ced277e07..36c985a16d 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h @@ -53,6 +53,13 @@ public: ~BufferingAudioReader(); + /** 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. + */ + void setReadTimeout (int timeoutMilliseconds) noexcept; + bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples); @@ -61,6 +68,7 @@ private: TimeSliceThread& thread; int64 nextReadPosition; const int numBlocks; + int timeoutMs; enum { samplesPerBlock = 32768 };