iphone - iOS - Detect Blow into Mic and convert the results! (swift) -
i need develop ios app in swift detects blow in microphone user. has challenge-game 2 players have blow iphone mic 1 after other. decibel values should measured , converted in meter or kilometer can determine winner. player "blows further" (player1: 50km, player2: 70km) wins.
is possible implementation?
i have code in swift , don't know how proceed:
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 automatically wrapped nsnumber objects, simplified [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); } }
thanks ahead!
close. have couple of issues. selector call crashes app because you're not passing argument , leveltimercallback()
expects one.
averagepowerperchannel
seems give me more real-time metering used instead of peakpowerperchannel
also, need set audio session. wasn't sure math about, got rid of here. i've pasted entire view controller below basic mic detection.
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 audiosession, set playandrecord , make active var audiosession:avaudiosession = avaudiosession.sharedinstance() audiosession.setcategory(avaudiosessioncategoryplayandrecord, error: nil) audiosession.setactive(true, error: nil) //set url audio file var documents: anyobject = nssearchpathfordirectoriesindomains( nssearchpathdirectory.documentdirectory, nssearchpathdomainmask.userdomainmask, true)[0] var str = documents.stringbyappendingpathcomponent("recordtest.caf") var url = nsurl.fileurlwithpath(str string) // make dictionary hold recording settings can instantiate our avaudiorecorder var recordsettings: [nsobject : anyobject] = [avformatidkey:kaudioformatappleima4, avsampleratekey:44100.0, avnumberofchannelskey:2,avencoderbitratekey:12800, avlinearpcmbitdepthkey:16, avencoderaudioqualitykey:avaudioquality.max.rawvalue ] //declare variable store returned error if have problem instantiating our avaudiorecorder var error: nserror? //instantiate avaudiorecorder recorder = avaudiorecorder(url:url, settings: recordsettings, error: &error) //if there's error, print shit - otherwise, run preparetorecord , meteringenabled turn on metering (must run in order) if let e = error { println(e.localizeddescription) } else { recorder.preparetorecord() recorder.meteringenabled = true //start recording recorder.record() //instantiate timer called whatever frequency want grab metering values self.leveltimer = nstimer.scheduledtimerwithtimeinterval(0.02, target: self, selector: selector("leveltimercallback"), userinfo: nil, repeats: true) } } //this selector/function called every time our timer (leveltime) fires func leveltimercallback() { //we have update meters before can metering values recorder.updatemeters() //print console if beyond threshold value. here i've used -7 if recorder.averagepowerforchannel(0) > -7 { print("dis da level i'm hearin' in dat mic ") println(recorder.averagepowerforchannel(0)) println("do thing want, mofo") } } override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can recreated. } }
Comments
Post a Comment