This is a silly little script I wrote one evening. When I was growing up, it was possible to dial POP-CORN on a phone and get a voice telling you what time it was. I thought it would be fun to get my Linux laptop to do the same thing. If you have a relatively stock Fedora Core 3 system, this should just work. Otherwise, you may need to tweak a few things.

If you aren't running Linux, then this won't work. Sorry.

You can download the script if it interests you. Run it at your own risk (I can't be held responsible if it eats your computer, but it really shouldn't).

#!/bin/sh
# This is a script to make the system speak the time accurately.  This
# would be a nice background task for a dedicated NTP box.  With all of
# the calls to date and festival, it's not terribly efficient, but it should
# do the job.
#
# This assumes that the festival text-to-speech system is installed, and
# that /bin/date speaks the GNU extensions.  This works fine under
# Fedora Core 3 linux.
#
# (C) 2005 Aaron Gage, free for non-commercial use

while /bin/true; do
	sleep 0.25
	let SECS=`date +%s` # seconds since epoch
	let NEXTSECS=10-$SECS%10 # roughly how long until the next beep

	# Get how many seconds will be at the next update (so it can
	# say "exactly" instead of "zero zero")
        let REMAINDER=`date --date="+$NEXTSECS sec" +"%s"`%60
	# Convert the AM/PM into something festival will say properly
	MERIDIAN=`date --date="+$NEXTSECS sec" +"%p"`

	if [ $MERIDIAN = "AM" ]; then
		AUDIBLE_MERIDIAN="A M"
	elif [ $MERIDIAN = "PM" ]; then
		AUDIBLE_MERIDIAN="P M"
	else AUDIBLE_MERIDIAN=""  # just in case
	fi

	# Determine if the minutes need some audible filler (so that
	# "twelve one PM" will become "twelve oh one PM")
	MINUTES=`date --date="+$NEXTSECS sec" +"%M"`
	if [ $MINUTES -lt 10 ]; then
		if [ $MINUTES -eq 0 ]; then
			FILLER=" o clock "
		else	FILLER=" o "
		fi
	else FILLER=""
	fi

	if [ $REMAINDER -eq 0 ]; then
		# exactly on a minute
		NEXTDATE=`date --date="+$NEXTSECS sec" +"%l: $FILLER %M $AUDIBLE_MERIDIAN exactly on %A %B %e"`
	else
		# non-zero seconds
		NEXTDATE=`date --date="+$NEXTSECS sec" +"%l: $FILLER %M and %S seconds $AUDIBLE_MERIDIAN on %A %B %e"`
	fi

	echo At the tone, the time will be $NEXTDATE | festival --tts
	# Now, try to accurately sleep off the remaining time until the beep
	let SLEEPSECS=\(10-\(`date +%s`%10\)\)*1000000-\(10\#`date +%N`\)/1000
	usleep $SLEEPSECS
	# Make noise (yes, this is silly)
	echo beep | festival --tts
done