martes, 13 de marzo de 2012

Primer Paso



Nombre de la aplicación: “Audio Sense”.

Primer objetivo: Comprender como se graba, a través del micrófono del móvil, en la RAM del terminal android, comprobando como se lleva a cabo ese proceso para luego saber tratar la señal adecuadamente, llegando finalmente a las vibraciones.

La finalidad de este primer “paso”  era llegar a tener un programa que grabase nuestra voz al darle a un botón (botón de comenzar), y después al volverle a dar al mismo botón (botón de terminar) dejase de grabar y reprodujese  lo grabado justo a continuación.

El primer paso fue crear la interfaz gráfica del programa con un botón que tuviese dos “posiciones”, una para empezar a grabar (comenzar) y otra para terminar de grabar y que reprodujese al instante (terminar). También añadimos otro botón para salir de la aplicación.


Configuramos los buffers, tanto el de grabación como el de reproducción, que son almacenados en la RAM del terminal. El buffer de grabación tiene una frecuencia de muestreo de 8 kHz, es decir, para tomar 8000 muestras por segundo. Cada muestra la configuramos para que esté codificada en 16 bits-PCM.

Después de toda la configuración de buffers y creación de botones, nos metimos ya en el proceso de grabación y reproducción.

La primera opción que propusimos fue que grabase como máximo durante 20 segundos. El  inicio de esta grabación era la pulsación del botón COMENZAR, y la finalización de la grabación era la pulsación del botón TERMINAR y a continuación de ésta reproducir lo grabado. La idea era que si el intervalo entre ambas pulsaciones superaba los 20 segundos, no influyese ya que el terminal dejaría solo de grabar al cubrir esos 20 segundos y la pulsación del botón terminar solo indicaría el inicio de la reproducción.

Esto lo implementamos mediante el método “read” de la clase AudioRecord. El problema que tenía esta implementación era que el programa se quedaba los 20 segundos esperando hasta que grabase todo y después lo reproducía. Por lo tanto solo teníamos la posibilidad de grabar 20 segundos sin poder nosotros decidir el fin de la grabación. Por tanto decidimos enfocarlo desde otro punto de vista.

 Lo siguiente que intentamos fue recoger los datos de la señal de audio (grabación) con menos bits . Por ejemplo, en vez de coger los 20 segundos como bloque de bits, los cogíamos por bloques de bits de contenido las muestras  de un segundo. Una vez implementado nos dimos cuenta que esta tampoco era la solución, ya que lo que necesitábamos era crear un segundo hilo para que la grabación se hiciese en segundo plano, mientras que en el primer plano se controlaba las pulsaciones de botones.

Para implementar esto, hicimos uso de una subclase llamada AsyncTask, capaz de crear un segundo hilo y que la grabación se hiciese en ese segundo plano.

Conseguimos que se grabase la voz el tiempo que queríamos nosotros pero reproducía durante los 20 segundo en vez de reproducir solo lo que habíamos grabado, sonando vacío en los huecos sin grabar.

Al final la solución definitiva fue crear un array bidimensional para que en cada “fila” del array se vaya guardando lo grabado por el micrófono de forma que cogemos pequeñas muestras de tantos bits como “columnas” del array. Además esta solución en vez de reproducir al terminar  de grabar, lo que hicimos fue reproducir cada “fila” del array una vez guardado la muestra en ella consiguiendo  el efecto de reproducción en tiempo real, dado el pequeño de éstas.

Por tanto la implementación final de éste módulo es todo lo explicado en el párrafo anterior en un segundo hilo gracias a la subclase Asynctask junto a la creación de botones y buffers y “tratamiento” de botones en un primer hilo (actividad principal).  

 Al pulsar el botón de COMENZAR,  la aplicación nos asiente la pulsación mediante el mensaje “grabando” y  al igual cuando pulsamos el botón de TERMINAR  mediante el mensaje “terminando”.

El aspecto final de la aplicación hasta ahora es el siguiente:





No hay comentarios:

Publicar un comentario