Tenia programado escribir en dos partes, sobre ASR y ahora sobre TTS (serian las dos cara de la moneda).
Siguiendo con la linea de programacion con AGI, ahora se me ocurre la opcion de dotar de un servicio de Text To Speech a nuestro Asterisk, del nivel AT&T Natural Voices utilizando el mismo sistema que aplicamos con nuestro sistema ASR en el anterior mensaje (como es un servicio con un modelo ASP evidentemente no tendremos problemas de licencias siempre y cuando ese sistema permanezca en activo). Lo malo, claro esta, que si ese servicio se modifica (la URL por ejemplo), nos quedamos sin “negocio”. Por eso que es conveniente si el sistema lo utilizamos en produccion y somos capaces de rentabilizarlo, pasar a un sistema de TTS local en nuestro sistema.
Para mantenernos en una linea open source, tenemos la opcion de Festival, el problema es que es de muy baja calidad comparado a soluciones de pago o la que voy a proponer aqui, a traves del TTS de Google
Texto a Voz con Google TTS
Vamos manos a la obra partiendo de la base AGI voy a obviar que se hicieron todos los pasos del mensaje anterior para instalar lo necesario (php-curl, y php-agi lo mas importante), hacemos lo siguiente:
Primero vamos a descargar un sistema para convertir de MP3 a WAV.
# aptitude install lame
Vamos a crear un Script PHP en /var/lib/asterisk/agi-bin/ podemos llamarlo por ejemplo asterisk-tts.php:
#!/usr/bin/php -q
<?php
require_once(‘phpagi-2.20/phpagi.php’);
$agi = new AGI();
# Necesitamos pasarle la Cadena de Texto desde el Asterisk, y la recogemos con esta variable.
$traduccion = $argv[1];
# Aqui descargamos el fichero Mp3 haciendo pensar a Google que somos un Navegador
shell_exec(“wget –header=’User-Agent:Mozilla/4.0′ ‘http://translate.google.com/translate_tts?tl=es&q=”.$traduccion.”‘ -O /var/lib/asterisk/sounds/google-tts.mp3″);
# Y convertimos el fichero con “lame” a wav que es reconocible por Asterisk
shell_exec(“lame -h –decode /var/lib/asterisk/sounds/google-tts.mp3 /var/lib/asterisk/sounds/google-tts.wav”);
$retString = “Fin de la conversion”;
$agi->verbose($retString);
?>
Finalmente creamos una extension en nuestro DialPlan para que haga esta “gestion”:
exten => 2000,1,Answer()
same => n,Set(TTSVAR = “Lo que queramos convertir”)
same => n,AGI(asterisk-tts.php,${TTSVAR})
same => n,Playback(google-tts)
same => n,Hangup()
Y ya esta, recargamos el dialplan como siempre, y marcando la extension 2000 oiremos con una voz muy sensual: “Lo que queramos convertir” … o algo asi
Como veis la dificultad de implantacion es nula, y eso es lo que mas me ha gustado de AGI, que no hace falta estar creando aplicaciones en C-Arcaico y recompilando el Asterisk con la app_c_arcaico y podemos tener una funcionalidad semejante (aunque no nativa y para los mas sibaritas, con menos rendimiento en terminos de picosegundos). Lo que tampoco tengo muy claro es que Google este feliz que esten utilizando su TTS masivamente, aunque estoy seguro que ya habra por ahi algun Call-Center que lo este haciendo. Si tienen experiencia me gustaria que me lo comentaran.
Texto a Voz con Festival TTS
Ahora os voy a explicar como hacer lo mismo, pero con el sistema TTS Festival en local, que os comente antes, y asi podeis comparar que os gusta mas:
Festival TTS digamos que fue desarrollado por una universidad e incorporado nativamente en Asterisk, asi que eso simplifica bastante las cosas ya que existe una Aplicacion especifica para el tratamiento de Texto a Voz directamente para el dial Plan (el modulo app_festival.so). Primero tenemos que comprobar si lo tenemos preparado.
Desde el CLI> module show like festival
Si aparece algo asi como app_festival.so y “1 modules loaded”, entonces ya lo tenemos, sino, nos toca recompilar Asterisk y en la parte de make menuselect tenemos que seleccionar el app_festival antes de hacer el “make && make install”
Ahora vamos a instalar festival
#aptitude install festival
Y ahora necesitamos voces en Español. Yo vivo en Andalucia ahora mismo, asi que barriendo para casa tenemos las que usa la junta de andalucia en la forja de Guadalinex:
http://forja.guadalinex.org/frs/?group_id=21
Vamos a descargar las de Silvia, para comparar el grado de sensualidad con respecto a Isabel de Google, todo sea por motivar a nuestros clientes varones.
# wget http://forja.guadalinex.org/frs/download.php/154/festvox-sflpc16k_1.0-1_all.deb
#dpkg -i festvox-sflpc16k_1.0-1_all.deb
Y borramos el fichero de configuracion de festival que crea automaticamente, para poder utilizar mejor, el generico de Festival.
#rm /etc/festival.scm
La voz queda automaticamente instalada en la ruta:
/usr/share/festival/voices/spanish/JuntaDeAndalucia_es_sf_diphone
Ahora necesitamos modificar el archivo de configuracion de Festival por defecto ubicado en /usr/share/festival/festival.scm al final del fichero agregamos:
(set! voice_default ‘voice_JuntaDeAndalucia_es_sf_diphone)
(define (tts_textasterisk string mode)
(let ((wholeutt (utt.synth (eval (list ‘Utterance ‘Text string)))))
(utt.wave.resample wholeutt 8000)
(utt.wave.rescale wholeutt 5)
(utt.send.wave.client wholeutt)))
(set! server_access_list ‘(“localhost\\.localdomain” “localhost”))
Con esto, nos permitira por un lado utilizar la voz de Silvia y por otro lado arrancar el servidor Festival
Ahora necesitamos configurar el servidor Festival, bajamos los ficheros de desarrollo de festival
#aptitude install festival-dev
Y copiamos el fichero de autoarranque de festival a nuestro /etc/init.d para que arranque automaticamente el servidor cada vez que iniciemos nuestra maquina Asterisk:
#cp /usr/share/doc/festival/examples/festival.init /etc/init.d/festival
#chmod +x /etc/init.d/festival
Antes de arrancar el servidor de Festival, necesitamos añadir una linea en /etc/default/festival:
RUN_FESTIVAL = yes
Y ahora si podemos arrancar el servidor Festival con exito:
/etc/init.d/festival start
Y para que arranque cada vez que iniciamos el sistema:
#ln -s /etc/init.d/festival /etc/rcS.d/S99festival
Ya esta todo casi listo, solo nos queda la parte mas facil, crear una extension en el DialPlan para ejectuar la aplicacion Festival
exten=> 3000,1,Answer()
same => n,Festival(Lo que queramos convertir)
same => n,Hangup()
Recargamos el dialplan como siempre y si marcamos la extension 3000, tendremos a Silvia dandonos el resultado.
Algunas cosas curiosas que he observado.
La version 1.0-1 de Guadalinex para Pedro parece que esta mal empaquetada. Instala sobre la version de Silvia (es_sf) en vez de (es_pa)
Se puede resolver de varias formas, una es, bajando las fuentes (Archivos de desarrollo de la voz de Pedro) en el directorio correspondiente /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone
Necesitamos desempaquetar tambien el .deb de Pedro con el comando “ar” (#ar x festvox-palpc16k_1.0-1_all.deb)
Y luego descomprimir data.tar.gz y a traves de la estructura de directorios llegar a …/usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group
Cambiamos el nombre al fichero que hay y lo copiamos a un nuevo directorio group dentro de nuestro directorio de Pedro antes creado
#mkdir /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group
#mv sflpc16k.group /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group/palpc16k.group
O lo ideal si a alguien le interesa que arregle ese fichero deb, no voy a ser yo, porque no me gusta demasiado.
Si tuviera que elegir personalmente un fichero para Festival en Español, eligiria de hecho, el fichero por defecto de festvox en español (el_diphone) que es el que mejor se entiende para mi gusto, aunque es voz masculina asi que no podriamos comparar bien para este ejemplo.
Se puede descargar y configurar siguendo los mismos pasos que antes, pero en el idioma por defecto poner “voice_el_diphone”
# aptitude install festvox-ellpc11k
Ahora puestos a comparar entre Festival TTS y Google TTS, creo que no hay color, pero para gustos los colores. Espero vuestras experiencias en el mundo del TTS.

1. Comment by Edu
16/dic/2011 at 00:25
Hola, lo primero gracias por el blog, las excelentes explicaciones y la impecable programación. Necesitaba utilizar el TTS de Google para una aplicación y este artículo me ha servido de mucha ayuda. He tenido algunos problemas que he resuelto de la siguiente manera:
1 – Además de instalar “php-curl” y “php-agi”, he tenido que instalar “php5″, para poder ejecutar el script php
2 – El shell_exec(wget) no me descargaba el mp3 tal como está redactado en el artículo, lo he cambiado por:
shell_exec(‘wget -q -N -U Mozilla -O ../var/lib/asterisk/sounds/google-tts.mp3 “http://translate.google.com/translate_tts?tl=es&q=’.$traduccion.’”‘);
ojo! el -N es importante si se quiere sobreescribir el mp3 varias veces
3 – El “wav” generado por lame no lo reproducía el asterisk, así que he utilizado ffshow y va de lujo:
shell_exec(“ffmpeg -v 0 -y -i ../var/lib/asterisk/sounds/google-tts.mp3 -ab 32 -ar 8000 ../var/lib/asterisk/sounds/google-tts.wav”);
-y para sobreescribir sin preguntar
Saludos!
2. Comment by SirLouen
16/dic/2011 at 19:33
Hola Edu, te comento
1. Sobre el tema del php5, como este mensaje venia un poco relacionado a articulos anteriores, sobreentendia que php5 ya estaba instalado en el sistema, porque yo recomiendo instalar el paquete LAMP (aunque luego mysql o apache no se usen, como estan “vacios” tampoco es que sea significativo su consumo, aunque efectivamente no es obligatorio, y como comentas, con php5 es suficiente para este ejemplo
2. Tengo que probar de nuevo eso del shell_exec porque la verdad es que como me funciono a la primera, tampoco hice muchas mas pruebas intensivas.
3. A mi me me reproducia sin problemas en wav generado por lame. Quiza haya alguna incompatibilidad con codecs, quiza sea por version de Asterisk o algo asi. De todas formas pondre tu solucion de ffshow como alternativa para prevenir como posible inconvencia
Gracias por todos los comentarios
Saludos
3. Comment by Edu
17/dic/2011 at 17:35
Ah, y un truquito más, para que TTS de google pronuncie bien las eñes y caracteres especiales! desde el script php:
shell_exec(‘wget -q -N -U Mozilla -O ../var/lib/asterisk/sounds/google-tts.mp3 “http://translate.google.com/translate_tts?tl=es&ie=UTF-8&q=’.urlencode($traduccion).’”‘);
Así me funcionó a mi.
4. Comment by Ricado
16/feb/2012 at 18:26
Gracias por el tutorial !!!
Habéis probado el googletts.agi?
http://zaf.github.com/asterisk-googletts/
5. Comment by SirLouen
17/feb/2012 at 18:56
Si es curioso Ricardo, lo vi en el blog del Elio Rojano. El primer commit lo hicieron el dia 27 de noviembre y yo escribi este articulo el 9 de diciembre. Se ve que nos iluminamos casi al mismo tiempo el Lefteris Zafiris y yo, aparte que el lo hizo mucho mas bonito con un repositorio Git
Lo que sigo preguntandome es hasta que punto Google disfruta con todo esto.