[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Search]

[patch]: ESpeak TTS server responsiveness



"Robert D. Crawford" <rdc1x@xxxxxxxxxxx> writes:

> In the .asoundrc file, without the patch applied, if point is on the
> first line and I use C-n to scroll down to line 20 to 25 it takes about
> 4 seconds for the speech to catch up and the line to be spoken.  With
> the parch applied it takes about 8 seconds.

There's a TCL procedure named tts_sync_state which is called fairly often.
tts_sync_state calls other TCL procedures.  In turn, those procedures call
out to functions from the ESpeak library.
Those library calls are fairly expensive in terms of
CPU time.  Often, tts_sync_state is called, but the state of the TTS engine
hasn't changed.  It's an expensive no-op.
The reason that tts_sync_state takes longer after my patch is that I fixed
some of the procedures that it uses.  Before yesterday's patch,
tts_sync_state often terminated prematurely, due to errors in its callees.

The procedures called by tts_sync_state need to be a bit
smarter.  Only call out to C functions when the state of the TTS engine
has actually changed.

So here's another patch.  This one should improve the responsiveness
of the ESpeak server.  The responsiveness is good enough that I haven't
resorted to using another TTS server during the past few hours.

This doesn't fix the stutter from word echo.  I still don't know what causes
that.  

Thank you for your helpful comments regarding my last patch!

-- Chris
Index: servers/espeak
===================================================================
--- servers/espeak	(revision 5922)
+++ servers/espeak	(working copy)
@@ -204,22 +204,26 @@
     d
 }
 
-proc tts_set_punctuations {mode} {
+proc tts_set_punctuations {mode {force 0}} {
     global tts
 
-    set tts(punctuations) $mode
-    punct $mode
-    service
+    if {($tts(punctuations) != $mode) || $force} {
+        set tts(punctuations) $mode
+        punct $mode
+        service
+    }
     return ""
 }
 
-proc tts_set_speech_rate {rate} {
+proc tts_set_speech_rate {rate {force 0}} {
     global tts
 
     set factor $tts(char_factor) 
-    set tts(speech_rate) $rate
-    setRate 0 $rate
-    service
+    if { ($tts(speech_rate) != $rate) || $force} {
+        set tts(speech_rate) $rate
+        setRate 0 $rate
+        service
+    }
     return ""
 }
 
@@ -322,57 +326,63 @@
 # - or highering pitch (tts_capitalize)
 # - or beeping (tts_allcaps_beep)
 #
-proc tts_split_caps {flag} {
+proc tts_split_caps {flag {force 0}} {
     global tts 
 
-    set tts(split_caps) $flag
-    if { $flag == 1 } {
-	set tts(allcaps_beep) 0
-	set tts(capitalize) 0
-	caps "spelling"
-    } else {
-	if { ( $tts(capitalize) == 0 ) && ( $tts(allcaps_beep) == 0 ) } {
-	    caps "none"
-	}
+    if { ($flag != $tts(split_caps)) || $force} {
+        set tts(split_caps) $flag
+        if { $flag == 1 } {
+    	set tts(allcaps_beep) 0
+    	set tts(capitalize) 0
+    	caps "spelling"
+        } else {
+    	if { ( $tts(capitalize) == 0 ) && ( $tts(allcaps_beep) == 0 ) } {
+    	    caps "none"
+    	}
+        }
+        service
     }
-    service
     return ""
 }
 
-proc tts_capitalize {flag} {
+proc tts_capitalize {flag {force 0}} {
     global tts 
 
-    set tts(capitalize) $flag
-
-    if { $flag == 1 } {
-	set tts(split_caps) 0
-	set tts(allcaps_beep) 0
-	caps "pitch"
-    } else {
-	if { ( $tts(split_caps) == 0 ) && ( $tts(allcaps_beep) == 0 ) } {
-	    caps "none"
-	}
+    if {($flag != $tts(capitalize)) || $force} {
+        set tts(capitalize) $flag
+    
+        if { $flag == 1 } {
+    	set tts(split_caps) 0
+    	set tts(allcaps_beep) 0
+    	caps "pitch"
+        } else {
+    	if { ( $tts(split_caps) == 0 ) && ( $tts(allcaps_beep) == 0 ) } {
+    	    caps "none"
+    	}
+        }
+    
+        service
     }
-
-    service
     return ""
 }
 
-proc tts_allcaps_beep {flag} {
+proc tts_allcaps_beep {flag {force 0}} {
     global tts 
 
-    set tts(allcaps_beep) $flag
-
-    if { $flag == 1 } {
-	set tts(split_caps) 0
-	set tts(capitalize) 0
-	caps "tone"
-    } else {
-	if { ( $tts(split_caps) == 0 ) && ( $tts(capitalize) == 0 ) } {
-	    caps "none"
-	}
+    if { ($tts(allcaps_beep) != $flag) || $force } {
+        set tts(allcaps_beep) $flag
+    
+        if { $flag == 1 } {
+    	set tts(split_caps) 0
+    	set tts(capitalize) 0
+    	caps "tone"
+        } else {
+    	if { ( $tts(split_caps) == 0 ) && ( $tts(capitalize) == 0 ) } {
+    	    caps "none"
+    	}
+        }
+        service
     }
-    service
     return ""
 }
 
@@ -514,6 +524,18 @@
 if {[file exists /proc/asound]} {
     set tts(play) /usr/bin/aplay
 }
+
+# The second argument of 1 to the tts_* procedures tells them to make a
+# library call.  These procedures only make library calls when they detect
+# changes to the $tts associative array or when they are given an optional
+# 2nd argument of 1.
+tts_set_punctuations $tts(punctuations) 1
+tts_set_speech_rate $tts(speech_rate) 1
+tts_capitalize $tts(capitalize) 1
+tts_allcaps_beep $tts(allcaps_beep) 1
+tts_split_caps 0 1
+# Initially, don't use ESpeak's split-caps behavior
+
 synth {<voice xml:lang="en" variant="1">eSpeak.}
 
 service


If you have questions about this archive or had problems using it, please send mail to:

priestdo@xxxxxxxxxxx No Soliciting!

Emacspeak List Archive | 2007 | 2006 | 2005 | 2004 | 2003 | 2002 | 2001 | 2000 | 1999 | 1998 | Pre 1998

Emacspeak Files | Emacspeak Blog