34 source (sourceReader), thread (timeSliceThread),
35 numBlocks (1 + (samplesToBuffer / samplesPerBlock))
44 for (
int i = 3; --i >= 0;)
45 readNextBufferChunk();
50 BufferingAudioReader::~BufferingAudioReader()
57 timeoutMs = timeoutMilliseconds;
61 int64 startSampleInFile,
int numSamples)
68 nextReadPosition = startSampleInFile;
70 while (numSamples > 0)
72 if (
auto block = getBlockContaining (startSampleInFile))
74 auto offset = (int) (startSampleInFile - block->range.getStart());
75 auto numToDo = jmin (numSamples, (
int) (block->range.getEnd() - startSampleInFile));
77 for (
int j = 0; j < numDestChannels; ++j)
79 if (
auto dest = (
float*) destSamples[j])
81 dest += startOffsetInDestBuffer;
90 startOffsetInDestBuffer += numToDo;
91 startSampleInFile += numToDo;
92 numSamples -= numToDo;
98 for (
int j = 0; j < numDestChannels; ++j)
99 if (
auto dest = (
float*) destSamples[j])
115 BufferingAudioReader::BufferedBlock::BufferedBlock (
AudioFormatReader& reader, int64 pos,
int numSamples)
116 : range (pos, pos + numSamples),
119 reader.
read (&buffer, 0, numSamples, pos,
true,
true);
122 BufferingAudioReader::BufferedBlock* BufferingAudioReader::getBlockContaining (int64 pos)
const noexcept
124 for (
auto* b : blocks)
125 if (b->range.contains (pos))
131 int BufferingAudioReader::useTimeSlice()
133 return readNextBufferChunk() ? 1 : 100;
136 bool BufferingAudioReader::readNextBufferChunk()
138 auto pos = nextReadPosition.load();
139 auto startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock;
140 auto endPos = startPos + numBlocks * samplesPerBlock;
144 for (
int i = blocks.
size(); --i >= 0;)
148 if (newBlocks.
size() == numBlocks)
150 newBlocks.
clear (
false);
154 for (
auto p = startPos; p < endPos; p += samplesPerBlock)
156 if (getBlockContaining (p) ==
nullptr)
158 newBlocks.
add (
new BufferedBlock (*source, p, samplesPerBlock));
168 for (
int i = blocks.
size(); --i >= 0;)
void clear(bool deleteObjects=true)
Clears the array, optionally deleting the objects inside it first.
static void JUCE_CALLTYPE copy(float *dest, const float *src, int numValues) noexcept
Copies a vector of floats.
BufferingAudioReader(AudioFormatReader *sourceReader, TimeSliceThread &timeSliceThread, int samplesToBuffer)
Creates a reader.
void removeTimeSliceClient(TimeSliceClient *clientToRemove)
Removes a client from the list.
ObjectClass * getUnchecked(const int index) const noexcept
Returns a pointer to the object at this index in the array, without checking whether the index is in-...
void setReadTimeout(int timeoutMilliseconds) noexcept
Sets a number of milliseconds that the reader can block for in its readSamples() method before giving...
bool readSamples(int **destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override
Subclasses must implement this method to perform the low-level read operation.
static void JUCE_CALLTYPE yield()
Yields the current thread's CPU time-slot and allows a new thread to run.
void removeObject(const ObjectClass *objectToRemove, bool deleteObject=true)
Removes a specified object from the array.
static void JUCE_CALLTYPE clear(float *dest, int numValues) noexcept
Clears a vector of floats.
A thread that keeps a list of clients, and calls each one in turn, giving them all a chance to run so...
int size() const noexcept
Returns the number of items currently in the array.
void addTimeSliceClient(TimeSliceClient *clientToAdd, int millisecondsBeforeStarting=0)
Adds a client to the list.
ObjectClass * add(ObjectClass *newObject) noexcept
Appends a new object to the end of the array.
Automatically locks and unlocks a mutex object.
void swapWith(OtherArrayType &otherArray) noexcept
This swaps the contents of this array with those of another array.
Automatically unlocks and re-locks a mutex object.
static uint32 getMillisecondCounter() noexcept
Returns the number of millisecs since a fixed event (usually system startup).