Understanding AudioSampleBuffer - copying

So I’m trying to understand how to copy one AudioSampleBuffer to another. Struggling a little.

I understand JUCE has some memcpy function, COPYFROM and another ADDFROM.

What I’m trying to do is when a file is loaded, loaded the samples from that file into a master AudioSampleBuffer, say called BufferStream. And continually fill up BufferStream for every file that is loaded.

Assuming I have to create a multi-dimensional for loop (auto channel, auto sample) and go through the .copyFrom function? Using ‘sample’ as the iterator?

    for (auto channel = 0; channel < fileBuffer.getNumChannels(); channel++)
    {
        for (auto sample = 0; sample < fileBuffer.getNumSamples(); sample++)
        {
            bufferStream.copyFrom(<#int destChannel#>, <#int destStartSample#>, <#const AudioBuffer<float> &source#>, <#int sourceChannel#>, <#int sourceStartSample#>, <#int numSamples#>)
        }
    }

Do I need to set the size of the ‘master’ buffer, BufferStream first?

Any help would be great :slight_smile:

You must not iterate over each sample when using copyFrom, that already does that iteration internally. You do, however, need to iterate over the channels. (For some reason, there isn’t a copyFrom overload that handles multiple channels directly.)

Ok thanks.

So this is the updated version to add any new buffer to an existing one… I have to set the size of the master buffer each time before I copy samples. Does this look correct?

    int newBufferSize = bufferStream.getNumSamples() + fileBuffer.getNumSamples();

    bufferStream.setSize(fileBuffer.getNumChannels(), newBufferSize);
    
    for (auto channel = 0; channel < fileBuffer.getNumChannels(); channel++)
    {
        bufferStream.addFrom(channel, 0, fileBuffer, channel, 0, fileBuffer.getNumSamples());
    }

addFrom sums the audio to the existing audio, it doesn’t mean the data is appended to the buffer. If you need to append, you need keep track of the destination start index yourself. (In addition to resizing the destination buffer.)

Oops… my bad. Forgot to change the addFrom to copyFrom.

Hmmm this isn’t working.

    int newBufferSize = bufferStream.getNumSamples() + fileBuffer.getNumSamples();

    bufferStream.setSize(fileBuffer.getNumChannels(), newBufferSize);

    for (auto channel = 0; channel < fileBuffer.getNumChannels(); channel++)
    {
        bufferStream.copyFrom(channel, 0, fileBuffer, channel, 0, fileBuffer.getNumSamples());
    }

Thinking I would have to iterate through the fileBuffer using a internal for loop, but as you said not to… Otherwise each time a new file is added, the bufferStream just gets replaced, and not appended.

Like I mentioned, you have to keep track of the destination buffer index. Your code looks like it’s always copying into the destination starting from index 0. (destStartSample in the documentation.)

Right… so I though using an internal for loop… But you said not to.

something like bufferStream.getNumSamples() (which would be 0 initially) plus an iterator.

for (auto sample = 0; sample < fileBuffer.getNumSamples(); sample++)
{
int iterator = bufferStream.getNumSamples() + sample;
}

You don’t need to loop over the samples yourself, the copyFrom method already does it for you. You can of course implement the sample iteration and copying completely yourself, if you wish to do so. (But then you wouldn’t be using the copyFrom method at all.)

Yes ok, but how would I iterator through the bufferStream position if I don’t have an iterator.

bufferStream.copyFrom(channel, **0**, fileBuffer, channel, 0, fileBuffer.getNumSamples());

Sorry, I’m struggling on this one.

Something like this :

int newDestPosition = bufferStream.getNumSamples();
    int newBufferSize = bufferStream.getNumSamples() + fileBuffer.getNumSamples();

    bufferStream.setSize(fileBuffer.getNumChannels(), newBufferSize);

    for (auto channel = 0; channel < fileBuffer.getNumChannels(); channel++)
    {
        bufferStream.copyFrom(channel, newDestPosition, fileBuffer, channel, 0, fileBuffer.getNumSamples());
    }

That code isn’t tested, but that would be the general idea.

Why are you trying to join multiple AudioBuffers into one, to begin with? Wouldn’t it be simpler to just have an array/vector for the buffers?