CentOS:5.1
Sphinx2
http://cmusphinx.sourceforge.net/sphinx2/doc/sphinx2.html
download: sphinx2
http://sourceforge.net/project/showfiles.php?group_id=1904&package_id=19...
Install to:
/usr/local/sphinx2
download: peech::Recognizer::SPX
http://search.cpan.org/~djhd/Speech-Recognizer-SPX-0.0801/SPX.pm
Install to:
/usr/local/Speech/Recoginzer
download: communicator
http://www.speech.cs.cmu.edu/sphinx/models/hmm/
Install to:
/usr/local/sphinx2/model/hmm/
use online tool build language models
http://www.speech.cs.cmu.edu/tools/lmtool.html
Two perl files:
sphinxserver.pl
#!/usr/bin/perl
# Based on Example Written by Josh McAllister
# http://turnkey-solution.com/asterisk-sphinx.html
$PORTTOUSE = 3010; # Use 3000 plus the number of your extension so that we are all unique
$SPHINXDIR = "/usr/local/sphinx2/";
use IO::Socket;
use Symbol;
use POSIX;
use Speech::Recognizer::SPX qw(:uttproc :fbs $SPHINXDIR);
use Speech::Recognizer::SPX::Server;
use Config;
# establish SERVER socket, bind and listen.
$server = IO::Socket::INET->new(LocalPort => $PORTTOUSE,
Type => SOCK_STREAM,
Proto => 'tcp',
Reuse => 1,
Listen => 10 )
or die "making socket: $@\n";
# global variables
$PREFORK = 3; # number of children to maintain
$MAX_CLIENTS_PER_CHILD = 50; # number of clients each child should process
%children = (); # keys are current child process IDs
$children = 0; # current number of children
sub REAPER { # takes care of dead children
$SIG{CHLD} = \&REAPER;
my $pid = wait;
$children --;
delete $children{$pid};
}
sub HUNTSMAN { # signal handler for SIGINT
local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children
kill 'INT' => keys %children;
exit; # clean up with dignity
}
# Fork off our children.
for (1 .. $PREFORK) {
make_new_child();
}
# Install signal handlers.
$SIG{CHLD} = \&REAPER;
$SIG{INT} = \&HUNTSMAN;
# And maintain the population.
while (1) {
sleep; # wait for a signal (i.e., child's death)
for ($i = $children; $i < $PREFORK; $i++) {
make_new_child(); # top up the child pool
}
}
sub make_new_child {
my $pid;
my $sigset;
# block signal for fork
$sigset = POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset)
or die "Can't block SIGINT for fork: $!\n";
die "fork: $!" unless defined ($pid = fork);
if ($pid) {
# Parent records the child's birth and returns.
sigprocmask(SIG_UNBLOCK, $sigset)
or die "Can't unblock SIGINT for fork: $!\n";
$children{$pid} = 1;
$children++;
return;
} else { #Child
fbs_init({-live => 'FALSE',
-samp => 8000,
-adcin => 'TRUE',
-ctloffset => 0,
-ctlcount => 100000000,
-cepdir => "$SPHINXDIR/model/lm/names",
-datadir => "$SPHINXDIR/model/lm/names",
-agcmax => 'FALSE',
-langwt => 6.5,
-fwdflatlw => 8.5,
-rescorelw => 9.5,
-ugwt => 0.5,
-fillpen => 1e-10,
-silpen => 1e-10, #0.005,
-inspen => 0.65,
-top => 1,
-topsenfrm => 3,
-topsenthresh => -70000,
-beam => 2e-06,
-npbeam => 2e-06,
-lpbeam => 2e-05,
-lponlybeam => 0.0005,
-nwbeam => 0.0005,
-fwdflat => 'FALSE',
-fwdflatbeam => 1e-08,
-fwdflatnwbeam=> 0.0003,
-bestpath => 'TRUE',
-kbdumpdir => "$SPHINXDIR/model/lm/names",
-lmfn => "$SPHINXDIR/model/lm/names/names.lm",
-dictfn => "$SPHINXDIR/model/lm/names/names.dic",
-phnfn => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format/phone",
-mapfn => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format/map",
-hmmdir => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format",
-hmmdirlist => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format",
-ndictfn => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format/noisedict",
'-8bsen' => 'TRUE',
-sendumpfn => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format/sendump",
-cbdir => "$SPHINXDIR/model/hmm/communicator/sphinx_2_format"});
# handle connections until we've reached $MAX_CLIENTS_PER_CHILD
for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
my $buf = undef;
$client = $server->accept() or last;
uttproc_begin_utt();
my $count = 0;
my $datasize = readline $client;
chomp $datasize;
my $b = read ($client, my($buf), $datasize);
#print "SERVER DEBUG: Expecting $datasize bytes, got $b bytes.\n";
uttproc_rawdata($buf, 1) or die "uttproc_rawdata failed";
uttproc_end_utt();
my ($fr, $hyp) = uttproc_result(1);
#print "frames $fr\n";
print STDERR "SERVER RESULT: $hyp\n";
print $client "$hyp";
close $client;
}
# tidy up gracefully and finish
# this exit is VERY important, otherwise the child will become
# a producer of more and more children, forking yourself into
# process death.
fbs_end();
exit;
}
}
sphinxclient.pl
#!/usr/bin/perl
# Based on Code Written by Josh McAllister
# http://turnkey-solution.com/asterisk-sphinx.html
$PORTTOUSE = 3010; # Use 3000 plus your extension so we are all unique
#die ("usage: $0 \n") if not -e $ARGV[0];
#print "Result: " . asr("$ARGV[0]") . "\n";
$WAVFILE = "/home/sve204/sphinx/name-in.wav"; # Monitor put's the -in on the file
#OR
#$WAVFILE = $ARGV[0];
print asr($WAVFILE) . "\n";
exit;
sub asr
{
use IO::Socket;
use FileHandle;
use IPC::Open2;
my $file = shift or return undef;
my $host = 'localhost';
my $port = $PORTTOUSE;
my $fh;
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => "$host",
PeerPort => "$port",
) or return "No Server Running";
open (FH, $file) || return undef;
$fh = *FH;
$file =~ /(gsm|wav)$/;
my $type = $1;
if ($type !~ /gsm|wav/) {
warn "Unknown file type ($file)";
return undef;
}
#print "FTYPE: $type\n";
#$pid = open2(*SOXIN, *SOXOUT, "sox -t $type - -s -r 16000 -w -t wav - 2>/dev/null") || warn ("Could not open2.\n");
binmode $fh;
#binmode SOXIN;
#binmode SOXOUT;
binmode $remote;
#while (defined(my $b = read $fh, my($buf), 4096))
#{
# last if $b == 0;
# $count += $b;
# print SOXOUT $buf;
#}
#close SOXOUT;
#$count = 0;
#my $sox = undef;
#while (defined(my $b = read SOXIN, my($buf), 4096)) {
# last if $b == 0;
# $count += $b;
# $sox .= $buf;
#}
#print $remote length($sox) . "\n";
#print $remote "$sox";
#close SOXIN;
#print "DEBUG: Waiting for result.\n";
binmode $sendbuf;
while (defined(my $b = read $fh, my($buf), 4096))
{
last if $b == 0;
$count += $b;
$sendbuf .= $buf;
}
print $remote length($sendbuf) . "\n";
print $remote "$sendbuf";
$count=0;
while (defined(my $b = read $remote, my($buf), 4096)) {
last if $b == 0;
$count += $b;
$result .= $buf;
}
close $fh;
close $remote;
return "$result";
}
dialplan
[sve204_sphinxclientserver]
exten => s,1,Wait(1);
exten => s,n,System(/usr/bin/perl /home/sve204/sphinx/sphinxserver.pl &);
exten => s,n,Playback(/home/sve204/sphinx/tellmeyourname);
exten => s,n,Monitor(wav,/home/sve204/sphinx/name);
exten => s,n,Wait(5);
exten => s,n,StopMonitor();
exten => s,n,Playback(/home/sve204/sphinx/ithinkyousaid);
exten => s,n,System(/usr/bin/perl /home/sve204/sphinx/sphinxclient.pl | /usr/bin/text2wave -scale 1.5 -F 8000 -o /home/sve204/sphinx/playbackname.wav);
exten => s,n,Playback(/home/sve204/sphinx/playbackname);
exten => s,n,Wait(5);
exten => s,n,Goto(sve204_sphinxclientserver,s,1);
