It allows you to type
say "Hello there"
on one PC and have the voice server speak the words.
Impress your friends, intimidate burglars or adapt it to other uses - up to you!
Hardware
The following hardware is required:
- 2 Linux systems with Perl installed.
- A voice synthesiser such as Votrax Type'N Talk attached to your serial port.
- A spare serial port on the voice server box so you can hook it up to the voice synthesiser.
Software
The software listed below is needed:
- See the code listed below. Both the client and utility "say" routines can be put on any PCs that need to send commands or speech messages. The server code is run as a daemon on the system that has the voice synthesiser attached.
- Perl should be installed.
Ideas
- Use this in conjuction with the Caller ID project on this site to verbally anounce callers before you answer the phone.
- Greet visitors at the front gate/door by linking to the Alarm project on this site.
Code
The server code:
#!/usr/bin/perl
#---------------------------------------------------------------
# TCP/IP Server
#
# Based on sample server p988 of Perl Black Book.
#
# Written 9/9/01: G.Collett
#---------------------------------------------------------------
# To do...
# - log data
# - handle piped data
#---------------------------------------------------------------
#---------------------------------------------------------------
# Initialisation
#---------------------------------------------------------------
# Use the socket library
use IO::Socket;
# Determine the current date and time
$now = `date +%Y%m%d%H%M%S`;
chop($now);
# Automatically flush output
$| = 1;
# Catch signals
$SIG{HUP} = \&CloseUp; #-1
$SIG{INT} = \&CloseUp; #-2
$SIG{QUIT} = \&CloseUp; #-3
$SIG{TRAP} = \&CloseUp; #-5
$SIG{KILL} = \&CloseUp; #-9
$SIG{TERM} = \&CloseUp; #-15
$SIG{STOP} = \&CloseUp; #-17
# Open a file to log all output
open(LOG, ">>server.log") or die "Unable to open log file\n";
print LOG "\n\n";
print LOG "-------------------------------------------\n";
print LOG "Starting server at $now...\n";
LOG->flush;
#---------------------------------------------------------------
# Start a listener on the local host port 8888 for 5 clients max
#---------------------------------------------------------------
$sock = new IO::Socket::INET->new
(
LocalAddr => '192.16.16.16',
LocalPort => 8888,
Proto => 'tcp',
Reuse => 1,
Listen => 5
) or die "Unable to start server: $!\n";
$sock->autoflush(1);
# Determine the current date and time
$now = `date +%Y%m%d%H%M%S`;
chop($now);
print LOG "Server started at $now\n\n";
LOG->flush;
#---------------------------------------------------------------
# Accept client connections
#---------------------------------------------------------------
while ($client = $sock->accept())
{
#---------------------------------------------------------------
# Now fork a thread to handle the client connection
#---------------------------------------------------------------
$| = 1;
$client_addr = $client->peerhost;
#print LOG "Client has connected from $client_addr\n";
LOG->flush;
unless (defined($child_pid = fork()))
{
die "Cannot fork\n";
}
#---------------------------------------------------------------
# Child thread (handles client connections)
#---------------------------------------------------------------
if ($child_pid)
{
$| = 1;
while ($line = <$client>)
{
chop($line);
# Determine the current date and time
$now = `date +%Y%m%d%H%M%S`;
chop($now);
print LOG "$now|$client_addr|$line\n";
LOG->flush;
&ProcessCmd($client_addr, $line);
}
LOG->flush;
$client->flush;
close($client);
# print LOG "Child ended\n";
# LOG->flush;
exit;
}
# Parent thread just loops back and listen for more connections
}
&CloseUp;
exit;
#---------------------------------------------------------------
# Catch all signals and shutdown gracefully.
#---------------------------------------------------------------
sub CloseUp
{
my $signal = shift;
print LOG "Server received signal [$signal]. Shutting down.\n";
close($client);
close($sock);
close(LOG);
exit;
}
#---------------------------------------------------------------
# Process commands from authorised hosts
#---------------------------------------------------------------
sub ProcessCmd
{
local ($client_addr, $line) = @_;
if ($client_addr eq '192.16.16.17')
{
if ($line eq 'FIREWALLUP')
{
$msg = "ADSL Connection is back on line at $now.";
`echo "$msg" | smbclient -M TERMINATOR`;
`echo "$msg" | smbclient -M GCLT2`;
`echo "$msg" | smbclient -M BRAD`;
`echo "$msg" | smbclient -M ERIN`;
`echo "$msg" | smbclient -M PEGASUS`;
}
if ($line eq 'FIREWALLDOWN')
{
$msg = "ADSL Connection has dropped out at $now. Please reset the modem.";
`echo "$msg" | smbclient -M TERMINATOR`;
`echo "$msg" | smbclient -M GCLT2`;
`echo "$msg" | smbclient -M BRAD`;
`echo "$msg" | smbclient -M ERIN`;
`echo "$msg" | smbclient -M PEGASUS`;
}
}
else
{
print LOG "Client $client_addr not authorised\n";
}
}
The client code:
#!/usr/bin/perl
#---------------------------------------------------------------
# TCP/IP Client
#
# Based on sample server p988 of Perl Black Book.
#
# Written 9/9/01: G.Collett
#---------------------------------------------------------------
#---------------------------------------------------------------
# Initialisation
#---------------------------------------------------------------
# Use the socket library
use IO::Socket;
# Automatically flush output
$| = 1;
# Catch signals
$SIG{HUP} = \&CloseUp; #-1
$SIG{INT} = \&CloseUp; #-2
$SIG{QUIT} = \&CloseUp; #-3
$SIG{TRAP} = \&CloseUp; #-5
$SIG{KILL} = \&CloseUp; #-9
$SIG{TERM} = \&CloseUp; #-15
$SIG{STOP} = \&CloseUp; #-17
#---------------------------------------------------------------
# Start a connection to the server
#---------------------------------------------------------------
print "Connecting to server....\n";
$sock = new IO::Socket::INET->new
(
PeerAddr => '192.16.16.16',
PeerPort => 8888,
Proto => 'tcp',
Reuse => 1,
Timeout => 5,
Type => SOCK_STREAM
) or die "Unable to connect to server: $!";
$sock->autoflush(1);
print "Connected\n\n";
#---------------------------------------------------------------
# Send all STDIN to the server
#---------------------------------------------------------------
STDIN->autoflush(1);
until (eof(STDIN))
{
$line = ;
chop($line);
# Write STDIN to the socket
print $sock "$line\n";
print "Sent [$line]\n";
}
ALLDONE:
# input complete so close up and exit
$sock->flush;
close($sock);
exit;
#---------------------------------------------------------------
# Catch all signals and shutdown gracefully.
#---------------------------------------------------------------
sub CloseUp
{
my $signal = shift;
print "Server received signal [$signal]. Shutting down.\n";
close($sock);
exit;
}
Client utilities: Application: "say"
#!/usr/local/bin/perl $msg = $ARGV[0]; print `echo "$msg" | voice_client.pl`; exit;
Click here to check out the list of other projects.
You may also like to click here to check out the list of Artificial Intelligence projects.
If you would like to get any further information on this or any of the other projects shown on this web site, please send an email to Acacia Lateral Technologies. or place a comment in our Guest Book
You might also like to submit your idea to our Free Ideas page for the benefit of other like-minded soles.