我想编写一个简单的应用程序,当麦克风的声级达到一定水平时,它会“做一些事情”,显示音频输入级别以获得额外的积分
无法在 swift 中找到任何达到此目的的示例 - 不想记录,只是监视
一直在查看 AVFoundation 类的文档,但无法起步
谢谢
让您可以使用以下代码:
func initalizeRecorder ()
{
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
try AVAudioSession.sharedInstance().setActive(true)
}catch{
print(error);
}
let stringDir:NSString = self.getDocumentsDirectory();
let audioFilename = stringDir.stringByAppendingPathComponent("recording.m4a")
let audioURL = NSURL(fileURLWithPath: audioFilename)
print("File Path : \(audioFilename)");
// make a dictionary to hold the recording settings so we can instantiate our AVAudioRecorder
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000.0,
AVNumberOfChannelsKey: 1 as NSNumber,
AVEncoderBitRateKey:12800 as NSNumber,
AVLinearPCMBitDepthKey:16 as NSNumber,
AVEncoderAudioQualityKey: AVAudioQuality.High.rawValue
]
do {
if audioRecorder == nil
{
audioRecorder = try AVAudioRecorder(URL: audioURL, settings: settings )
audioRecorder!.delegate = self
audioRecorder!.prepareToRecord();
audioRecorder!.meteringEnabled = true;
}
audioRecorder!.recordForDuration(NSTimeInterval(5.0));
} catch {
print("Error")
}
}
//GET DOCUMENT DIR PATH
func getDocumentsDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory
}
////START RECORDING
@IBAction func btnStartPress(sender: AnyObject) {
recordingSession = AVAudioSession.sharedInstance()
do {
recordingSession.requestRecordPermission() { [unowned self] (allowed: Bool) -> Void in
dispatch_async(dispatch_get_main_queue()) {
if allowed {
print("Allowd Permission Record!!")
self.initalizeRecorder ()
self.audioRecorder!.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("levelTimerCallback"), userInfo: nil, repeats: true)
} else {
// failed to record!
self.showPermissionAlert();
print("Failed Permission Record!!")
}
}
}
} catch {
// failed to record!
print("Failed Permission Record!!")
}
}
//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
if audioRecorder != nil
{
audioRecorder!.updateMeters()
let ALPHA : Double = 0.05;
let peakPowerForChannel : Double = pow(Double(10.0), (0.05) * Double(audioRecorder!.peakPowerForChannel(0)));
lowPassResults = ALPHA * peakPowerForChannel + Double((1.0) - ALPHA) * lowPassResults;
print("low pass res = \(lowPassResults)");
if (lowPassResults > 0.7 ){
print("Mic blow detected");
}
}
}
//STOP RECORDING
@IBAction func btnStopPress(sender: AnyObject) {
if audioRecorder != nil
{
audioRecorder!.stop()
self.levelTimer.invalidate()
}
}
在
AVAudioRecorder
中您可以“录制音频”(不必保存)并设置meteringEnabled
以使用该功能peakPowerForChannel(_:)
会的
返回给定通道所录制声音的峰值功率(以分贝为单位)。
如果对您有帮助,请告诉我。
@JayMehta 的代码,已更新至 Xcode 15.0
import UIKit
import AVFoundation
import DGCharts
struct Constants {
static let sampleTime = 0.02 // time between peak power calculations - seconds
static let filterTimeConstant = 0.4 // time to reach 63% of input - seconds
static let ALPHA = 1 - exp(-sampleTime / filterTimeConstant) // zero-order hold low-pass filter coefficient
}
class ViewController: UIViewController, AVAudioRecorderDelegate {
var audioRecorder: AVAudioRecorder?
var levelTimer = Timer()
var lowPassResults = 0.0
func initializeRecorder() {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
let stringDir = NSString(string: self.getDocumentsDirectory())
let audioFilename = stringDir.appendingPathComponent("recording.m4a")
let audioURL = URL(fileURLWithPath: audioFilename)
print("File Path: \(audioFilename)")
// make a dictionary to hold the recording settings so we can instantiate our AVAudioRecorder
let settings: [String : Any] = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000.0,
AVNumberOfChannelsKey: 1 as NSNumber,
AVEncoderBitRateKey: 12800 as NSNumber,
AVLinearPCMBitDepthKey: 16 as NSNumber,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
if audioRecorder == nil {
audioRecorder = try AVAudioRecorder(url: audioURL, settings: settings)
audioRecorder!.delegate = self
audioRecorder!.isMeteringEnabled = true
audioRecorder!.prepareToRecord()
}
audioRecorder!.record(forDuration: TimeInterval(5.0))
} catch {
print("Error")
}
}
// GET DOCUMENT DIR PATH
func getDocumentsDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
return documentsDirectory
}
// START RECORDING
@IBAction func btnStartPress(sender: AnyObject) {
AVAudioApplication.requestRecordPermission() { [unowned self] allowed in
if allowed {
print("Allowed permission to record!")
initializeRecorder()
audioRecorder!.record()
// instantiate a timer to be called with whatever frequency we want to grab metering values
levelTimer = Timer.scheduledTimer(timeInterval: Constants.sampleTime, target: self, selector: #selector(levelTimerCallback), userInfo: nil, repeats: true)
} else {
// failed to record!
// showPermissionAlert()
print("Failed permission to record!")
}
}
}
// This selector/function is called every time our timer (levelTime) fires
@objc func levelTimerCallback() {
// we have to update meters before we can get the metering values
audioRecorder!.updateMeters()
let peakPowerForChannel = pow(10, 0.05 * Double(audioRecorder!.peakPower(forChannel: 0)))
lowPassResults = Constants.ALPHA * peakPowerForChannel + (1 - Constants.ALPHA) * lowPassResults
print("low pass results = \(lowPassResults)")
if lowPassResults > 0.7 {
print("threshold exceeded")
}
}
// STOP RECORDING
@IBAction func btnStopPress(sender: AnyObject) {
audioRecorder!.stop()
levelTimer.invalidate()
}
}