Snow Leopard Broke my speech recognition.

Hi guys, my first post so please be nice.
OK, so I’ve been working on a simple applescript alarm clock having been inspired by a chap called aravinth here: http://forums.macrumors.com/archive/index.php/t-537002.html.

The idea is that it will talk to the user, read the weather forecast from a website, and any events from an xml file, then ask the user if they want to play some music/snooze the alarm/switch it off etc.

Now, I had a fully working applescript that I was quite pleased with, until I upgraded to snow leopard. Now the “listen for” command seems to work only the first time it is called, I don’t know if this is the fault of my script (likely) or of a bug in the speech recognition server…

Anyhow my script is here:


--VOLUME
--Set volume to 80%
set volume output volume 80

--TIME
--Get the current time
on thetime()
	
	-- hours
	set timeStr to time string of (current date)
	set Pos to offset of ":" in timeStr
	set theHour to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	
	-- minutes
	set Pos to offset of ":" in timeStr
	set theMin to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	
	
	return (theHour & ":" & theMin & "") as string
end thetime
--Done
-- This repeat loop allows the snooze function
repeat
	--WEATHER
	set TID to AppleScript's text item delimiters
	try
		--This webaddress points to a town near Durham, if you want to change the location, visit the site yourself, find your local town, and paste the relevant url into the script. Ensure that the url is entered after the cURL command.
		set webaddress to do shell script "curl [url=http://i.wund.com/global/stations/03242.html#conditions]http://i.wund.com/global/stations/03242.html#conditions"[/url]
		
		--Let's find the current temperature
		set AppleScript's text item delimiters to "<span class=\"nowrap\"><b>"
		set text1 to text item 3 of webaddress
		set AppleScript's text item delimiters to "</b>"
		set temp to text item 1 of text1
		set temp to round (temp)
		
		--And the outlook for the day
		set AppleScript's text item delimiters to "<div>"
		set text2 to text item 3 of webaddress
		set AppleScript's text item delimiters to "</div>"
		set outlook to text item 1 of text2
		set AppleScript's text item delimiters to TID
		--The temperature is now stored as "temp" and the outlook as "outlook" insha'allah. If not:
	on error
		set outlook to "unknown"
		set temp to "unknown"
	end try
	
	--TIMETABLE
	set d to (date string of (current date))
	set XMLfile to (path to desktop as text) & "Timetable.xml"
	tell application "System Events"
		tell XML element 1 of contents of XML file XMLfile
			set ents to (value of (XML elements whose name is word 1 of d)) as string
		end tell
	end tell
	
	
	--SPEAK
	--This tells the alarm what to say...
	--Good morning, the time is...
	set d to (date string of (current date))
	say "Good morning Richard, it is time to wake up."
	delay 1
	say "Its" & word 1 of d
	say "and its "
	say thetime()
	delay 1
	--Today's weather is/will be
	say "The outlook for the weather in Durham today is. " & outlook
	delay 1
	say "The current temperature is. " & temp
	if temp is not equal to "unknown" then
		say "degrees centigrade"
	end if
	delay 1
	
	--Timetable issues
	say ents
	delay 1
	
	--iTunes
	--Would you like some music?
	tell application "SpeechRecognitionServer"
		try
			set theResponse to listen for {"yes", "no", "quit"} with prompt "Would you like some music?" giving up after 20
		on error
			say "Sorry, I didn't hear that"
			set theResponse to "yes"
		end try
	end tell
	if theResponse is "yes" then
		delay 1
		say "Starting iTunes"
		delay 1
		tell application "iTunes"
			tell user playlist "Alarm"
				set shuffle to true
			end tell
			play user playlist "Alarm"
		end tell
		exit repeat
	else if theResponse is "quit" then
		exit repeat
	else if theResponse is "no" then
		delay 1
		tell application "SpeechRecognitionServer"
			try
				set theResponse to listen for {"snooze", "quit"} with prompt "Ok. Would you like to [[emph +]] snooze or [[emph +]] quit." giving up after 20
			on error
				say "Sorry, I didn't hear that"
				set theResponse to "snooze"
			end try
		end tell
		if theResponse is "snooze" then
			delay 1
			say "Snoozing for ten minutes. "
			delay 10 * 60
		else
			exit repeat
		end if
	end if
end repeat
delay 1
say "Quitting Alarm"

I realise it’s a bit rough around the edges but I’m new…

Anyway, has anyone else encountered a similar problem? Or is it just me? A (possibly) useful test might be:


try
	tell application "SpeechRecognitionServer"
		set response1 to listen for {"yes"} with prompt "Does this work?" giving up after 10
	end tell
on error
	set response1 to "no"
end try

try
	tell application "SpeechRecognitionServer"
		set response2 to listen for {"yes"} with prompt "How about now?" giving up after 10
	end tell
on error
	set response2 to "no"
end try

if response1 is "yes" and response2 is "yes" then
	say "Well that's great, but it doesn't work for me."
else if the response1 is "yes" and response2 is "no" then
	say "That's what I get."
else
	say "Well you have a different problem."
end if

Model: Macbook
AppleScript: 2.1
Browser: Safari 531.9
Operating System: Mac OS X (10.6)

No, you’re not imagining things. Apparently this is a known issue, there’s some chatter about it on Apple’s discussion forums. Word is to wait for 10.6.2 and see if that fixes it.

Thanks, I’ll wait for the update…

So far as my testing has shown, Speech Recognition Server is still broken in Mac OS X 10.6.2. At this point, not sure if there is a fix coming. I’ll try to find out what (if anything) is happening and report back here.

Hi,

I’m new to applescript, but interested in playing around with voice recognition. . .

This bug appears to be a ~30 second timeout in SpeechRecognitionServer. I was able to explicitly kill the process between calls to it and get my script to work. To do this in Applescript I modified the above test script to call “killall” in the terminal app.



try
	tell application "SpeechRecognitionServer"
		set response1 to listen for {"yes"} with prompt "Does this work?" giving up after 10
	end tell
on error
	set response1 to "no"
end try

--added terminal command to stop the SpeechRecognitionServer process
--This is a work around for the apparent timeout in Snow Leopard 10.6.2
tell application "Terminal" to do script "killall SpeechRecognitionServer"
delay 1

try
	tell application "SpeechRecognitionServer"
		set response2 to listen for {"yes"} with prompt "How about now?" giving up after 10
	end tell
on error
	set response2 to "no"
end try

if response1 is "yes" and response2 is "yes" then
	say "The terminal command fixed it."
else if the response1 is "yes" and response2 is "no" then
	say "That's what I get."
else
	say "Well you have a different problem."
end if


This leaves a terminal window on the screen each time, which I would be able to remove if I knew applescript better, but at least it allows me to repeatedly call SpeechRecognitionServer.

I hope they fix this bug in 10.6.3

How’s about this:

do shell script "killall SpeechRecognitionServer"

No Terminal window, and it should still work.

I’ve found the “do shell script” call quite useful, especially for reading/writing files and such. It’s easier, and a lot shorter than writing out a full AppleScript function sometimes. :wink:

-SuperScripter

Excellent, thanks for the work around guys! Hopefully apple will sort this out soon.

I think I’ll write it in cocoa now anyway as it’s getting a bit feature heavy for an applescript.