Old 02-09-2010, 08:00 AM   #1
RRokkenAudio
Human being with feelings
 
RRokkenAudio's Avatar
 
Join Date: Jun 2009
Location: Buffalo, NY
Posts: 777
Default RMS code

Looking for some rms code for a comp. A bit confusing so far, anyone have some floating around?
RRokkenAudio is offline   Reply With Quote
Old 02-10-2010, 10:17 PM   #2
robg
Human being with feelings
 
Join Date: Sep 2007
Location: Atascadero, CA
Posts: 305
Default

Do you need help calculating rms, or help with an existing formula in js?
robg is offline   Reply With Quote
Old 02-10-2010, 10:25 PM   #3
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 10,533
Default

Several JS have an RMS calc in them (schwa/audio_statistics and meters/dynamics_meter come to mind).
schwa is offline   Reply With Quote
Old 02-11-2010, 07:43 PM   #4
liteon
Human being with feelings
 
liteon's Avatar
 
Join Date: Apr 2008
Posts: 510
Default

i'm sure schwa's examples are well defined.

to simplify and perhaps give you a better chance to understand:

for a time domain calculation (which is very little more complicated than the basic 'average' function):


could be translated to:
Code:
rms = sqrt(sum/n);
the 'sum' parameter is defined as the sum of squares of input values (per sample x0..x[n]):
sum = x0*x0 + x1*x1 + ... + x[n]*x[n];
so you basically need to accumulate values into 'sum' and calculate 'rms' at a certain point. (but where?)

the 'n' parameter is the number of elements you've accumulated.
if you define a max window length 'n_max' (n_max = miliseconds*samplerate/1000) then you should reset 'sum' and any possible iterators to 0 when the iterator meats n_max.

but when calling rms = ....
'n' should be always equal to the number of accumulated elements (n = iterator value) and not 'n_max' - well unless you set rms calculation to be at iterator == n_max.

Last edited by liteon; 02-11-2010 at 07:50 PM.
liteon is offline   Reply With Quote
Old 02-12-2010, 06:27 AM   #5
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by liteon View Post
the 'n' parameter is the number of elements you've accumulated.
if you define a max window length 'n_max' (n_max = miliseconds*samplerate/1000) then you should reset 'sum' and any possible iterators to 0 when the iterator meats n_max.

but when calling rms = ....
'n' should be always equal to the number of accumulated elements (n = iterator value) and not 'n_max' - well unless you set rms calculation to be at iterator == n_max.
I might not get the wording, but from how I understood it have to disagree. [EDIT]

When you want RMS in a compressor (or any other realtime stream) you don't to reset the RMS nor the sum each time you processed one window. What you want is a so called running sum, that gives you the RMS at any given sample position in the stream.
So basically you have the usual formula:
rms = sqrt(sum/win_len);
with 'sum' being the sum of the square of the 'win_len' last samples (all samples before sample with index 0 are assumed to be 0.0).
So all you then need to do is keep a sum of the last 'win_len' samples squared in 'sum' and then apply the above formula to get the RMS.
An optimized way of keeping track of 'sum' would be to keep an array with the last 'win_len' samples squared and everytime you add a new squared sample to sum you also remove the square sampled value from 'win_len-1' from the array and add the current squared sample value, like this:
Code:
sum -= a[n];
a[n] = cur_spl^2;
sum += a[n];
rms = sqrt(sum/win_len);
n=(n+1)%win_len;
Of course there are approximations (RC-filter) that are WAY more faster.


EDIT: Ah liteon, I think I got it now, you'd only calculate RMS per block, which would be OK for a meter that doesn't have high update frequencies and the rest only makes sense if you calculate RMS for statistics in which the window size will be the length of the audio data you analyze.

Last edited by Mich; 02-12-2010 at 06:33 AM.
Mich is offline   Reply With Quote
Old 02-12-2010, 07:07 AM   #6
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 10,533
Default

Quote:
Originally Posted by liteon View Post
but when calling rms = ....
'n' should be always equal to the number of accumulated elements (n = iterator value) and not 'n_max'
liteon, your definitions and explanations are excellent, but I might disagree on this point. Setting the window to min(n,n_max) will cause the RMS value to be volatile on starting playback. Using a constant RMS window regardless of the amount of data collected will cause RMS to "fade in", which in most applications is preferable.
schwa is offline   Reply With Quote
Old 02-13-2010, 04:41 AM   #7
liteon
Human being with feelings
 
liteon's Avatar
 
Join Date: Apr 2008
Posts: 510
Default

yeah, my example isn't the best. its just a rms calculator, where the rms value can also be calculated at blocks with lengths different than the window length. per @block or per constant length. but the value is reset when the window length value is met, which is not best for a compressor.

the running rms example that mich has posted is perhaps the most accurate way to do it. here is the one-pole approximation he also mentions, which eliminates the need for a buffer:

Code:
@init
// window length = 300ms
win_len = 300*srate*0.001;
// filter coefficients
b1 = exp(-1/win_len);    // tau
a0 = 1 - b1;             // normalize filter output

@sample
// current sample
cur_spl = spl0;
// filter
fout = a0*(cur_spl*cur_spl) + b1*fout;
// get rms
rms = sqrt(fout);
more info:
http://en.wikipedia.org/wiki/RC_circ...considerations

--
liteon is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:19 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.