Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 7fd57af74f0f7f3d481304b83a3900cbe633cab3 @zaf committed Dec 28, 2011
Oops, something went wrong.
@@ -0,0 +1,2 @@
+2011-12-29 Lefteris Zafiris <zaf.000@gmail.com> - 0.1
+ Initial release 0.1
@@ -0,0 +1,47 @@
+=====================================================
+ Google Speech recognition script for Asterisk
+=====================================================
+
+This script makes use of Google's speech recognition engine
+in order to redner speech to text and return it back to the user
+as an asterisk channel variable.
+
+------------
+Requirements
+------------
+Perl The Perl Programming Language
+perl-libwww The World-Wide Web library for Perl
+sox Sound eXchange, sound processing program
+Internet access in order to contact google and get the speech data.
+
+------------
+Installation
+------------
+To install copy googlestt.agi to your agi-bin directory.
+Usually this is /var/lib/asterisk/agi-bin/
+To make sure check your /etc/asterisk/asterisk.conf file
+
+-----
+Usage
+-----
+agi(googlestt.agi)
+Records from the current channel. Pressing # terminates the recording and
+returns the generated text string as the value of the variable utterance.
+
+--------
+Examples
+--------
+sample dialplan code for your extensions.conf
+
+;Speech recognition test
+exten => 160,1,Answer()
+exten => 160,n,agi(speech-recog.agi)
+exten => 160,n,Noop(== The text you just said was: ${utterance} ==)
+exten => 160,n,Hangup()
+
+
+-------
+License
+-------
+The GoogleTTS script for asterisk is distributed under the GNU General Public
+License v2. See COPYING for details.
@@ -0,0 +1,2 @@
+Lefteris Zafiris <zaf.000@gmail.com>
+
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,60 @@
+#!/usr/bin/env perl
+
+#
+# Render speech to text using Google's speech recognition engine.
+#
+# Copyright (C) 2011, Lefteris Zafiris <zaf.000@gmail.com>
+#
+# This program is free software, distributed under the terms of
+# the GNU General Public License Version 2. See the COPYING file
+# at the top of the source tree.
+#
+
+use strict;
+use warnings;
+use LWP::UserAgent;
+
+if (!$ARGV[0] | $ARGV[0] eq '-h' | $ARGV[0] eq '--help') {
+ print "Google Speech regognition\n";
+ print "Usage: $0 [FILES]\n\n";
+ exit;
+}
+
+my $url = "http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium";
+my $samplerate = 8000;
+#my $filetype = "x-speex-with-header-byte";
+my $filetype = "x-flac";
+my $language = "en-US";
+my @file_list = @ARGV;
+
+foreach my $file (@file_list) {
+ print "Openning $file\n";
+ open(my $fh, "<", "$file") or die "Cant read file: $!";
+ my $audio = do { local $/; <$fh> };
+ close($fh);
+ my $ua = LWP::UserAgent->new;
+ $ua->agent("Mozilla/5.0 (X11; Linux) AppleWebKit/535.2 (KHTML, like Gecko)");
+ $ua->timeout(20);
+ my $response = $ua->post(
+ "$url&lang=$language",
+ Content_Type => "audio/$filetype; rate=$samplerate",
+ Content => "$audio",
+ );
+ last if (!$response->is_success);
+ my %response;
+ if ($response->content =~ /^\{"status":(\d*),"id":"(.*)","hypotheses":\[(.*)\]\}$/) {
+ $response{status} = "$1";
+ $response{id} = "$2";
+ if ($response{status} == 5) {
+ print "Error reading audio file\n";
+ last;
+ }
+ if ($3 =~ /^\{"utterance":"(.*)","confidence":(.*)\}/) {
+ $response{utterance} = "$1";
+ $response{confidence} = "$2";
+ }
+ }
+ printf "%-10s : %s\n", $_, $response{$_} foreach (keys %response);
+ #print $response->content;
+}
+exit;
@@ -0,0 +1,162 @@
+#!/usr/bin/env perl
+
+#
+# AGI script that renders speech to text using Google's speech recognition engine.
+#
+# Copyright (C) 2011, Lefteris Zafiris <zaf.000@gmail.com>
+#
+# This program is free software, distributed under the terms of
+# the GNU General Public License Version 2. See the COPYING file
+# at the top of the source tree.
+#
+
+use warnings;
+use strict;
+use File::Temp qw(tempfile);
+use LWP::UserAgent;
+$| = 1;
+
+# ----------------------------- #
+# User defined parameters: #
+# ----------------------------- #
+# Default language #
+my $language = "en-US";
+
+# Input audio sample rate #
+my $samplerate = 8000;
+
+# Verbose debugging messages #
+my $debug = 0;
+
+# ----------------------------- #
+
+my %AGI;
+my $ua;
+my $fh;
+my $tmpname;
+my $format;
+my @result;
+my $name;
+my $audio;
+my $uaresponse;
+my %response;
+my $timeout = 5000;
+my $tmpdir = "/tmp";
+my $maxlen = 2048;
+my $filetype = "x-flac";
+my $url = "http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium";
+my $sox = `/usr/bin/which sox`;
+
+# Store AGI input #
+while (<STDIN>) {
+ chomp;
+ last if (!length);
+ $AGI{$1} = $2 if (/^agi_(\w+)\:\s+(.*)$/);
+}
+
+$name = " -- $AGI{request}:";
+
+# Abort if required programs not found. #
+die "$name sox is missing. Aborting.\n" if (!$sox);
+
+chomp($sox);
+print STDERR "$name Found sox in: $sox\n" if ($debug);
+
+# Setting recording file format according to sample rate. #
+if ($samplerate == 16000) {
+ $format = "sln16";
+} else {
+ $format = "sln";
+ $samplerate = 8000;
+}
+
+# Answer channel if not already answered #
+print "CHANNEL STATUS\n";
+@result = &checkresponse();
+if ($result[0] == 4) {
+ print "ANSWER\n";
+ &checkresponse();
+}
+
+# Hnadle interrupts #
+$SIG{'INT'} = \&int_handler;
+$SIG{'HUP'} = \&int_handler;
+
+# Record file #
+($fh, $tmpname) = tempfile("stt_XXXXXX", DIR => $tmpdir, UNLINK => 1);
+print "RECORD FILE $tmpname $format \"#\" -1\n";
+@result = &checkresponse();
+die "$name Failed to record file, aborting...\n" if ($result[0] == -1);
+
+if ($debug) {
+ print STDERR "$name Playing back recorded file.\n";
+ print "STREAM FILE $tmpname \"\"\n";
+ @result = &checkresponse();
+ print STDERR "$name Failed to play file\n" if ($result[0] == -1);
+}
+
+system($sox, "--norm", "-b", "16", "-t", "raw", "-r", $samplerate, "-e", "signed-integer", "$tmpname.$format", "$tmpname.flac") == 0
+ or die "$name $sox failed: $?\n";
+open($fh, "<", "$tmpname.flac") or die "Can't read file: $!";
+$audio = do { local $/; <$fh> };
+close($fh);
+$ua = LWP::UserAgent->new;
+$ua->agent("Mozilla/5.0 (X11; Linux) AppleWebKit/535.2 (KHTML, like Gecko)");
+$ua->timeout(25);
+$uaresponse = $ua->post(
+ "$url&lang=$language",
+ Content_Type => "audio/$filetype; rate=$samplerate",
+ Content => "$audio",
+);
+die "$name Unable to get speech data.\n" if (!$uaresponse->is_success);
+
+if ($uaresponse->content =~ /^\{"status":(\d*),"id":"(.*)","hypotheses":\[(.*)\]\}$/) {
+ $response{status} = "$1";
+ $response{id} = "$2";
+ if ($response{status} == 5) {
+ die "Error reading audio file\n";
+ }
+ if ($3 =~ /^\{"utterance":"(.*)","confidence":(.*)\}/) {
+ $response{utterance} = "$1";
+ $response{confidence} = "$2";
+ }
+}
+foreach (keys %response) {
+ print STDERR "$name Setting variable: $_ = $response{$_}\n" if ($debug);
+ print "SET VARIABLE \"$_\" \"$response{$_}\"\n";
+ &checkresponse();
+}
+print STDERR "$name ", $uaresponse->content if ($debug);
+exit;
+
+sub checkresponse {
+ my $input = <STDIN>;
+ my @values;
+
+ chomp $input;
+ if ($input =~ /^200/) {
+ $input =~ /result=(-?\d+)\s?(.*)$/;
+ if (!length($1)) {
+ print STDERR "$name Command failed: $input\n";
+ @values = ("-1");
+ } else {
+ print STDERR "$name Command returned: $input\n" if ($debug);
+ @values = ("$1", "$2");
+ }
+ } else {
+ print STDERR "$name Unexpected result: $input\n";
+ @values = ("-1");
+ }
+ return @values;
+}
+
+sub int_handler {
+ die "$name Interrupt signal received, terminating...\n";
+}
+
+END {
+ if ($tmpname) {
+ print STDERR "$name Cleaning temp files.\n" if ($debug);
+ unlink glob "$tmpname*";
+ }
+}

0 comments on commit 7fd57af

Please sign in to comment.