0

I'm trying to leverage AVFoundation to measure sudden loud noises. The type of noise I'm trying to identify would be something like a gunshot for example or an equivalent sudden change in the ambient noise level. So far I've managed to derive the peak and average power level in dBFS with the following code.

public func start() throws {
    let recordSettings: [String: Any] = [
        AVSampleRateKey: 44100.0,
        AVFormatIDKey: kAudioFormatMPEG4AAC,
        AVNumberOfChannelsKey : 1,
        AVEncoderAudioQualityKey : AVAudioQuality.medium.rawValue,
    ]

    try audioSession.setCategory(.playAndRecord)
    try audioSession.setActive(true)

    let audioRecorder = try AVAudioRecorder(url: fileURL, settings: recordSettings)
    audioRecorder.isMeteringEnabled = true
    audioRecorder.record()

    timer = Timer.publish(every: 0.1, on: .main, in: .default)
        .autoconnect()
        .receive(on: acousticPressureOperationQueue)
        .sink { timestamp in
            audioRecorder.updateMeters()

            let average = audioRecorder.averagePower(forChannel: 0)
            let peak = audioRecorder.peakPower(forChannel: 0)
            let sample = Sample(timestamp: Date(), peak: peak, average: average)

            self.log.info("Sample(timestamp: \(sample.timestamp), peakPower: \(sample.peak), averagePower: \(sample.average))")
            self.eventPublisher.send(sample)
        }

    self.audioRecorder = audioRecorder
}

This gives me some feedback but the signal seems to get clipped easily. The baseline reading in my quiet office is approx. -50 dBFS and clapping my hands will max out the signal at 0 so clearly this is well below the threshold for the magnitude of sound I'm looking to identify.

I'm wondering if I'm on the right track here or do I need to change course. I'm realizing there's a very steep learning curve for audio on iOS so I'm hoping I can get some help here.

Other avenues I've started exploring are AVCaptureAudioChannel.averagePowerLevel/peakHoldLevel and AudioQueueLevelMeterState.mAveragePower/mPeakPower but the documentation is lacking and I'm not sure whether I need to go down these rabbit holes.

Ultimately, I don't need a very accurate reading, just to detect that a loud noise has occurred. Any help would be appreciated! Thanks in advance.

doovers
  • 8,545
  • 10
  • 42
  • 70

0 Answers0