Reputation: 99
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
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.
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