OK. After some experimenting I have a solution. This works consistently on both the simulator and my iOS 17 iPhone.
Manually downloaded voices simply work.
Settings > Accessibility > Live Speech (English US) on both the sim and my iphone. I downloaded Alex, Ava (Premium), Evan(Enhanced)
Then used this block to obtain the exact identifier for the voice:
let englishVoices = AVSpeechSynthesisVoice.speechVoices().filter { $0.language.starts(with: "en") }
for voice in englishVoices {
let quality = voice.quality == .enhanced ? "Enhanced" : "Default"
print("\(voice.identifier): \(quality)")
}
TTS as usual:
func speak(text: String) {
let utterance = AVSpeechUtterance(string: text)
if let voice = AVSpeechSynthesisVoice(identifier: "com.apple.voice.enhanced.en-US.Evan") {
utterance.voice = voice
}
// Other configs
utterance.rate = AVSpeechUtteranceDefaultSpeechRate
utterance.pitchMultiplier = 1.0
utterance.volume = 1.0
speechSynthesizer.speak(utterance)
}
It works for Alex, Evan, and Ava which are all that I've tested so far. I'm planning on popping up an alert in my app for the user to download one of these (or another once I test) if they initiate TTS and don't already have one of these voices available. No, it's not ideal to do that but it's a functional workaround in the meantime. Otherwise I can fall back on one of the very terrible old voices (Trinoids, anyone?) that are working by default as listed in my reply above.
Also, I was incorrect about Fred and similar voices that have data in their .audioFileSettings dictionary not working on my device. I was, in fact, failing to release the audio context after speech recognition. My app uses both STT and TTS, although STT doesn't work reliably in the sim (this is a known issue) so I wasn't initiating it there. On my test iPhone, failing to return the AVAudioSession to category .ambient or .playback after SST caused the issue. Fred, Tessa, Kathy, Ralph, Zarvox etc. all work on both the simulator and my test iPhone now. Of course a) no one want's to use those voices; and b) The rest definitely don't work.
I tried setting values in the .audioFileSettings dictionary for other voices like Sara, Ellen etc. thinking that I might have some success. But of course, that property is read-only.
I think at this point I'm comfortable concluding that the issue is those empty .audioFileSettings dictionaries that are properties of each voice in the bundled iOS 17 SDK. Specifically, it is this class: https://developer.apple.com/documentation/avfaudio/avspeechsynthesisvoice that's the problem
New, user downloaded voices will have the necessary data in their audioFileSettings dictionaries, as do very old (and somewhat useless Apple voices bundled in the SDK)
This should be an easy, quick fix for an AV Framework engineer at Apple.
Post
Replies
Boosts
Views
Activity
Other devs / other posts report that voices that don't work seem to also have their .audioFileSettings property like this [ : ] ... empty!
I ran
func testVoices() {
let voiceList = AVSpeechSynthesisVoice.speechVoices()
for voice in voiceList {
print(voice.name + ": \(voice.audioFileSettings)")
}
}
Output shows a handful of voices (including Fred) have data in their .audioFileSettings property ( and unfortunately most have [ : ] )
Voices that have settings seem to work in the simulator - although it's spotty on an actual iOS 17 device. Fred, for example, works only 1/30 of the time when tested on my iPhone but is fine in the simulator.
~~ My Voice Settings Output~~
Majed: [:]
Daria: [:]
Montse: [:]
Zuzana: [:]
Sara: [:]
Anna: [:]
Melina: [:]
Karen: [:]
Daniel: [:]
Moira: [:]
Rishi: [:]
Trinoids: ["AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVSampleRateKey": 22050, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsFloatKey": 1, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1]
Albert: ["AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 22050, "AVLinearPCMIsBigEndianKey": 0, "AVFormatIDKey": 1819304813, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1]
ester: ["AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVNumberOfChannelsKey": 1, "AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVSampleRateKey": 22050, "AVLinearPCMBitDepthKey": 32]
Samantha: [:]
Whisper: ["AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVNumberOfChannelsKey": 1, "AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVSampleRateKey": 22050, "AVLinearPCMBitDepthKey": 32]
Superstar: ["AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsFloatKey": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsBigEndianKey": 0]
Bells: ["AVLinearPCMBitDepthKey": 32, "AVNumberOfChannelsKey": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsFloatKey": 1]
Organ: ["AVLinearPCMBitDepthKey": 32, "AVNumberOfChannelsKey": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsFloatKey": 1]
Bad News: ["AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVNumberOfChannelsKey": 1, "AVFormatIDKey": 1819304813, "AVLinearPCMIsBigEndianKey": 0, "AVSampleRateKey": 22050, "AVLinearPCMBitDepthKey": 32]
Bubbles: ["AVFormatIDKey": 1819304813, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 22050, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsBigEndianKey": 0, "AVNumberOfChannelsKey": 1]
Junior: ["AVLinearPCMBitDepthKey": 32, "AVFormatIDKey": 1819304813, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050]
Bahh: ["AVLinearPCMBitDepthKey": 32, "AVFormatIDKey": 1819304813, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050]
Wobble: ["AVLinearPCMBitDepthKey": 32, "AVFormatIDKey": 1819304813, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050]
Boing: ["AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 22050, "AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMIsFloatKey": 1, "AVFormatIDKey": 1819304813]
Good News: ["AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsFloatKey": 1, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813]
Zarvox: ["AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsFloatKey": 1, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813]
Ralph: ["AVLinearPCMIsBigEndianKey": 0, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsFloatKey": 1, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813]
Cellos: ["AVLinearPCMIsBigEndianKey": 0, "AVFormatIDKey": 1819304813, "AVLinearPCMIsNonInterleaved": 1, "AVSampleRateKey": 22050, "AVNumberOfChannelsKey": 1, "AVLinearPCMIsFloatKey": 1, "AVLinearPCMBitDepthKey": 32]
Kathy: ["AVNumberOfChannelsKey": 1, "AVLinearPCMIsFloatKey": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsBigEndianKey": 0]
Fred: ["AVNumberOfChannelsKey": 1, "AVLinearPCMIsFloatKey": 1, "AVSampleRateKey": 22050, "AVFormatIDKey": 1819304813, "AVLinearPCMBitDepthKey": 32, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsBigEndianKey": 0]
Tessa: [:]
Mónica: [:]
Paulina: [:]
Satu: [:]
Amélie: [:]
Thomas: [:]
Carmit: [:]
Lekha: [:]
Lana: [:]
Tünde: [:]
Damayanti: [:]
Alice: [:]
Kyoko: [:]
Yuna: [:]
Amira: [:]
Nora: [:]
Ellen: [:]
Xander: [:]
Zosia: [:]
Luciana: [:]
Joana: [:]
Ioana: [:]
Milena: [:]
Laura: [:]
Alva: [:]
Kanya: [:]
Yelda: [:]
Lesya: [:]
Linh: [:]
Tingting: [:]
Sinji: [:]
Meijia: [:]
What version of xCode are you using? Did you literally try to add the key to the info.plist file? Because if you are using xCode 15, the preferred way to add the key is to enter it in the Info tab for the Target
Select the Project in the leftmost xCode pane > select the target > select the Info tab ... add it under Custom iOS Target properties using the + sign.
This, I believe is new philosophy from Apple. You may never even see the info.plist file. Since xCode 15 (4 weeks ago for me) my info.plist remains empty even when I have added custom target properties via the info tab. And things work – in particular, Speech Recognition is working. But it's working on actual iPhone and iPad devices. It is buggy in the simulator (this is documented). So don't let errors reported by the simulator inform you too much here.
And to be clear, this is not just a simulator issue?
" ... nothing at all happened ... " on real device means no problems on the device (so it works)? Or no sound on the device (it's broken there too)?