27 : isCurrentlyLooping (shouldLoop)
53 auto& dst = *bufferToFill.
buffer;
54 auto channels = jmin (dst.getNumChannels(), buffer.
getNumChannels());
60 for (; (i < n || isCurrentlyLooping) && (pos < m); i += max)
62 max = jmin (m - pos, n - (i % n));
65 for (; ch < channels; ++ch)
66 dst.copyFrom (ch, bufferToFill.
startSample + pos, buffer, ch, i % n, max);
68 for (; ch < dst.getNumChannels(); ++ch)
69 dst.clear (ch, bufferToFill.
startSample + pos, max);
75 dst.clear (bufferToFill.
startSample + pos, m - pos);
83 position = (int) newPosition;
99 return isCurrentlyLooping;
104 isCurrentlyLooping = shouldLoop;
111struct MemoryAudioSourceTests final :
public UnitTest
113 MemoryAudioSourceTests() :
UnitTest (
"MemoryAudioSource", UnitTestCategories::audio) {}
115 void runTest()
override
117 constexpr int blockSize = 512;
118 AudioBuffer<float> bufferToFill { 2, blockSize };
119 AudioSourceChannelInfo channelInfo { bufferToFill };
121 beginTest (
"A zero-length buffer produces silence, whether or not looping is enabled");
123 for (
const bool enableLooping : {
false,
true })
125 AudioBuffer<float> buffer;
126 MemoryAudioSource source { buffer,
true,
false };
127 source.setLooping (enableLooping);
128 source.prepareToPlay (blockSize, 44100.0);
130 for (
int i = 0; i < 2; ++i)
132 play (source, channelInfo);
133 expect (isSilent (bufferToFill));
138 beginTest (
"A short buffer without looping is played once and followed by silence");
140 auto buffer = getShortBuffer();
141 MemoryAudioSource source { buffer,
true,
false };
142 source.setLooping (
false);
143 source.prepareToPlay (blockSize, 44100.0);
145 play (source, channelInfo);
148 copy.setSize (buffer.getNumChannels(), blockSize,
true,
true,
false);
150 expect (bufferToFill == copy);
152 play (source, channelInfo);
154 expect (isSilent (bufferToFill));
157 beginTest (
"A short buffer with looping is played multiple times");
159 auto buffer = getShortBuffer();
160 MemoryAudioSource source { buffer,
true,
false };
161 source.setLooping (
true);
162 source.prepareToPlay (blockSize, 44100.0);
164 play (source, channelInfo);
166 for (
int sample = 0; sample < buffer.getNumSamples(); ++sample)
167 expectEquals (bufferToFill.getSample (0, sample + buffer.getNumSamples()), buffer.getSample (0, sample));
169 expect (! isSilent (bufferToFill));
172 beginTest (
"A long buffer without looping is played once");
174 auto buffer = getLongBuffer();
175 MemoryAudioSource source { buffer,
true,
false };
176 source.setLooping (
false);
177 source.prepareToPlay (blockSize, 44100.0);
179 play (source, channelInfo);
182 copy.setSize (buffer.getNumChannels(), blockSize,
true,
true,
false);
184 expect (bufferToFill == copy);
186 for (
int i = 0; i < 10; ++i)
187 play (source, channelInfo);
189 expect (isSilent (bufferToFill));
192 beginTest (
"A long buffer with looping is played multiple times");
194 auto buffer = getLongBuffer();
195 MemoryAudioSource source { buffer,
true,
false };
196 source.setLooping (
true);
197 source.prepareToPlay (blockSize, 44100.0);
199 for (
int i = 0; i < 100; ++i)
201 play (source, channelInfo);
202 expectEquals (bufferToFill.getSample (0, 0), buffer.getSample (0, (i * blockSize) % buffer.getNumSamples()));
207 static AudioBuffer<float> getTestBuffer (
int length)
209 AudioBuffer<float> buffer { 2, length };
211 for (
int channel = 0; channel < buffer.getNumChannels(); ++channel)
212 for (
int sample = 0; sample < buffer.getNumSamples(); ++sample)
213 buffer.setSample (channel, sample, jmap ((
float) sample, 0.0f, (
float) length, -1.0f, 1.0f));
218 static AudioBuffer<float> getShortBuffer() {
return getTestBuffer (5); }
219 static AudioBuffer<float> getLongBuffer() {
return getTestBuffer (1000); }
221 static void play (MemoryAudioSource& source, AudioSourceChannelInfo& info)
223 info.clearActiveBufferRegion();
224 source.getNextAudioBlock (info);
227 static bool isSilent (
const AudioBuffer<float>& b)
229 for (
int channel = 0; channel < b.getNumChannels(); ++channel)
230 if (b.findMinMax (channel, 0, b.getNumSamples()) != Range<float>{})
237static MemoryAudioSourceTests memoryAudioSourceTests;
void makeCopyOf(const AudioBuffer< OtherType > &other, bool avoidReallocating=false)
int getNumChannels() const noexcept
int getNumSamples() const noexcept
void setDataToReferTo(Type *const *dataToReferTo, int newNumChannels, int newStartSample, int newNumSamples)
Type *const * getArrayOfWritePointers() noexcept
bool isLooping() const override
int64 getNextReadPosition() const override
MemoryAudioSource(AudioBuffer< float > &audioBuffer, bool copyMemory, bool shouldLoop=false)
void setNextReadPosition(int64 newPosition) override
int64 getTotalLength() const override
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override
void setLooping(bool shouldLoop) override
void getNextAudioBlock(const AudioSourceChannelInfo &bufferToFill) override
void releaseResources() override
void clearActiveBufferRegion() const
AudioBuffer< float > * buffer