I am trying to get the power of audio by looping on the audio samples and getting the average power per channel.
I want to get a value between 0 and 1 that reflect the intensity of the audio being played. Right now I am getting dB (decibel value) which is a float value from -160 (near silent) to 0 (very loud).
Here is my code written in Swift:
func configureAudio() {
audioController.play()
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
audioController.numberOfLoops = 0
audioController.meteringEnabled = true
var audTimer = CADisplayLink(target: self, selector: "monitorAudio")
audTimer.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
}
func monitorAudio() {
audioController.updateMeters()
var dB = Float(0)
for i in 0..<audioController.numberOfChannels {
dB += audioController.averagePowerForChannel(i)
}
dB /= Float(audioController.numberOfChannels)
//code that I copied from website but obviously it is not normalization
var power = (Int(log10(dB+161)/log10(1.5) * 100) - 1220) * 6
if power < 0 {
power = 0
}
println(power)
}
I am not sure if the dB value i am getting is accurate or am I doing something wrong?
right now I am getting values between 0-190 using some code I found but it doesn't make much sense for me.
What I need is to normalize the dB values I am getting to be between 0 - 1
EDIT - Feel free to write code in Obective-C
averagePowerForChannel
returns a dB value where 0 dB
represents digital full scale. If you want value between 0 and 1 then dB most certainly is not the right scale for you.
As your code is kind of hinting at the function for turning a digital level into dB is
dB = 20 * log10(ffs);
so when ffs = 1.0, dB is 0 and when ffs == 0 then dB is -inf.
You just need to go the other way.
var power = exp(10, dB/20);