0

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.

  1. 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!

  2. How can I convert DBFS to DB?

  3. 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.

TylerP
  • 9,600
  • 4
  • 39
  • 43
  • Are you maybe attempting to make those recordings in a loud environment? The microphone is very sensitive on its own and a lot of noise will go through, resulting in a constant high power results (especially in the `measuerment` audio session mode afaik). This would also explain why the difference is so small for when you talk. If that's the case, I would suggest exploring `AVAudioEngine` and the `installTap` method. This will allow for more fine-grained control, although it won't resolve the noise problem. – dziobaczy Nov 13 '22 at 22:30

0 Answers0