I know this is going to be annoying to whoever made the float* const* breaking change, as that was likely a lot of a rewrite, but I’d still like to make a point. Initially I was not opposed to float* const* because it seemed reasonable to think an AudioBuffer shouldn’t just randomly change whatever their inner buffer points to. Sure. I just took all my self-written DSP libraries and changed the methods from float** to float* const*. That was alright.
However I just ran into a situation where float** would behave better. I’m writing a multiband split and my idea was I want to have all the bands next to each other in memory, so my AudioBuffer is numBands * numChannels. That would mean when actually processing the multiband split you have to sometimes make temporary smaller buffers out of the big one to pass those to the things that do individual things per band. That can look like this:
void splitBands(const float* const* samplesIn, int numChannels, int numSamples) noexcept
{
auto ar = bands.getArrayOfWritePointers();
for (auto c = 0; c < NumCrossOvers; ++c)
{
const auto c2 = c + 2;
float* const bufferLow[2] = { ar[c], ar[c + 1] };
float* const bufferHigh[2] = { ar[c2], ar[c2 + 1] };
auto& crossover = crossovers[c];
crossover.split(samplesIn, bufferLow, bufferHigh, numChannels, numSamples);
}
}
But I’m getting a little annoyed at continuously having to getArrayOfWritePointers() and do all that {} stuff in my methods. It has a bad readability. My goal is to have a method that can get a float* const* out of the big buffer that represents just a specific band, so I wrote one:
float* const* getBuffer(int b) noexcept
{
b *= 2;
auto ar = bands.getArrayOfWritePointers();
float* const buf[] = { ar[b], ar[b +1] };
return buf;
}
C++ doesn’t let me do this, because “buf” doesn’t exist anymore when the scope of the method ends, which for some reason is unacceptable even if the object is just a pointer that points to other pointers. It was suggested to me to try this instead:
void getBuffer(float* const* buf, int b) noexcept
{
b *= 2;
auto ar = bands.getArrayOfWritePointers();
buf[0] = ar[b];
buf[1] = ar[b + 1];
}
but this is where the const in float* const* comes into play. you can’t reassign the pointers of a float* const*, so this is impossible.
i argue this is not the only situation where it would be useful to keep this non-const. basically all setups where there’s parallel processing could benefit from this being purely float**, because those are all situations where someone could come to the conclusion that it’s nice to have a big buffer for all the channels.