28 bool deleteSourceWhenDeleted,
32 : source (s, deleteSourceWhenDeleted),
33 backgroundThread (thread),
35 numberOfChannels (numChannels),
40 jassert (numberOfSamplesToBuffer > 1024);
92 buffer.
setSize (numberOfChannels, 0);
98 source->releaseResources();
124 if (validStart < validEnd)
138 validEnd - validStart);
162 if (source ==
nullptr || source->getTotalLength() <= 0)
170 auto now = startTime;
172 auto elapsed = (now >= startTime ? now - startTime
183 && validStart < validEnd
190 && ! bufferReadyEvent.
wait (
static_cast<int> (timeout -
elapsed)))
196 elapsed = (now >= startTime ? now - startTime
205 jassert (source->getTotalLength() > 0);
206 const auto pos = nextPlayPos.
load();
208 return (source->isLooping() && nextPlayPos > 0)
209 ? pos % source->getTotalLength()
221Range<int> BufferingAudioSource::getValidBufferRange (
int numSamples)
const
225 const auto pos = nextPlayPos.
load();
227 return { (
int) (
jlimit (bufferValidStart, bufferValidEnd, pos) - pos),
228 (
int) (
jlimit (bufferValidStart, bufferValidEnd, pos + numSamples) - pos) };
231bool BufferingAudioSource::readNextBufferChunk()
241 bufferValidStart = 0;
259 bufferValidStart = 0;
262 else if (std::abs ((
int) (
newBVS - bufferValidStart)) > 512
263 || std::abs ((
int) (
newBVE - bufferValidEnd)) > 512)
270 bufferValidStart =
newBVS;
271 bufferValidEnd =
jmin (bufferValidEnd,
newBVE);
305 bufferValidStart =
newBVS;
309 bufferReadyEvent.
signal();
313void BufferingAudioSource::readBufferSection (
int64 start,
int length,
int bufferOffset)
315 if (source->getNextReadPosition() != start)
316 source->setNextReadPosition (start);
318 AudioSourceChannelInfo info (&buffer,
bufferOffset, length);
321 source->getNextAudioBlock (info);
324int BufferingAudioSource::useTimeSlice()
326 return readNextBufferChunk() ? 1 : 100;
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Changes the buffer's size or number of channels.
int getNumChannels() const noexcept
Returns the number of channels of audio data that this buffer contains.
int getNumSamples() const noexcept
Returns the number of samples allocated in each of the buffer's channels.
void clear() noexcept
Clears all the samples in all channels and marks the buffer as cleared.
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
Copies samples from another buffer to this one.
void getNextAudioBlock(const AudioSourceChannelInfo &) override
Implementation of the AudioSource method.
void setNextReadPosition(int64 newPosition) override
Implements the PositionableAudioSource method.
int64 getTotalLength() const override
Implements the PositionableAudioSource method.
~BufferingAudioSource() override
Destructor.
BufferingAudioSource(PositionableAudioSource *source, TimeSliceThread &backgroundThread, bool deleteSourceWhenDeleted, int numberOfSamplesToBuffer, int numberOfChannels=2, bool prefillBufferOnPrepareToPlay=true)
Creates a BufferingAudioSource.
bool waitForNextAudioBlockReady(const AudioSourceChannelInfo &info, uint32 timeout)
A useful function to block until the next the buffer info can be filled.
bool isLooping() const override
Implements the PositionableAudioSource method.
void releaseResources() override
Implementation of the AudioSource method.
int64 getNextReadPosition() const override
Implements the PositionableAudioSource method.
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override
Implementation of the AudioSource method.
Automatically locks and unlocks a mutex object.
Automatically unlocks and re-locks a mutex object.
A type of AudioSource which can be repositioned.
A general-purpose range object, that simply represents any linear range with a start and end point.
static void JUCE_CALLTYPE sleep(int milliseconds)
Suspends the execution of the current thread until the specified timeout period has elapsed (note tha...
A thread that keeps a list of clients, and calls each one in turn, giving them all a chance to run so...
void removeTimeSliceClient(TimeSliceClient *clientToRemove)
Removes a client from the list.
void addTimeSliceClient(TimeSliceClient *clientToAdd, int millisecondsBeforeStarting=0)
Adds a client to the list.
void moveToFrontOfQueue(TimeSliceClient *clientToMove)
If the given client is waiting in the queue, it will be moved to the front and given a time-slice as ...
static uint32 getMillisecondCounter() noexcept
Returns the number of millisecs since a fixed event (usually system startup).
void signal() const
Wakes up any threads that are currently waiting on this object.
bool wait(double timeOutMilliseconds=-1.0) const
Suspends the calling thread until the event has been signalled.
CriticalSection::ScopedLockType ScopedLock
Automatically locks and unlocks a CriticalSection object.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
long long int64
A platform-independent 64-bit integer type.
Used by AudioSource::getNextAudioBlock().
int numSamples
The number of samples in the buffer which the callback is expected to fill with data.
void clearActiveBufferRegion() const
Convenient method to clear the buffer if the source is not producing any data.
AudioBuffer< float > * buffer
The destination buffer to fill with audio data.
int startSample
The first sample in the buffer from which the callback is expected to write data.