5 Replies
      Latest reply on Jun 7, 2019 7:16 PM by Trumpeter
      Elagoon Level 1 Level 1 (0 points)

        import UIKit

        import Speech

        class ViewController: UIViewController, SFSpeechRecognizerDelegate ,AVSpeechSynthesizerDelegate {

         

          @IBOutlet weak var textView: UITextView!

         

            private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US"))!

         

            private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?

            private var recognitionTask: SFSpeechRecognitionTask?

            private let audioEngine = AVAudioEngine()

         

            private var audio : AVAudioInputNode? = nil

           var audioSession : AVAudioSession? = nil

          override func viewDidLoad() {

                super.viewDidLoad()

          

                self.getSpeech(asSpeach: "how are you ?")

          

                speechRecognizer.delegate = self

          

                SFSpeechRecognizer.requestAuthorization { (authStatus) in

              

                    var isButtonEnabled = false

              

                    switch authStatus {

                    case .authorized:

                        isButtonEnabled = true

                  

                    case .denied:

                        isButtonEnabled = false

                        print("User denied access to speech recognition")

                  

                    case .restricted:

                        isButtonEnabled = false

                        print("Speech recognition restricted on this device")

                  

                    case .notDetermined:

                        isButtonEnabled = false

                        print("Speech recognition not yet authorized")

                    }

              

                }

          }

         

            func endAudio()

            {

                if audioEngine.isRunning {

                    AudioOutputUnitStop((audioEngine.inputNode?.audioUnit)!)

                    AudioUnitUninitialize((audioEngine.inputNode?.audioUnit)!)

                    audioEngine.stop()

                }

            }

            func startRecording() {

                if recognitionTask != nil {

                    recognitionTask?.cancel()

                    recognitionTask = nil

                }

          

                AudioOutputUnitStop((audioEngine.inputNode?.audioUnit)!)

                AudioUnitUninitialize((audioEngine.inputNode?.audioUnit)!)

                audioSession = AVAudioSession.sharedInstance()

                do {

                    try audioSession?.setCategory(AVAudioSessionCategoryPlayAndRecord)

                    try audioSession?.setMode(AVAudioSessionModeMeasurement)

                    try audioSession?.setActive(true, with: .notifyOthersOnDeactivation)

                } catch {

                    print("audioSession properties weren't set because of an error.")

                }

          

                recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

          

                guard let inputNode = audioEngine.inputNode else {

                    print("Audio engine has no input node")

              

                }

                audio=inputNode

                audio?.removeTap(onBus: 2)

          

          

                guard let recognitionRequest = recognitionRequest else {

                    fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")

                }

          

                recognitionRequest.shouldReportPartialResults = true

          

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

              

                    var isFinal = false

              

                    if result != nil {

                  

                        self.textView.text = result?.bestTranscription.formattedString

                        isFinal = (result?.isFinal)!

                        if self.textView.text == "Fine" || self.textView.text == "Find"

                        {

                            self.audioEngine.stop()

                            self.textView.text = ""

                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {

                          

                                self.getSpeech(asSpeach: "how are you ?")

                            }

                        }

                    }

              

                    if error != nil || isFinal {

                  

                        self.audioEngine.stop()

                        inputNode.removeTap(onBus: 2)

                  

                        self.recognitionRequest = nil

                        self.recognitionTask = nil

                    }

                })

          

                let recordingFormat = inputNode.outputFormat(forBus: 2)

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

                    self.recognitionRequest?.append(buffer)

                }

          

                audioEngine.prepare()

          

                do {

                    try audioEngine.start()

                } catch {

                    print("audioEngine couldn't start because of an error.")

                }

          

                textView.text = "Say something, I'm listening!"

          

          

          

            }

         

            func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {

                if available {

                    //something

                } else {

                    //else thing

                }

            }

            func getSpeech(asSpeach:String)

            {

                audioSession  = AVAudioSession.sharedInstance()

                do {

                    try audioSession?.overrideOutputAudioPort(.speaker)

                } catch {

                    print(error.localizedDescription)

                }

                let synthesizer = AVSpeechSynthesizer()

                let utterance = AVSpeechUtterance(string: asSpeach)

                utterance.rate = AVSpeechUtteranceDefaultSpeechRate

                synthesizer.delegate=self

                synthesizer.speak(utterance)

          

           

          

          

            }

            public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance)

            {

                audioEngine.stop()

                do {

                try audioSession?.setActive(false)

                }

                catch {

                    print("error.localizedDescription")

                    print(error.localizedDescription)

                }

                print("speech synthesizer ended")

                if(audioEngine.isRunning)

                {

                    endAudio()

                }

          

                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

                    self.startRecording()

                }

          

            }

        }

         

         

        As requirement first dictet one string  and if the string is a keyword (as per business rule) dictet again but getting crash think the crash is for mismatching the audioformat for dictet and speech .

         

        The error message is

        ERROR:    [0x1b2a4cb40] >avae> AVAudioIONodeImpl.mm:884: SetOutputFormat: required condition is false: format.sampleRate == hwFormat.sampleRate

        Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: format.sampleRate == hwFormat.sampleRate'

         

        Think the problem is with AVAudioSession please suggest i am trying many times but dont have a luck till now