48 thread.removeTimeSliceClient (
this);
57 int64 startSampleInFile,
int numSamples)
66 bool allSamplesRead =
true;
68 while (numSamples > 0)
72 auto offset = (
int) (startSampleInFile - block->range.getStart());
73 auto numToDo =
jmin (numSamples, (
int) (block->range.getEnd() - startSampleInFile));
75 for (
int j = 0;
j < numDestChannels; ++
j)
77 if (
auto* dest = (
float*) destSamples[
j])
79 dest += startOffsetInDestBuffer;
82 FloatVectorOperations::copy (dest, block->buffer.getReadPointer (
j, offset), numToDo);
84 FloatVectorOperations::clear (dest, numToDo);
88 startOffsetInDestBuffer += numToDo;
89 startSampleInFile += numToDo;
90 numSamples -= numToDo;
92 allSamplesRead = allSamplesRead && block->allSamplesRead;
98 for (
int j = 0;
j < numDestChannels; ++
j)
99 if (
auto* dest = (
float*) destSamples[
j])
100 FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples);
102 allSamplesRead =
false;
113 return allSamplesRead;
117 :
range (pos, pos + numSamples),
126 if (
b->range.contains (pos))
144 for (
int i =
blocks.size(); --
i >= 0;)
150 newBlocks.
clear (
false);
168 for (
int i =
blocks.size(); --
i >= 0;)
181 if (
a.getNumChannels() !=
b.getNumChannels() ||
a.getNumSamples() !=
b.getNumSamples())
184 for (
int channel = 0; channel <
a.getNumChannels(); ++channel)
186 auto* aPtr =
a.getReadPointer (channel);
187 auto* bPtr =
b.getReadPointer (channel);
189 if (std::vector<float> (aPtr, aPtr +
a.getNumSamples())
190 != std::vector<float> (bPtr, bPtr +
b.getNumSamples()))
199static bool isSilent (
const AudioBuffer<float>&
b)
201 for (
int channel = 0; channel <
b.getNumChannels(); ++channel)
202 if (
b.findMinMax (channel, 0,
b.getNumSamples()) != Range<float>{})
210 explicit TestAudioFormatReader (AudioBuffer<float>&
b)
211 : AudioFormatReader (
nullptr, {}),
214 sampleRate = 44100.0f;
216 usesFloatingPointData =
true;
217 lengthInSamples =
buffer.getNumSamples();
218 numChannels = (
unsigned int)
buffer.getNumChannels();
221 bool readSamples (
int** destChannels,
int numDestChannels,
int startOffsetInDestBuffer,
222 int64 startSampleInFile,
int numSamples)
override
224 clearSamplesBeyondAvailableLength (destChannels, numDestChannels, startOffsetInDestBuffer,
225 startSampleInFile, numSamples, lengthInSamples);
227 for (
int j = 0;
j < numDestChannels; ++
j)
229 static_assert (
sizeof (
int) ==
sizeof (float),
230 "Int and float size must match in order for pointer arithmetic to work correctly");
232 if (
auto* dest =
reinterpret_cast<float*
> (destChannels[
j]))
234 dest += startOffsetInDestBuffer;
236 if (
j < (
int) numChannels)
237 FloatVectorOperations::copy (dest,
buffer.getReadPointer (
j, (
int) startSampleInFile), numSamples);
239 FloatVectorOperations::clear (dest, numSamples);
246 const AudioBuffer<float>&
buffer;
249class BufferingAudioReaderTests :
public UnitTest
252 BufferingAudioReaderTests() : UnitTest (
"BufferingAudioReader", UnitTestCategories::audio) {}
254 void runTest()
override
256 TimeSliceThread timeSlice (
"TestBackgroundThread");
257 timeSlice.startThread (5);
259 beginTest (
"Timeout");
261 struct BlockingReader :
public AudioFormatReader
264 : AudioFormatReader (
nullptr, {})
266 sampleRate = 44100.0f;
268 usesFloatingPointData =
true;
269 lengthInSamples = 1024;
273 bool readSamples (
int**,
int,
int,
int64,
int)
override
280 BufferingAudioReader bufferingReader (
new BlockingReader(), timeSlice, 64);
281 bufferingReader.setReadTimeout (10);
283 AudioBuffer<float> readBuffer { 2, 1024 };
286 read (bufferingReader, readBuffer);
288 expect (isSilent (readBuffer));
291 beginTest (
"Read samples");
293 for (
auto i = 4;
i < 18; ++
i)
295 const auto backgroundBufferSize = 1 <<
i;
296 auto buffer = generateTestBuffer (backgroundBufferSize);
298 BufferingAudioReader bufferingReader (
new TestAudioFormatReader (buffer), timeSlice, backgroundBufferSize);
299 bufferingReader.setReadTimeout (-1);
301 AudioBuffer<float> readBuffer {
buffer.getNumChannels(),
buffer.getNumSamples() };
302 read (bufferingReader, readBuffer);
304 expect (buffer == readBuffer);
310 AudioBuffer<float> generateTestBuffer (
int bufferSize)
const
312 auto random = getRandom();
314 AudioBuffer<float>
buffer { 2, random.nextInt ({ bufferSize, bufferSize * 10 }) };
316 for (
int channel = 0; channel <
buffer.getNumChannels(); ++channel)
323 void read (BufferingAudioReader& reader, AudioBuffer<float>& readBuffer)
325 constexpr int blockSize = 1024;
327 const auto numSamples = readBuffer.getNumSamples();
332 reader.read (&readBuffer, readPos,
jmin (blockSize, numSamples - readPos), readPos,
true,
true);
334 readPos += blockSize;
336 if (readPos >= numSamples)
342static BufferingAudioReaderTests bufferingAudioReaderTests;
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
#define nullptr
Definition DistrhoDefines.h:75
uint8_t a
Definition Spc_Cpu.h:141
int64_t int64
Definition basics.h:91
Definition juce_AudioSampleBuffer.h:34
bool readSamples(int **destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override
Definition juce_BufferingAudioFormatReader.cpp:56
CriticalSection lock
Definition juce_BufferingAudioFormatReader.h:91
static constexpr int samplesPerBlock
Definition juce_BufferingAudioFormatReader.h:83
BufferingAudioReader(AudioFormatReader *sourceReader, TimeSliceThread &timeSliceThread, int samplesToBuffer)
Definition juce_BufferingAudioFormatReader.cpp:29
TimeSliceThread & thread
Definition juce_BufferingAudioFormatReader.h:86
std::atomic< int64 > nextReadPosition
Definition juce_BufferingAudioFormatReader.h:87
OwnedArray< BufferedBlock > blocks
Definition juce_BufferingAudioFormatReader.h:92
int timeoutMs
Definition juce_BufferingAudioFormatReader.h:89
BufferedBlock * getBlockContaining(int64 pos) const noexcept
Definition juce_BufferingAudioFormatReader.cpp:123
void setReadTimeout(int timeoutMilliseconds) noexcept
Definition juce_BufferingAudioFormatReader.cpp:51
const int numBlocks
Definition juce_BufferingAudioFormatReader.h:88
std::unique_ptr< AudioFormatReader > source
Definition juce_BufferingAudioFormatReader.h:85
bool readNextBufferChunk()
Definition juce_BufferingAudioFormatReader.cpp:137
int useTimeSlice() override
Definition juce_BufferingAudioFormatReader.cpp:132
~BufferingAudioReader() override
Definition juce_BufferingAudioFormatReader.cpp:46
Definition juce_OwnedArray.h:51
int size() const noexcept
Definition juce_OwnedArray.h:130
void swapWith(OtherArrayType &otherArray) noexcept
Definition juce_OwnedArray.h:762
void clear(bool deleteObjects=true)
Definition juce_OwnedArray.h:107
ObjectClass * add(ObjectClass *newObject)
Definition juce_OwnedArray.h:294
void removeObject(const ObjectClass *objectToRemove, bool deleteObject=true)
Definition juce_OwnedArray.h:655
Definition juce_Range.h:40
static void JUCE_CALLTYPE yield()
Definition juce_posix_SharedCode.h:1033
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
friend class TimeSliceThread
Definition juce_TimeSliceThread.h:68
void addTimeSliceClient(TimeSliceClient *clientToAdd, int millisecondsBeforeStarting=0)
Definition juce_TimeSliceThread.cpp:36
register unsigned j
Definition inflate.c:1576
register unsigned i
Definition inflate.c:1575
JOCTET * buffer
Definition juce_JPEGLoader.cpp:302
Definition carla_juce.cpp:31
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
unsigned int uint32
Definition juce_MathsFunctions.h:45
long long int64
Definition juce_MathsFunctions.h:54
CriticalSection::ScopedUnlockType ScopedUnlock
Definition juce_CriticalSection.h:226
bool isSilent(const SampleFrame *src, int frames)
Definition MixHelpers.cpp:72
#define true
Definition ordinals.h:82
Definition juce_BufferingAudioFormatReader.h:71
BufferedBlock(AudioFormatReader &reader, int64 pos, int numSamples)
Definition juce_BufferingAudioFormatReader.cpp:116
AudioBuffer< float > buffer
Definition juce_BufferingAudioFormatReader.h:75
Range< int64 > range
Definition juce_BufferingAudioFormatReader.h:74
bool allSamplesRead
Definition juce_BufferingAudioFormatReader.h:76
signed int sample
Definition tap_dynamics_m.c:41
uch * p
Definition crypt.c:594
typedef int(UZ_EXP MsgFn)()