How to get the names of all installed system voices

As you already know, you can quickly transform your expensive Mac into a cheap language gifted parrot by executing AppleScript code like follows:


say "Hello, my name is Polly, I am a lonely and language gifted parrot with a sexy voice, living inside your fine Mac." using "Vicki"

You are not limited to the voice named Vicki used in the example above, as your Mac offers several other cool voices, which are installed here:

/System/Library/Speech/Voices/

Now how can we get a list containing the names of all available system voices?

Unfortunately AppleScript itself does not offer a command for this. And scanning the system’s Voices folder for the SpeechVoice bundles and then extracting their folder names (e.g. GoodNews) is also not sufficient. That’s because some voice names are delimited by a space and don’t correspond to the folder name used for their SpeechVoice bundle (e.g. voice name: ‘Good News’, bundle name: ‘GoodNews.SpeechVoice’).

But don’t give up! The rescue is near! Apple offers a Cocoa class named NSSpeechSynthesizer that allows to get a list of available voices and obtain details about their attributes. We can’t utilize this handy Cocoa class directly with AppleScript, but can easily ask a Python helper script to do it for us (using the «do shell script» command).

This solution requires Mac OS X 10.5 Leopard or a Mac OS X system where PyObjC is installed.

For your convenience I have put together a small sample script, which you can download right here to run and inspect it on your fine Mac:

System Voice Test ¢ A sample script showing how to get a list of installed system voice names (ca. 33.6 KB)

Important: Opening and saving the below script code in Script Editor won’t result in a usable AppleScript! That is because the AppleScript internally relies on a little Python helper script, which is located inside its Application bundle. Therefor please download the complete script here.


-- author: Martin Michel
-- created: 19.05.2008
-- requires:
-- ¢ Mac OS X 10.5 Leopard or
-- ¢ a Mac OS X system with PyObjC installed:
-- <http://pyobjc.sourceforge.net/>

-- This AppleScript lets you choose a system voice name from a list
-- containing all installed system voices and then says a short sentence
-- using the choses system voice name.

-- This AppleScript shows how to retrieve all system voice names using a
-- Python script that utilizes the NSSpeechSynthesizer.

property mytitle : "System Voice Test"

-- I am the main routine invoked when the user double clicks the script's icon
on run
	try
		-- get the chosen system voice name
		set sysvoicename to my choosesysvoicename()
		-- user canceled...
		if sysvoicename is missing value then
			return
		end if
		-- say the message using the chosen system voice name
		set msg to ("Hello, my name is " & sysvoicename & ".")
		say msg using sysvoicename
		-- catching unexpected erros
	on error errmsg number errnum
		my dsperrmsg(errmsg, errnum)
	end try
end run

-- I am displaying a list containing all system voice names to choose from
-- >>> I return the choses system voice name or «missing value» in case the user
-- >>> cancels the dialog
on choosesysvoicename()
	set sysvoicenames to my getsysvoicenames()
	choose from list sysvoicenames with prompt "Please choose a voice:" without multiple selections allowed and empty selection allowed
	set choice to result
	if choice is not false then
		set sysvoicename to (item 1 of choice) as Unicode text
		return sysvoicename
	else
		return missing value
	end if
end choosesysvoicename

-- I am returning a list containing the names of the system voices currently
-- installed on the Mac OS X system
-- >>> I am using a Python script named «sysvoices.py» to accomplish my task
on getsysvoicenames()
	set pyscriptpath to POSIX path of (((path to me) as Unicode text) & "Contents:Resources:sysvoices.py")
	set command to "/usr/bin/python " & quoted form of pyscriptpath
	set command to command as «class utf8»
	set sysvoicenames to paragraphs of (do shell script command)
	return sysvoicenames
end getsysvoicenames

-- I am displaying error messages to the user
on dsperrmsg(errmsg, errnum)
	tell me
		activate
		display dialog "Sorry, an error occured:" & return & return & errmsg & " (" & errnum & ")" buttons {"OK"} default button 1 with icon stop with title mytitle giving up after 60
	end tell
end dsperrmsg