Newbie here. Need help with this applescript/Using Text to Audio

Hey guys, I am trying to put a simple script together using mac voices to record text.

Below is my script which is of course not done, and I need help with it.

I want it to cycle through ALL the voices of the MAC and then when the user picks the one that is right, then he can save the audio file.

How do I do this?


set anSwer to the text returned of (display dialog "What text do you want to record?" default answer "") as text
set fileName to "audio.aiff"
set video_path to ((path to desktop as text) & fileName)

tell application "System Events"
	try
		say "Using Fred's voice...,  " & anSwer using "Fred"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			say anSwer using "Fred" saving to video_path
		else
			-- I want it to loop to the next voice and keep looping until the user finds the right voice to save.
			
		end if
	on error
		display dialog "Didn't Work"
	end try
end tell


That’s a good question. How would you find a list of all the voices? :smiley:

I found one answer:

ls /System/Library/Speech/Voices | sed ‘s/.SpeechVoice$//’

here:

http://stackoverflow.com/questions/1489800/getting-list-of-mac-text-to-speech-voices-programmatically

Here’s a bit for script editor:


set cmd to "ls /System/Library/Speech/Voices | sed 's/.SpeechVoice$//'"
do shell script cmd

gl,

Hey keli,

Thanks. But, maybe I wasn’t totally clear in the problem I was having. I have all the voices already, I was trying to have my script loop through each one.

However I figured it out on my own (below). Now I wish the script could be cleaned up more as it seems a little long and I am sure that there is a way to shorten it down.

Anyway, thanks for your concern.

Here is the script:


set anSwer to the text returned of (display dialog "What text do you want to record?" default answer "") as text
tell application "System Events"
	
        display dialog "First each of the men's voice. You can save more than one voice if you want."
	
	try
		say "Using Fred's voice...,  " & anSwer using "Fred"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Fred.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Fred" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Bruce's voice...,  " & anSwer using "Bruce"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Bruce.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Bruce" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Alex's voice...,  " & anSwer using "Alex"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Alex.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Alex" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Albert's voice...,  " & anSwer using "Albert"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Albert.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Albert" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Ralph's voice...,  " & anSwer using "Ralph"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Ralph.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Ralph" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Junior's voice...,  " & anSwer using "Junior"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Junior.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Junior" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	
	display dialog "Now each of the women's voices. You can save more than one voice if you want."
	try
		say "Using Vicky's voice...,  " & anSwer using "Vicky"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Vicky.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Vicky" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Agnes voice...,  " & anSwer using "Agnes"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Agnes.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Agnes" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Kathy's voice...,  " & anSwer using "Kathy"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Kathy.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Kathy" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Princess voice...,  " & anSwer using "Princess"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Princess.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Princess" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	try
		say "Using Victoria's voice...,  " & anSwer using "Victoria"
		display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
		if the button returned of the result is "Yes" then
			set fileName to "Victoria.aiff"
			set video_path to ((path to desktop as text) & fileName)
			say anSwer using "Victoria" saving to video_path
		else
			display dialog "Not good? Ok, moving onto the next voice."
		end if
	on error
		display dialog "Didn't Work"
	end try
	display dialog "You are done! That's all the voices on MAC"
	
end tell



Sorry, I was thinking about the user selecting a voice like this:


set cmd to "ls /System/Library/Speech/Voices | sed 's/.SpeechVoice$//'"
set the_voices to (do shell script cmd)
set voice_list to paragraphs of the_voices
set user_voice to item 1 of (choose from list voice_list)
say "hello, I'm " & (user_voice as string) using user_voice

I don’t know why yet, but some voices don’t work getting the list like this. Here the button names would need to be changed (like to “try” and “select”). It depends what you’re trying to do. Just my own thoughts.

gl,

It’s fine.

That’s pretty cool though. If there is a way that I can use that instead of what I have then that would smoke.

Let me try figuring it out.

Thanks.

Phil

Kel1,

Hey I am almost there!

Instead of pulling up the full list of voices (as your cmd does), is there a way to just pull up a list of the following voices:

Fred
Bruce
Alex
Albert
Ralph
Vicky
Agnes
Kathy
Victoria

There must be a way to adjust your cmd to do that right?

Thanks.

Phil

Yeah, but I can’t get the error handler right. Here’s what I got so far:


global new_voice
set voices_folder to (path to "fvoc")
tell application "System Events"
	set temp_list to name of every folder of voices_folder whose name does not contain "compact"
end tell
set the_ext to ".SpeechVoice"
set voice_list to StripExt(temp_list, the_ext)
set is_done to false
set default_items to {}
set new_voice to "Victoria"
repeat until is_done is true
	try
		set user_choice to (choose from list voice_list with title "Voices" with prompt "Choose a voice:" default items default_items OK button name "Try" cancel button name "Select")
		set default_items to {user_choice}
		copy user_choice to new_voice
		say "Hello, I'm " & (user_choice as string) using user_choice
	on error -- user pressed "Select" cancel button
		say "Hello, I'm " & (new_voice as string) using new_voice
		set is_done to true
	end try
end repeat

on StripExt(the_list, the_ext)
	set the_list to the_list as string
	set tids to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the_ext
	set the_list to text items of the_list
	set AppleScript's text item delimiters to tids
	return the_list
end StripExt

I think they changed something.

Editted: I think when the user cancels, the variables become null. I just used the global variable to see if that would work. Maybe I need to sleep on it if I can. :slight_smile:

Editted: I would also like the default button to be the select button. But, I switched it around just to try and make it work.

Thanks. There was actually an easier way to do this. Took me a while to figure it out.

Here is the complete script.


set anSwer to the text returned of (display dialog "What text do you want to record?" default answer "") as text
set the_names to {"Fred", "Bruce", "Alex", "Albert", "Ralph", "Junior", "Vicky", "Agnes", "Kathy", "Princess", "Victoria"}

repeat with this_name in the_names
	tell application "System Events"
		try
			say "Using " & this_name & "'s voice...,  " & anSwer using this_name
			display dialog "Do you want to save this as an Audio File?" buttons {"Yes", "No"} default button 1
			if the button returned of the result is "Yes" then
				set fileName to this_name & ".aiff"
				set video_path to ((path to desktop as text) & fileName)
				say anSwer using this_name saving to video_path
			else
				display dialog "Not good? Ok, moving onto the next voice."
			end if
		on error
			display dialog "Didn't Work"
		end try
	end tell
end repeat
display dialog "You are done!"


But thanks anyway for your help.

Hi pjdube,

What I was thinking is that the user might not want to go through all the voices. But, if you got what you wanted it’s great. I’m still wondering why the variables seem to not hold their values when the user clicks the cancel button. I have to check this out when I get up.

gl,

Ok great. Yes this may help me. When you do figure it out, let me know!

Thanks man!

I will. :smiley:

Have a good one.

This is the best workaround I can do for now:


set voices_folder to (path to "fvoc")
tell application "System Events"
	set temp_list to name of every folder of voices_folder whose name does not contain "compact"
end tell
set the_ext to ".SpeechVoice"
set voice_list to StripExt(temp_list, the_ext)
set is_done to false
set default_items to {}
repeat until is_done is true
	try
		set user_choice to (choose from list voice_list with title "Voices" with prompt "Choose a voice:" default items default_items OK button name "Try")
		set default_items to {user_choice}
		say "Hello, I'm " & (user_choice as string) using user_choice
		try
			display dialog "Select this voice?"
			set is_done to true
		end try
	end try
end repeat
return user_choice

on StripExt(the_list, the_ext)
	set the_list to the_list as string
	set tids to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the_ext
	set the_list to text items of the_list
	set AppleScript's text item delimiters to tids
	return reverse of rest of reverse of the_list
end StripExt

gl,

I think I’ve found why a few voices don’t work. You need the virtual name. I think, you need to look through the names and find the actual characters. Hmmm… Maybe switching to the Finder might work. Might be something with the text of the folders names.

You know what it was, all the voices with two words were stripped of spaces in their screen names. Here’s a fix quick fix on my computer:


set voices_folder to (path to "fvoc")
tell application "System Events"
	set temp_list to name of every folder of voices_folder whose name does not contain "compact"
end tell
set the_ext to ".SpeechVoice"
set voice_list to StripExt(temp_list, the_ext)
set item 4 of voice_list to "Bad News"
set item 13 of voice_list to "Good News"
set item 17 of voice_list to "Pipe Organ"
set is_done to false
set default_items to {}
repeat until is_done is true
	try
		set user_choice to (choose from list voice_list with title "Voices" with prompt "Choose a voice:" default items default_items OK button name "Try")
		set default_items to {user_choice}
		say "Hello, I'm " & (user_choice as string) using user_choice
		try
			display dialog "Select this voice?"
			set is_done to true
		end try
	end try
end repeat
return user_choice

on StripExt(the_list, the_ext)
	set the_list to the_list as string
	set tids to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the_ext
	set the_list to text items of the_list
	set AppleScript's text item delimiters to tids
	return reverse of rest of reverse of the_list
end StripExt

Now we just need to add spaces in voices with two words in their names.

gl,

Editted: excepting “Pipe Organ”. The name of the folder on my computer is "Organ."etc. I don’t see “Pipe” anywhere?? Maybe the system has a preset list or aliases somewhere? I might have to search the system for “Pipe Organ”.

Editted: I think I know why “Pipe Organ”. Because there are many types of "Organ"s. So, they left that open.

Rewrote script to fix some voices as workaround:


set voices_folder to (path to "fvoc")
tell application "System Events"
	set temp_list to name of every folder of voices_folder whose name does not contain "compact"
end tell
set the_ext to ".SpeechVoice"
set voice_list to StripExt(temp_list, the_ext)
-- fix some voice names
set c to count voice_list
repeat with n from 1 to c
	if item n of voice_list is "BadNews" then
		set item n of voice_list to "Bad News"
	else if item n of voice_list is "GoodNews" then
		set item n of voice_list to "Good News"
	else if item n of voice_list is "Organ" then
		set item n of voice_list to "Pipe Organ"
	end if
end repeat
--
set is_done to false
set default_items to {}
repeat until is_done is true
	try
		set user_choice to (choose from list voice_list with title "Voices" with prompt "Choose a voice:" default items default_items OK button name "Try")
		set default_items to {user_choice}
		say "Hello, I'm " & (user_choice as string) using user_choice
		try
			display dialog "Select this voice?"
			set is_done to true
		end try
	end try
end repeat
return user_choice

on StripExt(the_list, the_ext)
	set the_list to the_list as string
	set tids to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the_ext
	set the_list to text items of the_list
	set AppleScript's text item delimiters to tids
	return reverse of rest of reverse of the_list
end StripExt

Hope it works.

gl,

Hi pjdube,

It’s amazing what a good sleep will do!

Here’s the new-old script:


set voices_folder to (path to "fvoc")
set the_ext to ".SpeechVoice"
tell application "System Events"
	set temp_list to name of every folder of voices_folder whose name ends with the_ext and name does not contain "compact"
end tell
set voice_list to StripExt(temp_list, the_ext)
-- fix some voice names
set c to count voice_list
repeat with n from 1 to c
	if item n of voice_list is "BadNews" then
		set item n of voice_list to "Bad News"
	else if item n of voice_list is "GoodNews" then
		set item n of voice_list to "Good News"
	else if item n of voice_list is "Organ" then
		set item n of voice_list to "Pipe Organ"
	end if
end repeat
--
set user_choice to {item 1 of voice_list}
repeat
	say "Hello, I'm " & (user_choice as string) using user_choice without waiting until completion
	choose from list voice_list with title "Choose Voices" with prompt ("Current voice: " & user_choice) default items user_choice OK button name "Change" cancel button name "Exit"
	set r to result
	if r is false then
		exit repeat
	else
		set user_choice to r
	end if
end repeat
say "Goodbye." using user_choice
return user_choice

on StripExt(the_list, the_ext)
	set the_list to the_list as string
	set tids to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the_ext
	set the_list to text items of the_list
	set AppleScript's text item delimiters to tids
	return reverse of rest of reverse of the_list
end StripExt

Still have to test it more and make some tweeks, but it looks ok.

Editted: tweaked the script. This should be ok.

gl,

Great. Tested it and it works.

Thanks a lot man.