AudioBuffer<float> cast to std::vector<float>


#1

Hello,
I have function that needs as input data std::vector<float>. An I want to send there data from AudioBuffer<float>
Of course I can make for loop, and insert all samples from AudioBuffer to some vector. But I wonder is there simpler way to do that just by (std::vectot<float>)AudioBuffer<float> or something like that?


#2

Those classes are not compatible, there’s no way to just do a simple cast. You will need to copy the data.


#3

Thanks for help.


#4

Well, if you don’t deal with an AudioBuffer you create yourself (—> not the one passed by processBlock) you could create a std::vector and let your audio buffer use the vector‘s memory. But be aware that this will only work safely if the std::vector doesn’t change in size, as it might reallocate in that case


#5

OK, but how to do that? How to set AudioBuffer use the vector memory? I know I can make for loop and push back to my vector each sample od AudioBuffer. But I think you mean something different. Could you explain, please?


#6
float* start = buffer.getWritePointer(0); // get the pointer to the first sample of the first channel
int size = buffer.getNumSamples(); 
std::vector<float> my_vector (start, start + size); // this will copy the data as a vector

#7

You’ll want to set the size of the vector accordingly in prepareToPlay so you avoid allocations during your processing

myProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    // myVector as a member variable of your processor
    myVector.resize(samplesPerBlock);
}

And then fill the vector with the buffer passed in in processBlock


#8

Let’s assume you want to create a single-channel buffer. Then you can do this:

myProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    // myVector and myAudioBufferUsingVectorMemory as a member variable of your processor
    myVector.resize (samplesPerBlock);
    float* dataPtrs[1] = {myVector.data()};

    myAudioBufferUsingVectorMemory.setDataToReferTo (dataPtrs, 1, samplesPerBlock);
}

Through calling std::vector::resize the vector re-allocates its underlying memory. Now you can fetch the pointer to this data by calling std::vector::data. Feed it into an array of float pointers with the size 1 and then passing this to AudioBuffer::setDataToReferTo let’s the audio buffer scan the array of pointers passed and then pick the pointers in this array to use this memory region to work with. Now manipulating any sample in the myAudioBufferUsingVectorMemory will actually manipulate the data in the memory owned by myVector. This means that you might pass this vector to another function that reads from it after you have filled it this way. However I’d strongly advise you to NOT do it the other way round (use the vector for write-access) if you are not 100% sure of what you are doing.

Extending this to a multi-channel setup should be straightforward, just make dataPtrs bigger, use multiple vectors and store all their data pointers into the array.