swiftavspeechsynthesizeravspeechutterance

AVSpeechUtterance: how to fetch a random array and use a specific voice?


While working at using Swift to spew forth quotations, I'm running into issues with the repetition of the same command.

Here's what I have right now

import AVFoundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let QuoteArray = [
"Quote1",
"Quote2",
"Quote3",
]

let max = QuoteArray.count

let synthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: QuoteArray[Int.random(in: 0 ... max)])
utterance.rate = 0.5
utterance.voice = AVSpeechSynthesisVoice(language: "en-AU")
synthesizer.speak(AVSpeechUtterance(string: QuoteArray[Int.random(in: 0 ... max)]))
sleep(5)
synthesizer.speak(AVSpeechUtterance(string: QuoteArray[Int.random(in: 0 ... max)]))
sleep(10)
synthesizer.speak(AVSpeechUtterance(string: QuoteArray[Int.random(in: 0 ... max)]))

I'm not sure how to both pick a random array position, and to fool around with the synthesisvoice and speed. I'm trying to make it so that 3 random quotes are read randomly, yet I can't seem to get it to work properly.

If I modify the last few lines so instead of AVSpeechUtterance(string...they say utterance, I cannot run a 2nd or 3rd quote because of a SIGBART error.

Any ideas?

utterance.rate = 35
utterance.pitchMultiplier = 3
utterance.voice = AVSpeechSynthesisVoice(language: "en-AU")
synth.speak(utterance)
sleep(5)
synth.speak(utterance)
sleep(10)
synth.speak(utterance)
sleep(15)

if i try to bring it back to these utterances, i get a

error: Execution was interrupted, reason: signal SIGABRT.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation."

enter image description here


Solution

  • I'm not sure how to both pick a random array position...

    Hereunder a solution for your problem (swift 5.0, iOS 12) tested in a playground blank project:

        import AVFoundation
        import UIKit
    
        let synthesizer = AVSpeechSynthesizer()
        let QuoteArray = ["Quote1",
                          "Quote2",
                          "Quote3"]
    
        func newRandomUtterance() -> AVSpeechUtterance {
    
            let utterance = AVSpeechUtterance(string: QuoteArray[Int.random(in: 0..<QuoteArray.count)])
            utterance.rate = AVSpeechUtteranceDefaultSpeechRate
            utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
    
            return utterance
         }
    
        for _ in 1...3 { synthesizer.speak(newRandomUtterance()) }
    

    ... and to fool around with the synthesisvoice and speed.

    There are a detailed summary of the WWDC 2018 video dealing with the speech synthesizer and a full explanation with code snippets (ObjC and Swift) that can help if the example above isn't enough.

    You will now be able to fetch a random array and use a specific voice.