I have used AVAudioRecorder and AVAudioSession which gives me values in decibels in the range 0 (extremely loud) to -160(near silence). In the app, I have to plot an A-rating i.e.dB(A) curve for real time audio measurements received from the iPhone microphone.
I am implementing the following procedure -
Get the dB value from the AVAudioRecorder
NSDictionary* recorderSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatAppleIMA4],AVFormatIDKey,
[NSNumber numberWithInt:44100],AVSampleRateKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:8],AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
nil];
float dbValue = [self.recorder averagePowerForChannel:0]; //which returns a dB value in 0 to -160 range
Obtain a positive dB value, float posdBValue = dbValue+160; for example, if dbValue=-100, then posdBValue = -110+160 = 50dB
Calculate dB(A) values by adding A-weighting for different 1/3 octave frequency bands Reference for A-weighting values - http://personal.cityu.edu.hk/~bsapplec/single.htm
Plot the dB(A) values Vs Frequncy bands on the graph
Questions 1. Is this the correct way to find out dB(A) values from decibels? 2. Is FFT supposed to be used? If yes, where and how does FFT fit into the calculations? 3. Based on a single dB value returned from averagePowerForChannel method, do I have to calculate different dB values for all the center frequencies in 24 Octave bands? If yes, how? 4. Can anyone suggest a solution, open-source library, references for iPhone code?
I am at a complete loss. I feel I am missing out on something. Please help! I just need to figure out the calculations and logic for now. Thank you.
In your first question about obtaining a dB(A) value by adding an arbitrary dB value: I think the answer is no, that is not correct. In digital audio, 0dB is considered a full scale signal with lower amplitudes going negative.
As for the 1/3rd octave analyzer: Let's start with the definition of an octave. An octave means a doubling or halving of a frequency. So 20Hz and 40Hz are an octave apart. If you divide an octave logarithmically into 3 ranges those are called 1/3rd octave bands.
The job of a 1/3rd octave analyzer is to display in meter form the level of each of the bands over a given frequency range. Choosing a range of 20Hz to 20kHz, the first meter you'd have a bar indicating the level with a center frequency of 20Hz, a lower band limit of of 17.8 Hz and an upper band limit of 22.4 Hz. And so on up the spectrum.
The most common way this is implemented is with a bank of bandpass filters, each tuned to one of the center frequencies. You then take the output from the filter and compute the RMS and that becomes the level for that band. If you are doing this in software then there is a fair amount of DSP knowledge required to design the filters and the computational overhead is rather high (31 filters to cover 20Hz to 20kHz).
Another approach is to use an FFT. With this approach the goal is to lump together FFT bins around the center frequency and compute the total energy. The trick is in choosing which bands to lump because FFT bins are equally spaced in hertz.
I don't know what sample rate you are recording at but it's pretty easy to compute what your bin widths and bin centers are going to be:
The bin width is equal to the sampleRate/FFTlength. A 66536 pt FFT at 48kHz gives a bin width of 0.73Hz. Bin 24 has a bin lower limit at 17.58 and a bin center at 17.95, which is reasonably close to the lower band limit of a 1/3rd octave filter. And bin 30 has a upper limit of 22.71 and a center of 22.34, reasonable close to 22.4Hz. As you might notice, you are introducing some amount of error due to the frequency resolution of the FFT. You can reduce this error by increasing the size of the FFT.
Here's the calculator I used for finding the FFT frequencies and the 1/3 octave filter frequencies: http://www.zytrax.com/tech/audio/calculator.html