Arjun321
Arjun321

Reputation: 99

IOS/Swift/AVSpeechSynthesizer: Control Speed of Enqueued Utterances

In order to exert greater control over speech in the spirit of this tutorial for an audiobook although I'm not following it exactly, I have tried sending smaller pieces of a string such as phrases in separate chunks. The speech synthesizer enqueues each utterance and speaks them one after the other. In theory, this is supposed to give you greater control to make speech sound less robotic.

I can get the synthesizer to speak the chunks in order however there is a long delay between each so it sounds way worse than just sending all the text at the same time.

Is there anyway to speed up the queue so that the utterances are spoken one after the other with no delay?

Setting the properties: utt.preUtteranceDelay and utt.postUtteranceDelay to zero seconds does not seem to have any effect

Here is my code:

phraseCounter = 0
func readParagraph(test: String) {
              let phrases = test.components(separatedBy: " ")
            for phrase in phrases {
              phraseCounter = phraseCounter+1
                let utt = AVSpeechUtterance(string:phrase)
                let preUtteranceDelayInSecond = 0
                let postUtteranceDelayInSecond = 0
                utt.preUtteranceDelay = TimeInterval.init(exactly:preUtteranceDelayInSecond)!
                utt.postUtteranceDelay = TimeInterval.init(exactly:postUtteranceDelayInSecond)!
                 voice.delegate = self
               if (phraseCounter == 2) {
    utt.rate = .8
}
voice.speak(utt)
}        
}

Upvotes: 2

Views: 992

Answers (1)

XLE_22
XLE_22

Reputation: 5671

Is there anyway to speed up the queue so that the utterances are spoken one after the other with no delay?

As you did, the only way is to set the post and pre UtteranceDelay properties to 0 which is the default value by the way. enter image description here

As recommended here, I implemented the code snippet hereafter (Xcode 10, Swift 5.0 and iOS 12.3.1) to check the impact of different UtteranceDelay values ⟹ 0 is the best solution to improve the speed of enqueued utterances.

var synthesizer = AVSpeechSynthesizer()
var playQueue = [AVSpeechUtterance]()


override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    for i in 1...10 {

        let stringNb = "Sentence number " + String(i) + " of the speech synthesizer."

        let utterance = AVSpeechUtterance(string: stringNb)
        utterance.rate = AVSpeechUtteranceDefaultSpeechRate
        utterance.pitchMultiplier = 1.0
        utterance.volume = 1.0

        utterance.postUtteranceDelay = 0.0
        utterance.preUtteranceDelay = 0.0

        playQueue.append(utterance)
    }

    synthesizer.delegate = self

    for utterance in playQueue {
        synthesizer.speak(utterance)
    }
}

If a delay is too important with the '0' value in your code, the incoming string is maybe the problem? (adapt the code snippet above to your needs)

Upvotes: 0

Related Questions