NSSpeechSynthesizer get Siri voices on macOS

Viewed 985

Is there a way to get the Siri voices for NSSpeechSynthesizer? NSSpeechSynthesizer.availableVoices() does not list them, but maybe there is an undocumented trick or something?

I've also tried to use AVSpeech​Synthesizer, even tough it should be available on macOS 10.14+, I couldn't get it to read out loud …

I've used a Playground to test this with the following code from NSHipster:

import Cocoa
import AVFoundation

let string = "Hello, World!"
let utterance = AVSpeechUtterance(string: string)

let synthesizer = AVSpeechSynthesizer()
synthesizer.speak(utterance)
1 Answers

Siri voice

I'm not aware of any trick to make the Siri voice available and I'm afraid it's impossible to make it working via public API.

  • Both NSSpeechSynthesizer and AVSpeechSynthesizer do utilize SpeechSynthesis.framework (included in the ApplicationServices.framework).
  • Quickly checked it and the function BuildDefaultVoiceList(bool) checks bundle identifier (via PermitAllVoices which compares it with com.apple.VoiceOverUtility, com.apple.VoiceOver, com.apple.VoiceOverUtilityCacheBuilder).
  • There're other checks probably.

All the voices are stored in the /System/Library/Speech/Voices folder. Tried to copy the voice, change Info.plist values to make it look like another voice, but still not available/working.

How far do you want to go? Do you want to disable SIP, modify framework, preload your stuff, ... Is it worth it?

AVSpeech​Synthesizer on macOS

It works, but it's buggy and you have to kill the service from time to time.

List of available voices

AVSpeechSynthesisVoice.speechVoices().forEach { voice in
    print("Name: \(voice.name) Language: \(voice.language) Identifier: \(voice.identifier)")
}

Speak

let utterance = AVSpeechUtterance(string: "Ahoj, jak se máš?")
utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.speech.synthesis.voice.zuzana.premium")

let synthesizer = AVSpeechSynthesizer()
synthesizer.speak(utterance)

Doesn't speak?

All the following methods (delegate) are called when you call speak(utterance) and it works as it should:

Something's wrong if you get just the speechSynthesizer(_:didCancel:) method call and you have to kill the speechsynthesisd process:

kill `pgrep speechsynthesisd`

Then try again, it fixes the issue for me.

Additional voices installation

  • System Preferences - Accessibility - Speech
  • System Voice - click & scroll down & select Customize...
  • Select additional voice to install
Related