I'm trying to measure audio sound frequency in decibels, but I'm getting issues. I have used AVAudioSession & AVAudioRecorder to record audio and used averagePower & peakPower methods to get power levels.
According to the Apple document averagePower could be -160 (minimum) to 0 (maximum), but when I started recording it s showing me -60 to -50 power even in a silent environment. When I started speaking it moves to -40 to -30. I feel it is wrong. Any suggestion would be appreciated!
How can I convert DBFS to DB?
Also there is method powerToDecibels(_:zeroReference:) in Accelerate which converts power to db but it is not working. Can I know what is the value of
zeroReference
? or how can I used it to convert?
Here is my code to record audio. Please let me know if anything is wrong:
import UIKit
import AVFoundation
import Accelerate
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setUpAudioCapture()
// Do any additional setup after loading the view.
}
private func setUpAudioCapture() {
let recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord)
try recordingSession.setActive(true)
try recordingSession.setMode(.measurement)
recordingSession.requestRecordPermission({ result in
guard result else { return }
})
captureAudio()
} catch {
print("ERROR: Failed to set up recording session.")
}
}
private func captureAudio() {
let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioFilename = documentPath.appendingPathComponent("record.caf")
let settings:[String : Any] =
[
AVFormatIDKey :kAudioFormatAppleIMA4 as AnyObject,
AVSampleRateKey:44100,
AVNumberOfChannelsKey:1,
AVLinearPCMBitDepthKey:32 ,
AVLinearPCMIsBigEndianKey:false,
AVLinearPCMIsFloatKey:false,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
]
do {
let audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.prepareToRecord()
audioRecorder.record()
audioRecorder.isMeteringEnabled = true
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
audioRecorder.updateMeters()
let db = audioRecorder.averagePower(forChannel: 0)
let peakdb = audioRecorder.peakPower(forChannel: 0)
let pTd = vDSP.powerToDecibels([db], zeroReference: -80)
print("Avg",db, "peak",peakdb, "powerToDecibels", pTd)
}
} catch {
print("ERROR: Failed to start recording process.")
}
}
}
I want record audio and measure sound in db.