mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Avoided some unnecessary reallocations in AudioBuffer::setSize()
This commit is contained in:
parent
e8490fbf71
commit
3d69ce6856
1 changed files with 54 additions and 51 deletions
|
|
@ -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);
|
||||
|
||||
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
|
||||
|
||||
auto newChannels = reinterpret_cast<Type**> (newData.get());
|
||||
auto newChan = reinterpret_cast<Type*> (newData + channelListSize);
|
||||
|
||||
for (int j = 0; j < newNumChannels; ++j)
|
||||
if (avoidReallocating && newNumChannels <= numChannels && newNumSamples <= size)
|
||||
{
|
||||
newChannels[j] = newChan;
|
||||
newChan += allocatedSamplesPerChannel;
|
||||
// no need to do any remapping in this case, as the channel pointers will remain correct!
|
||||
}
|
||||
|
||||
if (! isClear)
|
||||
else
|
||||
{
|
||||
auto numChansToCopy = jmin (numChannels, newNumChannels);
|
||||
HeapBlock<char, true> newData;
|
||||
newData.allocate (newTotalBytes, clearExtraSpace || isClear);
|
||||
|
||||
for (int i = 0; i < numChansToCopy; ++i)
|
||||
FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy);
|
||||
auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (! isClear)
|
||||
{
|
||||
auto numChansToCopy = jmin (numChannels, newNumChannels);
|
||||
|
||||
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…
Add table
Add a link
Reference in a new issue