jueves, 28 de marzo de 2013
Entrada 8: Memoria - S16&D17/03/2013
Durante este fin de semana hemos estado elaborando la memoria correspondiente al primer hito de la práctica. A diferencia del blog (este), donde estamos estructurando la práctica de forma cronológica para que cualquiera pueda ver los pasos que seguimos y el trabajo que hemos realizado, en la memoria estructuramos el proyecto por módulos. Para que podáis ver que os parece aquí os dejamos el enlace a dropbox, con la memoria en pdf:
LID on RPi: Memoria del primer hito.
martes, 26 de marzo de 2013
Entrada 7: Programa principal - V15/03/2013
A la hora de utilizar el sistema, y también pensando un tener una interfaz con el usuario, hemos decidido hacer un programa principal que vaya mostrando trazas mientras realiza el proceso completo del sistema: grabar el audio -> enviarlo al servidor -> realizar el reconocimiento del idioma -> mostrar el resultado.
Este programa lo hemos desarrollado en shell script de forma que se ejecuta en una terminal, es decir, todavía no tenemos una interfaz gráfica "bonita". A continuación mostramos el código fuente comentado del script:
#!/bin/sh # Dirección del servidor ssh server=diego@10.42.0.1 # Ruta al proyecto en el servidor LID_RPi_DIR=/home/diego/Dropbox/Universidad/SDG2_Matlab/LID_RPi # Destino del fichero de audio AUDIO_DIR=${LID_RPi_DIR}/audio # Ruta al fichero con los resultados del reconocimiento SCORES=${LID_RPi_DIR}/ivectoresMFCC/plenty_closed/results_512G_i400/plenty_closed_acus_400i_512G_WithLN_hmmHung_isEval__Albayzin_TEST.scores # Nombre del fichero de audio WAV_NAME=tmp # Configuración del micrófono amixer –c 1 sset Mic,0 100%,100% unmute cap 1>/dev/null # Grabación de la voz del usuario echo Pulse Enter para comenzar a grabar read keypress arecord –D hw:1,0 –f S16_LE –c 1 –r 8000 –B 900000 ${WAV_NAME}.WAV & >/dev/null 2>&1 echo Grabando… Pulse Enter para finalizar la grabación read keypress killall arecord 1>/dev/null # Envío del fichero de audio al servidor echo Enviando la información al servidor… scp ${WAV_NAME}.wav $server:$AUDIO_DIR >/dev/null 2>&1 || (echo “No se ha podido conectar con el servidor” && exit 1) # Actualizar la lista con el nombre del archivo para luego poder identificarlo echo Procesando… ssh $server “echo $WAV_NAME > ‘${LID_RPi_DIR}/prueba.lst’” >/dev/null 2>&1 # Ejecución del programa en el servidor ssh $server ${LID_RPi_DIR}/runAll2.sh >/dev/null 2>&1 # Muestra de los SCORES por la consola ssh $server cat ${SCORES} echo “¡Listo!”El único problema que hemos encontrado con el script es que cada vez que se realiza una conexión con el servidor te pide la contraseña, y esto no nos parecía viable ya que el usuario podría (debería) no conocer la contraseña que le da acceso a nuestro servidor. Por ello, a continuación contamos como se realiza dicha conexión en más detalle de lo que lo hicimos en la Entrada 1 y explicamos como hemos solucionado el problema de la autenticación.
Al principio decidimos usar el protocolo SSH debido a su sencillez. El nombre viene del acrónimo Secure Shell y es un protocolo de comunicaciones que permite acceder a la Shell o intérprete de comandos de una máquina a través de la red de forma encriptada. Funciona sobre TCP, asegurándonos fiabilidad, una característica a tener en cuenta, ya que vamos a enviar ficheros y necesitamos que lleguen correctamente.
Para la implementación de este protocolo, hemos utilizado openssh, que tiene dos opciones: openssh-client y openssh-server. openssh-client permite acceder a una terminal remota, mientras que openssh-server es el que permite al ordenador ser accedido de forma remota. Por tanto, para realizar la conexión Raspberry Pi <–> Servidor, será necesario tener instalado openssh-client en la Raspberry Pi (el cual, como en muchas distribuciones de Linux, ya viene incluido) y openssh-server en el servidor. Para instalar openssh-server introducimos en la terminal del servidor:
$ sudo apt-get install openssh-serverUna vez instalado openssh en ambos dispositivos, ya podemos acceder al servidor desde la Raspberry Pi y realizar las operaciones que ya mencionamos en dicha Entrada 1.
Ahora bien, como ya hemos dicho, cada vez que se ejecuta uno de estos comandos pide la contraseña del usuario con el que accedemos al servidor. Para evitar esto hay que usar claves DSA. Cuando se generan este tipo de claves, se crean dos ficheros: uno que contiene la clave pública del cliente, y la cual hay que copiar en el fichero de claves autorizadas del servidor, y otro que contiene la clave privada. El proceso que seguimos es el siguiente:
- Generar las claves dsa con el programa ssh-keygen (incluido en openssh):
$ ssh-keygen –t dsa
- Darle permisos de lectura y ejecución a todos los usuarios, y de escritura sólo al propietario a la carpeta .ssh:
$ mkdir .ssh $ chmod 755 .ssh
- Enviar la clave pública (id_dsa.pub) al servidor como authorized_keys y darle permisos de lectura y escritura al propietario:
$ scp ~/.ssh/id_dsa.pub usuario@dirección_servidor:.ssh/authorized_keys $ chmod 600 ~/.ssh/authorized_keys
Y una vez hemos realizado estos pasos ya podemos realizar todas las operaciones que soporte ssh sin que nos pidan una contraseña de validación por cada paso que demos.
domingo, 24 de marzo de 2013
Entrada 6: Resolución de problemas de ejecución - M12/03/2013
Como hemos comentado en la entrada anterior, el programa lanzaba una excepción porque intentaba acceder a unos datos vacíos. Después de un rato investigando y mirando todos los directorios
descubrimos que algunos de los archivos de datos que se generan estaban
vacíos, y al relanzar el programa no los generaba de nuevo si no que
partía de ellos.
No sabemos por qué pudo pasar esto, pero es posible que al intentar lanzar el programa cuando todavía no tenía todas las herramientas (SPro y Alize/LIA_RAL) instaladas no pudo generar estos archivos. En cualquier caso, la solución fue borrar todos estos archivos vacíos de forma que al volver a lanzar el programa, esta vez lo primero que hizo fue generarlos de nuevo.
A pesar de estos cambios seguía sin completarse la ejecución, sólo que esta vez las excepciones no nos daban mucha información de que estaba fallando. Esta vez lo que ocurría es que había una parte del código desordenado, de forma que las rutas de unos de los archivos de datos generados no cuadraban con las rutas de otra parte del programa. Así que realizamos los siguientes cambios, todos en el archivo go.testWavFileWithIVectors.sh:
En esta entrada quizá deberíamos haber puesto algún pantallazo de los errores que hemos mencionado al principio pero se nos olvidó hacerlos.
No sabemos por qué pudo pasar esto, pero es posible que al intentar lanzar el programa cuando todavía no tenía todas las herramientas (SPro y Alize/LIA_RAL) instaladas no pudo generar estos archivos. En cualquier caso, la solución fue borrar todos estos archivos vacíos de forma que al volver a lanzar el programa, esta vez lo primero que hizo fue generarlos de nuevo.
A pesar de estos cambios seguía sin completarse la ejecución, sólo que esta vez las excepciones no nos daban mucha información de que estaba fallando. Esta vez lo que ocurría es que había una parte del código desordenado, de forma que las rutas de unos de los archivos de datos generados no cuadraban con las rutas de otra parte del programa. Así que realizamos los siguientes cambios, todos en el archivo go.testWavFileWithIVectors.sh:
#La línea 273 la metemos dentro de la estructura if, entre las líneas 276 y 277: awk 'BEGIN{FS="=|\\[|]|,|{|}"} r==1{missing[$1".fea"]=1;} r==2{if(missing[$2]>0 {print $0 } }' r=1 $OUT_DIR/stats_${SUFFIX}/missing_${SUFFIX}.lst r=2 $OUT_DIR/ivec/ascii_out_${NGAUSS}G_${NIVEC}i/process_segm_test_${SUFFIX}.lst |sed 's/\.fea//g' > $OUT_DIR/stats_${SUFFIX}/stats_segm_${SUFFIX}.lstUna vez terminamos de realizar todos estos cambios volvimos a lanzar el programa, y esta vez nos decía que fallaba en la línea 34 del createNISTFileForTestFiles.pl por un command not found. Si vamos a esa línea podemos ver lo siguiente:
#En la línea 359 aparece una ruta equivocada, de forma que la línea debería ser: (cat $OUT_DIR/ivec/ascii_out_${NGAUSS}G_${NIVEC}i/generate_test.m | $matlab $matlab_executable_parameters ) 2>&1 |tee $OUT_DIR/generate_test.log
my $sTime = `soxi -D $sFilename`;Parece ser que no teníamos instalado el programa soxi, que también era necesario, por lo que instalamos todo el paquete escribiendo en la terminal:
$ sudo apt-get install soxDe esta forma hemos conseguido que ya se ejecute por completo y sin lanzar excepciones el módulo que realiza el reconocimiento del idioma, justo a 5 días de presentar la memoria del primer hito.
En esta entrada quizá deberíamos haber puesto algún pantallazo de los errores que hemos mencionado al principio pero se nos olvidó hacerlos.
lunes, 18 de marzo de 2013
Entrada 5: Problemas de ejecución: rutas - V8/03/2013
Una vez estamos en la carpeta del proyecto LID_RPi, el programa de identificación del lenguaje parte de runAll2.sh, que a su vez empieza a llamar a otros scripts. La primera vez que lo lanzamos, para ver que tal funcionaba, no llegó a ejecutarse puesto que se produjeron errores. A paritr de ahí tuvimos que empezar a hacer cambios para conseguir eliminar los fallos.
El primer cambio que tuvimos que realizar fue el de cambiar las rutas para que concordasen con nuestra estructura de directorios, así como cambiar las menciones a matlab64 por matlab, que es la versión que tenemos. De esta forma las líneas a modificar son:
Después de realizar estos cambios seguía sin completarse la ejecución, puesto que llegaba un momento en el que lanzaba una excepción un tanto extraña, puesto que intentaba acceder a unos datos vacíos. A continuación mostramos el pantallazo:
Matlab trata los datos como matrices, y al intentar acceder a una posición de un array vacío es cuando lanzaba la excepción. Tran un largo rato mirando las funciones .m en las que se lanzaba la excepción descubrimos que ahí no estaba el problema, sino que tenía que ser otra cosa la que fallaba, por lo que decidimos dejarlo para la siguiente sesión.
El primer cambio que tuvimos que realizar fue el de cambiar las rutas para que concordasen con nuestra estructura de directorios, así como cambiar las menciones a matlab64 por matlab, que es la versión que tenemos. De esta forma las líneas a modificar son:
- Dentro de runAll2.sh:
#En la línea 3 ponemos: BIN_DIR=~/Dropbox/Universidad/SDG2_Matlab/LID_RPi #Y en la línea 12: sMatlab='matlab' #Antes de la línea 22 añadimos esta línea para que se #encuentren los ficheros desde la RPi: cd $BIN_DIR
- Dentro de go.testWavFileWithIVectors.sh:
#La línea 247 deberá ser:
matlab_init="addpath(genpath('/home/diego/Dropbox/Universidad/SDG2_Matlab/LID_RPi/bin_matlab'))"
- Dentro de go.calculateScore.sh:
#En la línea 45 tiene que poner:
matlab=”matlab”
Después de realizar estos cambios seguía sin completarse la ejecución, puesto que llegaba un momento en el que lanzaba una excepción un tanto extraña, puesto que intentaba acceder a unos datos vacíos. A continuación mostramos el pantallazo:
Matlab trata los datos como matrices, y al intentar acceder a una posición de un array vacío es cuando lanzaba la excepción. Tran un largo rato mirando las funciones .m en las que se lanzaba la excepción descubrimos que ahí no estaba el problema, sino que tenía que ser otra cosa la que fallaba, por lo que decidimos dejarlo para la siguiente sesión.
sábado, 16 de marzo de 2013
Entrada 4: Compilación de herramientas. Intento de ejecución con Octave. - M5/03/2013
Para el procesado de los ficheros de audio, no sólo era necesario usar Matlab/Octave, sino que además necesitamos usar dos toolkits de procesado de audio enfocados al procesado del lenguaje: SPro y Alize.
Las funciones de estos programas son, por un lado preparar las señales que llegan, con herramientas como el detector de energía, que se encargan de eliminar las partes en las que nadie habla, y por otro de generar una serie de datos relevantes de la señal (parametrizar) que permitan posteriormente decidir a partir de estas características cuál es el idioma en el que se está hablando.
Primero instalamos SPro. Nos descargamos la versión 5.0 de la página oficial: https://gforge.inria.fr/frs/?group_id=532. Una vez descargado, seguimos las instrucciones del archivo INSTALL incluido en la carpeta del SPro:
-En una terminal, acceder a la ruta de la carpeta:
El compilador (gcc) no reconocía las funciones sqrt, cos, y sin, correspondientes a la librería matemática. Investigando lo único que encontramos fue que para que gcc importase dicha librería había que añadir al final de los comandos dentro del makefile la opción -lm. Pero eso ya estaba.
Después de un rato intentando solucionarlo, la solución fue compilar el programa en otro ordenador y con otra versión del gcc, donde no dio error, e instalarlo en el servidor. El problema, por lo visto, estaba en la versión de gcc que usamos (gcc 4.7.2), ya que compilándolo con la 4.4 no da ningún problema.
Una vez instalado SPro, pasamos a instalar Alize y LIA_RAL. El procedimiento fue el mismo que antes, utilizando los mismos comandos tras decargarnos las últimas versiones (la 2.0 en ambos) en el sitio web del programa: http://mistral. univ-avignon.fr /download.html. Sin embargo, en este caso no tuvimos ningún problema durante la instalación.
Las funciones de estos programas son, por un lado preparar las señales que llegan, con herramientas como el detector de energía, que se encargan de eliminar las partes en las que nadie habla, y por otro de generar una serie de datos relevantes de la señal (parametrizar) que permitan posteriormente decidir a partir de estas características cuál es el idioma en el que se está hablando.
Primero instalamos SPro. Nos descargamos la versión 5.0 de la página oficial: https://gforge.inria.fr/frs/?group_id=532. Una vez descargado, seguimos las instrucciones del archivo INSTALL incluido en la carpeta del SPro:
-En una terminal, acceder a la ruta de la carpeta:
$ cd ruta-Una vez en la carpeta, ejecutar el fichero de configuración y compilar el paquete:
$ ./configure $ make-Y por último, instalarlo:
$ make installY ya está... O eso parecía, pero al compilar (make), nos salía el siguiente error:
Después de un rato intentando solucionarlo, la solución fue compilar el programa en otro ordenador y con otra versión del gcc, donde no dio error, e instalarlo en el servidor. El problema, por lo visto, estaba en la versión de gcc que usamos (gcc 4.7.2), ya que compilándolo con la 4.4 no da ningún problema.
Una vez instalado SPro, pasamos a instalar Alize y LIA_RAL. El procedimiento fue el mismo que antes, utilizando los mismos comandos tras decargarnos las últimas versiones (la 2.0 en ambos) en el sitio web del programa: http://mistral.
martes, 12 de marzo de 2013
Entrada 3: Instalación de Matlab en el servidor - M26/02/2013
Para el procesado matemático de los ficheros de audio grabados, se utilizan una serie de programas que funcionan sobre Matlab. Matlab es un software matemático orientado al tratamiento de grandes datos operando con ellos como si fuesen matrices. Es una herramienta muy extendida en el procesado de señales, tanto audio, como imágenes, vídeo, etc. de ahí que sea el que utilizamos.
El problema de Matlab es que utiliza licencias privadas (no baratas, precisamente) y por tanto, hemos decidido buscar una alternativa. La más inmediata y conocida es Octave. Octave es una herramienta de software libre orientada, al igual que Matlab, al tratamiento de señales y que busca ser compatible con ésta. Instalar octave en Linux fue tan sencillo como poner en la terminal:
Para la instalación de Matlab, seguimos los pasos que se describen en el siguiente enlace:
https://help.ubuntu.com/community/MATLAB
El problema de Matlab es que utiliza licencias privadas (no baratas, precisamente) y por tanto, hemos decidido buscar una alternativa. La más inmediata y conocida es Octave. Octave es una herramienta de software libre orientada, al igual que Matlab, al tratamiento de señales y que busca ser compatible con ésta. Instalar octave en Linux fue tan sencillo como poner en la terminal:
$ sudo apt-get install octaveEn este momento comenzamos a adaptar los scripts de reconocimiento de idioma a Octave, ya que los shell scripts que se ejecutaban en el proceso de reconocimiento, llamaban a Matlab. Además, a pesar de que Octave es muy compatible con Matlab, algunas funciones concretas son distintas, por lo que tras un par de horas, intentando adaptar las funciones decidimos también instalar Matlab para verificar primero que el módulo de reconocimiento de idioma ejecuta sin errores.
Para la instalación de Matlab, seguimos los pasos que se describen en el siguiente enlace:
https://help.ubuntu.com/community/MATLAB
viernes, 8 de marzo de 2013
Entrada 2: Entrada de audio en la RPi - S23/02/2013
Para la realización de la práctica necesitamos disponer de una entrada de audio a la Raspberry, puesto que vamos a tener que realizar grabaciones de voz del usuario para realizar el reconocimiento de su idioma. La Raspberry Pi no incluye ninguna entrada de audio de serie, por lo que hay que buscar una forma alternativa de realizar la captura del audio.
Las distintas alternativas que barajamos son: utilizar un micrófono o cámara USB, grabar el sonido mediante un dispositivo Android y posteriormente transmitirlo a la Raspberry Pi, o, como última opción, utilizar los puertos GPIO y un conversor A/D para capturar la señal de un micrófono con conector mini-jack.
Puesto que la idea es llegar a tener un sistema empotrado, la primera opción que hemos probado ha sido la de utilizar un micrófono USB. Hemos usado un micrófono como los que vienen con el juego SingStar para la PlayStation 2, que tienen un conector USB. Cuando lo conectamos a la Raspberry, no sabíamos si lo había reconocido como dispositivo de entrada de audio, por lo que (después de investigar un rato) descubrimos el comando alsamixer, que muestra el control de volumen de linux.
Aquí es donde vimos que sí que había reconocido el micrófono y que lo había reconocido como dispositivo 1. Para configurar el micrófono (volumen, mute, etc) utilizamos el comando amixer de la siguiente forma
$ amixer -c 1 sset Mic,0 100%,100% unmute cap
Con esto activamos la captura de sonido de la tarjeta (-c) 1 y ponemos el volumen al 100% (en ambos canales, aunque sólo usaremos uno de ellos). Una vez configurado el micrófono, pasamos a la grabación. Desde la terminal se puede grabar usando el comando arecord. Este comando permite elegir el formato del archivo grabado.
$ arecord -D hw:1,0 -f S16_LE -c 1 -r 8000 -B 900000 "ruta_fichero/nombre_fichero.wav"
Con la opción -D seleccionamos la tarjeta 1, con -f seleccionamos una codificación Little Endian de 16 bits con signo por muestra, con la opción -c 1 indicamos que la grabación es mono, y con -r 8000 elegimos la frecuencia de muestreo a 8 kHz. Con estas opciones se producía un error por desbordamiento del buffer, por lo que además tuvimos que añadir la opción -B, que fuimos calibrando hasta tomar un valor de 900000 con el cuál no lanza errores.
martes, 5 de marzo de 2013
Entrada 1: Puesta a punto - M19/02/2013
Esta entrada se corresponde a lo que hicimos el 19 de febrero, que fue el primer día en el que empezamos a hacer cosas. Puesto que fue nuestra primera sesión de trabajo, lo que hicimios fue principalmente la puesta a punto de lo que van a ser nuestras herramientas de trabajo a lo largo de la práctica.
Lo primero que hicimos fue preparar la Raspberry Pi. A continuación os ponemos los pasos que seguimos para ello:
Para empezar tenemos que descargarnos el sistema operativo. El SO que instalamos nosotros es Raspbian, una versión de Debian orientada a la Raspberry, que se puede conseguir desde la página de descargas de la página oficial de Raspberry Pi: http://www.raspberrypi.org/downloads.
Lo siguiente que hay que hacer es instalar el sistema operativo en la tarjeta SD. Este apartado quizá tenga interés más allá de la práctica puesto que cualquiera puede querer tener su propia Raspberry. Dependiendo de si lo hacemos desde Windows o Linux habrá que seguir un método u otro:
-Desde Linux:
Ejecutamos este comando desde la terminal:
$ sudo dd if=ruta_a_la_imagen of=/dev/sdbDonde /dev/sbd es la tarjeta SD.
-Desde Windows:
Necesitamos el programa Win32DiskImager . Una vez descargado, abrimos el programa, seleccionamos la imagen, la letra que se corresponde a la tarjeta SD y le damos a Write.
Una vez instalado, sólo queda introducir la tarjeta en la Raspberry y encenderla.
Lo primero que nos preguntará será si queremos configurarla. Si queremos acceder a esta pantalla de configuración más tarde solo tenemos que usar el comando "raspi-config". De esta configuración, la opción que más nos interesa para el proyecto es la que habilita el ssh-server, lo cual nos permitirá acceder a la Raspberry desde otro ordenador y poder controlarla sin tener que depender de tener teclado y pantalla.
------------------------------------------------------------------------------------------------------------------------------
Posteriormente pasamos a la configuración del servidor. En nuestro caso esto no ha supuesto un gran trabajo puesto que vamos a utilizar un servidor que ya estaba en funcionamiento, por lo que unicamente hemos tenido que crearnos un usuario para la conexión con dicho servidor.
Por último, nos centramos en verificar que la conexión entre la Raspberry Pi y el servidor funciona y permanece operativa. Para ello usamos ssh, un protocolo de comunicación que nos permite acceder a la terminal de otro ordenador.
Los comandos ssh que nos permiten realizar el acceso remoto a una máquina, así como la transferencia de ficheros entre ambas máquinas son (respectivamente):
#Para acceder al servidor $ ssh usuario@direccion_servidor #Tras lo cual nos pedirá la contraseña de usuario #Para copiar ficheros del cliente al servidor (o viceversa) $ scp ruta_fichero usuario@direccion_servidor:ruta_destino #En este caso también nos pedirá contraseña
Antes de terminar esta entrada al blog os dejamos una foto en la que se puede observar como la Raspberry Pi ya está en funcionamiento, y se ha establecido una conexión ssh para acceder a la Raspberry:
Suscribirse a:
Comentarios (Atom)