1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

AudioIODeviceCallback, AudioBuffer, AudioFormatReader: Use const T* const* for multi-channel data

This commit is contained in:
attila 2022-09-13 17:41:41 +02:00 committed by Attila Szarvas
parent 37d57810f2
commit f075de78fa
44 changed files with 150 additions and 92 deletions

View file

@ -4,6 +4,35 @@ JUCE breaking changes
develop develop
======= =======
Change
------
The type representing multi-channel audio data has been changed from T** to
T* const*. Affected classes are AudioIODeviceCallback, AudioBuffer and
AudioFormatReader.
Possible Issues
---------------
Code overriding the affected AudioIODeviceCallback and AudioFormatReader
functions will fail to compile. Code that interacts with the return value of
AudioBuffer::getArrayOfReadPointers() and AudioBuffer::getArrayOfWritePointers()
may fail to compile.
Workaround
----------
Functions overriding the affected AudioIODeviceCallback and AudioFormatReader
members will need to be changed to confirm to the new signature. Type
declarations related to getArrayOfReadPointers() and getArrayOfWritePointers()
of AudioBuffer may have to be adjusted.
Rationale
---------
While the previous signature permitted it, changing the channel pointers by the
previously used types was already being considered illegal. The earlier type
however prevented passing T** values to parameters with type const T**. In some
places this necessitated the usage of const_cast. The new signature can bind to
T** values and the awkward casting can be avoided.
Change Change
------ ------
The minimum supported C++ standard is now C++17 and the oldest supported The minimum supported C++ standard is now C++17 and the oldest supported

View file

@ -45,8 +45,8 @@ public:
clear(); clear();
} }
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels, void audioDeviceIOCallback (const float* const* inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, float* const* outputChannelData, int numOutputChannels,
int numberOfSamples) override int numberOfSamples) override
{ {
for (int i = 0; i < numberOfSamples; ++i) for (int i = 0; i < numberOfSamples; ++i)

View file

@ -136,8 +136,8 @@ public:
void audioDeviceStopped() override {} void audioDeviceStopped() override {}
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels, void audioDeviceIOCallback (const float* const* inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, int numSamples) override float* const* outputChannelData, int numOutputChannels, int numSamples) override
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);

View file

@ -134,8 +134,8 @@ public:
sampleRate = 0; sampleRate = 0;
} }
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels, void audioDeviceIOCallback (const float* const* inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, float* const* outputChannelData, int numOutputChannels,
int numSamples) override int numSamples) override
{ {
const ScopedLock sl (writerLock); const ScopedLock sl (writerLock);

View file

@ -689,8 +689,8 @@ public:
} }
//============================================================================== //==============================================================================
void audioDeviceIOCallback (const float** /*inputChannelData*/, int /*numInputChannels*/, void audioDeviceIOCallback (const float* const* /*inputChannelData*/, int /*numInputChannels*/,
float** outputChannelData, int numOutputChannels, float* const* outputChannelData, int numOutputChannels,
int numSamples) override int numSamples) override
{ {
AudioBuffer<float> buffer (outputChannelData, numOutputChannels, numSamples); AudioBuffer<float> buffer (outputChannelData, numOutputChannels, numSamples);

View file

@ -662,7 +662,7 @@ private:
{ {
using ElementType = std::remove_pointer_t<decltype (DataFormat::data)>; using ElementType = std::remove_pointer_t<decltype (DataFormat::data)>;
using ChannelType = std::conditional_t<IsConst, const ElementType*, ElementType*>; using ChannelType = std::conditional_t<IsConst, const ElementType*, ElementType*>;
using DataType = std::conditional_t<IsInterleaved, ChannelType, ChannelType*>; using DataType = std::conditional_t<IsInterleaved, ChannelType, ChannelType const*>;
using PointerType = Pointer<DataFormat, using PointerType = Pointer<DataFormat,
Endianness, Endianness,
std::conditional_t<IsInterleaved, Interleaved, NonInterleaved>, std::conditional_t<IsInterleaved, Interleaved, NonInterleaved>,

View file

@ -324,7 +324,7 @@ public:
Don't modify any of the pointers that are returned, and bear in mind that Don't modify any of the pointers that are returned, and bear in mind that
these will become invalid if the buffer is resized. these will become invalid if the buffer is resized.
*/ */
const Type** getArrayOfReadPointers() const noexcept { return const_cast<const Type**> (channels); } const Type* const* getArrayOfReadPointers() const noexcept { return channels; }
/** Returns an array of pointers to the channels in the buffer. /** Returns an array of pointers to the channels in the buffer.
@ -339,7 +339,7 @@ public:
@see setNotClear @see setNotClear
*/ */
Type** getArrayOfWritePointers() noexcept { isClear = false; return channels; } Type* const* getArrayOfWritePointers() noexcept { isClear = false; return channels; }
//============================================================================== //==============================================================================
/** Changes the buffer's size or number of channels. /** Changes the buffer's size or number of channels.
@ -465,7 +465,7 @@ public:
@param newNumSamples the number of samples to use - this must correspond to the @param newNumSamples the number of samples to use - this must correspond to the
size of the arrays passed in size of the arrays passed in
*/ */
void setDataToReferTo (Type** dataToReferTo, void setDataToReferTo (Type* const* dataToReferTo,
int newNumChannels, int newNumChannels,
int newStartSample, int newStartSample,
int newNumSamples) int newNumSamples)
@ -506,7 +506,7 @@ public:
@param newNumSamples the number of samples to use - this must correspond to the @param newNumSamples the number of samples to use - this must correspond to the
size of the arrays passed in size of the arrays passed in
*/ */
void setDataToReferTo (Type** dataToReferTo, void setDataToReferTo (Type* const* dataToReferTo,
int newNumChannels, int newNumChannels,
int newNumSamples) int newNumSamples)
{ {

View file

@ -69,9 +69,9 @@ public:
CallbackHandler (AudioDeviceManager& adm) noexcept : owner (adm) {} CallbackHandler (AudioDeviceManager& adm) noexcept : owner (adm) {}
private: private:
void audioDeviceIOCallbackWithContext (const float** ins, void audioDeviceIOCallbackWithContext (const float* const* ins,
int numIns, int numIns,
float** outs, float* const* outs,
int numOuts, int numOuts,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context) override const AudioIODeviceCallbackContext& context) override
@ -982,9 +982,9 @@ void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToR
} }
} }
void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData, void AudioDeviceManager::audioDeviceIOCallbackInt (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context) const AudioIODeviceCallbackContext& context)
@ -1006,7 +1006,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat
numSamples, numSamples,
context); context);
auto** tempChans = tempBuffer.getArrayOfWritePointers(); auto* const* tempChans = tempBuffer.getArrayOfWritePointers();
for (int i = callbacks.size(); --i > 0;) for (int i = callbacks.size(); --i > 0;)
{ {
@ -1048,7 +1048,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat
testSound.reset(); testSound.reset();
} }
outputLevelGetter->updateLevel (const_cast<const float**> (outputChannelData), numOutputChannels, numSamples); outputLevelGetter->updateLevel (outputChannelData, numOutputChannels, numSamples);
} }
void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device) void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
@ -1891,7 +1891,7 @@ private:
std::function<void()> stopped; std::function<void()> stopped;
std::function<void()> error; std::function<void()> error;
void audioDeviceIOCallback (const float**, int, float**, int, int) override { NullCheckedInvocation::invoke (callback); } void audioDeviceIOCallback (const float* const*, int, float* const*, int, int) override { NullCheckedInvocation::invoke (callback); }
void audioDeviceAboutToStart (AudioIODevice*) override { NullCheckedInvocation::invoke (aboutToStart); } void audioDeviceAboutToStart (AudioIODevice*) override { NullCheckedInvocation::invoke (aboutToStart); }
void audioDeviceStopped() override { NullCheckedInvocation::invoke (stopped); } void audioDeviceStopped() override { NullCheckedInvocation::invoke (stopped); }
void audioDeviceError (const String&) override { NullCheckedInvocation::invoke (error); } void audioDeviceError (const String&) override { NullCheckedInvocation::invoke (error); }

View file

@ -526,9 +526,9 @@ private:
class CallbackHandler; class CallbackHandler;
std::unique_ptr<CallbackHandler> callbackHandler; std::unique_ptr<CallbackHandler> callbackHandler;
void audioDeviceIOCallbackInt (const float** inputChannelData, void audioDeviceIOCallbackInt (const float* const* inputChannelData,
int totalNumInputChannels, int totalNumInputChannels,
float** outputChannelData, float* const* outputChannelData,
int totalNumOutputChannels, int totalNumOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context); const AudioIODeviceCallbackContext& context);

View file

@ -91,9 +91,9 @@ public:
performance. So make sure your code can cope with reasonable performance. So make sure your code can cope with reasonable
changes in the buffer size from one callback to the next. changes in the buffer size from one callback to the next.
*/ */
virtual void audioDeviceIOCallback (const float** inputChannelData, virtual void audioDeviceIOCallback (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples) int numSamples)
{ {
@ -105,9 +105,9 @@ public:
The default implementation of this function will call audioDeviceIOCallback(), The default implementation of this function will call audioDeviceIOCallback(),
but you can override this function if you need to make use of the context information. but you can override this function if you need to make use of the context information.
*/ */
virtual void audioDeviceIOCallbackWithContext (const float** inputChannelData, virtual void audioDeviceIOCallbackWithContext (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context) const AudioIODeviceCallbackContext& context)

View file

@ -423,8 +423,8 @@ private:
} }
} }
void process (const float** inputChannelData, int numInputChannels, void process (const float* const* inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, int32_t numFrames) float* const* outputChannelData, int numOutputChannels, int32_t numFrames)
{ {
if (auto* cb = callback.exchange (nullptr)) if (auto* cb = callback.exchange (nullptr))
{ {

View file

@ -892,8 +892,8 @@ struct iOSAudioIODevice::Pimpl : public AsyncUpdater
if ((int) numFrames > channelData.getFloatBufferSize()) if ((int) numFrames > channelData.getFloatBufferSize())
channelData.setFloatBufferSize ((int) numFrames); channelData.setFloatBufferSize ((int) numFrames);
float** const inputData = channelData.audioData.getArrayOfWritePointers(); float* const* const inputData = channelData.audioData.getArrayOfWritePointers();
float** const outputData = inputData + channelData.inputs->numActiveChannels; float* const* const outputData = inputData + channelData.inputs->numActiveChannels;
if (useInput) if (useInput)
{ {

View file

@ -462,7 +462,7 @@ private:
if (callback != nullptr) if (callback != nullptr)
{ {
if ((numActiveInChans + numActiveOutChans) > 0) if ((numActiveInChans + numActiveOutChans) > 0)
callback->audioDeviceIOCallbackWithContext (const_cast<const float**> (inChans.getData()), callback->audioDeviceIOCallbackWithContext (inChans.getData(),
numActiveInChans, numActiveInChans,
outChans, outChans,
numActiveOutChans, numActiveOutChans,

View file

@ -852,7 +852,7 @@ public:
const auto nanos = timeStamp != nullptr ? timeConversions.hostTimeToNanos (timeStamp->mHostTime) : 0; const auto nanos = timeStamp != nullptr ? timeConversions.hostTimeToNanos (timeStamp->mHostTime) : 0;
callback->audioDeviceIOCallbackWithContext (const_cast<const float**> (tempInputBuffers.get()), callback->audioDeviceIOCallbackWithContext (tempInputBuffers.get(),
numInputChans, numInputChans,
tempOutputBuffers, tempOutputBuffers,
numOutputChans, numOutputChans,
@ -1685,8 +1685,8 @@ private:
bool active = false; bool active = false;
String lastError; String lastError;
AudioBuffer<float> fifos; AudioBuffer<float> fifos;
const float** fifoReadPointers = nullptr; const float* const* fifoReadPointers = nullptr;
float** fifoWritePointers = nullptr; float* const* fifoWritePointers = nullptr;
WaitableEvent threadInitialised; WaitableEvent threadInitialised;
CriticalSection closeLock; CriticalSection closeLock;
@ -2032,9 +2032,9 @@ private:
outputFifo.finishedWrite (size1 + size2); outputFifo.finishedWrite (size1 + size2);
} }
void audioDeviceIOCallbackWithContext (const float** inputChannelData, void audioDeviceIOCallbackWithContext (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext&) override const AudioIODeviceCallbackContext&) override

View file

@ -1326,7 +1326,7 @@ private:
inputFormat[i].convertToFloat (infos[i].buffers[bufferIndex], inBuffers[i], samps); inputFormat[i].convertToFloat (infos[i].buffers[bufferIndex], inBuffers[i], samps);
} }
currentCallback->audioDeviceIOCallbackWithContext (const_cast<const float**> (inBuffers.getData()), currentCallback->audioDeviceIOCallbackWithContext (inBuffers.getData(),
numActiveInputChans, numActiveInputChans,
outBuffers, outBuffers,
numActiveOutputChans, numActiveOutputChans,

View file

@ -1552,7 +1552,7 @@ public:
const ScopedTryLock sl (startStopLock); const ScopedTryLock sl (startStopLock);
if (sl.isLocked() && isStarted) if (sl.isLocked() && isStarted)
callback->audioDeviceIOCallbackWithContext (const_cast<const float**> (inputBuffers), callback->audioDeviceIOCallbackWithContext (inputBuffers,
numInputBuffers, numInputBuffers,
outputBuffers, outputBuffers,
numOutputBuffers, numOutputBuffers,
@ -1566,7 +1566,7 @@ public:
{ {
// Note that this function is handed the input device so it can check for the event and make sure // Note that this function is handed the input device so it can check for the event and make sure
// the input reservoir is filled up correctly even when bufferSize > device actualBufferSize // the input reservoir is filled up correctly even when bufferSize > device actualBufferSize
outputDevice->copyBuffers (const_cast<const float**> (outputBuffers), numOutputBuffers, bufferSize, inputDevice.get(), *this); outputDevice->copyBuffers (outputBuffers, numOutputBuffers, bufferSize, inputDevice.get(), *this);
if (outputDevice->sampleRateHasChanged) if (outputDevice->sampleRateHasChanged)
{ {

View file

@ -56,9 +56,9 @@ void AudioSourcePlayer::setGain (const float newGain) noexcept
gain = newGain; gain = newGain;
} }
void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData, void AudioSourcePlayer::audioDeviceIOCallback (const float* const* inputChannelData,
int totalNumInputChannels, int totalNumInputChannels,
float** outputChannelData, float* const* outputChannelData,
int totalNumOutputChannels, int totalNumOutputChannels,
int numSamples) int numSamples)
{ {

View file

@ -80,9 +80,9 @@ public:
//============================================================================== //==============================================================================
/** Implementation of the AudioIODeviceCallback method. */ /** Implementation of the AudioIODeviceCallback method. */
void audioDeviceIOCallback (const float** inputChannelData, void audioDeviceIOCallback (const float* const* inputChannelData,
int totalNumInputChannels, int totalNumInputChannels,
float** outputChannelData, float* const* outputChannelData,
int totalNumOutputChannels, int totalNumOutputChannels,
int numSamples) override; int numSamples) override;

View file

@ -573,7 +573,7 @@ public:
} }
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
@ -829,7 +829,7 @@ public:
{ {
} }
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,

View file

@ -502,7 +502,7 @@ public:
} }
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,

View file

@ -230,7 +230,7 @@ public:
reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true); reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true);
} }
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
if (! ok) if (! ok)

View file

@ -2975,7 +2975,7 @@ public:
} }
} }
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
if (destSamples == nullptr) if (destSamples == nullptr)
@ -3033,7 +3033,7 @@ public:
} }
const int numToCopy = jmin (decodedEnd - decodedStart, numSamples); const int numToCopy = jmin (decodedEnd - decodedStart, numSamples);
float* const* const dst = reinterpret_cast<float**> (destSamples); float* const* const dst = reinterpret_cast<float* const*> (destSamples);
memcpy (dst[0] + startOffsetInDestBuffer, decoded0 + decodedStart, (size_t) numToCopy * sizeof (float)); memcpy (dst[0] + startOffsetInDestBuffer, decoded0 + decodedStart, (size_t) numToCopy * sizeof (float));
if (numDestChannels > 1 && dst[1] != nullptr) if (numDestChannels > 1 && dst[1] != nullptr)

View file

@ -158,7 +158,7 @@ public:
} }
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
const auto getBufferedRange = [this] { return bufferedRange; }; const auto getBufferedRange = [this] { return bufferedRange; };

View file

@ -1476,7 +1476,7 @@ public:
} }
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
@ -1852,7 +1852,7 @@ public:
{ {
} }
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,

View file

@ -163,7 +163,7 @@ public:
wmSyncReader->Close(); wmSyncReader->Close();
} }
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
if (sampleRate <= 0) if (sampleRate <= 0)

View file

@ -115,7 +115,7 @@ void ARAAudioSourceReader::willDestroyAudioSource (ARAAudioSource* audioSource)
invalidate(); invalidate();
} }
bool ARAAudioSourceReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool ARAAudioSourceReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) int64 startSampleInFile, int numSamples)
{ {
const auto destSize = (bitsPerSample / 8) * (size_t) numSamples; const auto destSize = (bitsPerSample / 8) * (size_t) numSamples;
@ -237,7 +237,7 @@ void ARAPlaybackRegionReader::invalidate()
playbackRenderer.reset(); playbackRenderer.reset();
} }
bool ARAPlaybackRegionReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool ARAPlaybackRegionReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) int64 startSampleInFile, int numSamples)
{ {
bool success = false; bool success = false;

View file

@ -83,7 +83,7 @@ public:
~ARAAudioSourceReader() override; ~ARAAudioSourceReader() override;
bool readSamples (int** destSamples, bool readSamples (int* const* destSamples,
int numDestChannels, int numDestChannels,
int startOffsetInDestBuffer, int startOffsetInDestBuffer,
int64 startSampleInFile, int64 startSampleInFile,
@ -166,7 +166,7 @@ public:
*/ */
void invalidate(); void invalidate();
bool readSamples (int** destSamples, bool readSamples (int* const* destSamples,
int numDestChannels, int numDestChannels,
int startOffsetInDestBuffer, int startOffsetInDestBuffer,
int64 startSampleInFile, int64 startSampleInFile,

View file

@ -86,7 +86,7 @@ bool AudioFormatReader::read (int* const* destChannels,
if (numSamplesToRead <= 0) if (numSamplesToRead <= 0)
return true; return true;
if (! readSamples (const_cast<int**> (destChannels), if (! readSamples (destChannels,
jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer, jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
startSampleInSource, numSamplesToRead)) startSampleInSource, numSamplesToRead))
return false; return false;

View file

@ -267,7 +267,7 @@ public:
to begin reading. This value is guaranteed to be >= 0. to begin reading. This value is guaranteed to be >= 0.
@param numSamples the number of samples to read @param numSamples the number of samples to read
*/ */
virtual bool readSamples (int** destChannels, virtual bool readSamples (int* const* destChannels,
int numDestChannels, int numDestChannels,
int startOffsetInDestBuffer, int startOffsetInDestBuffer,
int64 startSampleInFile, int64 startSampleInFile,
@ -306,7 +306,7 @@ protected:
/** Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie /** Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie
beyond the end of their available length. beyond the end of their available length.
*/ */
static void clearSamplesBeyondAvailableLength (int** destChannels, int numDestChannels, static void clearSamplesBeyondAvailableLength (int* const* destChannels, int numDestChannels,
int startOffsetInDestBuffer, int64 startSampleInFile, int startOffsetInDestBuffer, int64 startSampleInFile,
int& numSamples, int64 fileLengthInSamples) int& numSamples, int64 fileLengthInSamples)
{ {

View file

@ -50,7 +50,7 @@ AudioSubsectionReader::~AudioSubsectionReader()
} }
//============================================================================== //==============================================================================
bool AudioSubsectionReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool AudioSubsectionReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) int64 startSampleInFile, int numSamples)
{ {
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,

View file

@ -66,7 +66,7 @@ public:
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override; int64 startSampleInFile, int numSamples) override;
void readMaxLevels (int64 startSample, int64 numSamples, void readMaxLevels (int64 startSample, int64 numSamples,

View file

@ -53,7 +53,7 @@ void BufferingAudioReader::setReadTimeout (int timeoutMilliseconds) noexcept
timeoutMs = timeoutMilliseconds; timeoutMs = timeoutMilliseconds;
} }
bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool BufferingAudioReader::readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) int64 startSampleInFile, int numSamples)
{ {
auto startTime = Time::getMillisecondCounter(); auto startTime = Time::getMillisecondCounter();
@ -218,7 +218,7 @@ struct TestAudioFormatReader : public AudioFormatReader
numChannels = (unsigned int) buffer.getNumChannels(); numChannels = (unsigned int) buffer.getNumChannels();
} }
bool readSamples (int** destChannels, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destChannels, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override int64 startSampleInFile, int numSamples) override
{ {
clearSamplesBeyondAvailableLength (destChannels, numDestChannels, startOffsetInDestBuffer, clearSamplesBeyondAvailableLength (destChannels, numDestChannels, startOffsetInDestBuffer,
@ -270,7 +270,7 @@ public:
numChannels = 2; numChannels = 2;
} }
bool readSamples (int**, int, int, int64, int) override bool readSamples (int* const*, int, int, int64, int) override
{ {
Thread::sleep (100); Thread::sleep (100);
return true; return true;

View file

@ -63,7 +63,7 @@ public:
void setReadTimeout (int timeoutMilliseconds) noexcept; void setReadTimeout (int timeoutMilliseconds) noexcept;
//============================================================================== //==============================================================================
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, bool readSamples (int* const* destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples) override; int64 startSampleInFile, int numSamples) override;
private: private:

View file

@ -484,7 +484,7 @@ public:
template<typename UnaryFunction> template<typename UnaryFunction>
static void iterateAudioBuffer (AudioBuffer<float>& ab, UnaryFunction fn) static void iterateAudioBuffer (AudioBuffer<float>& ab, UnaryFunction fn)
{ {
float** sampleData = ab.getArrayOfWritePointers(); float* const* sampleData = ab.getArrayOfWritePointers();
for (int c = ab.getNumChannels(); --c >= 0;) for (int c = ab.getNumChannels(); --c >= 0;)
for (int s = ab.getNumSamples(); --s >= 0;) for (int s = ab.getNumSamples(); --s >= 0;)

View file

@ -448,9 +448,9 @@ private:
inner.audioDeviceAboutToStart (device); inner.audioDeviceAboutToStart (device);
} }
void audioDeviceIOCallbackWithContext (const float** inputChannelData, void audioDeviceIOCallbackWithContext (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context) override const AudioIODeviceCallbackContext& context) override
@ -600,9 +600,9 @@ private:
}; };
//============================================================================== //==============================================================================
void audioDeviceIOCallbackWithContext (const float** inputChannelData, void audioDeviceIOCallbackWithContext (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples, int numSamples,
const AudioIODeviceCallbackContext& context) override const AudioIODeviceCallbackContext& context) override

View file

@ -829,6 +829,34 @@ static const int defaultVSTBlockSizeValue = 512;
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
class TempChannelPointers
{
public:
template <typename T>
auto getArrayOfModifiableWritePointers (AudioBuffer<T>& buffer)
{
auto& pointers = getPointers (Tag<T>{});
jassert ((int) pointers.size() < buffer.getNumChannels());
pointers.resize (jmax (pointers.size(), (size_t) buffer.getNumChannels()));
std::copy (buffer.getArrayOfWritePointers(),
buffer.getArrayOfWritePointers() + buffer.getNumChannels(),
pointers.begin());
return pointers.data();
}
private:
template <typename> struct Tag {};
auto& getPointers (Tag<float>) { return floatPointers; }
auto& getPointers (Tag<double>) { return doublePointers; }
std::vector<float*> floatPointers { 128 };
std::vector<double*> doublePointers { 128 };
};
//============================================================================== //==============================================================================
struct VSTPluginInstance final : public AudioPluginInstance, struct VSTPluginInstance final : public AudioPluginInstance,
private Timer, private Timer,
@ -2026,6 +2054,7 @@ private:
bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false; bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false;
mutable StringArray programNames; mutable StringArray programNames;
AudioBuffer<float> outOfPlaceBuffer; AudioBuffer<float> outOfPlaceBuffer;
TempChannelPointers tempChannelPointers[2];
CriticalSection midiInLock; CriticalSection midiInLock;
MidiBuffer incomingMidi; MidiBuffer incomingMidi;
@ -2456,16 +2485,16 @@ private:
{ {
if ((vstEffect->flags & Vst2::effFlagsCanReplacing) != 0) if ((vstEffect->flags & Vst2::effFlagsCanReplacing) != 0)
{ {
vstEffect->processReplacing (vstEffect, buffer.getArrayOfWritePointers(), vstEffect->processReplacing (vstEffect, tempChannelPointers[0].getArrayOfModifiableWritePointers (buffer),
buffer.getArrayOfWritePointers(), sampleFrames); tempChannelPointers[1].getArrayOfModifiableWritePointers (buffer), sampleFrames);
} }
else else
{ {
outOfPlaceBuffer.setSize (vstEffect->numOutputs, sampleFrames); outOfPlaceBuffer.setSize (vstEffect->numOutputs, sampleFrames);
outOfPlaceBuffer.clear(); outOfPlaceBuffer.clear();
vstEffect->process (vstEffect, buffer.getArrayOfWritePointers(), vstEffect->process (vstEffect, tempChannelPointers[0].getArrayOfModifiableWritePointers (buffer),
outOfPlaceBuffer.getArrayOfWritePointers(), sampleFrames); tempChannelPointers[1].getArrayOfModifiableWritePointers (outOfPlaceBuffer), sampleFrames);
for (int i = vstEffect->numOutputs; --i >= 0;) for (int i = vstEffect->numOutputs; --i >= 0;)
buffer.copyFrom (i, 0, outOfPlaceBuffer.getReadPointer (i), sampleFrames); buffer.copyFrom (i, 0, outOfPlaceBuffer.getReadPointer (i), sampleFrames);
@ -2474,8 +2503,8 @@ private:
inline void invokeProcessFunction (AudioBuffer<double>& buffer, int32 sampleFrames) inline void invokeProcessFunction (AudioBuffer<double>& buffer, int32 sampleFrames)
{ {
vstEffect->processDoubleReplacing (vstEffect, buffer.getArrayOfWritePointers(), vstEffect->processDoubleReplacing (vstEffect, tempChannelPointers[0].getArrayOfModifiableWritePointers (buffer),
buffer.getArrayOfWritePointers(), sampleFrames); tempChannelPointers[1].getArrayOfModifiableWritePointers (buffer), sampleFrames);
} }
//============================================================================== //==============================================================================

View file

@ -444,7 +444,7 @@ struct GraphRenderSequence
struct Context struct Context
{ {
FloatType** audioBuffers; FloatType* const* audioBuffers;
MidiBuffer* midiBuffers; MidiBuffer* midiBuffers;
AudioPlayHead* audioPlayHead; AudioPlayHead* audioPlayHead;
int numSamples; int numSamples;

View file

@ -119,7 +119,7 @@ void AudioVisualiserComponent::clear()
c->clear(); c->clear();
} }
void AudioVisualiserComponent::pushBuffer (const float** d, int numChannels, int num) void AudioVisualiserComponent::pushBuffer (const float* const* d, int numChannels, int num)
{ {
numChannels = jmin (numChannels, channels.size()); numChannels = jmin (numChannels, channels.size());

View file

@ -87,7 +87,7 @@ public:
The number of channels provided here is expected to match the number of channels The number of channels provided here is expected to match the number of channels
that this AudioVisualiserComponent has been told to use. that this AudioVisualiserComponent has been told to use.
*/ */
void pushBuffer (const float** channelData, int numChannels, int numSamples); void pushBuffer (const float* const* channelData, int numChannels, int numSamples);
/** Pushes a single sample (per channel). /** Pushes a single sample (per channel).
The number of channels provided here is expected to match the number of channels The number of channels provided here is expected to match the number of channels

View file

@ -30,10 +30,10 @@ template <typename Value>
struct ChannelInfo struct ChannelInfo
{ {
ChannelInfo() = default; ChannelInfo() = default;
ChannelInfo (Value** dataIn, int numChannelsIn) ChannelInfo (Value* const* dataIn, int numChannelsIn)
: data (dataIn), numChannels (numChannelsIn) {} : data (dataIn), numChannels (numChannelsIn) {}
Value** data = nullptr; Value* const* data = nullptr;
int numChannels = 0; int numChannels = 0;
}; };
@ -235,9 +235,9 @@ void AudioProcessorPlayer::setMidiOutput (MidiOutput* midiOutputToUse)
} }
//============================================================================== //==============================================================================
void AudioProcessorPlayer::audioDeviceIOCallbackWithContext (const float** const inputChannelData, void AudioProcessorPlayer::audioDeviceIOCallbackWithContext (const float* const* const inputChannelData,
const int numInputChannels, const int numInputChannels,
float** const outputChannelData, float* const* const outputChannelData,
const int numOutputChannels, const int numOutputChannels,
const int numSamples, const int numSamples,
const AudioIODeviceCallbackContext& context) const AudioIODeviceCallbackContext& context)

View file

@ -92,7 +92,7 @@ public:
//============================================================================== //==============================================================================
/** @internal */ /** @internal */
void audioDeviceIOCallbackWithContext (const float**, int, float**, int, int, const AudioIODeviceCallbackContext&) override; void audioDeviceIOCallbackWithContext (const float* const*, int, float* const*, int, int, const AudioIODeviceCallbackContext&) override;
/** @internal */ /** @internal */
void audioDeviceAboutToStart (AudioIODevice*) override; void audioDeviceAboutToStart (AudioIODevice*) override;
/** @internal */ /** @internal */

View file

@ -242,9 +242,9 @@ void SoundPlayer::playTestSound()
} }
//============================================================================== //==============================================================================
void SoundPlayer::audioDeviceIOCallback (const float** inputChannelData, void SoundPlayer::audioDeviceIOCallback (const float* const* inputChannelData,
int numInputChannels, int numInputChannels,
float** outputChannelData, float* const* outputChannelData,
int numOutputChannels, int numOutputChannels,
int numSamples) int numSamples)
{ {

View file

@ -110,7 +110,7 @@ public:
//============================================================================== //==============================================================================
/** @internal */ /** @internal */
void audioDeviceIOCallback (const float**, int, float**, int, int) override; void audioDeviceIOCallback (const float* const*, int, float* const*, int, int) override;
/** @internal */ /** @internal */
void audioDeviceAboutToStart (AudioIODevice*) override; void audioDeviceAboutToStart (AudioIODevice*) override;
/** @internal */ /** @internal */

View file

@ -62,7 +62,7 @@ class ConvolutionTest : public UnitTest
AudioBuffer<float> result (2, length); AudioBuffer<float> result (2, length);
result.clear(); result.clear();
auto** channels = result.getArrayOfWritePointers(); auto* const* channels = result.getArrayOfWritePointers();
std::for_each (channels, channels + result.getNumChannels(), [length] (auto* channel) std::for_each (channels, channels + result.getNumChannels(), [length] (auto* channel)
{ {
std::fill (channel, channel + length, 1.0f); std::fill (channel, channel + length, 1.0f);