diff --git a/extras/Demo/Source/Demos/AudioLatencyDemo.cpp b/extras/Demo/Source/Demos/AudioLatencyDemo.cpp index c679caf6d5..f29694e751 100644 --- a/extras/Demo/Source/Demos/AudioLatencyDemo.cpp +++ b/extras/Demo/Source/Demos/AudioLatencyDemo.cpp @@ -137,8 +137,8 @@ public: if (testIsRunning) { - float* const recordingBuffer = recordedSound.getSampleData (0, 0); - const float* const playBuffer = testSound.getSampleData (0, 0); + float* const recordingBuffer = recordedSound.getWritePointer (0); + const float* const playBuffer = testSound.getReadPointer (0); for (int i = 0; i < numSamples; ++i) { @@ -188,12 +188,11 @@ private: const int length = ((int) sampleRate) / 4; testSound.setSize (1, length); testSound.clear(); - float* s = testSound.getSampleData (0, 0); Random rand; for (int i = 0; i < length; ++i) - s[i] = (rand.nextFloat() - rand.nextFloat() + rand.nextFloat() - rand.nextFloat()) * 0.06f; + testSound.setSample (0, i, (rand.nextFloat() - rand.nextFloat() + rand.nextFloat() - rand.nextFloat()) * 0.06f); spikePositions.clear(); @@ -204,8 +203,8 @@ private: { spikePositions.add (spikePos); - s[spikePos] = 0.99f; - s[spikePos + 1] = -0.99f; + testSound.setSample (0, spikePos, 0.99f); + testSound.setSample (0, spikePos + 1, -0.99f); spikePos += spikeDelta; spikeDelta += spikeDelta / 6 + rand.nextInt (5); @@ -217,7 +216,7 @@ private: { const float minSpikeLevel = 5.0f; const double smooth = 0.975; - const float* s = buffer.getSampleData (0, 0); + const float* s = buffer.getReadPointer (0); const int spikeDriftAllowed = 5; Array spikesFound; diff --git a/extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp b/extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp index d5124519fa..f2e9b9aa24 100644 --- a/extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp +++ b/extras/Demo/Source/Demos/AudioSynthesiserDemo.cpp @@ -104,7 +104,7 @@ struct SineWaveVoice : public SynthesiserVoice const float currentSample = (float) (sin (currentAngle) * level * tailOff); for (int i = outputBuffer.getNumChannels(); --i >= 0;) - *outputBuffer.getSampleData (i, startSample) += currentSample; + outputBuffer.addSample (i, startSample, currentSample); currentAngle += angleDelta; ++startSample; @@ -127,7 +127,7 @@ struct SineWaveVoice : public SynthesiserVoice const float currentSample = (float) (sin (currentAngle) * level); for (int i = outputBuffer.getNumChannels(); --i >= 0;) - *outputBuffer.getSampleData (i, startSample) += currentSample; + outputBuffer.addSample (i, startSample, currentSample); currentAngle += angleDelta; ++startSample; diff --git a/extras/Introjucer/JuceLibraryCode/BinaryData.cpp b/extras/Introjucer/JuceLibraryCode/BinaryData.cpp index ef5a35b4b6..8fa27b5295 100644 --- a/extras/Introjucer/JuceLibraryCode/BinaryData.cpp +++ b/extras/Introjucer/JuceLibraryCode/BinaryData.cpp @@ -386,7 +386,7 @@ static const unsigned char temp_binary_data_6[] = " // audio processing...\r\n" " for (int channel = 0; channel < getNumInputChannels(); ++channel)\r\n" " {\r\n" -" float* channelData = buffer.getSampleData (channel);\r\n" +" float* channelData = buffer.getWritePointer (channel);\r\n" "\r\n" " // ..do something to the data...\r\n" " }\r\n" @@ -1234,7 +1234,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw case 0xe8b08520: numBytes = 1050; return colourscheme_light_xml; case 0x27c5a93a: numBytes = 1008; return jucer_AudioPluginEditorTemplate_cpp; case 0x4d0721bf: numBytes = 799; return jucer_AudioPluginEditorTemplate_h; - case 0x51b49ac5: numBytes = 4638; return jucer_AudioPluginFilterTemplate_cpp; + case 0x51b49ac5: numBytes = 4640; return jucer_AudioPluginFilterTemplate_cpp; case 0x488afa0a: numBytes = 2488; return jucer_AudioPluginFilterTemplate_h; case 0xabad7041: numBytes = 2083; return jucer_ComponentTemplate_cpp; case 0xfc72fe86: numBytes = 2156; return jucer_ComponentTemplate_h; diff --git a/extras/Introjucer/JuceLibraryCode/BinaryData.h b/extras/Introjucer/JuceLibraryCode/BinaryData.h index 9b351817af..7ccadd2365 100644 --- a/extras/Introjucer/JuceLibraryCode/BinaryData.h +++ b/extras/Introjucer/JuceLibraryCode/BinaryData.h @@ -28,7 +28,7 @@ namespace BinaryData const int jucer_AudioPluginEditorTemplate_hSize = 799; extern const char* jucer_AudioPluginFilterTemplate_cpp; - const int jucer_AudioPluginFilterTemplate_cppSize = 4638; + const int jucer_AudioPluginFilterTemplate_cppSize = 4640; extern const char* jucer_AudioPluginFilterTemplate_h; const int jucer_AudioPluginFilterTemplate_hSize = 2488; diff --git a/extras/Introjucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp b/extras/Introjucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp index 4dfbf7995a..fad44550da 100644 --- a/extras/Introjucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp +++ b/extras/Introjucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp @@ -140,7 +140,7 @@ void FILTERCLASSNAME::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiM // audio processing... for (int channel = 0; channel < getNumInputChannels(); ++channel) { - float* channelData = buffer.getSampleData (channel); + float* channelData = buffer.getWritePointer (channel); // ..do something to the data... } diff --git a/extras/audio plugin demo/Source/PluginProcessor.cpp b/extras/audio plugin demo/Source/PluginProcessor.cpp index 664a21cc9b..39a633e835 100644 --- a/extras/audio plugin demo/Source/PluginProcessor.cpp +++ b/extras/audio plugin demo/Source/PluginProcessor.cpp @@ -95,7 +95,7 @@ public: const float currentSample = (float) (sin (currentAngle) * level * tailOff); for (int i = outputBuffer.getNumChannels(); --i >= 0;) - *outputBuffer.getSampleData (i, startSample) += currentSample; + outputBuffer.addSample (i, startSample, currentSample); currentAngle += angleDelta; ++startSample; @@ -118,7 +118,7 @@ public: const float currentSample = (float) (sin (currentAngle) * level); for (int i = outputBuffer.getNumChannels(); --i >= 0;) - *outputBuffer.getSampleData (i, startSample) += currentSample; + outputBuffer.addSample (i, startSample, currentSample); currentAngle += angleDelta; ++startSample; @@ -263,8 +263,8 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi // Apply our delay effect to the new output.. for (channel = 0; channel < getNumInputChannels(); ++channel) { - float* channelData = buffer.getSampleData (channel); - float* delayData = delayBuffer.getSampleData (jmin (channel, delayBuffer.getNumChannels() - 1)); + float* channelData = buffer.getWritePointer (channel); + float* delayData = delayBuffer.getWritePointer (jmin (channel, delayBuffer.getNumChannels() - 1)); dp = delayPosition; for (int i = 0; i < numSamples; ++i) diff --git a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp index 0200d1443b..3addc5a193 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp @@ -46,8 +46,15 @@ AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) noexcept { allocateData(); - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); + if (other.isClear) + { + clear(); + } + else + { + for (int i = 0; i < numChannels; ++i) + FloatVectorOperations::copy (channels[i], other.channels[i], size); + } } } @@ -66,6 +73,7 @@ void AudioSampleBuffer::allocateData() } channels [numChannels] = nullptr; + isClear = false; } AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, @@ -85,7 +93,8 @@ AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, const int numSamples) noexcept : numChannels (numChans), size (numSamples), - allocatedBytes (0) + allocatedBytes (0), + isClear (false) { jassert (numChans > 0); allocateChannels (dataToReferTo, startSample); @@ -104,6 +113,7 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, size = newNumSamples; allocateChannels (dataToReferTo, 0); + jassert (! isClear); } void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int offset) @@ -128,6 +138,7 @@ void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int } channels [numChannels] = nullptr; + isClear = false; } AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) noexcept @@ -136,8 +147,15 @@ AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) { setSize (other.getNumChannels(), other.getNumSamples(), false, false, false); - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); + if (other.isClear) + { + clear(); + } + else + { + for (int i = 0; i < numChannels; ++i) + FloatVectorOperations::copy (channels[i], other.channels[i], size); + } } return *this; @@ -165,13 +183,13 @@ void AudioSampleBuffer::setSize (const int newNumChannels, if (keepExistingContent) { - HeapBlock newData; - newData.allocate (newTotalBytes, clearExtraSpace); + HeapBlock newData; + newData.allocate (newTotalBytes, clearExtraSpace || isClear); const size_t numSamplesToCopy = (size_t) jmin (newNumSamples, size); - float** const newChannels = reinterpret_cast (newData.getData()); - float* newChan = reinterpret_cast (newData + channelListSize); + float** const newChannels = reinterpret_cast (newData.getData()); + float* newChan = reinterpret_cast (newData + channelListSize); for (int j = 0; j < newNumChannels; ++j) { @@ -179,9 +197,12 @@ void AudioSampleBuffer::setSize (const int newNumChannels, newChan += allocatedSamplesPerChannel; } - const int numChansToCopy = jmin (numChannels, newNumChannels); - for (int i = 0; i < numChansToCopy; ++i) - FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy); + if (! isClear) + { + const int numChansToCopy = jmin (numChannels, newNumChannels); + for (int i = 0; i < numChansToCopy; ++i) + FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy); + } allocatedData.swapWith (newData); allocatedBytes = newTotalBytes; @@ -191,17 +212,17 @@ void AudioSampleBuffer::setSize (const int newNumChannels, { if (avoidReallocating && allocatedBytes >= newTotalBytes) { - if (clearExtraSpace) + if (clearExtraSpace || isClear) allocatedData.clear (newTotalBytes); } else { allocatedBytes = newTotalBytes; - allocatedData.allocate (newTotalBytes, clearExtraSpace); - channels = reinterpret_cast (allocatedData.getData()); + allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); + channels = reinterpret_cast (allocatedData.getData()); } - float* chan = reinterpret_cast (allocatedData + channelListSize); + float* chan = reinterpret_cast (allocatedData + channelListSize); for (int i = 0; i < newNumChannels; ++i) { channels[i] = chan; @@ -217,8 +238,13 @@ void AudioSampleBuffer::setSize (const int newNumChannels, void AudioSampleBuffer::clear() noexcept { - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i], size); + if (! isClear) + { + for (int i = 0; i < numChannels; ++i) + FloatVectorOperations::clear (channels[i], size); + + isClear = true; + } } void AudioSampleBuffer::clear (const int startSample, @@ -226,8 +252,14 @@ void AudioSampleBuffer::clear (const int startSample, { jassert (startSample >= 0 && startSample + numSamples <= size); - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i] + startSample, numSamples); + if (! isClear) + { + if (startSample == 0 && numSamples == size) + isClear = true; + + for (int i = 0; i < numChannels; ++i) + FloatVectorOperations::clear (channels[i] + startSample, numSamples); + } } void AudioSampleBuffer::clear (const int channel, @@ -237,7 +269,31 @@ void AudioSampleBuffer::clear (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - FloatVectorOperations::clear (channels [channel] + startSample, numSamples); + if (! isClear) + FloatVectorOperations::clear (channels [channel] + startSample, numSamples); +} + +float AudioSampleBuffer::getSample (int channel, int index) const noexcept +{ + jassert (isPositiveAndBelow (channel, numChannels)); + jassert (isPositiveAndBelow (index, size)); + return *(channels [channel] + index); +} + +void AudioSampleBuffer::setSample (int channel, int index, float newValue) noexcept +{ + jassert (isPositiveAndBelow (channel, numChannels)); + jassert (isPositiveAndBelow (index, size)); + *(channels [channel] + index) = newValue; + isClear = false; +} + +void AudioSampleBuffer::addSample (int channel, int index, float valueToAdd) noexcept +{ + jassert (isPositiveAndBelow (channel, numChannels)); + jassert (isPositiveAndBelow (index, size)); + *(channels [channel] + index) += valueToAdd; + isClear = false; } void AudioSampleBuffer::applyGain (const int channel, @@ -248,7 +304,7 @@ void AudioSampleBuffer::applyGain (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - if (gain != 1.0f) + if (gain != 1.0f && ! isClear) { float* const d = channels [channel] + startSample; @@ -265,22 +321,25 @@ void AudioSampleBuffer::applyGainRamp (const int channel, float startGain, float endGain) noexcept { - if (startGain == endGain) + if (! isClear) { - applyGain (channel, startSample, numSamples, startGain); - } - else - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + if (startGain == endGain) + { + applyGain (channel, startSample, numSamples, startGain); + } + else + { + jassert (isPositiveAndBelow (channel, numChannels)); + jassert (startSample >= 0 && startSample + numSamples <= size); - const float increment = (endGain - startGain) / numSamples; - float* d = channels [channel] + startSample; + const float increment = (endGain - startGain) / numSamples; + float* d = channels [channel] + startSample; - while (--numSamples >= 0) - { - *d++ *= startGain; - startGain += increment; + while (--numSamples >= 0) + { + *d++ *= startGain; + startGain += increment; + } } } } @@ -317,15 +376,27 @@ void AudioSampleBuffer::addFrom (const int destChannel, jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - if (gain != 0.0f && numSamples > 0) + if (gain != 0.0f && numSamples > 0 && ! source.isClear) { float* const d = channels [destChannel] + destStartSample; const float* const s = source.channels [sourceChannel] + sourceStartSample; - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); + if (isClear) + { + isClear = false; + + if (gain != 1.0f) + FloatVectorOperations::copyWithMultiply (d, s, gain, numSamples); + else + FloatVectorOperations::copy (d, s, numSamples); + } else - FloatVectorOperations::add (d, s, numSamples); + { + if (gain != 1.0f) + FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); + else + FloatVectorOperations::add (d, s, numSamples); + } } } @@ -343,10 +414,22 @@ void AudioSampleBuffer::addFrom (const int destChannel, { float* const d = channels [destChannel] + destStartSample; - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, source, gain, numSamples); + if (isClear) + { + isClear = false; + + if (gain != 1.0f) + FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); + else + FloatVectorOperations::copy (d, source, numSamples); + } else - FloatVectorOperations::add (d, source, numSamples); + { + if (gain != 1.0f) + FloatVectorOperations::addWithMultiply (d, source, gain, numSamples); + else + FloatVectorOperations::add (d, source, numSamples); + } } } @@ -369,6 +452,7 @@ void AudioSampleBuffer::addFromWithRamp (const int destChannel, { if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) { + isClear = false; const float increment = (endGain - startGain) / numSamples; float* d = channels [destChannel] + destStartSample; @@ -395,9 +479,20 @@ void AudioSampleBuffer::copyFrom (const int destChannel, jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); if (numSamples > 0) - FloatVectorOperations::copy (channels [destChannel] + destStartSample, - source.channels [sourceChannel] + sourceStartSample, - numSamples); + { + if (source.isClear) + { + if (! isClear) + FloatVectorOperations::clear (channels [destChannel] + destStartSample, numSamples); + } + else + { + isClear = false; + FloatVectorOperations::copy (channels [destChannel] + destStartSample, + source.channels [sourceChannel] + sourceStartSample, + numSamples); + } + } } void AudioSampleBuffer::copyFrom (const int destChannel, @@ -410,7 +505,10 @@ void AudioSampleBuffer::copyFrom (const int destChannel, jassert (source != nullptr); if (numSamples > 0) + { + isClear = false; FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples); + } } void AudioSampleBuffer::copyFrom (const int destChannel, @@ -425,17 +523,24 @@ void AudioSampleBuffer::copyFrom (const int destChannel, if (numSamples > 0) { - float* d = channels [destChannel] + destStartSample; + float* const d = channels [destChannel] + destStartSample; if (gain != 1.0f) { if (gain == 0) - FloatVectorOperations::clear (d, numSamples); + { + if (! isClear) + FloatVectorOperations::clear (d, numSamples); + } else + { + isClear = false; FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); + } } else { + isClear = false; FloatVectorOperations::copy (d, source, numSamples); } } @@ -460,6 +565,7 @@ void AudioSampleBuffer::copyFromWithRamp (const int destChannel, { if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) { + isClear = false; const float increment = (endGain - startGain) / numSamples; float* d = channels [destChannel] + destStartSample; @@ -477,8 +583,9 @@ void AudioSampleBuffer::reverse (int channel, int startSample, int numSamples) c jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - std::reverse (channels[channel] + startSample, - channels[channel] + startSample + numSamples); + if (! isClear) + std::reverse (channels[channel] + startSample, + channels[channel] + startSample + numSamples); } void AudioSampleBuffer::reverse (int startSample, int numSamples) const noexcept @@ -494,6 +601,9 @@ Range AudioSampleBuffer::findMinMax (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); + if (isClear) + return Range(); + return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples); } @@ -504,6 +614,9 @@ float AudioSampleBuffer::getMagnitude (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); + if (isClear) + return 0.0f; + const Range r (findMinMax (channel, startSample, numSamples)); return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd()); @@ -513,8 +626,9 @@ float AudioSampleBuffer::getMagnitude (int startSample, int numSamples) const no { float mag = 0.0f; - for (int i = 0; i < numChannels; ++i) - mag = jmax (mag, getMagnitude (i, startSample, numSamples)); + if (! isClear) + for (int i = 0; i < numChannels; ++i) + mag = jmax (mag, getMagnitude (i, startSample, numSamples)); return mag; } @@ -526,7 +640,7 @@ float AudioSampleBuffer::getRMSLevel (const int channel, jassert (isPositiveAndBelow (channel, numChannels)); jassert (startSample >= 0 && startSample + numSamples <= size); - if (numSamples <= 0 || channel < 0 || channel >= numChannels) + if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear) return 0.0f; const float* const data = channels [channel] + startSample; diff --git a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h index e5161af2aa..2674ad048c 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h +++ b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h @@ -116,27 +116,58 @@ public: */ int getNumSamples() const noexcept { return size; } - /** Returns a pointer one of the buffer's channels. + /** Returns a pointer to an array of read-only samples in one of the buffer's channels. For speed, this doesn't check whether the channel number is out of range, so be careful when using it! + If you need to write to the data, do NOT call this method and const_cast the + result! Instead, you must call getWritePointer so that the buffer knows you're + planning on modifying the data. */ - float* getSampleData (const int channelNumber) const noexcept + const float* getReadPointer (int channelNumber) const noexcept { jassert (isPositiveAndBelow (channelNumber, numChannels)); return channels [channelNumber]; } - /** Returns a pointer to a sample in one of the buffer's channels. + /** Returns a pointer to an array of read-only samples in one of the buffer's channels. + For speed, this doesn't check whether the channel number or index are out of range, + so be careful when using it! + If you need to write to the data, do NOT call this method and const_cast the + result! Instead, you must call getWritePointer so that the buffer knows you're + planning on modifying the data. + */ + const float* getReadPointer (int channelNumber, int sampleIndex) const noexcept + { + jassert (isPositiveAndBelow (channelNumber, numChannels)); + jassert (isPositiveAndBelow (sampleIndex, size)); + return channels [channelNumber] + sampleIndex; + } - For speed, this doesn't check whether the channel and sample number - are out-of-range, so be careful when using it! + /** Returns a writeable pointer to one of the buffer's channels. + For speed, this doesn't check whether the channel number is out of range, + so be careful when using it! + Note that if you're not planning on writing to the data, you should always + use getReadPointer instead. */ - float* getSampleData (const int channelNumber, - const int sampleOffset) const noexcept + float* getWritePointer (int channelNumber) noexcept { jassert (isPositiveAndBelow (channelNumber, numChannels)); - jassert (isPositiveAndBelow (sampleOffset, size)); - return channels [channelNumber] + sampleOffset; + isClear = false; + return channels [channelNumber]; + } + + /** Returns a writeable pointer to one of the buffer's channels. + For speed, this doesn't check whether the channel number or index are out of range, + so be careful when using it! + Note that if you're not planning on writing to the data, you should + use getReadPointer instead. + */ + float* getWritePointer (int channelNumber, int sampleIndex) noexcept + { + jassert (isPositiveAndBelow (channelNumber, numChannels)); + jassert (isPositiveAndBelow (sampleIndex, size)); + isClear = false; + return channels [channelNumber] + sampleIndex; } /** Returns an array of pointers to the channels in the buffer. @@ -144,7 +175,14 @@ public: Don't modify any of the pointers that are returned, and bear in mind that these will become invalid if the buffer is resized. */ - float** getArrayOfChannels() const noexcept { return channels; } + const float** getArrayOfReadPointers() const noexcept { return const_cast (channels); } + + /** Returns an array of pointers to the channels in the buffer. + + Don't modify any of the pointers that are returned, and bear in mind that + these will become invalid if the buffer is resized. + */ + float** getArrayOfWritePointers() noexcept { isClear = false; return channels; } //============================================================================== /** Changes the buffer's size or number of channels. @@ -216,6 +254,36 @@ public: int startSample, int numSamples) noexcept; + /** Returns true if the buffer has been entirely cleared. + Note that this does not actually measure the contents of the buffer - it simply + returns a flag that is set when the buffer is cleared, and which is reset whenever + functions like getWritePointer() are invoked. That means the method does not take + any time, but it may return false negatives when in fact the buffer is still empty. + */ + bool hasBeenCleared() const noexcept { return isClear; } + + //============================================================================== + /** Returns a sample from the buffer. + The channel and index are not checked - they are expected to be in-range. If not, + an assertion will be thrown, but in a release build, you're into 'undefined behaviour' + territory. + */ + float getSample (int channel, int sampleIndex) const noexcept; + + /** Sets a sample in the buffer. + The channel and index are not checked - they are expected to be in-range. If not, + an assertion will be thrown, but in a release build, you're into 'undefined behaviour' + territory. + */ + void setSample (int destChannel, int destSample, float newValue) noexcept; + + /** Adds a value to a sample in the buffer. + The channel and index are not checked - they are expected to be in-range. If not, + an assertion will be thrown, but in a release build, you're into 'undefined behaviour' + territory. + */ + void addSample (int destChannel, int destSample, float valueToAdd) noexcept; + /** Applies a gain multiple to a region of one channel. For speed, this doesn't check whether the channel and sample number @@ -422,13 +490,27 @@ public: /** Reverses a part of the buffer. */ void reverse (int startSample, int numSamples) const noexcept; + //============================================================================== + #ifndef DOXYGEN + // Note that these methods have now been replaced by getReadPointer() and getWritePointer() + JUCE_DEPRECATED (const float* getSampleData (int channel) const) { return getReadPointer (channel); } + JUCE_DEPRECATED (const float* getSampleData (int channel, int index) const) { return getReadPointer (channel, index); } + JUCE_DEPRECATED (float* getSampleData (int channel)) { return getWritePointer (channel); } + JUCE_DEPRECATED (float* getSampleData (int channel, int index)) { return getWritePointer (channel, index); } + + // These have been replaced by getArrayOfReadPointers() and getArrayOfWritePointers() + JUCE_DEPRECATED (const float** getArrayOfChannels() const) { return getArrayOfReadPointers(); } + JUCE_DEPRECATED (float** getArrayOfChannels()) { return getArrayOfWritePointers(); } + #endif + private: //============================================================================== int numChannels, size; size_t allocatedBytes; float** channels; - HeapBlock allocatedData; + HeapBlock allocatedData; float* preallocatedChannelSpace [32]; + bool isClear; void allocateData(); void allocateChannels (float* const* dataToReferTo, int offset); diff --git a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp index 712a24b9d3..08e87f0c1d 100644 --- a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp @@ -72,6 +72,6 @@ void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& buff for (int i = 0; i < numChannels; ++i) iirFilters.getUnchecked(i) - ->processSamples (bufferToFill.buffer->getSampleData (i, bufferToFill.startSample), + ->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), bufferToFill.numSamples); } diff --git a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp index 4f8c4cf25b..a48ed43e1e 100644 --- a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp @@ -121,7 +121,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf // for down-sampling, pre-apply the filter.. for (int i = channelsToProcess; --i >= 0;) - applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]); + applyFilter (buffer.getWritePointer (i, endOfBufferPos), numToDo, filterStates[i]); } sampsInBuffer += numToDo; @@ -130,8 +130,8 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf for (int channel = 0; channel < channelsToProcess; ++channel) { - destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); - srcBuffers[channel] = buffer.getSampleData (channel, 0); + destBuffers[channel] = info.buffer->getWritePointer (channel, info.startSample); + srcBuffers[channel] = buffer.getReadPointer (channel); } int nextPos = (bufferPos + 1) % bufferSize; @@ -163,14 +163,14 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf { // for up-sampling, apply the filter after transposing.. for (int i = channelsToProcess; --i >= 0;) - applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); + applyFilter (info.buffer->getWritePointer (i, info.startSample), info.numSamples, filterStates[i]); } else if (localRatio <= 1.0001 && info.numSamples > 0) { // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities for (int i = channelsToProcess; --i >= 0;) { - const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); + const float* const endOfBuffer = info.buffer->getReadPointer (i, info.startSample + info.numSamples - 1); FilterState& fs = filterStates[i]; if (info.numSamples > 1) diff --git a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h index 76e79ef156..20886e68ba 100644 --- a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h @@ -81,7 +81,8 @@ private: double coefficients[6]; SpinLock ratioLock; const int numChannels; - HeapBlock destBuffers, srcBuffers; + HeapBlock destBuffers; + HeapBlock srcBuffers; void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6); void createLowPass (double proportionalRate); diff --git a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp index fc38e60543..d630075371 100644 --- a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp @@ -48,12 +48,12 @@ void ReverbAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT if (! bypass) { - float* const firstChannel = bufferToFill.buffer->getSampleData (0, bufferToFill.startSample); + float* const firstChannel = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample); if (bufferToFill.buffer->getNumChannels() > 1) { reverb.processStereo (firstChannel, - bufferToFill.buffer->getSampleData (1, bufferToFill.startSample), + bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample), bufferToFill.numSamples); } else diff --git a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp index 7f5b9393f5..a0e04eff24 100644 --- a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp @@ -70,6 +70,6 @@ void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& currentPhase += phasePerSample; for (int j = info.buffer->getNumChannels(); --j >= 0;) - *info.buffer->getSampleData (j, info.startSample + i) = sample; + info.buffer->setSample (j, info.startSample + i, sample); } } diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index 1be78fed7e..8ab2096a38 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -728,7 +728,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels, outputChannelData, numOutputChannels, numSamples); - float** const tempChans = tempBuffer.getArrayOfChannels(); + float** const tempChans = tempBuffer.getArrayOfWritePointers(); for (int i = callbacks.size(); --i > 0;) { @@ -757,7 +757,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat if (testSound != nullptr) { const int numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition); - const float* const src = testSound->getSampleData (0, testSoundPosition); + const float* const src = testSound->getReadPointer (0, testSoundPosition); for (int i = 0; i < numOutputChannels; ++i) for (int j = 0; j < numSamps; ++j) @@ -951,16 +951,15 @@ void AudioDeviceManager::playTestSound() const double sampleRate = currentAudioDevice->getCurrentSampleRate(); const int soundLength = (int) sampleRate; - AudioSampleBuffer* const newSound = new AudioSampleBuffer (1, soundLength); - float* samples = newSound->getSampleData (0); - const double frequency = 440.0; const float amplitude = 0.5f; const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency); + AudioSampleBuffer* const newSound = new AudioSampleBuffer (1, soundLength); + for (int i = 0; i < soundLength; ++i) - samples[i] = amplitude * (float) std::sin (i * phasePerSample); + newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample)); newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f); newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f); diff --git a/modules/juce_audio_devices/native/juce_android_Audio.cpp b/modules/juce_audio_devices/native/juce_android_Audio.cpp index 2e3cd7e937..80711da9e2 100644 --- a/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_android_Audio.cpp @@ -304,7 +304,7 @@ public: for (int chan = 0; chan < inputChannelBuffer.getNumChannels(); ++chan) { - AudioData::Pointer d (inputChannelBuffer.getSampleData (chan)); + AudioData::Pointer d (inputChannelBuffer.getWritePointer (chan)); if (chan < numDeviceInputChannels) { @@ -328,8 +328,8 @@ public: if (callback != nullptr) { - callback->audioDeviceIOCallback ((const float**) inputChannelBuffer.getArrayOfChannels(), numClientInputChannels, - outputChannelBuffer.getArrayOfChannels(), numClientOutputChannels, + callback->audioDeviceIOCallback (inputChannelBuffer.getArrayOfReadPointers(), numClientInputChannels, + outputChannelBuffer.getArrayOfWritePointers(), numClientOutputChannels, actualBufferSize); } else @@ -349,7 +349,7 @@ public: { AudioData::Pointer d (dest + chan, numDeviceOutputChannels); - const float* const sourceChanData = outputChannelBuffer.getSampleData (jmin (chan, outputChannelBuffer.getNumChannels() - 1)); + const float* const sourceChanData = outputChannelBuffer.getReadPointer (jmin (chan, outputChannelBuffer.getNumChannels() - 1)); AudioData::Pointer s (sourceChanData); d.convertSamples (s, actualBufferSize); } diff --git a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index eb60dcc75c..842b42e53a 100644 --- a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -179,10 +179,8 @@ public: if (callback != nullptr) { - callback->audioDeviceIOCallback (numInputChannels > 0 ? (const float**) inputBuffer.getArrayOfChannels() : nullptr, - numInputChannels, - numOutputChannels > 0 ? outputBuffer.getArrayOfChannels() : nullptr, - numOutputChannels, + callback->audioDeviceIOCallback (numInputChannels > 0 ? inputBuffer.getArrayOfReadPointers() : nullptr, numInputChannels, + numOutputChannels > 0 ? outputBuffer.getArrayOfWritePointers() : nullptr, numOutputChannels, actualBufferSize); } else @@ -404,7 +402,7 @@ private: typedef AudioData::Pointer SrcSampleType; DstSampleType dstData (destBuffer + i, bufferList.numChannels); - SrcSampleType srcData (buffer.getSampleData (i, offset)); + SrcSampleType srcData (buffer.getReadPointer (i, offset)); dstData.convertSamples (srcData, bufferList.numSamples); } @@ -522,7 +520,7 @@ private: typedef AudioData::Pointer DstSampleType; typedef AudioData::Pointer SrcSampleType; - DstSampleType dstData (buffer.getSampleData (i, offset)); + DstSampleType dstData (buffer.getWritePointer (i, offset)); SrcSampleType srcData (srcBuffer + i, bufferList.numChannels); dstData.convertSamples (srcData, bufferList.numSamples); } diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.cpp b/modules/juce_audio_devices/native/juce_ios_Audio.cpp index f20ea444f2..6016a51420 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_ios_Audio.cpp @@ -227,10 +227,10 @@ private: zeromem (outputChannels, sizeof (outputChannels)); for (int i = 0; i < numInputChannels; ++i) - inputChannels[i] = floatData.getSampleData (i); + inputChannels[i] = floatData.getWritePointer (i); for (int i = 0; i < numOutputChannels; ++i) - outputChannels[i] = floatData.getSampleData (i + numInputChannels); + outputChannels[i] = floatData.getWritePointer (i + numInputChannels); } } diff --git a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp index 9bc9a26498..9bc7ecf4bb 100644 --- a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp @@ -311,7 +311,7 @@ public: bool writeToOutputDevice (AudioSampleBuffer& outputChannelBuffer, const int numSamples) { jassert (numChannelsRunning <= outputChannelBuffer.getNumChannels()); - float** const data = outputChannelBuffer.getArrayOfChannels(); + float* const* const data = outputChannelBuffer.getArrayOfWritePointers(); snd_pcm_sframes_t numDone = 0; if (isInterleaved) @@ -343,7 +343,7 @@ public: bool readFromInputDevice (AudioSampleBuffer& inputChannelBuffer, const int numSamples) { jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels()); - float** const data = inputChannelBuffer.getArrayOfChannels(); + float* const* const data = inputChannelBuffer.getArrayOfWritePointers(); if (isInterleaved) { @@ -497,7 +497,7 @@ public: { if (inputChannels[i]) { - inputChannelDataForCallback.add (inputChannelBuffer.getSampleData (i)); + inputChannelDataForCallback.add (inputChannelBuffer.getReadPointer (i)); currentInputChans.setBit (i); } } @@ -516,7 +516,7 @@ public: { if (outputChannels[i]) { - outputChannelDataForCallback.add (outputChannelBuffer.getSampleData (i)); + outputChannelDataForCallback.add (outputChannelBuffer.getWritePointer (i)); currentOutputChans.setBit (i); } } @@ -666,7 +666,7 @@ public: if (callback != nullptr) { - callback->audioDeviceIOCallback ((const float**) inputChannelDataForCallback.getRawDataPointer(), + callback->audioDeviceIOCallback (inputChannelDataForCallback.getRawDataPointer(), inputChannelDataForCallback.size(), outputChannelDataForCallback.getRawDataPointer(), outputChannelDataForCallback.size(), @@ -736,7 +736,8 @@ private: CriticalSection callbackLock; AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; - Array inputChannelDataForCallback, outputChannelDataForCallback; + Array inputChannelDataForCallback; + Array outputChannelDataForCallback; unsigned int minChansOut, maxChansOut; unsigned int minChansIn, maxChansIn; diff --git a/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm b/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm index 137d44380b..8dd7bfad16 100644 --- a/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm +++ b/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm @@ -129,9 +129,9 @@ private: typedef AudioData::Pointer SourceSampleFormat; CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (tempBuffer.getSampleData (0)), numSamples); + left.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (0)), numSamples); CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (tempBuffer.getSampleData (1)), numSamples); + right.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (1)), numSamples); source->readPosition += numSamples; } diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index 74e7a6c227..9fb77ddb24 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -1319,14 +1319,15 @@ private: AudioSampleBuffer buffer (fifos.getNumChannels(), numSamples); buffer.clear(); - Array inputChans, outputChans; + Array inputChans; + Array outputChans; for (int i = 0; i < devices.size(); ++i) { DeviceWrapper& d = *devices.getUnchecked(i); - for (int j = 0; j < d.numInputChans; ++j) inputChans.add (buffer.getSampleData (d.inputIndex + j)); - for (int j = 0; j < d.numOutputChans; ++j) outputChans.add (buffer.getSampleData (d.outputIndex + j)); + for (int j = 0; j < d.numInputChans; ++j) inputChans.add (buffer.getReadPointer (d.inputIndex + j)); + for (int j = 0; j < d.numOutputChans; ++j) outputChans.add (buffer.getWritePointer (d.outputIndex + j)); } const int numInputChans = inputChans.size(); @@ -1535,8 +1536,8 @@ private: for (int i = 0; i < numInputChans; ++i) { const int index = inputIndex + i; - float* const dest = destBuffer.getSampleData (index); - const float* const src = owner.fifos.getSampleData (index); + float* const dest = destBuffer.getWritePointer (index); + const float* const src = owner.fifos.getReadPointer (index); if (size1 > 0) FloatVectorOperations::copy (dest, src + start1, size1); if (size2 > 0) FloatVectorOperations::copy (dest + size1, src + start2, size2); @@ -1561,8 +1562,8 @@ private: for (int i = 0; i < numOutputChans; ++i) { const int index = outputIndex + i; - float* const dest = owner.fifos.getSampleData (index); - const float* const src = srcBuffer.getSampleData (index); + float* const dest = owner.fifos.getWritePointer (index); + const float* const src = srcBuffer.getReadPointer (index); if (size1 > 0) FloatVectorOperations::copy (dest + start1, src, size1); if (size2 > 0) FloatVectorOperations::copy (dest + start2, src + size1, size2); @@ -1590,7 +1591,7 @@ private: for (int i = 0; i < numInputChannels; ++i) { - float* const dest = buf.getSampleData (inputIndex + i); + float* const dest = buf.getWritePointer (inputIndex + i); const float* const src = inputChannelData[i]; if (size1 > 0) FloatVectorOperations::copy (dest + start1, src, size1); @@ -1622,7 +1623,7 @@ private: for (int i = 0; i < numOutputChannels; ++i) { float* const dest = outputChannelData[i]; - const float* const src = buf.getSampleData (outputIndex + i); + const float* const src = buf.getReadPointer (outputIndex + i); if (size1 > 0) FloatVectorOperations::copy (dest, src + start1, size1); if (size2 > 0) FloatVectorOperations::copy (dest + size1, src + start2, size2); diff --git a/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp b/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp index e17079791f..3c3befb80f 100644 --- a/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp +++ b/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp @@ -391,9 +391,9 @@ bool AudioCDBurner::addAudioTrack (AudioSource* audioSource, int numSamples) AudioData::NonInterleaved, AudioData::Const> SourceSampleFormat; CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (sourceBuffer.getSampleData (0)), samplesPerBlock); + left.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (0)), samplesPerBlock); CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (sourceBuffer.getSampleData (1)), samplesPerBlock); + right.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (1)), samplesPerBlock); hr = pimpl->redbook->AddAudioTrackBlocks (buffer, bytesPerBlock); diff --git a/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp b/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp index 3eb0757b30..d04902b628 100644 --- a/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp +++ b/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp @@ -998,10 +998,8 @@ public: if (isStarted) { - callback->audioDeviceIOCallback (const_cast (inputBuffers.getArrayOfChannels()), - inputBuffers.getNumChannels(), - outputBuffers.getArrayOfChannels(), - outputBuffers.getNumChannels(), + callback->audioDeviceIOCallback (inputBuffers.getArrayOfReadPointers(), inputBuffers.getNumChannels(), + outputBuffers.getArrayOfWritePointers(), outputBuffers.getNumChannels(), bufferSizeSamples); } else @@ -1105,13 +1103,8 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, for (int i = 0; i <= enabledInputs.getHighestBit(); i += 2) { - float* left = nullptr; - if (enabledInputs[i]) - left = inputBuffers.getSampleData (numIns++); - - float* right = nullptr; - if (enabledInputs[i + 1]) - right = inputBuffers.getSampleData (numIns++); + float* left = enabledInputs[i] ? inputBuffers.getWritePointer (numIns++) : nullptr; + float* right = enabledInputs[i + 1] ? inputBuffers.getWritePointer (numIns++) : nullptr; if (left != nullptr || right != nullptr) inChans.add (new DSoundInternalInChannel (dlh.inputDeviceNames [inputDeviceIndex], @@ -1131,13 +1124,8 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, for (int i = 0; i <= enabledOutputs.getHighestBit(); i += 2) { - float* left = nullptr; - if (enabledOutputs[i]) - left = outputBuffers.getSampleData (numOuts++); - - float* right = nullptr; - if (enabledOutputs[i + 1]) - right = outputBuffers.getSampleData (numOuts++); + float* left = enabledOutputs[i] ? outputBuffers.getWritePointer (numOuts++) : nullptr; + float* right = enabledOutputs[i + 1] ? outputBuffers.getWritePointer (numOuts++) : nullptr; if (left != nullptr || right != nullptr) outChans.add (new DSoundInternalOutChannel (dlh.outputDeviceNames[outputDeviceIndex], diff --git a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index 4940d3e676..24f2d62318 100644 --- a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -1063,8 +1063,8 @@ public: AudioSampleBuffer ins (jmax (1, numInputBuffers), bufferSize + 32); AudioSampleBuffer outs (jmax (1, numOutputBuffers), bufferSize + 32); - float** const inputBuffers = ins.getArrayOfChannels(); - float** const outputBuffers = outs.getArrayOfChannels(); + float** const inputBuffers = ins.getArrayOfWritePointers(); + float** const outputBuffers = outs.getArrayOfWritePointers(); ins.clear(); while (! threadShouldExit()) diff --git a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp index ecfccb2f33..45b2a3ad6c 100644 --- a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp +++ b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp @@ -115,7 +115,7 @@ void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData, for (int i = numOutputs; i < numInputs; ++i) { - channels[numActiveChans] = tempBuffer.getSampleData (i - numOutputs, 0); + channels[numActiveChans] = tempBuffer.getWritePointer (i - numOutputs); memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples); ++numActiveChans; } diff --git a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp index 35cbf49e00..99c9fe105c 100644 --- a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp @@ -176,7 +176,7 @@ public: for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) if (destSamples[i] != nullptr) memcpy (destSamples[i] + startOffsetInDestBuffer, - reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)), + reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), sizeof (int) * (size_t) num); startOffsetInDestBuffer += num; @@ -243,7 +243,7 @@ public: if (src != nullptr) { - int* const dest = reinterpret_cast (reservoir.getSampleData(i)); + int* const dest = reinterpret_cast (reservoir.getWritePointer(i)); for (int j = 0; j < numSamples; ++j) dest[j] = src[j] << bitsToShift; diff --git a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp index b6932902bc..e6303dc818 100644 --- a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp @@ -173,7 +173,7 @@ public: for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) if (destSamples[i] != nullptr) memcpy (destSamples[i] + startOffsetInDestBuffer, - reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)), + reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), sizeof (float) * (size_t) numToUse); startSampleInFile += numToUse; @@ -210,11 +210,7 @@ public: jassert (samps <= numToRead); for (int i = jmin ((int) numChannels, reservoir.getNumChannels()); --i >= 0;) - { - memcpy (reservoir.getSampleData (i, offset), - dataIn[i], - sizeof (float) * (size_t) samps); - } + memcpy (reservoir.getWritePointer (i, offset), dataIn[i], sizeof (float) * (size_t) samps); numToRead -= samps; offset += samps; diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp index 16821e75ca..501e33921e 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp @@ -106,7 +106,7 @@ static void readChannels (AudioFormatReader& reader, const int64 readerStartSample, const int numTargetChannels) { for (int j = 0; j < numTargetChannels; ++j) - chans[j] = reinterpret_cast (buffer->getSampleData (j, startSample)); + chans[j] = reinterpret_cast (buffer->getWritePointer (j, startSample)); chans[numTargetChannels] = nullptr; reader.read (chans, numTargetChannels, readerStartSample, numSamples, true); @@ -128,8 +128,8 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer, if (numTargetChannels <= 2) { - int* const dest0 = reinterpret_cast (buffer->getSampleData (0, startSample)); - int* const dest1 = reinterpret_cast (numTargetChannels > 1 ? buffer->getSampleData (1, startSample) : nullptr); + int* const dest0 = reinterpret_cast (buffer->getWritePointer (0, startSample)); + int* const dest1 = reinterpret_cast (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr); int* chans[3]; if (useReaderLeftChan == useReaderRightChan) @@ -168,7 +168,7 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer, if (! usesFloatingPointData) for (int j = 0; j < numTargetChannels; ++j) - if (float* const d = buffer->getSampleData (j, startSample)) + if (float* const d = buffer->getWritePointer (j, startSample)) FloatVectorOperations::convertFixedToFloat (d, reinterpret_cast (d), 1.0f / 0x7fffffff, numSamples); } } @@ -221,7 +221,7 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples const int bufferSize = (int) jmin (numSamples, (int64) 4096); AudioSampleBuffer tempSampleBuffer ((int) numChannels, bufferSize); - float** const floatBuffer = tempSampleBuffer.getArrayOfChannels(); + float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers(); int* const* intBuffer = reinterpret_cast (floatBuffer); if (usesFloatingPointData) diff --git a/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp b/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp index 9ca6756c68..cd1ffc9a73 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp @@ -68,7 +68,7 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader, int* buffers [128] = { 0 }; for (int i = tempBuffer.getNumChannels(); --i >= 0;) - buffers[i] = reinterpret_cast (tempBuffer.getSampleData (i, 0)); + buffers[i] = reinterpret_cast (tempBuffer.getWritePointer (i, 0)); if (numSamplesToRead < 0) numSamplesToRead = reader.lengthInSamples; @@ -170,13 +170,13 @@ bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& sou jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && numSourceChannels > 0); if (startSample == 0) - return writeFromFloatArrays (source.getArrayOfChannels(), numSourceChannels, numSamples); + return writeFromFloatArrays (source.getArrayOfReadPointers(), numSourceChannels, numSamples); const float* chans [256]; jassert ((int) numChannels < numElementsInArray (chans)); for (int i = 0; i < numSourceChannels; ++i) - chans[i] = source.getSampleData (i, startSample); + chans[i] = source.getReadPointer (i, startSample); chans[numSourceChannels] = nullptr; diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index fe20524c50..ecfe1d457a 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -77,7 +77,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, dest += startOffsetInDestBuffer; if (j < (int) numChannels) - FloatVectorOperations::copy (dest, block->buffer.getSampleData (j, offset), numToDo); + FloatVectorOperations::copy (dest, block->buffer.getReadPointer (j, offset), numToDo); else FloatVectorOperations::clear (dest, numToDo); } diff --git a/modules/juce_audio_formats/sampler/juce_Sampler.cpp b/modules/juce_audio_formats/sampler/juce_Sampler.cpp index fb51dcff21..9dbe7b3c56 100644 --- a/modules/juce_audio_formats/sampler/juce_Sampler.cpp +++ b/modules/juce_audio_formats/sampler/juce_Sampler.cpp @@ -154,12 +154,12 @@ void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSa { if (const SamplerSound* const playingSound = static_cast (getCurrentlyPlayingSound().get())) { - const float* const inL = playingSound->data->getSampleData (0, 0); + const float* const inL = playingSound->data->getReadPointer (0); const float* const inR = playingSound->data->getNumChannels() > 1 - ? playingSound->data->getSampleData (1, 0) : nullptr; + ? playingSound->data->getReadPointer (1) : nullptr; - float* outL = outputBuffer.getSampleData (0, startSample); - float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getSampleData (1, startSample) : nullptr; + float* outL = outputBuffer.getWritePointer (0, startSample); + float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getWritePointer (1, startSample) : nullptr; while (--numSamples >= 0) { diff --git a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm index 0e51b82c70..e1ee779196 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -779,7 +779,7 @@ public: needToReinterleave = true; for (unsigned int subChan = 0; subChan < buf.mNumberChannels && numOutChans < numOut; ++subChan) - channels [numOutChans++] = bufferSpace.getSampleData (nextSpareBufferChan++); + channels [numOutChans++] = bufferSpace.getWritePointer (nextSpareBufferChan++); } if (numOutChans >= numOut) @@ -814,7 +814,7 @@ public: } else { - dest = bufferSpace.getSampleData (nextSpareBufferChan++); + dest = bufferSpace.getWritePointer (nextSpareBufferChan++); channels [numInChans++] = dest; } @@ -915,7 +915,7 @@ public: { for (unsigned int subChan = 0; subChan < buf.mNumberChannels; ++subChan) { - const float* src = bufferSpace.getSampleData (nextSpareBufferChan++); + const float* src = bufferSpace.getReadPointer (nextSpareBufferChan++); float* dest = ((float*) buf.mData) + subChan; for (int j = (int) numSamples; --j >= 0;) diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index d852d15bbd..b993f8e5aa 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -472,7 +472,7 @@ public: processTempBuffer.setSize (numIn, numSamples, false, false, true); for (int i = numIn; --i >= 0;) - memcpy (processTempBuffer.getSampleData (i), outputs[i], sizeof (float) * (size_t) numSamples); + processTempBuffer.copyFrom (i, 0, outputs[i], numSamples); processReplacing (inputs, outputs, numSamples); diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index f7709bb7b2..006f6889cc 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -1225,7 +1225,7 @@ public: } for (int i = 0; i < numOutputChans; ++i) - FloatVectorOperations::copy (data.outputs[0].channelBuffers32[i], buffer.getSampleData (i), (int) data.numSamples); + FloatVectorOperations::copy (data.outputs[0].channelBuffers32[i], buffer.getReadPointer (i), (int) data.numSamples); // clear extra busses.. if (data.outputs != nullptr) diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index cf2efcbeb0..c9fafe2c8e 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -530,7 +530,7 @@ public: { abl->mBuffers[j].mNumberChannels = 1; abl->mBuffers[j].mDataByteSize = sizeof (float) * numSamples; - abl->mBuffers[j].mData = buffer.getSampleData (i * numOutputBusChannels + j, 0); + abl->mBuffers[j].mData = buffer.getWritePointer (i * numOutputBusChannels + j); } } @@ -1050,7 +1050,7 @@ private: if (bufferChannel < currentBuffer->getNumChannels()) { memcpy (ioData->mBuffers[i].mData, - currentBuffer->getSampleData (bufferChannel, 0), + currentBuffer->getReadPointer (bufferChannel), sizeof (float) * inNumberFrames); } else diff --git a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp index d528a271d7..81b369a6ac 100644 --- a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp @@ -294,13 +294,13 @@ public: { for (int i = 0; i < inputs.size(); ++i) plugin->connect_port (handle, inputs[i], - i < buffer.getNumChannels() ? buffer.getSampleData (i) : nullptr); + i < buffer.getNumChannels() ? buffer.getWritePointer (i) : nullptr); if (plugin->run != nullptr) { for (int i = 0; i < outputs.size(); ++i) plugin->connect_port (handle, outputs.getUnchecked(i), - i < buffer.getNumChannels() ? buffer.getSampleData (i) : nullptr); + i < buffer.getNumChannels() ? buffer.getWritePointer (i) : nullptr); plugin->run (handle, numSamples); return; @@ -312,7 +312,7 @@ public: tempBuffer.clear(); for (int i = 0; i < outputs.size(); ++i) - plugin->connect_port (handle, outputs.getUnchecked(i), tempBuffer.getSampleData (i)); + plugin->connect_port (handle, outputs.getUnchecked(i), tempBuffer.getWritePointer (i)); plugin->run_adding (handle, numSamples); diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 2c575f314c..d66a7598d7 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -339,7 +339,7 @@ namespace VST3BufferExchange */ void associateBufferTo (Steinberg::Vst::AudioBusBuffers& vstBuffers, Bus& bus, - const AudioSampleBuffer& buffer, + AudioSampleBuffer& buffer, int numChannels, int channelStartOffset, int sampleOffset = 0) noexcept { @@ -349,7 +349,7 @@ namespace VST3BufferExchange bus.clearQuick(); for (int i = channelStartOffset; i < channelEnd; ++i) - bus.add (buffer.getSampleData (i, sampleOffset)); + bus.add (buffer.getWritePointer (i, sampleOffset)); vstBuffers.channelBuffers32 = bus.getRawDataPointer(); vstBuffers.numChannels = numChannels; diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 4a386c2171..5f2d4f5610 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -175,9 +175,9 @@ static void setStateForAllBussesOfType (Vst::IComponent* component, //============================================================================== /** Assigns a complete AudioSampleBuffer's channels to an AudioBusBuffers' */ -static void associateWholeBufferTo (Vst::AudioBusBuffers& vstBuffers, const AudioSampleBuffer& buffer) noexcept +static void associateWholeBufferTo (Vst::AudioBusBuffers& vstBuffers, AudioSampleBuffer& buffer) noexcept { - vstBuffers.channelBuffers32 = buffer.getArrayOfChannels(); + vstBuffers.channelBuffers32 = buffer.getArrayOfWritePointers(); vstBuffers.numChannels = buffer.getNumChannels(); vstBuffers.silenceFlags = 0; } diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 3d29db0487..c6084e39a7 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -1062,17 +1062,17 @@ public: if ((effect->flags & effFlagsCanReplacing) != 0) { - effect->processReplacing (effect, buffer.getArrayOfChannels(), buffer.getArrayOfChannels(), numSamples); + effect->processReplacing (effect, buffer.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), numSamples); } else { tempBuffer.setSize (effect->numOutputs, numSamples); tempBuffer.clear(); - effect->process (effect, buffer.getArrayOfChannels(), tempBuffer.getArrayOfChannels(), numSamples); + effect->process (effect, buffer.getArrayOfWritePointers(), tempBuffer.getArrayOfWritePointers(), numSamples); for (int i = effect->numOutputs; --i >= 0;) - buffer.copyFrom (i, 0, tempBuffer.getSampleData (i), numSamples); + buffer.copyFrom (i, 0, tempBuffer.getReadPointer (i), numSamples); } } else diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index c1f192902a..0dd5a14fac 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -175,7 +175,7 @@ public: void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) { - float* data = sharedBufferChans.getSampleData (channel, 0); + float* data = sharedBufferChans.getWritePointer (channel, 0); for (int i = numSamples; --i >= 0;) { @@ -219,7 +219,7 @@ public: void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray & sharedMidiBuffers, const int numSamples) { for (int i = totalChans; --i >= 0;) - channels[i] = sharedBufferChans.getSampleData (audioChannelsToUse.getUnchecked (i), 0); + channels[i] = sharedBufferChans.getWritePointer (audioChannelsToUse.getUnchecked (i), 0); AudioSampleBuffer buffer (channels, totalChans, numSamples); @@ -230,8 +230,8 @@ public: AudioProcessor* const processor; private: - Array audioChannelsToUse; - HeapBlock channels; + Array audioChannelsToUse; + HeapBlock channels; int totalChans; int midiBufferToUse; diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp index cfa475ed88..f15f86566b 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp @@ -706,7 +706,7 @@ void AudioThumbnail::addBlock (const int64 startSample, const AudioSampleBuffer& for (int chan = 0; chan < numChans; ++chan) { - const float* const sourceData = incoming.getSampleData (chan, startOffsetInBuffer); + const float* const sourceData = incoming.getReadPointer (chan, startOffsetInBuffer); MinMaxValue* const dest = thumbData + numToDo * chan; thumbChannels [chan] = dest; diff --git a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp index 18e14104d8..649406fa9d 100644 --- a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp +++ b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp @@ -94,7 +94,7 @@ void AudioProcessorPlayer::audioDeviceIOCallback (const float** const inputChann for (int i = numOutputChannels; i < numInputChannels; ++i) { - channels[totalNumChans] = tempBuffer.getSampleData (i - numOutputChannels, 0); + channels[totalNumChans] = tempBuffer.getWritePointer (i - numOutputChannels); memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * (size_t) numSamples); ++totalNumChans; }