Search code examples
iosswiftspeech-recognitionspeech

speechRecognizer not returning answer


I was following some tutorials on the iOS 10 speech recognition API (https://code.tutsplus.com/tutorials/using-the-speech-recognition-api-in-ios-10--cms-28032?ec_unit=translation-info-language) and my version just doesn't work. There is no text response for the voice input. I followed the tutorial but I had to make some changes (apparently newer versions of Swift don't accept some lines of code exactly as they were on the tutorial). Can you guys give me some ideas of how and why it's not working?

This is the method I'm running:

func startRecording() {
    // Setup audio engine and speech recognizer
    let node = audioEngine.inputNode
    let recordingFormat = node.outputFormat(forBus: 0)
    node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
        self.request.append(buffer)
    }

    // Prepare and start recording
    audioEngine.prepare()
    do {
        try audioEngine.start()
        self.status = .recognizing
    } catch {
        return print(error)
    }

    // Analyze the speech
    recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { result, error in
        if let result = result {
            self.tview.text = result.bestTranscription.formattedString
            NSLog(result.bestTranscription.formattedString)
        } else if let error = error {
            print(error)
            NSLog(error.localizedDescription)
        }
    })
}

When debugging, neither speechRecognizer or recognitionTask have nil values.

This is how I defined the variables on the ViewController:

let audioEngine = AVAudioEngine()
let speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer()
let request = SFSpeechAudioBufferRecognitionRequest()
var recognitionTask: SFSpeechRecognitionTask?

Working setup: Tested on 2017 iPad, iOS 11.4. Xcode 9.4.1, Swift 4.1.

Thanks!


Solution

  • This problem cause because of AVAudioSession not set to Record. Try this.

    In View Controller add

    let audioSession = AVAudioSession.sharedInstance()
    

    Your final method will be.

    func startRecording() {
        //Change / Edit Start
        do {
            try audioSession.setCategory(AVAudioSessionCategoryRecord)
            try audioSession.setMode(AVAudioSessionModeMeasurement)
            try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
        } catch {
            print("audioSession properties weren't set because of an error.")
        }
        //Change / Edit Finished
        // Setup audio engine and speech recognizer
        let node = audioEngine.inputNode
        let recordingFormat = node.outputFormat(forBus: 0)
        node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
            self.request.append(buffer)
        }
    
        // Prepare and start recording
        audioEngine.prepare()
        do {
            try audioEngine.start()
            self.status = .recognizing
        } catch {
            return print(error)
        }
    
        // Analyze the speech
        recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { result, error in
            if let result = result {
                self.tview.text = result.bestTranscription.formattedString
                NSLog(result.bestTranscription.formattedString)
            } else if let error = error {
                print(error)
                NSLog(error.localizedDescription)
            }
        })
    }