En esta prctica diseamos un medidor de volumen sencillo. El volumen de una seal de audio est directamente relacionado con la intensidad de seal sonora. Vamos, a mayor volumen, mayor intensidad.
Conocer el valor del volumen instantneo puede ser til para saber si estamos provocando un clipping de la seal digitalizada al salirnos del rango dinmico del quantificador. El clipping es una forma indeseable de distorsin que provoca una gran cantidad de altas frecuencias.
Suponiendo que estamos usando un micrfono para registrar un sonido, para evitar el clipping podemos hacer dos cosas. La primera es alejar el micrfono de la fuente de sonido y la segunda reducir la ganancia del canal de entrada (al que tenemos conectado el micrfono). En ambos casos el resultado ser semejante (si no hay ruido sonoro en el entorno del micrfono).
Java es un lenguaje de programacin creado por Sun Microsystems Inc.. Su invencin y uso son relativamente recientes, y se utiliza fundamentalmente porque su vasta biblioteca de objetos son capaces de realizar una gran cantidad de tareas. En nuestro caso vamos a aprovecharnos de su potencia para el diseo de interfaces grficos.
Java es un lenguaje que sigue la filosofa de la programacin orientada a objetos. De hecho, en Java casi todo es un objeto excepto los tipos de datos primitivos (que no lo son por motivos de eficiencia).
Un objeto es una coleccin de estructuras de datos (simples o compuestas por otras) y un conjunto de mtodos. Adems, en Java es muy corriente usar la herencia, por lo que estos mtodos (funciones miembro) y estructuras de datos pueden estar declaradas en algn punto superior dentro de la jerarqua de clases.
Los objetos (instancias de las clases) se crean siempre de forma dinmica y se llaman unos a otros (o mejor dicho, desde los mtodos de unos se invocan a los mtodos de otros), comenzando siempre por el que contiene el mtodo main. Por tanto, un programa escrito en Java tiene la siguiente estructura genrica:
En Java se referencia a una clase dentro de la jerarqua de clases usando la directiva import. Esto tiene que hacerse para cada clase referenciada, si es que esta no se define en el directorio en el que se ejecuta la aplicacin o en la variable de entorno que indica qu directorios debe recorrer la mquina virtual a la hora de ejecutar la aplicacin.
Para el que nunca ha programado en Java este apartado le ser de utilidad. La teora es bastante simple: (1) escribir el programa segn la sintaxis del programa, (2) compilarlo y (3) ejecutarlo. Bueno, hasta aqu todo bastante sencillo. Sin embargo, hay que tener en cuenta que realmente:
La razn de usar una mquina virtual es que as, el cdigo code-byte se puede ejecutar en cualquier computadora que disponga de una mquina de Java. De esta forma generamos cdigo “ejecutable” totalmente portable.
Java (al igual que el C o el C++, por ejemplo) puede manejar dos flujos de datos llamados entrada y salida estndar. Estos flujos se redirigen entre procesos a nivel del shell de Unix usando el smbolo |, llamado normalmente “pipe”. Dicho smbolo indica que vamos a conectar la salida estndar de un proceso (el que se referencia a la izquierda del pipe) a la entrada estndar de otro (el que se llama a la derecha). Los pipes son canales de comunicacin entre procesos buffereados lo que significa que la transferencia se produce por bloques de datos de un determinado tamao (4 Kbytes tpicamente), aunque nosotros transfiramos bloques de un tamao diferente.
El medidor de volumen es un programa escrito en Java llamado VolMeter. Es un bucle sin fin que lee la entrada estndar y calcula el valor mximo (en valor absoluto) para cada canal de un conjunto de muestras. Este valor mximo es el que se utiliza para pintar las columnas con los volmenes.
VolMeter acepta una secuencia RAW (sin cabecera) de muestras a travs de entrada estndar. Debe tratarse de una secuencia de muestras de 16 bits, con signo, en formato little endian (el usado en las mquinas Intel). Se esperan dos canales.
VolMeter slo acepta un parmetro de entrada desde la lnea de comandos: el tamao del buffer de audio. Con l controlamos el nmero de muestras a las que se le calcula el mximo antes de calcular el valor del volumen.
La nica salida del programa es una ventana con una doble columna con el volumen de cada canal de la seal. La ventana es redimensionable.
Compilar un programa escrito en C o en Java es muy sencillo a travs del intrprete de comandos. Basta con invocar al compilador correspondiente y con los argumentos adecuados. Tras la compilacin generaremos un fichero que puede ser ejecutado directamente por la computadora (en el caso del C) o interpretado por una mquina virtual (en el caso del Java).
El nico inconveniente que tiene compilar usando shell es que en muchas ocasiones escribimos exactamente lo mismo. Para ayudarnos en esta tarea se utiliza el programa make. Este programa ejecuta los comandos interactivos escritos en un fichero llamado Makefile. Dicho fichero tiene una estructura muy simple:
As, cuando escribamos:
el programa make comprobar si objetivo es ms viejo (atendiendo a la fecha de la ltima modificacin de los ficheros) que alguna de sus dependencias y si as es, ejecutar los comandos para conseguir objetivo. Como veremos, los objetivos pueden ser ficheros u objetivos que generen ficheros (como el objetivo all).
Ntese que el objetivo jar genera un fichero .jar que contiene las clases (en este ejemplo slo una) y un fichero de configuracin almacenado en meta-inf/manifest.mf. El conenido de este fichero es:
La idea de generar un fichero .jar se debe a que en ocasiones (aunque no en esta,) los programas en Java generan muchas clases. Una forma de agruparlas en un nico fichero (y de paso, comprimirlas porque un .jar es idntico a un .zip) es hacer este proceso.