Verbio es un sistema de reconocimiento y síntesis de voz (ASR y TTS) independiente del locutor. Mediante un AGI podemos llamar a Verbio para así crear un IVR controlado mediante voz en vez de marcaciones.
Usando las diferentes gramáticas que nos ofrece Verbio o las creadas por nosotros mismos, podemos reconocer teléfonos, DNI, nombres y lo que se nos ocurra. Esto permite una interacción mucho más natural con nuestra centralita Asterisk que la típica marcación para navegar un menú.
Supondremos Verbio instalado y configurado ya en nuestro servidor por lo que no hablaremos de la configuración de Verbio. Eso sería material de otro artículo.
Un ejemplo sencillo: La centralita da un mensaje de bienvenida a una llamada entrante. Pide el nombre de Juan o de Pepe para transferir a la extensión adecuada o se disculpa y pide de nuevo el nombre si no ha entendido lo dicho.
DIALPLAN:
exten => 888,1,NoOp(Llamada entrante)
exten => 888,n,Playback(bienvenido_diga_nombre)
exten => 888,n,Goto(889,1)
exten => 889,1,AGI(ASR.agi|nombres.txt|ISOLATED|2|5000)
exten => 889,n,GotoIf($[$[${VASR_RESULT} != ERROR] & $[${VASR_SCORE}>${UMBRAL}]]?400,1:401,1)
;
;Si no hay error en el reconocimiento
;si juan vete a juan y si no vete a pepe
exten => 400,1,n,GotoIf($[${VASR_RESULT} = JUAN]?200,1:201,1)
;
;Si hay error en el reconocimiento disculpas y vuelve al ASR
exten => 401,1,Playback(no_he_entendido_repita)
exten => 401,n,Goto(889,1)
;
exten => 200,1,NoOp(Extension de Juan)
exten => 201,1,NoOp(Extension de Pepe)
;
;si queremos tts
exten => xxx,1,AGI(TTS.agi|es|laura|Hola mundo hoy es ${DIA_DE_LA SEMANA})
El ASR.agi es un script que recibe como parámetro el tipo de gramática así como el fichero de gramática que vamos a usar. De esta forma, podemos usar el mismo AGI para interpretar nombres, números…
Su funcionamiento es muy simple: Graba lo que el usuario ha dicho, ejecuta el cliente de verbio para ASR y devuelve el valor reconocido así como una puntuación que nos indica lo fiable que ha sido el reconocimiento. Estos valores son los que utilizamos en el dialplan para saltar a una u otra extensión.
ASR.agi:
-
#!/usr/bin/perl
-
use strict;
-
#
-
$|=1;
-
#
-
# Setup some variables
-
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
#
-
#
-
#Recogemos las cosas que nos pasa asterisk
-
while() {
-
-
-
if (/^agi_
(w+
):
s+
(.*
)$/
) {
-
$AGI{$1} = $2;
-
}
-
}
-
#
-
#Ahora unas cuantas variables mas
-
my $uid = "$AGI{uniqueid}";
-
my $ruid =
sprintf("%d",
$uid);
#%d signed int, %u unsigned int
-
my $asr_cfg = "es";
-
my $lang = "es";
-
my $voc_file = $ARGV[0];
-
my $gram_type = $ARGV[1];
-
my $rectime = $ARGV[3];
-
my $vf2t_cmd = "verbiof2t";
-
my $result = 0;
-
my $basedir = "/var/lib/asterisk/verbio";
-
my $vf2tpath = "/usr/bin";
-
my $verbiowavedir = "audio";
-
my $myrecpath = "$basedir/$verbiowavedir";
-
my $voc_path = "$basedir/gram";
-
my $myrecfile = "verbio-rec-$ruid";
-
my $codec = "alaw";
-
my $skip = "0";
-
my $silence = $ARGV[3]
-
my $offset = "0";
-
my $voxserver = "127.0.0.1";
-
#
-
#
-
#Vamos a grabar lo que se dice
-
print STDERR "Empezamos a grabarn";
-
print "RECORD FILE $myrecpath/$myrecfile $codec $stoprec $rectime $offset $playbeep s=$silence n";
-
my $result = <STDIN> ;
-
#
-
#
-
# Creamos el comando de reconocimiento
-
my $comando = "/usr/bin/verbiof2t -l $lang -g $voc_path/$voc_file -t $gram_type -f $myrecpath/$myrecfile.$codec -c $codec -d $ruid -s $voxserver -k $skip";
-
#ahora ejecutamos el comando
-
-
my $result = <STDIN> ;
-
#
-
open VF2T,
"$comando |" or die "Error en ejecucion del cliente verbio";
-
my $data = ;
-
my @datax =
split(‘:_##_:’,
$data);
-
-
#
-
my $exit_value=$? >>8;
-
if( $exit_value != 1)
-
{
-
print "SET VARIABLE VASR_RESULT \"ERROR\"n";
-
unlink($myrecpath.
"/".
$myrecfile.
".".
$codec);
-
-
}
-
#
-
#
-
#Quitar espacios de las variables
-
-
-
-
#
-
#Redondeo del score
-
$datax[2] =
sprintf("%d",
$datax[2]);
-
#
-
#Seteamos las variables de asterisk
-
print "SET VARIABLE VASR_INDEX $datax[0]n";
-
print "SET VARIABLE VASR_RESULT $datax[1]n";
-
print "SET VARIABLE VASR_SCORE $datax[2]n";
-
#
-
#
-
print STDERR "ASR terminadon";
-
#
-
#borramos ficheros temporales y salimos
-
unlink($myrecpath.
"/".
$myrecfile.
".".
$codec);
-
Se puede ver que el script setea las variables VASR_RESULT con el resultado del ASR y VASR_SCORE con la puntuación obtenida. En el dialplan se comprueba que el resultado no sea ERROR y que la puntuación supere un cierto umbral de fiabilidad para que el ASR se considere correcto.
En este ejemplo hemos usado el tipo de gramática ISOLATED y un fichero de gramática nombres.txt. EL fichero de gramática es muy sencillo: Es un fichero de texto con las salidas del ASR asociadas a las entradas esperadas y separadas mediante un tabulador:
NOMBRES.TXT:
JUAN juan
PEPE pepe
Es importante observar, que sea cual sea la entrada del usuario, Verbio lo interpretará como una de las entradas esperadas y por lo tanto, aunque se diga patata, Verbio nos devolverá JUAN o PEPE. Naturalmente, la puntuación del reconocimiento será menor y podemos dar por inválido el reconocimiento en el dialplan al no haber superado ${UMBRAL}.
El valor de UMBRAL es algo que se ha de estimar después de hacer pruebas, pero un valor de 25-30 para una gramática ISOLATED de este ejemplo es una buena aproximación.
La parte del TTS es casi idéntica a la de ASR: Un script que genera un fichero de audio a partir del texto que se le pasa como parámetro y que lo reproduce.
TTS.agi:
-
#!/usr/bin/perl
-
use strict;
-
#
-
$|=1;
-
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
#
-
#
-
#Recogemos las cosas que nos pasa asterisk
-
while() {
-
-
-
if (/^agi_
(w+
):
s+
(.*
)$/
) {
-
$AGI{$1} = $2;
-
}
-
}
-
#
-
#Ahora unas cuantas variables
-
my $uid = "$AGI{uniqueid}";
-
-
my $language = $ARGV[0];
-
my $speaker = $ARGV[1];
-
my $text = $ARGV[2];
-
my $textfile = "verbio-tts-$ruid.txt";
-
my $wavefile = "verbio-tts-$ruid";
-
my $result = 0;
-
my $basedir = "/var/lib/asterisk/verbio";
-
my $verbiowavedir = "audio";
-
my $verbiotextdir = "text";
-
my $text2filedir = "/usr/bin";
-
my $vt2f_cmd = "verbiot2f";
-
my $voxserver = "127.0.0.1";
-
my $codec = "alaw";
-
my $sounddir = "$basedir/$verbiowavedir";
-
my $textfiledir = "$basedir/$verbiotextdir";
-
#
-
#
-
# Vamos a crear un fichero de texto con los parametros que nos pasa el asr por medio de asterisk
-
open(fileOUT,
">$textfiledir".
"/$textfile");
-
-
-
#
-
#Generamos el fichero audio para poder reproducirlo
-
my $comando = $text2filedir."/$vt2f_cmd -l $language -k $speaker -t $textfiledir/$textfile -f $sounddir/$wavefile -c $codec -d $ruid -s $voxserver";
-
-
#
-
#
-
my $filetoplay = $sounddir."/".$wavefile;
-
print "STREAM FILE $filetoplay \"#\"n";
-
#
-
Con esto ya tenemos una implementación sencilla de Verbio integrado en Asterisk. Hacer un menú personalizado, mejorar los TTS con el uso de variables y usar diferentes gramáticas es trivial a partir de este punto.
Para terminar con este post sólo queda comentar lo bueno y lo malo de mis primeras experiencias con Verbio y Asterisk.
LO BUENO:
- Verbio es independiente del locutor y no requiere entrenamiento previo para reconocer voces en un ASR.
- El reconocimiento tiene muy buen desempeño en ficheros de gramática pequeños.
- El servicio técnico de Verbio ha sido sencillamente genial en cada llamada que le hemos hecho con dudas y problemas.
- Desarrollado por empresa catalana, verbio ofrece gramáticas para castellano, euskera, gallego y catalán entre otras.
LO MALO:
- Las gramáticas buit-in de Verbio no se han comportado tan bien como la ISOLATED. En concreto, la de telefonía, aunque reconoce muy bien el número dado, no devuelve un score fiable.
- La documentación que viene con Verbio es insuficiente y anticuada.
- Los paquetes debian que hemos usado eran rpm “alienizados”. Faltaba una librería que hubo que pedir al servicio técnico de Verbio.
- Verbio no es software libre.
CONCLUSIONES
Por las pruebas que hemos hecho, se puede usar verbio para un IVR controlado por voz o para recoger datos de clientes que llamen para dejarlos (un concurso o una reserva de billetes por ejemplo) siempre y cuando haya una extensión con un operador humano que coja las llamadas fallidas.
Hemos comprobado que muy por encima del error técnico (fallos de reconocimiento o de la centralita) esta el error social: Mucha gente no se siente cómoda hablando con un operador artificial y no hace caso de las instrucciones, por muy sencillas que estas sean; esta gente ha de tener el recurso de poder acceder a un operador humano. Aún no se puede dejar todo en manos de la máquina.
ACTUALIZACIÓN: Ahora ya hay una forma de usar verbio directamente desde dialplan sin necesidad de usar AGIs. En este mismo blog se puede encontrar una entrada al respecto.
Te ha gustado? Compartelo: