Browse Source

Avoided some unnecessary reallocations in AudioBuffer::setSize()

tags/2021-05-28
jules 8 years ago
parent
commit
3d69ce6856
1 changed files with 53 additions and 50 deletions
  1. +53
    -50
      modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h

+ 53
- 50
modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h View File

@@ -34,9 +34,7 @@ public:
//==============================================================================
/** Creates an empty buffer with 0 channels and 0 length. */
AudioBuffer() noexcept
: numChannels (0), size (0), allocatedBytes (0),
channels (static_cast<Type**> (preallocatedChannelSpace)),
isClear (false)
: channels (static_cast<Type**> (preallocatedChannelSpace))
{
}
@@ -78,8 +76,7 @@ public:
int numChannelsToUse,
int numSamples)
: numChannels (numChannelsToUse),
size (numSamples),
allocatedBytes (0)
size (numSamples)
{
jassert (dataToReferTo != nullptr);
jassert (numChannelsToUse >= 0 && numSamples >= 0);
@@ -107,9 +104,7 @@ public:
int startSample,
int numSamples)
: numChannels (numChannelsToUse),
size (numSamples),
allocatedBytes (0),
isClear (false)
size (numSamples)
{
jassert (dataToReferTo != nullptr);
jassert (numChannelsToUse >= 0 && startSample >= 0 && numSamples >= 0);
@@ -322,6 +317,9 @@ public:
a new allocation will be done so that the buffer uses takes up the minimum amount
of memory that it needs.
Note that if keepExistingContent and avoidReallocating are both true, then it will
only avoid reallocating if neither the channel count or length in samples increase.
If the required memory can't be allocated, this will throw a std::bad_alloc exception.
*/
void setSize (int newNumChannels,
@@ -335,38 +333,45 @@ public:
if (newNumSamples != size || newNumChannels != numChannels)
{
const auto allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u;
const auto channelListSize = ((sizeof (Type*) * (size_t) (newNumChannels + 1)) + 15) & ~15u;
const auto newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (Type))
+ channelListSize + 32;
auto allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u;
auto channelListSize = ((sizeof (Type*) * (size_t) (newNumChannels + 1)) + 15) & ~15u;
auto newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (Type))
+ channelListSize + 32;
if (keepExistingContent)
{
HeapBlock<char, true> newData;
newData.allocate (newTotalBytes, clearExtraSpace || isClear);
if (avoidReallocating && newNumChannels <= numChannels && newNumSamples <= size)
{
// no need to do any remapping in this case, as the channel pointers will remain correct!
}
else
{
HeapBlock<char, true> newData;
newData.allocate (newTotalBytes, clearExtraSpace || isClear);
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
auto newChannels = reinterpret_cast<Type**> (newData.get());
auto newChan = reinterpret_cast<Type*> (newData + channelListSize);
auto newChannels = reinterpret_cast<Type**> (newData.get());
auto newChan = reinterpret_cast<Type*> (newData + channelListSize);
for (int j = 0; j < newNumChannels; ++j)
{
newChannels[j] = newChan;
newChan += allocatedSamplesPerChannel;
}
for (int j = 0; j < newNumChannels; ++j)
{
newChannels[j] = newChan;
newChan += allocatedSamplesPerChannel;
}
if (! isClear)
{
auto numChansToCopy = jmin (numChannels, newNumChannels);
if (! isClear)
{
auto numChansToCopy = jmin (numChannels, newNumChannels);
for (int i = 0; i < numChansToCopy; ++i)
FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy);
}
for (int i = 0; i < numChansToCopy; ++i)
FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy);
}
allocatedData.swapWith (newData);
allocatedBytes = newTotalBytes;
channels = newChannels;
allocatedData.swapWith (newData);
allocatedBytes = newTotalBytes;
channels = newChannels;
}
}
else
{
@@ -391,7 +396,7 @@ public:
}
}
channels[newNumChannels] = 0;
channels[newNumChannels] = nullptr;
size = newNumSamples;
numChannels = newNumChannels;
}
@@ -593,11 +598,11 @@ public:
jassert (isPositiveAndBelow (channel, numChannels));
jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
if (gain != (Type) 1 && ! isClear)
if (gain != Type (1) && ! isClear)
{
auto* d = channels[channel] + startSample;
if (gain == 0)
if (gain == Type())
FloatVectorOperations::clear (d, numSamples);
else
FloatVectorOperations::multiply (d, gain, numSamples);
@@ -691,7 +696,7 @@ public:
int sourceChannel,
int sourceStartSample,
int numSamples,
Type gainToApplyToSource = (Type) 1) noexcept
Type gainToApplyToSource = Type (1)) noexcept
{
jassert (&source != this || sourceChannel != destChannel);
jassert (isPositiveAndBelow (destChannel, numChannels));
@@ -708,14 +713,14 @@ public:
{
isClear = false;
if (gainToApplyToSource != (Type) 1)
if (gainToApplyToSource != Type (1))
FloatVectorOperations::copyWithMultiply (d, s, gainToApplyToSource, numSamples);
else
FloatVectorOperations::copy (d, s, numSamples);
}
else
{
if (gainToApplyToSource != (Type) 1)
if (gainToApplyToSource != Type (1))
FloatVectorOperations::addWithMultiply (d, s, gainToApplyToSource, numSamples);
else
FloatVectorOperations::add (d, s, numSamples);
@@ -723,7 +728,6 @@ public:
}
}
/** Adds samples from an array of floats to one of the channels.
@param destChannel the channel within this buffer to add the samples to
@@ -739,7 +743,7 @@ public:
int destStartSample,
const Type* source,
int numSamples,
Type gainToApplyToSource = (Type) 1) noexcept
Type gainToApplyToSource = Type (1)) noexcept
{
jassert (isPositiveAndBelow (destChannel, numChannels));
jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
@@ -753,14 +757,14 @@ public:
{
isClear = false;
if (gainToApplyToSource != (Type) 1)
if (gainToApplyToSource != Type (1))
FloatVectorOperations::copyWithMultiply (d, source, gainToApplyToSource, numSamples);
else
FloatVectorOperations::copy (d, source, numSamples);
}
else
{
if (gainToApplyToSource != (Type) 1)
if (gainToApplyToSource != Type (1))
FloatVectorOperations::addWithMultiply (d, source, gainToApplyToSource, numSamples);
else
FloatVectorOperations::add (d, source, numSamples);
@@ -902,9 +906,9 @@ public:
{
auto* d = channels[destChannel] + destStartSample;
if (gain != (Type) 1)
if (gain != Type (1))
{
if (gain == 0)
if (gain == Type())
{
if (! isClear)
FloatVectorOperations::clear (d, numSamples);
@@ -1002,7 +1006,7 @@ public:
/** Finds the highest absolute sample value within a region on all channels. */
Type getMagnitude (int startSample, int numSamples) const noexcept
{
Type mag = 0;
Type mag = {};
if (! isClear)
for (int i = 0; i < numChannels; ++i)
@@ -1025,11 +1029,11 @@ public:
for (int i = 0; i < numSamples; ++i)
{
const Type sample = data[i];
auto sample = data[i];
sum += sample * sample;
}
return (Type) std::sqrt (sum / numSamples);
return static_cast<Type> (std::sqrt (sum / numSamples));
}
/** Reverses a part of a channel. */
@@ -1053,12 +1057,12 @@ public:
private:
//==============================================================================
int numChannels, size;
size_t allocatedBytes;
int numChannels = 0, size = 0;
size_t allocatedBytes = 0;
Type** channels;
HeapBlock<char, true> allocatedData;
Type* preallocatedChannelSpace[32];
bool isClear;
bool isClear = false;
void allocateData()
{
@@ -1098,7 +1102,6 @@ private:
{
// you have to pass in the same number of valid pointers as numChannels
jassert (dataToReferTo[i] != nullptr);
channels[i] = dataToReferTo[i] + offset;
}


Loading…
Cancel
Save