AVSpeechSynthesisVoice.speechVoices() problem

I've used AVSpeechSynthesisVoice.speechVoices() to acquire the list of voices available on a device. I've then extracted the voices available in my target language by collecting only those whose language matches AVSpeechSynthesisVoice.currentLanguageCode(). My code showed Fred, Samantha, Victoria, and Alex. All voices worked right in my app's voice example except Alex, which was replaced by Samantha. At this point on the device, Settings -> Accessibility -> Spoken Content -> Voices -> English showed Fred, Samantha, and Victoria as available. I have since downloaded Alex. Everything works the same except the Alex voice is now used successfully. So...

Why was Alex being reported as available when it was not, and how can I detect that in my code so I don't indicate to a user that a voice is available when it is not?

Device is iPhone 12 running iOS 15.4.1; development system is MacBook Pro running MacOS 12.3.1 and Xcode 13.3.1.

  • UPDATE: I deleted Alex from the iPhone and re-ran the subject routine. Alex no longer showed up in the AVSpeechSynthesisVoice.speechVoices() result. Nothing like inconsistent results to make you confident in system behavior. Anyway, if others try this and fail to replicate my earlier results, I guess that's to be expected because I can't repeat it myself.

    As an FYI, the iPhone 12 simulator settings show an odd setting in Spoken Content for Alex. Alex has no ">" mark and no "download from the cloud" link. Alex does show up as an available voice but fails to speak. Samantha speaks for Alex. This brings me back to the original question, which I guess can be rephrased as, "Can AVSpeechSynthesisVoice.speechVoices() be made to work reliably on all devices and the simulator?" Or can some indication be made if the system substitutes another voice? For instance, the voice substitution for unavailable voices occurs when the synthesizer is called to speak. If the voice for the utterance could be updated to reflect the voice actually used, the discrepancy between the initially set voice and the effective voice could be discovered and the initially set voice could be deleted from the list of available voices. The only requirement would be that the expected-to-be-available voices be run through a "silent" synthesizer.speak() to verify their actual availability; again, if the expected voice and the actual voice differed, the developer could remove the expected voice from the available voice list.

    Just a thought.

    If anyone has any similar experiences, I'd be glad to hear about them.

Add a Comment