Incorrect value in decibel measurement AVFoundation

I get on the output wrong decibel value when silent get 0.00 if I create noise goes up to 0.02 - 0.03. Something I do wrong, because I measured with another application with silence, I get about 20 db, with noise about 50 db.

struct NoiseMeterView: View {

    let audioRecorder: AVAudioRecorder
    @State var timer: Timer?
    @State var decibels: Float = 0

    init() {
        let audioFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("audio.m4a")
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 16000,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
        ]

        do {
            audioRecorder = try AVAudioRecorder(url: audioFileURL, settings: settings)
        } catch let error {
            fatalError("Error creating audio recorder: \(error.localizedDescription)")
        }
    }

    var body: some View {
        VStack {
            Text("Noise Level: \(String(format: "%.2f", decibels)) dB")
                .font(.title)
                .padding()
            Button(action: {
                if timer == nil {
                    startMetering()
                } else {
                    stopMetering()
                }
            }) {
                Text(timer == nil ? "Start" : "Stop")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }

    func startMetering() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.record)
            try AVAudioSession.sharedInstance().setActive(true)
        } catch let error {
            print("Error setting up audio session: \(error.localizedDescription)")
            return
        }
        audioRecorder.isMeteringEnabled = true
        audioRecorder.record()
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                audioRecorder.updateMeters()
                var decibels = audioRecorder.peakPower(forChannel: 0)
                decibels = min(max(decibels, -120), 0)
                self.decibels = pow(10, (decibels / 20))
            }
    }

    func stopMetering() {
        timer?.invalidate()
        timer = nil
        audioRecorder.stop()
    }
}

what values are you comparing? The var decibels returned by audioRecorder.peakPower, or your own self.decibels? The value returned by AVAudioRecorder is already in units of dB. It is a relative power, not amplitude measurement. So if you expect your noise to be at 80dB below full scale, its power is at 40dB below full scale. So you might expect decibels to have a value of around -40.

I don't think you should be converting twice. Also, you're using the a dB conversion formula appropriate for amplitude, not power.

pow(10, (-40/20)) is equal to 0.01, which is of the order of magnitude you are seeing.

Your other measurements (20dB "silence", 50dB "noise") appear to be amplitude measurements relative to some stable (low) level.

Incorrect value in decibel measurement AVFoundation
 
 
Q