[SOLVED] Asterisk integration with sphinx2 - Perl Make Error


#1

While this issue is not directly related to Asterisk, someone around here might have some experience on how to work through this. I am attempting to get Sphinx Voice Rec (v2.0.6) working with Asterisk, as per these guidelines:

turnkey-solution.com/asterisk-sphinx.html

The problem is, one of the required Perl components will not compile:

search.cpan.org/~djhd/Speech-Rec … 602/SPX.pm

[quote=“Make Error”]waldorf:/usr/src/Speech-Recognizer-SPX-0.0602 # make
make[1]: Entering directory /usr/src/Speech-Recognizer-SPX-0.0602/Audio' cc -c -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -g -O2 -DVERSION="0.0101" -DXS_VERSION="0.0101" -fPIC "-I/usr/lib/perl5/5.8.7/i586-linux-thread-multi/CORE" SPX.c SPX.c: In function ‘XS_cont_ad_tPtr_set_params’: SPX.c:722: error: too few arguments to function ‘cont_ad_set_params’ SPX.xs: In function ‘XS_cont_ad_tPtr_get_params’: SPX.xs:418: error: too few arguments to function ‘cont_ad_get_params’ SPX.c: In function ‘XS_cont_ad_tPtr_set_logfp’: SPX.c:966: warning: passing argument 1 of ‘cont_ad_set_logfp’ from incompatible pointer type SPX.c:966: error: too few arguments to function ‘cont_ad_set_logfp’ make[1]: *** [SPX.o] Error 1 make[1]: Leaving directory/usr/src/Speech-Recognizer-SPX-0.0602/Audio’
make: *** [subdirs] Error 2
waldorf:/usr/src/Speech-Recognizer-SPX-0.0602 # [/quote]

Any ideas on how to get past this issue?


#2

I did two things to get this working:

  • On RedHat I had to do this:

export LD_LIBRARY_PATH=/usr/local/lib

  • Then modified client script from this example (with the assistance of the author of the tutorial):

turnkey-solution.com/asterisk-sphinx.html

  • /var/lib/asterisk/agi-bin/sphinx.agi

[code]#!/usr/bin/perl

sphinx.agi

Copyright © 2005 Josh McAllister

This program is free software; you can redistribute it and/or modify

it under the same terms as Perl itself.

Written by Josh McAllister

use Asterisk::AGI;
my $AGI = new Asterisk::AGI;
%input = $AGI->ReadParse();

sub asr {
use IO::Socket;
use FileHandle;
use IPC::Open2;
my $file = shift or return undef;
my $host = shift || ‘localhost’;
my $port = shift || ‘1069’;
my $fh;

my $remote = IO::Socket::INET->new(
Proto => “tcp”,
PeerAddr => “$host”,
PeerPort => “$port”,
) or return undef;

#Idea here being that you can pass a reference to an existing file handle… not yet implemented, just pass a filename.
if (ref $file) {
my $fh = $file;
} else {
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 8000 -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”;

$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”;
}

sub confirm {
while (my $tries <= 3) {
$tries++;

     $AGI->stream_file("vr/say_yes_no",'""');

     $AGI->stream_file("beep",'""');
     $AGI->record_file("/tmp/$$", 'gsm', '0',3000);
     $AGI->stream_file("beep",'""');


     #Here is where the magic happens, this is calling the asr sub from sphinx-netclient.pl
     #Again, this sub needs to be in this same script. $vresponse will contain the
     #transcription of the what the caler said.

     my $vresponse = asr("/tmp/$$.gsm");
     $AGI->verbose("CONFIRM: $vresponse");

     next if $vresponse !~ /YES|NO|ACCEPT|CANCEL/;

     $gotresp = 1;


     if ($vresponse =~ /NO|CANCEL/i) {
        sleep 1;
        $AGI->stream_file("cancelled",'""');
        return undef;
     } else {
    $AGI->set_variable('RESPONSE', 'YES');
        return 1;
     }

  }

  if (! $gotresp) {
     sleep 1;
     $AGI->stream_file("invalid_selection",'""');
     return undef;
  }

}

$AGI->stream_file(“vr/green_eggs_ham”,’""’);
unless ( confirm() ) {
#They said no
$AGI->set_variable(‘RESPONSE’, ‘NO’);
exit;
}
[/code]


#3

What do you think of sphinx?

For example (if you don’t mind a few questions :smiley: ):

How hard is it to work with (to build, to customize, etc.)?

Does it recognize “free form” speech, or do you have to program in a grammar? How hard is that? Is it well documented?

How accurate does it seem to be? Do you train it for different speakers?

Does it use vxml?

How cleanly does it integrate with Asterisk (i.e., do you integrate via AGI, or is there a “sphinx application” you can call)?

How resource intensive does it seem to be?

I’ve got a “backburner project” that might benefit from speech recognition, and I’ve played a tiny bit with Voxeo, but it’s hard to see how to integrate that with Asterisk in a scalable manner. Two minutes googling “sphinx” scared me off a while back.

Cheers,
john


#4

To all of your questions yes, no and maybe. It is early days for me an Sphinx, so still working to understand the framework, the capabilities, scalability, etc. The initial setup was not necessarily intuitive and the expansion of the grammar/dictionary and scale seems like it will be tedious work. Let the fun begin.


#5

Oops – just noticed the date of your post. Hadn’t checked here in a while, and for some reason I thought this post was from a while back. I’d like to check back with you after you have some more time with sphinx if you don’t mind.

cheers,
john