How to detect max dB Swift

不羁的心 提交于 2019-12-21 05:51:12

问题


I'm trying to detect dB on a iOS Device, however, I am new to AV audio foundation can't really get to figure it out. I have come across this post: iOS - Detect Blow into Mic and convert the results! (swift), but it is not working for me.

My current code is this:

import Foundation
import UIKit
import AVFoundation
import CoreAudio

class ViewController: UIViewController {

var recorder: AVAudioRecorder!
var levelTimer = NSTimer()
var lowPassResults: Double = 0.0

override func viewDidLoad() {
    super.viewDidLoad()

    //make an AudioSession, set it to PlayAndRecord and make it active
    var audioSession:AVAudioSession = AVAudioSession.sharedInstance()
    audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: nil)
    audioSession.setActive(true, error: nil)

    //set up the URL for the audio file
    var documents: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory,  NSSearchPathDomainMask.UserDomainMask, true)[0]
    var str =  documents.stringByAppendingPathComponent("recordTest.caf")
    var url = NSURL.fileURLWithPath(str as String)

    // make a dictionary to hold the recording settings so we can instantiate our AVAudioRecorder
    var recordSettings: [NSObject : AnyObject] = [AVFormatIDKey:kAudioFormatAppleIMA4,
                                                  AVSampleRateKey:44100.0,
                                                  AVNumberOfChannelsKey:2,AVEncoderBitRateKey:12800,
                                                  AVLinearPCMBitDepthKey:16,
                                                  AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue

    ]

    //declare a variable to store the returned error if we have a problem instantiating our AVAudioRecorder
    var error: NSError?

    //Instantiate an AVAudioRecorder
    recorder = AVAudioRecorder(URL:url, settings: recordSettings, error: &error)
    //If there's an error, print otherwise, run prepareToRecord and meteringEnabled to turn on metering (must be run in that order)
    if let e = error {
        print(e.localizedDescription)
    } else {
        recorder.prepareToRecord()
        recorder.meteringEnabled = true

        //start recording
        recorder.record()

        //instantiate a timer to be called with whatever frequency we want to grab metering values
        self.levelTimer = NSTimer.scheduledTimerWithTimeInterval(0.02, target: self, selector: #selector(ViewController.levelTimerCallback), userInfo: nil, repeats: true)

    }

}

//This selector/function is called every time our timer (levelTime) fires
func levelTimerCallback() {
    //we have to update meters before we can get the metering values
    recorder.updateMeters()

    //print to the console if we are beyond a threshold value. Here I've used -7
    if recorder.averagePowerForChannel(0) > -7 {
        print("Dis be da level I'm hearin' you in dat mic ")
        print(recorder.averagePowerForChannel(0))
        print("Do the thing I want, mofo")
    }
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

回答1:


i was currently building my app about movie making,and learned something about how to metering sound level in dB.

the origin data of recorder.averagePowerForChannel is not really dB level of the sound,it's provide a level range which is -160 - 0,so we need some modification to make this data more reasonable

so i was finding some thing that makes this data(value) convert to dB level data.

(Sorry about forgot where i was found it!)

here is the code

/**
 Format dBFS to dB

 - author: RÅGE_Devil_Jåmeson
 - date: (2016-07-13) 20:07:03

 - parameter dBFSValue: raw value of averagePowerOfChannel

 - returns: formatted value
 */
func dBFS_convertTo_dB (dBFSValue: Float) -> Float
{
var level:Float = 0.0
let peak_bottom:Float = -60.0 // dBFS -> -160..0   so it can be -80 or -60

if dBFSValue < peak_bottom
{
    level = 0.0
}
else if dBFSValue >= 0.0
{
    level = 1.0
}
else
{
    let root:Float              =   2.0
    let minAmp:Float            =   powf(10.0, 0.05 * peak_bottom)
    let inverseAmpRange:Float   =   1.0 / (1.0 - minAmp)
    let amp:Float               =   powf(10.0, 0.05 * dBFSValue)
    let adjAmp:Float            =   (amp - minAmp) * inverseAmpRange

    level = powf(adjAmp, 1.0 / root)
}
return level
}

i was noticed that you are recording whit 2 channels so it will be little different with my code;

wish could help you out or give you some ideas :D

LAST UPDATE

Change coding language to swift



来源:https://stackoverflow.com/questions/38246919/how-to-detect-max-db-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!