Questions about code whose radius changes depending on the size of the sound

Hi I want to get a number for the volume of sound. So I found an example and entered the code.

 for (int i = 0; i<bufferSize;i++){
  
    left = input[i*2]*0.5;
    right = input[i*2+1]*0.5;

    volume += left * left;
    volume += right * right;
}
volume = sqrt(volume/(bufferSize*2));
}

But I don’t know the meaning of the audioIn function.

I wonder why input[i*2] means and why 0.5 times and what the formula for volume means.
For your information, I know the sample rate and buffer size.

And I wonder if there is a way to make the circle grow bigger and smaller when the sound gets louder. I am thinking about it, too.

void audioIn( float* input, int bufferSize, int nChannels);

ofSoundStream soundInput;

float volume;

};


#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
soundInput.setup(this,0,2,44100,256,4);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
ofDrawBitmapString("Volume = " + to_string(volume) ,0, 50);
ofDrawCircle(0,0,ofMap(volume,0.0,2.0,60.0,300.0));
}

//--------------------------------------------------------------
void ofApp::audioIn(float *input, int bufferSize, int nChannels){
float left,right;
volume = 0.0;
for (int i = 0; i<bufferSize;i++){
    left = input[i*2]*0.5;
    right = input[i*2+1]*0.5;
    
    volume += left * left;
    volume += right * right;
}
volume = sqrt(volume/(bufferSize*2));
}

Hi @jewel,

the audioIn is a callback function that will be called by openFrameworks every time new audio data is available to process. Similar to the draw() function that get’s called automatically.

The for loop at the beginning of your question looks like it is calculating the RMS of the input signal.
The expression input[i*2] will only take even samples from the buffer (0,2,4,…),
whilst input[i*2+1] only provides odd samples (1,3,5,…). Since audio samples of multiple channels are are usually interleaved the input will contain samples for left (L) and right® like [LRLRLRLRLRL…].

I am not entirely sure about the 0.5, but I think that is related to the 2 channels you are having.

Regarding the size of the circle, the rms is usually less than the peak value which is in the range of [-1, 1] for samples from your sound card. You could use ofMap like in the example you found.

Does that answer your questions?

Best regards

2 Likes

You are a hero to me. Thank you for such a good answer.

Is it called interleaved by storing left samples in odd numbers and right samples in even numbers?
And I wonder what input means to the audioin function. Does it mean the size of each sample?

Interleaved only means that in case of multiple channels there will be the first sample of each channel, before the second, instead of all samples from channel 1 followed by the next channel and so on.
In openFrameworks the first sample at 0 is from the left channel. So, left samples are stored in even numbers and right samples are in odd numbers.
The input variable of audioIn is a float pointer, that’s why there is the *.
Input is the first address of a “vector” with float numbers of length bufferSize. Since in C++ you start indexing from 0, the last element in the input vector is bufferSize-1. That’s why the for loop goes from i=0 to i < bufferSize.