Reputation: 21
I am detecting microphone blow and using this to trigger an animation and am getting this error message. "constant 'error' used before being intialised". This is the code I have:
override func viewDidLoad() {
super.viewDidLoad()
//make an AudioSession, set it to PlayAndRecord and make it active
let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryRecord)
try! audioSession.setActive(true)
//set up the URL for the audio file
let documents: AnyObject = NSSearchPathForDirectoriesInDomains( FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as AnyObject
let str = (documents as! NSString).appending("recordTest.caf")
NSURL.fileURL(withPath: str as String)
// make a dictionary to hold the recording settings so we can instantiate our AVAudioRecorder
let recordSettings: [NSObject : AnyObject] = [AVFormatIDKey as NSObject:kAudioFormatAppleIMA4 as AnyObject,
AVSampleRateKey as NSObject:44100.0 as AnyObject,
AVNumberOfChannelsKey as NSObject:2 as AnyObject,AVEncoderBitRateKey as NSObject:12800 as AnyObject,
AVLinearPCMBitDepthKey as NSObject:16 as AnyObject,
AVEncoderAudioQualityKey as NSObject:AVAudioQuality.max.rawValue as AnyObject
]
//declare a variable to store the returned error if we have a problem instantiating our AVAudioRecorder
let error: NSError?
//Instantiate an AVAudioRecorder
recorder = try! AVAudioRecorder(url: documents as! URL, settings: recordSettings as! [String : Any])
//If there's an error, print it - 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.isMeteringEnabled = true
//start recording
recorder.record()
//instantiate a timer to be called with whatever frequency we want to grab metering values
self.levelTimer = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(ViewController.levelTimerCallback), userInfo: nil, repeats: true)
}
}
//selector/function is called every time our timer (levelTime) fires
func levelTimerCallback() {
//update meters
recorder.updateMeters()
//print to the console if we are beyond a threshold value
if recorder.averagePower(forChannel: 0) > -7 {
print("Mic Blow Detected ")
print(recorder.averagePower(forChannel: 0))
isAnimating = false
} else {
isAnimating = true
}
}
It also seems that this line is forcing the app to quit so obviously this is where the issue is but I am new to Xcode and cannot spot what I have done wrong, if anyone has ideas on what I should change this too that would be great.
recorder = try! AVAudioRecorder(url: documents as! URL, settings: recordSettings as! [String : Any])
Thanks in advance!
Upvotes: 0
Views: 3310
Reputation: 23711
You have no code that could have set the value of error
between the point that it is declared and the point that it is used. For error possibly take on a new value, it would have to be passed to the constructor for the AVAudioRecorder
. You could initialize the error with:
let error : Error? = nil
But again this would be frivolous because there is no chance for it's value to change (it is a let
variable) and even if it were a var, it is not passed to any code between when it is declared and when it is used in the if let
construction.
You are crashing because you have told the system that you want to create the AVAudioRecorder but it should never fail (that's try!
). More likely you want to do something like:
let documentSearchPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDir = documentSearchPaths[0] as NSString
let recordingFilePath = documentsDir.appendingPathComponent("recordTest.caf")
let recordingFileURL = NSURL.fileURL(withPath: recordingFilePath)
var recorder : AVAudioRecorder?
do{
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(AVAudioSessionCategoryRecord)
try audioSession.setActive(true)
// make a dictionary to hold the recording settings so we can instantiate our AVAudioRecorder
let recordSettings: [String : Any] = [AVFormatIDKey : kAudioFormatAppleIMA4,
AVSampleRateKey : NSNumber(value: 44100.0),
AVNumberOfChannelsKey : NSNumber(value: 2),
AVEncoderBitRateKey : NSNumber(value: 12800),
AVLinearPCMBitDepthKey : NSNumber(value: 16),
AVEncoderAudioQualityKey :NSNumber(value: AVAudioQuality.max.rawValue)
]
recorder = try AVAudioRecorder(url: recordingFileURL, settings: recordSettings)
} catch let audio_error as NSError {
print("Setting up the audio recording failed with error \(audio_error)")
}
if let recorder = recorder {
recorder.prepareToRecord()
recorder.isMeteringEnabled = true
//start recording
recorder.record()
//etc...
}
Upvotes: 2