iosaudioavaudioplayerdecibel

How can I normalized decibel value and make it between 0 and 1


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


Solution

  • 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);