Speak from Terminal

Hello.

Save it as a shell script and chmod u+x afterwards, then you can enter date|speak on the commandline for instance. speak “An error occured” is an example of another way to invoke it. :slight_smile:

[code]#!/bin/bash

© McUsr and put into Public Domain. You may not post this script elsewhere,

nor put into a repository but please refer to this link: GPL 1.0

Release 2.0.3

declare prgname version Usage args theVoice theFile tempfoo TMPFILE curdir the_res
prgname=basename $0
PATH=“/bin:/usr/bin”
version=“0”
Usage=“Usage : $prgname [-h] [-l] || [-V voice] || [-f file] || [ "words to speak" ]”
phelp()
{
echo "
$Usage
Speaks text either given from the commandline, from a file with the -f option, or from standard input.

-h shows this help
-l lists the voices
-V chooses the voice you want to use.
-f specifies a file to speak

Example:
$prgname -V Bruce "Hello World"
$prgname -V Bruce -f /Users/You/your/file/to/speak
" 1>&2
}
theVoice=Bruce
cmd=Just_speak
args=getopt hlV:f: $* 2>/dev/null
if [ $? -ne 0 ]
then
echo $Usage
exit 1
fi
arg=“__”
set – $args

for i
do
case “$i”
in
-h)
phelp ;
exit 0 ;;
-l)
cmd=list_voices ;
shift ;;
# output the list of the voice names.
-V) shift;
theVoice=“$1” ;
cmd=set_voice ;
shift ;;
# set the voice This one is independent of file.
-f) shift ;
theFile=“$1” ;
export cmd=file_arg ;
shift ;;
# file to speak
esac
done

if [ “$cmd” = “list_voices” ] ; then
cat <<EOF
Agnes
Albert
Alex
BadNews
Bahh
Bells
Boing
Bruce
Bubbles
Cellos
Deranged
Fred
GoodNews
Hysterical
Junior
Kathy
Organ
Princess
Ralph
Trinoids
Vicki
Victoria
Whisper
Zarvox
EOF
exit 0
elif [ $# -eq 1 ] ; then
shift
set – “$theVoice”
else
shift
set – “$theVoice” “$@”
fi

if there are no commandline arguments left, and no file argument, then we’ll

use the standard input. We must also cater for the case with voice.

if [ $# -gt 1 ] ; then
osascript <<END! - “$*”
on run {T}
set Applescript’s text item delimiters to “”
set T to T as text
set theVoiceList 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”}
set theVoice to word 1 of T
set theSpeach to word 2 thru -1 of T as text
if theVoice is in theVoiceList then
say theSpeach using ( theVoice as list )
else
say theSpeach using {“Victoria”}
end if
end run
END!

elif [ “$cmd” = “file_arg” ] ; then
cat “$theFile” >|/tmp/saying2
sed ‘s:[][^$.*/#]:\&:g’ “$theFile” >|/tmp/saying2
osascript <<END! - “$@”
on run { T }
set Applescript’s text item delimiters to “”
set T to T as text
set theVoiceList 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”}
set theVoice to word 1 of T
set theSpeach to do shell script “cat /tmp/saying2”
if theVoice is in theVoiceList then
say theSpeach using ( theVoice as list )
else
say T using {“Victoria”}
end if
end run
END!

else
rm /tmp/saying 2>/dev/null || echo >/dev/null
while read a ; do
echo “$a” >>/tmp/saying
done
sed ‘s:[][^$.*/#]:\&:g’ /tmp/saying >|/tmp/saying2
osascript <<END! - “$@”
on run { T }
set Applescript’s text item delimiters to “”
set T to T as text
set theVoiceList 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”}
set theVoice to word 1 of T
set theSpeach to do shell script “cat /tmp/saying2”
if theVoice is in theVoiceList then
say theSpeach using ( theVoice as list )
else
say T using {“Victoria”}
end if
end run
END!
fi[/code]

Updated to handle various text files better. :slight_smile:

Not particularily elegant, but with bells and whistles. ( post #1 )

  • Lists the voices with the -l option
  • Sets voice with -V option
  • Reads from a file with -f option
  • reads “arguments” :slight_smile: from commandline, if no -f option is given
  • Gets what to speak from standard input, that is, from a pipe if no arguments are given on the commandline.
  • -h gives help!

Enjoy!

Here is a little spinoff I made, when I got to the voices.

It may be useful if you are wondering what voice to use. I don’t think every voice works on every system by the way.

set AppleScript's text item delimiters to ""
set {a, l} to {voices, {}}
tell application id "sevs"
	-- your code goes here...
	set a to name of every disk item of folder (path to voices folder as text) as text
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ".SpeechVoice"}
	set l to every text item of a
	set AppleScript's text item delimiters to linefeed
	set l to l as text
	set AppleScript's text item delimiters to tids
	do shell script "cat -  <<<" & quoted form of l & " >/tmp/voices ; open -fgb \"com.apple.textedit\" /tmp/voices"
end tell

I have removed a couple of small bugs in the script above, due to lack of initialization of shell variables in some cases.

Hello!

I was looking for a way to implement pause when I discovered the obvious. I can just hit ^Z int the Terminal window, to suspend it, and the enter fg 1, when I want to continue listening.

( I, at least can’t make the speak text service pause speaking in Safari.)

The downside, is however, that the OsaScript that speaks the text, seems to lock up the sound channel, so I can’t just take a break from the sound-book, and listen to some music. :expressionless: