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

[Speech-30] fixes and such



Okay...there are a lot of changes that I made...some of them add new
problems.  It'll keep us busy ;p


This is a unified diff patch against v0.29.
Apply using 'patch < wm29to30.patch'
Going down through my patch, here are some of the changes...:

First of all...I think I found a problem in tts_file.  Currently, the
use_festival_tts_file sub will send a command EVERY two seconds to the
server, regardless of whether or not text has been sent to the FIFO.  Upon
receiving a tts_file request, the server waits until there is some text to
parse in the FIFO.  This, I believe, overloads the server with commands
that it will probably never reach, so, I changed the default behavior to
use Say_Text by default.

I added the -H and -P command line arguments for specifying the Host and
Port, although this introduces a new problem.  Festival, by default, is
set to deny access to anyone but localhost.  Connecting to a server in
which you don't have access to disconnects you right away, but speechd
doesn't notice this, and eventually dies.  Also, I added a quick fix to
check of the host is "localhost" before running festival...this is only
temporary...hopefully, because it wouldn't work if the user used
127.0.0.1, or his machine name, etc.

Removed a ".wav player =..." option...I have no idea what it did...but, it
wasn't in use.

I moved the -h help option check above the config file checks and made
the config file checks look cleaner.

Fixed the regex expression that escapes quotes and backslashes...

I added sanity checks for $handle, before it writes to it.  If it doesn't
find $handle, then it will try &connect_to_festival.

The 'or die' for use_festival_tts_file was in the wrong place...corrected.

Finally...the broken pipe problem.  Yesterday, I added a 'recv' function
to maybe see if the festival server was saying something before it
disconnected speechd (something like an idle timeout function).  I'm not
sure...but...I think it stopped the disconnections.  Does anyone know if
there's an incoming data buffer that needs to be cleared occasionally?
I'm thinking that was the problem...the recv buffer just overflowed.
So...it now recv's 50 bytes of data each loop.

And one problem that kinda annoys me...is that when we run festival, it
puts it in the background, and stays alive even when speechd dies.  Do we
have to put it in the background or do we even need to run it?  It would
be much easier to keep the user responsible for running it.

That's about it...i'm tired. ;p

-- 
Michael Matsumura
michael@limit.org
--- speechd	Tue Aug  3 20:18:10 1999
+++ /usr/local/bin/speechd	Wed Aug  4 19:05:26 1999
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 
-# speechd v0.29
+# speechd v0.30
 # Implements /dev/speech
 #
 # This program is released under the GNU General Public License.
@@ -34,19 +34,21 @@
 
 # You may wish to modify the following -- use_festival_tts_file is 
 # less likely to have security bugs, use_festival_SayText is more efficient.
-# I figure that while we're undef'ing $/ (so that input isn't broken on
-# newlines, there really is no reason to use the SayText version.  
+# (tts_file is still under development...)
+
 sub use_festival {
-  &use_festival_tts_file;
-  #&use_festival_SayText;
+  #&use_festival_tts_file;
+  &use_festival_SayText;
 }
 
 sub cmdlinehelp {
-  print "Usage: $0 [-q] [-Q] [-f] -s festival|rsynth\n";
-  print "    or $0 [-h]\n";
+  print "Usage: speechd [-qQf] [-H <host>] [-P <port>] [-s <festival|rsynth>]\n";
+  print "    or speechd [-h]\n";
   print "       -q  Quiet mode (Supresses STDOUT)\n";
   print "       -Q  Very quiet mode (Supresses STDOUT and STDERR)\n";
   print "       -f  Run in foreground (Don't daemonize)\n";
+  print "       -H  Set the host to use (Default: localhost)\n";
+  print "       -P  Set the port to use (Default: 1314)\n";
   print "       -s  Sets the speech synthesis package to use\n";
   print "       -h  This help text\n";
   print "\n";
@@ -72,33 +74,23 @@
   exit;
 } # from dsirc by orabidoo <roger.espel.llima@pobox.com>
 
-&Getopts('hqQfs:');
+&Getopts('hqQfH:P:s:');
+
+if ($opt_h) { &cmdlinehelp; exit; }
 
 #read in /etc/speechdrc
 print "Checking for /etc/speechdrc...";
-if (do "/etc/speechdrc")
-{
-  print "loaded.\n";
-} else {
-  print "not found.\n";
-}
+if (do "/etc/speechdrc") { print "loaded.\n"; }
+                    else { print "not found.\n"; }
 
 #read in ~/.speechdrc
 print "Checking for $ENV{HOME}/.speechdrc...";
-if (do "$ENV{HOME}/.speechdrc")
-{
-  print "loaded.\n";
-} else
-{
-  print "not found.\n";
-}
+if (do "$ENV{HOME}/.speechdrc") { print "loaded.\n"; }
+                           else { print "not found.\n"; }
 
-if ($opt_s ne "")
-{
-  $synth=$opt_s;
-}
+if ($opt_s ne "") { $synth=$opt_s; }
 
-if (($synth ne "festival" && $synth ne "rsynth") || $opt_h)
+if ($synth ne "festival" && $synth ne "rsynth")
 {
   &cmdlinehelp;
   exit;
@@ -108,8 +100,10 @@
 if ($opt_q) { open STDOUT, ">/dev/null" or die "Can't write to /dev/null: $!"; }
 if (!$opt_f) { &daemonize; }
 
-print "Speech synthesis system = \"$synth\", .wav player = \"$player\".\n";
+if ($opt_H) { $host = $opt_H; }
+if ($opt_P) { $port = $opt_P; }
 
+print "Speech synthesis system = \"$synth\"\n";
 
 # change to /dev/speech if you really want to use it, otherwise
 # this assumes a file in the pwd
@@ -126,8 +120,8 @@
   use IO::Socket;
 
   # create a tcp connection to the festival server
-  $port = "1314";
-  $host = "localhost";
+  if (!$host) { $host = "localhost"; }
+  if (!$port) { $port = "1314"; }
 
   &connect_to_festival;
 } 
@@ -168,10 +162,14 @@
     # reads will block till someone writes something
     $text = <FIFO>;
   
-    #escape characters between []
-    $text =~ s/["\\]/\\$1/g;
-  
-    print $handle "(SayText \"$text\")" or die "Could not write to Festival ($!)\n";
+    # escape backslashes and quotes
+    $text =~ s/(["\\])/\\$1/g;
+    if ($handle) {   # Sanity checks are always nice...
+      print $handle "(SayText \"$text\")" or die "Could not write to Festival ($!)\n";
+      recv($handle, $info, 50, 0);
+    } else {
+      &connect_to_festival;
+    }
     close FIFO;
     sleep 2;  # this is recommended by the perlipc
               # manpage to avoid dup signals
@@ -179,10 +177,15 @@
 }
 
 sub use_festival_tts_file {
-  print "Called use_festival_tts_file.\n" or die "Could not write to Festival ($!)\n";
+  print "Called use_festival_tts_file.\n";
   local $SIG{PIPE} = \&connect_to_festival;
   while(1) {
-    print $handle "(tts_file \"/dev/speech\")";
+    if ($handle) {   # Sanity checks are always nice...
+      print $handle "(tts_file \"/dev/speech\")"  or die "Could not write to Festival ($!)\n";
+      recv($handle, $info, 50, 0);
+    } else {
+      &connect_to_festival;
+    }
     sleep 2;  # this is recommended by the perlipc
               # manpage to avoid dup signals
   }
@@ -207,7 +210,7 @@
   $handle = "";
   $tries = 0;
 
-  while ($handle eq "") 
+  while ($handle eq "")
   {
     print "($tries) Attempting to connect to the Festival server.\n";
     if ($handle = IO::Socket::INET->new(Proto     => "tcp",
@@ -222,8 +225,10 @@
         print "Waiting for Festival server to load -- Can't connect to port $port on $host yet ($!).\n";
       } else
       {
-        print "Failed to connect to Festival server, attempting to load it myself.\n";
-        system ('festival --server &');
+        if ($host eq "localhost") {
+          print "Failed to connect to Festival server, attempting to load it myself.\n";
+          system ('festival --server &');
+        }
       }
       sleep 1;
     }