ofSoundBuffer: get pointer to channel array

Hi,

I am trying to use ofSoundBuffer with some audio effects library. To do so I need to be able to get the input buffer variable as 2 pointer arrays, each containing the data from one channel or the other.
I was trying something like below but it doesn’t work since as I understand the data is interleaved in ofSoundBuffer.

void ofApp::process(ofSoundBuffer &buffer)
{
    // Separate the soundbuffer in the 2 channels
    float** audio = new (float *[2]);
    audio[0] = &buffer[0];    // Channel 0
    audio[1] = &buffer[1];    // Channel 1
    
    effect->processReplacing(effect, audio, audio, buffer.getNumFrames());
    
    delete [] audio;
}

Any idea how I could solve this simply, without needed to use extensive for loops?

The example below is almost working but I get lots of glitches and nasty sounds.

void ofApp::process(ofSoundBuffer &buffer)
{
    // Separate the soundbuffer in the 2 channels
    ofSoundBuffer rBuffer;
    ofSoundBuffer lBuffer;
    buffer.getChannel(rBuffer, 0);
    buffer.getChannel(lBuffer, 1);
    
    // Convert the 2 sound buffer into a float**
    float** audio = new (float *[2]);
    audio[0] = &rBuffer[0];
    audio[1] = &lBuffer[0];
    
    effect->processReplacing(effect, audio, audio, buffer.getNumFrames());    
    buffer.setChannel(rBuffer, 0);
    buffer.setChannel(lBuffer, 1);
    
    delete [] audio;
}

Thanks!

the way you are doing it in your second example seems correct. i’m not sure of the api of the library you are using so not sure about the float**…, it seems weird that you have to pass audio twice to the processReplacing function.

Also make sure that you are in release, running in debug can be slow enough that the computation doesn’t finish on time so you hear noises.

And i would move the ofSoundBuffer rBuffer and lBuffer out of the function so they are not being constantly allocated which can be slow

Thanks, I tried your advices and I realised something weird with ofSoundBuffer.

If I have a function like the following, it woks fine.

void ofApp::fillBuffer(ofSoundBuffer &buffer)
{
    // Fill the buffer, frame by frame
    for(int i = 0; i < buffer.getNumFrames(); i++) {
        // Read 1 sample from a file and put it in our buffer
        play(buffer.getSample(i, 0), buffer.getSample(i, 1));
    }
}

But if I do something like below, I hear a little bit of electrical noise (which seems to be coming only on the right channel).

ofSoundBuffer rBuffer;
ofSoundBuffer lBuffer;
rBuffer.allocate(BUFFERSIZE, 1);
lBuffer.allocate(BUFFERSIZE, 1);


void ofApp::process(ofSoundBuffer &buffer)
{
    // Fill the buffer, frame by frame
    for(int i = 0; i < buffer.getNumFrames(); i++) {
        // Read 1 sample from a file and put it in our buffer
        play(rBuffer.getSample(i, 0), lBuffer.getSample(i, 0));
    }
    
    buffer.setChannel(rBuffer, 0);
    buffer.setChannel(lBuffer, 1);
}

I had this electrical noise before but I thought that it was because of the effects. Now I think it’s more how I use ofSoundBuffer.

are you running in release?

Yes

can you upload a small example that shows the problem? i’m looking at those functions in ofSoundBuffer but they look correct to me

mmh, no actually there really seems to be a bug in setChannel, are you using 0.9.8?

I took the soundBuffer example and managed to reproduce the problem I have.
The fillBuffer_1() function is fine but the fillBuffer_2() is making this weird noise.

testSoundBuffer.zip (24.4 KB)

Edit: Yes on 0.9.8, I am on origin/stable at the moment.

can you check if changing line 518 in ofSoundBuffer.cpp in setChannel from

const float * inBufferPtr = &(inBuffer[targetChannel]);

to:

const float * inBufferPtr = &(inBuffer[0]);

solves the problem?

also in line 501 in getChannel, i believe the correct would be:

	copyTo(targetBuffer, getNumFrames(), 0, 0);

but that shouldn’t be a problem in your case

1 Like

Yes it does solve the problem! Super!