简体   繁体   中英

Siri Kit (Speech to text) disabling my TTS (Text to speech) iOS

I'm trying to run Text To Speech (AVSpeechSynthesizer) along with Speech To Text from Siri Kit, but I'm stuck with it.

My TTS works perfectly until I run the code to execute the STT, after that my TTS doesn't work anymore. I debugged the code and during the executing of the code, no errors happen, but my text is not transforming to speech. I think somehow my STT is disabling the output microphone and that's why the TTS doesn't transform the text to speech anymore, well, that's just a theory. Ops: My TTS stops working, but my STT works perfectly

Any tips?

Here's my viewController's code:

@IBOutlet weak var microphoneButton: UIButton!

//text to speech
let speechSynthesizer = AVSpeechSynthesizer()

//speech to text
private var speechRecognizer: SFSpeechRecognizer!

private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private var audioEngine = AVAudioEngine()

@IBAction func textToSpeech(_ sender: Any) {

    if let word = wordTextField.text{

        if !speechSynthesizer.isSpeaking {


            //get current dictionary
            let dictionary = fetchSelectedDictionary()

            //get current language
            let language = languagesWithCodes[(dictionary?.language)!]

            let speechUtterance = AVSpeechUtterance(string: word)
                speechUtterance.voice = AVSpeechSynthesisVoice(language: language)
                speechUtterance.rate = 0.4
             //speechUtterance.pitchMultiplier = pitch
             //speechUtterance.volume = volume
                speechSynthesizer.speak(speechUtterance)

        }
        else{
            speechSynthesizer.continueSpeaking()
        }

    }
}

@IBAction func speechToText(_ sender: Any) {

    if audioEngine.isRunning {
        audioEngine.stop()
        recognitionRequest?.endAudio()
        microphoneButton.isEnabled = false
        microphoneButton.setTitle("Start Recording", for: .normal)
    } else {
        startRecording()
        microphoneButton.setTitle("Stop Recording", for: .normal)
    }

}

func startRecording() {

    if recognitionTask != nil {
        recognitionTask?.cancel()
        recognitionTask = nil
    }

    let audioSession = AVAudioSession.sharedInstance()
    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.")
    }

    recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

    guard let inputNode = audioEngine.inputNode else {
        fatalError("Audio engine has no input node")
    }

    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.wordTextField.text = result?.bestTranscription.formattedString
            isFinal = (result?.isFinal)!
        }

        if error != nil || isFinal {
            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)

            self.recognitionRequest = nil
            self.recognitionTask = nil

            self.microphoneButton.isEnabled = true
        }
    })

    let recordingFormat = inputNode.outputFormat(forBus: 0)
    inputNode.installTap(onBus: 0, 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.")
    }

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

}

Probably because your audiosession is in Record mode, You have 2 solutions, first would be to set your try audioSession.setCategory(AVAudioSessionCategoryRecord) to AVAudioSessionCategoryPlayAndRecord (This will work) but a cleaner way would be to get a separate function for saying something and then set your AVAudioSessionCategory to AVAudioSessionCategoryPlayback

Hope this helped.

This line:

try audioSession.setMode(AVAudioSessionModeMeasurement)

is probably the reason. It can cause the volume to be throttled so low, that it sounds like it is off. Try:

try audioSession.setMode(AVAudioSessionModeDefault)

and see if it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM