37 usesFloatingPointData (
false),
52 usesFloatingPointData (
false),
64static void convertFloatsToInts (
int* dest,
const float*
src,
int numSamples)
noexcept
66 while (--numSamples >= 0)
71 *dest = std::numeric_limits<int>::min();
73 *dest = std::numeric_limits<int>::max();
75 *dest = roundToInt (std::numeric_limits<int>::max() *
samp);
85 const int bufferSize = 16384;
88 int*
buffers[128] = {
nullptr };
90 for (
int i = tempBuffer.getNumChannels(); --i >= 0;)
91 buffers[i] =
reinterpret_cast<int*
> (tempBuffer.getWritePointer (i, 0));
111 constexpr auto scaleFactor = 1.0f /
static_cast<float> (0x7fffffff);
114 FloatVectorOperations::convertFixedToFloat ((
float*) b, (
int*) b,
scaleFactor,
numToDo);
116 convertFloatsToInts ((
int*) b, (
float*) b,
numToDo);
139 info.clearActiveBufferRegion();
158 return write ((
const int**) channels, numSamples);
160 std::vector<int*>
chans (256);
161 std::vector<int>
scratch (4096);
172 while (numSamples > 0)
177 convertFloatsToInts (
chans[(
size_t) i], channels[(
size_t) i] + startSample,
numToDo);
192 jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() &&
numSourceChannels > 0);
194 if (startSample == 0)
197 const float*
chans[256];
201 chans[i] = source.getReadPointer (i, startSample);
219 buffer (channels, numSamples),
220 timeSliceThread (
tst),
223 timeSliceThread.addTimeSliceClient (
this);
229 timeSliceThread.removeTimeSliceClient (
this);
231 while (writePendingData() == 0)
235 bool write (
const float*
const* data,
int numSamples)
237 if (numSamples <= 0 || ! isRunning)
240 jassert (timeSliceThread.isThreadRunning());
242 int start1, size1, start2, size2;
243 fifo.prepareToWrite (numSamples, start1, size1, start2, size2);
245 if (size1 + size2 < numSamples)
248 for (
int i = buffer.getNumChannels(); --i >= 0;)
250 buffer.copyFrom (i, start1, data[i], size1);
251 buffer.copyFrom (i, start2, data[i] + size1, size2);
254 fifo.finishedWrite (size1 + size2);
255 timeSliceThread.notify();
259 int useTimeSlice()
override
261 return writePendingData();
264 int writePendingData()
266 auto numToDo = fifo.getTotalSize() / 4;
268 int start1, size1, start2, size2;
269 fifo.prepareToRead (numToDo, start1, size1, start2, size2);
274 writer->writeFromAudioSampleBuffer (buffer, start1, size1);
276 const ScopedLock sl (thumbnailLock);
278 if (receiver !=
nullptr)
279 receiver->addBlock (samplesWritten, buffer, start1, size1);
281 samplesWritten += size1;
285 writer->writeFromAudioSampleBuffer (buffer, start2, size2);
287 if (receiver !=
nullptr)
288 receiver->addBlock (samplesWritten, buffer, start2, size2);
290 samplesWritten += size2;
293 fifo.finishedRead (size1 + size2);
295 if (samplesPerFlush > 0)
297 flushSampleCounter -= size1 + size2;
299 if (flushSampleCounter <= 0)
301 flushSampleCounter = samplesPerFlush;
309 void setDataReceiver (IncomingDataReceiver* newReceiver)
311 if (newReceiver !=
nullptr)
312 newReceiver->reset (buffer.getNumChannels(), writer->getSampleRate(), 0);
314 const ScopedLock sl (thumbnailLock);
315 receiver = newReceiver;
319 void setFlushInterval (
int numSamples)
noexcept
321 samplesPerFlush = numSamples;
326 AudioBuffer<float> buffer;
327 TimeSliceThread& timeSliceThread;
328 std::unique_ptr<AudioFormatWriter> writer;
329 CriticalSection thumbnailLock;
330 IncomingDataReceiver* receiver = {};
331 int64 samplesWritten = 0;
332 int samplesPerFlush = 0, flushSampleCounter = 0;
333 std::atomic<bool> isRunning {
true };
335 JUCE_DECLARE_NON_COPYABLE (Buffer)
349 return buffer->write (data, numSamples);
354 buffer->setDataReceiver (receiver);
virtual void getNextAudioBlock(const AudioSourceChannelInfo &bufferToFill)=0