• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How metering is calculated...
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How metering is calculated...


  • Subject: Re: How metering is calculated...
  • From: Brian Willoughby <email@hidden>
  • Date: Mon, 1 Mar 2010 11:51:53 -0800


On Mar 1, 2010, at 10:07, Grant Robinson wrote:
On Mon, Mar 1, 2010 at 10:38 AM, Brian Willoughby <email@hidden > wrote:
You left out a critical aspect of your algorithm. The 'M' in RMS stands for
Mean, but you don't mention how you are calculating the mean. I suspect
this is where your problem lies.

From what I have read, RMS is the square root of the mathematical mean of the sum of the values squared. So, for each channel, I do the following: float sum = 0.0; while (looping) { int16_t val = *data; float normalVal = val / 32767.0; sum += (normalVal * normalVal); numSamples++; }

float rms = sqrtf(sum/numSamples);
float power = 20*log10f(rms/base);

You basically have it right, except you still have no indication of how many audio samples are involved in your loop. The size of the buffer that is averaged will affect the result. You cannot simply use the buffer size provided by the audio system, because that can be different under certain conditions. In other words, numSamples cannot vary or else your results will differ.


In order to emulate an analog meter, you must calculate the Mean value over a specific amount of time. Typically, this is 300 milliseconds, if I recall correctly. I cannot say what time duration Apple is using for their meters, but 300 ms is probably a good starting point. Note that you must account for the sample rate when calculating the duration of the averaging, so your metering code must therefor adapt to sample rate.

One thing to keep in mind is that if the buffers you're provided do not evenly divide into 300 ms, then you will have to handle this carefully. If you are calculating peak hold, then you'll have to find a way to carry the 300 ms average across buffers, otherwise you might miss a maximum that happens to fall in a time which spans two buffers. Thankfully, you do not necessarily need to update the RMS meter on every sample, so you can perhaps make some optimizations for providing fewer results and thus saving on calculations. Keep in mind that optimizations can cause your code to miss peak values, though.


Also, I am surprised that you mention 'normalized.' In my book, that is a
verb, so I am concerned that you are normalizing the values, which would
alter them. In other words, 'normalized' usually refers to a process, so
you should be clear as to whether you are processing the values in some way
at that stage.

From my understanding, raw 16-bit signed integer audio values are a fixed-point number representing the voltage at the time the audio stream was sampled. So, by normalizing, I mean turning it from a fixed-point integer number into a float decimal number in the range -1.0 to 1.0 (which you can see in the above calculation). Is that more-or-less correct?

Perhaps I am being pedantic, but the music industry definition of 'normalize' is a process which searches for the maximum peak in a selection of audio and then applies a gain to bring that peak to the maximum possible value - i.e. full scale. But that would alter the data before metering and you don't want to do that.


What you want, and what you're basically doing, is to 'convert' whenever you start with integer and desire float.

In your specific case, the 32767.0 constant is incorrect. The correct conversion value between integer and float is always a power of two, no matter the bit depth. Thus, you should be using 32768.0 (if you doubt this, the topic has been covered many, many times in the archives of this mailing list).

If you were writing an AudioUnit or using CoreAudio's AudioFile classes, then the conversion to float would be properly handled for you. Looking back at your original message, I see that you're writing this on Windows, so I suppose it is necessary for you to handle the conversion yourself.

Good luck!

Brian Willoughby
Sound Consulting

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: How metering is calculated...
      • From: James McCartney <email@hidden>
References: 
 >Re: How metering is calculated... (From: Brian Willoughby <email@hidden>)
 >Re: How metering is calculated... (From: Grant Robinson <email@hidden>)

  • Prev by Date: Re: How metering is calculated...
  • Next by Date: Re: Input sidechain and AU-Lab
  • Previous by thread: Re: How metering is calculated...
  • Next by thread: Re: How metering is calculated...
  • Index(es):
    • Date
    • Thread