How to get On-Device Speech Recognition to work continuously?

Hello,


I am unable to get my on-device speech recognition to work continuously. I know there is a 1 minute limit for Server based recognition but recent advances revealed in WWDC 2019 show that there is no limit for on-device recognition. Link below is the WWDC 2019 video on this.

Can anyone tell me what's wrong with my code or what I need to do to make it continuous? It is stopping the audio engine once transcription is done. But I dont want it to do so. Even if I by pass stopping the audio engine stop, it is still not recognizing and transcribing anymore speech. Look forward to some insight or recommendations. Thank-you!!!


https://developer.apple.com/videos/play/wwdc2019/256/



private func startRecording() throws {

// Cancel the previous task if it's running.

recognitionTask?.cancel()

self.recognitionTask = nil

// Configure the audio session for the app.

let audioSession = AVAudioSession.sharedInstance()

try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)

try audioSession.setActive(true, options: .notifyOthersOnDeactivation)

let inputNode = audioEngine.inputNode

// Create and configure the speech recognition request.

recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

guard let recognitionRequest = recognitionRequest else { fatalError("Unable to create a SFSpeechAudioBufferRecognitionRequest object") }

recognitionRequest.shouldReportPartialResults = true

// Keep speech recognition data on device

if #available(iOS 13, *) {

recognitionRequest.requiresOnDeviceRecognition = false

}


// Create a recognition task for the speech recognition session.

// Keep a reference to the task so that it can be canceled.

recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in

var isFinal = false

if let result = result {

// Update the text view with the results.

self.textView.text = result.bestTranscription.formattedString

isFinal = result.isFinal

print("Text \(result.bestTranscription.formattedString)")

}


if error != nil || isFinal {

// Stop recognizing speech if there is a problem.

self.audioEngine.stop()

inputNode.removeTap(onBus: 0)


self.recognitionRequest = nil

self.recognitionTask = nil


self.recordButton.isEnabled = true

self.recordButton.setTitle("Start Journaling", for: [])

}

}


// Configure the microphone input.

let recordingFormat = inputNode.outputFormat(forBus: 0)

inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in

self.recognitionRequest?.append(buffer)

}

audioEngine.prepare()

try audioEngine.start()

// Let the user know to start talking.

textView.text = "(Go ahead, I'm listening)"

}


You just need to set requiresOnDeviceRecognition to true for the behavior you're looking for. Note isFinal seems to be for server based results only so isFinal is never returned when you use on device recognition.
Code Block
// Keep speech recognition data on device
if #available(iOS 13, *) {
//recognitionRequest.requiresOnDeviceRecognition = false
recognitionRequest.requiresOnDeviceRecognition = true
}

How to get On-Device Speech Recognition to work continuously?
 
 
Q