Andreas Prang
Andreas Prang

Reputation: 2217

Changing the default text-to-speech voice

Tell application "System Preferences" 
    set "default voice" to "Agnes" 
end tell 

The result is:

Can’t set "default voice" to "anna". Access not allowed.

Upvotes: 1

Views: 4062

Answers (5)

Mr. Science
Mr. Science

Reputation: 39

Since this question is 12 yrs old, I have an updated answer: This AppleScript changes the default System Voice (for me) in System 10.14.6 (Mojave). This script opens "System Preferences", then Navigates to the "Accessibility" panel, selects "Speech", then switches from one voice to another. *Note: Users may be required to add Apple's "Script Editor" app to "Accessibility" in the "Security & Privacy" panel of System Preferences (mine is set that way).

--OPEN SYSTEM PREFERENCES:
tell application "System Preferences" to activate
tell application "System Events"
    
    --OPEN THE ACCESSIBILITY PANEL:
    tell application process "System Preferences"
        if name of window 1 is "System Preferences" then
            repeat until (name of window 1 is "Accessibility")
                click button "Accessibility" of scroll area 1 of window "System Preferences" of application process "System Preferences" of application "System Events"
                delay 1
            end repeat
        end if
        
        --SELECT THE SPEECH MENU:
        tell window "Accessibility"
            tell table 1 of scroll area 1
                repeat with nmbr from 1 to (count of every row) --probably row 7
                    set UIelement to first UI element of row nmbr
                    if name of UIelement is "Speech" then
                        set selected of (row nmbr of table 1 of scroll area 1 of window "Accessibility" of application process "System Preferences" of application "System Events") to true
                    end if
                end repeat
            end tell
            
            --TOGGLE VOICE:
            set SystemVoice to value of pop up button "System Voice:" of group 1 of window "Accessibility" of application process "System Preferences" of application "System Events"
            if SystemVoice is not "Alex" then
                set SystemVoice to "Alex"
            else if SystemVoice is "Alex" then
                set SystemVoice to "Victoria"
            end if
            click pop up button "System Voice:" of group 1
            delay 1
            click menu item SystemVoice of menu 1 of pop up button "System Voice:" of group 1
            delay 1
        end tell
        
        --CLOSE SYSTEM PREFERENCES:
        set CloseButton to first button of window 1 whose description is "close button"
        click CloseButton
    end tell
end tell

--CONFIRM VOICE SETTINGS:
say "System voice is set to, " & SystemVoice
return SystemVoice

Upvotes: 0

mklement0
mklement0

Reputation: 437408

There are two problems with your approach:

  • The dictionary for the System Preferences app contains no default voice element or any other for changing the TTS (text-to-speech) default voice (as of OS X 10.11); in fact, it seems that Apple provides no programmatic way of changing the default voice (not even via its NSSpeechSynthesizer Cocoa class).
  • By double-quoting default voice, you're trying to assign a value to a string literal, which will always fail.

Note: An earlier version of this answer pointed to a Bash script named voice in a Dropbox location; this script has since been renamed to voices, had its syntax revised, and is now properly published as an open-source project - see below.

Unfortunately, as of OSX 10.11 (El Capitan), there is no documented programmatic way to change the default voice.

It can be done, but doing so requires on undocumented system internals, so future compatibility is not guaranteed.

voices is a CLI I wrote that does just that - verified to work on OSX 10.11 down to OSX 10.8.

You could then do the following from AppleScript :

do shell script "/path/to/voices -d {voiceName}"

For instance, if you place voices in /usr/local/bin and want to switch to Agnes as the default voice, use:

do shell script "/usr/local/bin/voices -d Agnes"

If you happen to have Node.js installed, you can install voices to /usr/local/bin with

npm install voices -g

Otherwise, follow the instructions here.

Upvotes: 6

eplt
eplt

Reputation: 106

To get it working with Yosemite, you will need to add the following 2 lines to the bottom of the script provided by mklement0 above:

Original Link to the file from mklement0: https://dl.dropboxusercontent.com/u/10047483/voice

Add the two lines below to restart SpeechSynthesisServer, otherwise you can't use the shortcut key to immediately access the new default voice:

killall SpeechSynthesisServer
open /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesisServer.app

Upvotes: 1

Lri
Lri

Reputation: 27613

Changes to ~/Library/Preferences/com.apple.speech.voice.prefs.plist seem to be applied immediately.

d=com.apple.speech.voice.prefs
if [[ $(defaults read $d SelectedVoiceName) = Kathy ]]; then
  defaults write $d SelectedVoiceCreator -int 1835364215
  defaults write $d SelectedVoiceID -int 201
  defaults write $d SelectedVoiceName Alex  
else
  defaults write $d SelectedVoiceCreator -int 1836346163
  defaults write $d SelectedVoiceID -int 2
  defaults write $d SelectedVoiceName Kathy
fi

Another option using UI scripting:

tell application "System Preferences"
    reveal anchor "TTS" of pane "com.apple.preference.speech"
end tell
tell application "System Events" to tell process "System Preferences"
    tell pop up button 1 of tab group 1 of window 1
        delay 0.1
        click
        if value is "Alex" then
            click menu item "Kathy" of menu 1
        else
            click menu item "Alex" of menu 1
        end if
    end tell
end tell
quit application "System Preferences"

Without the delay the value was Loading Voices… if System Preferences wasn't open before.

Upvotes: 3

Andreas Prang
Andreas Prang

Reputation: 2217

This is working:

property currentVoice : "Vicki"

set systemVoices to {"Agnes", "Albert", "Alex", "BadNews", "Bahh", "Bells", "Boing", "Bruce", ¬
 "Bubbles", "Cellos", "Deranged", "Fred", "GoodNews", "Hysterical", "Junior", "Kathy", ¬
 "Organ", "Princess", "Ralph", "Trinoids", "Vicki", "Victoria", "Whisper", "Zarvox"}

    repeat

     activate me

     set theResult to display dialog "Say What?" default answer ¬

      "" buttons {"Quit", "Speak", "Change Voice"} ¬

      default button "Speak" cancel button "Quit"


if button returned of theResult is "Quit" then exit repeat

 else if button returned of theResult is "Change Voice" then

  set currentVoice to item 1 of ¬

(choose from list systemVoices with prompt "Choose new voice.")

 end if

 if text returned of theResult is not "" then

  say text returned of theResult using currentVoice volume 1

 end if

end repeat

Upvotes: 0

Related Questions