2015-07-05 4 views
7

मुझे एक आईओएस ऐप विकसित करने की जरूरत है जो उपयोगकर्ता से माइक्रोफोन में एक झटका का पता लगाता है। यह एक चुनौती-खेल होना है जहां दो खिलाड़ियों को एक के बाद आईफोन माइक में उड़ना होगा। डेसिबल मूल्यों को मापना चाहिए और मीटर या किलोमीटर में परिवर्तित किया जाना चाहिए ताकि मैं एक विजेता निर्धारित कर सकूं। वह खिलाड़ी जो "आगे बढ़ता है" (खिलाड़ी 1: 50 किमी, प्लेयर 2: 70 किमी) जीतता है।आईओएस - माइक में उड़ें और परिणामों को रूपांतरित करें! (स्विफ्ट)

क्या यह एक संभावित कार्यान्वयन है?

मैं तेजी में इस कोड है और मैं नहीं जानता कि आगे बढ़ने के लिए कैसे:

import Foundation 
import UIKit 
import AVFoundation 
import CoreAudio 

class ViewController: UIViewController { 
// @IBOutlet weak var mainImage: UIImageView! 

var recorder: AVAudioRecorder! 
var levelTimer = NSTimer() 
var lowPassResults: Double = 0.0 
override func viewDidLoad() { 
    super.viewDidLoad() 
    let url = NSURL.fileURLWithPath("dev/null") 
    //numbers are automatically wrapped into NSNumber objects, so I simplified that to [NSString : NSNumber] 
    var settings : [NSString : NSNumber] = [AVSampleRateKey: 44100.0, AVFormatIDKey: kAudioFormatAppleLossless, AVNumberOfChannelsKey: 1, AVEncoderAudioQualityKey: AVAudioQuality.Max.rawValue] 
    var error: NSError? 
    // mainImage?.image = UIImage(named: "flyForReal.png"); 
    recorder = AVAudioRecorder(URL:url, settings:settings, error:&error) 

    if((recorder) != nil){ 
     recorder.prepareToRecord() 
     recorder.meteringEnabled = true 
     recorder.record() 
     levelTimer = NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: Selector("levelTimerCallback"), userInfo: nil, repeats: true) 
    } 
    else{ 
     NSLog("%@", "Error"); 
    } 
} 
func levelTimerCallback(timer:NSTimer) { 
    recorder.updateMeters() 

    let ALPHA: Double = 0.05 
    var peakPowerForChannel = pow(Double(10), (0.05 * Double(recorder.peakPowerForChannel(0)))) 
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults; 
    if(lowPassResults > 0.95){ 
     NSLog("@Mic blow detected"); 
    } 
    NSLog("@Average input: %f Peak input: %f Low pass results: %f", recorder.averagePowerForChannel(0), recorder.peakPowerForChannel(0), lowPassResults); 
} 
} 

धन्यवाद आगे!

उत्तर

9

बंद करें। आपके पास कुछ मुद्दे हैं। आपका चयनकर्ता कॉल ऐप को क्रैश करता है क्योंकि आप कोई तर्क नहीं दे रहे हैं और levelTimerCallback() एक की अपेक्षा करता है।

averagePowerPerChannel मुझे एक अधिक वास्तविक समय पैमाइश देने के लिए तो मैं प्रयोग किया जाता है कि peakPowerPerChannel

इसके अलावा के बजाय, आप एक ऑडियो सत्र सेट करने की जरूरत है लगता है। मुझे सच में यकीन नहीं था कि वह गणित क्या था, इसलिए मैंने इसे यहां से छुटकारा दिलाया। मैंने मूल माइक डिटेक्शन के लिए नीचे संपूर्ण दृश्य नियंत्रक चिपकाया है।

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, error: 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 that shit - otherwise, run prepareToRecord and meteringEnabled to turn on metering (must be run in that order) 
    if let e = error { 
     println(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("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 ") 
     println(recorder.averagePowerForChannel(0)) 
     println("Do the thing I want, mofo") 
    } 
} 



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


} 
3

मैंने एंड्रयू के उत्तर को स्विफ्ट 4 में परिवर्तित कर दिया, और यह बहुत अच्छा काम करता है! धन्यवाद!

import Foundation 
import UIKit 
import AVFoundation 
import CoreAudio 

class ViewController: UIViewController { 

    var recorder: AVAudioRecorder! 
    var levelTimer = Timer() 

    let LEVEL_THRESHOLD: Float = -10.0 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let documents = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0]) 
     let url = documents.appendingPathComponent("record.caf") 

     let recordSettings: [String: Any] = [ 
      AVFormatIDKey:    kAudioFormatAppleIMA4, 
      AVSampleRateKey:   44100.0, 
      AVNumberOfChannelsKey:  2, 
      AVEncoderBitRateKey:  12800, 
      AVLinearPCMBitDepthKey:  16, 
      AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue 
     ] 

     let audioSession = AVAudioSession.sharedInstance() 
     do { 
      try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord) 
      try audioSession.setActive(true) 
      try recorder = AVAudioRecorder(url:url, settings: recordSettings) 

     } catch { 
      return 
     } 

     recorder.prepareToRecord() 
     recorder.isMeteringEnabled = true 
     recorder.record() 

     levelTimer = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(levelTimerCallback), userInfo: nil, repeats: true) 

    } 

    @objc func levelTimerCallback() { 
     recorder.updateMeters() 

     let level = recorder.averagePower(forChannel: 0) 
     let isLoud = level > LEVEL_THRESHOLD 

     // do whatever you want with isLoud 
    } 

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


} 
संबंधित मुद्दे