1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An AudioFormatReader that uses a background thread to pre-read data from
another reader.
@see AudioFormatReader
@tags{Audio}
*/
class JUCE_API BufferingAudioReader : public AudioFormatReader,
private TimeSliceClient
{
public:
/** Creates a reader.
@param sourceReader the source reader to wrap. This BufferingAudioReader
takes ownership of this object and will delete it later
when no longer needed
@param timeSliceThread the thread that should be used to do the background reading.
Make sure that the thread you supply is running, and won't
be deleted while the reader object still exists.
@param samplesToBuffer the total number of samples to buffer ahead.
*/
BufferingAudioReader (AudioFormatReader* sourceReader,
TimeSliceThread& timeSliceThread,
int samplesToBuffer);
~BufferingAudioReader() override;
/** 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) override;
private:
std::unique_ptr<AudioFormatReader> source;
TimeSliceThread& thread;
std::atomic<int64> nextReadPosition { 0 };
const int numBlocks;
int timeoutMs = 0;
enum { samplesPerBlock = 32768 };
struct BufferedBlock
{
BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples);
Range<int64> range;
AudioBuffer<float> buffer;
};
CriticalSection lock;
OwnedArray<BufferedBlock> blocks;
BufferedBlock* getBlockContaining (int64 pos) const noexcept;
int useTimeSlice() override;
bool readNextBufferChunk();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader)
};
} // namespace juce
|