How to get rms value of an input channel in an audo app


#1

Hi again! I need to get the rms value of an input channel (in an audio app) instead of the main output channels for which I can use buffer->getRMSLevel().
I there a way to do that?
I have those buffers

const float* buf0 = bufferToFill.buffer->getReadPointer(0);
const float* buf1 = bufferToFill.buffer->getReadPointer(1);

#2

with bufferToFill.buffer you have access to the AudioBuffer, just call getRMSLevel() on it :slight_smile:


#3

After having read this and your other thread, I get the feeling that on thing is not clear to you: bufferToFill is a buffer that contains the input samples first. After getNextAudioBlock has returned the content of bufferToFill will be interpreted as output samples.

This means, while processing audio you usually replace the input samples with the output samples while working on the same buffer. If you don’t do anything to the buffer, the input samples will equal the output samples (you asked why you experience this behavior in this thread :Audio App for mix input from external audio card starts with sound even if the getNextAudioBlock() is empty). This is why you need to clear the buffer if you want to output silence.

Now getReadPointer just returns you a const pointer, e.g. a pointer that allows read operation only on the underlying memory only. In fact getReadPointer and getWritePointer will point to the SAME memory location, the only difference is that getWritePointer will allow you to change the content of that memory location, while getReadPointer doesn’t. If you don’t need write access to the data, using getReadPointer is the better choice.

I image you assumed that getReadPointer will provide you access to your input samples, while bufferToFill actually points to another memory region containing your output samples? I hope I got you right and didn’t explain something completely obvious to you :wink:


#4

Ok, excuse me for the late… Yes, I thought that getReadPointer provide me access to the input sample and getWritePointer contains the output sample… I was wrong!
But I have solved my problem calling a bufferToFill.buffer->clear(channel, startSample, numSamples); on the channels that make sound even if I don’t process them…
Thank you anyway for the explanation!


#5

what do you mean? If I call getRMSLevel on channel 0 it returns me the level of the left channel in output, not the input channel, but I’ve solved it taking the level from the buffer pointer directly:

rms1 = buf0[sample];

in the getNextAudioBlock(), and it seems to work well when I turn it to db with:

int db1 = 20 * log10(rms1);

#6

As @PluginPenguin stated before: at the begin of your getNextAudioBlock() method, the buffer holds the input data. Your task is to use this data, process it, and write it back to exact the same position. It’s both your input AND output buffer.

With your approach using only one sample, you won’t get the RMS level, as RMS stands for root mean square.
The steps for calculating RMS:

  • square a bunch of consecutive samples
  • add the squares
  • divide the result by the number of samples
  • take the root
  • optional: convert to decibels (btw handy class: Decibels)

or: calling the method getRMSLevel()


#7

Mhm… I didn’t know that, thank you, I’ll try the way you said.