When assigning AudioSampleBuffers (using overloaded =) it will reallocate by default.
I think its best practice to avoid reallocating (as this is mostly for the audio thread) if the buffer already has enough bytes allocated, and so I’m forced to write my own AudioSampleBuffer assignment procedure.
I think most are interested in avoiding reallocation by default, and so this is an inquiry to change the default AudioSampleBuffer operator = to avoid reallocation.
I’d except it to do exactly what it already does: makes a copy of the audio buffer in the destination.
I just don’t like the memory semantics of reallocating if there is already enough bytes allocated in the destination buffer. In fact, it use the AudioSampleBuffer.setSize(…) which defaults to not-reallocating, but it doesnt use that default.
You’re right, that’s not a bad idea. In fact, almost all STL containers do not maintain the capacity of a container when assigning. For example:
std::vector<double> small (10, 0.0);
small.reserve (10000);
std::cout << small.capacity() << std::endl;
std::vector<double> big (50, 0.0);
big = small;
std::cout << small.capacity() << std::endl;
Will print:
10000
50
So the assignment operator does not preserve the capacity - it only copies the elements.
However, changing this would be a breaking change which could mess up a lot of JUCE user’s projects in a subtle way. Imagine a plug-in setting up a bunch of buffers in the prepareToPlay method like this:
void prepareToPlay (double /*sampleRate*/, int actualBufferSize) override
{
// Make sure the buffer has the capacity for maxBufferSize
AudioSampleBufferf myBuffer (2, kMaxBufferSize);
myBuffer.setSize (2, actualBufferSize, false, false, true);
// We need several buffers with this capacity and size
aBuffer = myBuffer; bBuffer = myBuffer; cBuffer = myBuffer;
}
The user then wants to be able to call setSize on all of the above buffers in the processBlock method without re-allocating
void processBlock (AudioSampleBuffer& buffer, MidiBuffer&)
{
int n = buffer.getNumSamples();
jassert (n < kMaxBufferSize);
// this should never allocate even if n is larger than actualBufferSize
cBuffer.setSize (2, n, false, false, true);
}
No, as the types are known at compile-time the compiler will do no bit-conversion if the types are the same. When compiling for release, VS replaces the loop with a memcpy and XCode produces this tight loop: