如何检测max dB Swift

时间:2016-07-07 13:35:10

标签: ios swift avfoundation

我正在尝试在iOS设备上检测dB,但是,我是AV音频基础的新手无法真正弄明白。我遇到过这篇文章:iOS - Detect Blow into Mic and convert the results! (swift),但它不适用于我。

我目前的代码是:

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 个答案:

答案 0 :(得分:4)

我目前正在构建关于电影制作的应用程序,并学习了如何以dB为单位测量声级。

recorder.averagePowerForChannel 的原始数据实际上不是声音的dB级别,它提供的级别范围 -160 - 0 ,所以我们需要进行一些修改才能使这些数据更合理

所以我发现了一些使这个数据(值)转换为dB级数据的东西。

(抱歉忘记了我被发现的地方!)

这是代码

/**
 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
}

我注意到你正在录制2个频道,所以它与我的代码差别不大;

希望可以帮助你或给你一些想法:D

最后更新

将编码语言改为swift