Audio en Java Parte II
Audio en Java Parte II
Audio en Java Parte II
acerca de los dispositivos que hayan sido instalados y de sus capacidades. Ofreciendo varias formas para reportar los componentes de audio disponibles y los programas puedan acceder a ellas. La clase AudioSystem. Esta clase es til para los programas ya que se usa como punto de entrada para acceder a los recursos de audio. Enseguida se muestran algunos de los recursos de audio que una aplicacin podra obtener de la clase AudioSystem: MEZCLADORES Un sistema podra tener mltiples mezcladores, aunque usualmente hay una entrada de audio y una salida. La clase AudioSystem ofrece la lista de todos los mezcladores instalados. LINEAS Aun cuando cada lnea est asociada con un mezclador, un programa de aplicacin puede obtener directamente la lnea desde AudioSystem, sin tratar explcitamente con mezcladores. CONVERSIONES DE FORMATOS. Un programa de aplicacin puede usar los formatos de conversin para trasladar datos de audio desde un formato a otro. ARCHIVOS Y FLUJOS. La clase AudioSystem ofrece mtodos para transportar los archivos de audio en los flujos de audio. Tambin puede reportar el formato de un archivo de sonido y puede escribir archivos en diferentes formatos.
INFORMACION DE OBJETOS Varias de la API de sonido de java ofrecen informacin til acerca de sus interfaces asociados, por ejemplo: Mixer.Info Ofrece detalles acerca del mezclador instalado. Tal como vendedor nombre, descripcin, versin, etc. Line.Info Obtiene la clase de una lnea especfica. Las subclases de LineInfo incluyen Port.Info y DataLine.info, las cuales obtienen detalles relevantes de un puerto especfico y su lnea de datos respectiva.
OBTENIENDO UN MEZCLADOR. Generalmente una de las primeras cosas que un programa (que usa la API de sonido de java) lo que necesita hacer primero es obtener un mezclador o al menos la lnea de un mesclador, de modo que pueda leer o enviar sonido en la computadora, su programa podra necesitar un mezclador especifico
IVAN ANGUIANO 4-6 (ya revisado) o tal vez deseara exhibir la lista de todos los mezcladores disponibles para que el usuario pueda seleccionar uno La clase AudioSystem ofrece el siguiente mtodo: static Mixer.Info[] getMixerInfo(); Cada objetoMixer.Info regresado por el mtodo identifica algn tipo de mezclador que est instalado (usualmente un sistema tiene al menos un mezclador de algn tipo dado o ms de un tipo) el programa de aplicacin puede interar en los objetos de Mixer.Info, para encontrar el apropiado de acuerdo a sus necesidades. La clase Mixer.Info incluye las siguientes cadenas que permiten identificar el tipo de mezclador
*Nombre *Versin *Vendedor *Descripcin Una vez que un mezclador apropiado es encontrado el programa de aplicacin invoca al siguiente mtodo de la clase AudioSystem para obtener el mezclador deseado. static Mixer getMixer(Mixer.Info info) Si necesita un mezclador que pueda escribir sus datos de audio mezclados en un cierto nmero de lneas de datos destino simultneamente, buscara en cada mezclador con el mtodo int getMaxLines (Line.Info info) Aqu el Line.Info debe especificar un TargetDataLine (Linea de datos destino).
Obteniendo una lnea del tipo deseado. Hay dos formas de obtener un linea: *Directamente desde el objeto AudioSystem *De un mezclador que haya obtenido previamente del objeto AudioSystem.
Se asume que no ha obtenido un mezclador y su programa es tan simple que solo necesita un cierto tipo de lnea, los detalles del mezclador no le interesan puede usar el mtodo de AudioSystem.
(ya revisado)
El cual es semejante a getMixer visto previamente. En ambos mtodos, el argumento almacena informacin acerca de la clase o lnea deseada. Line.Info es una clase abstracta, de modo que se deben usar las subclases (PortoInfo o DataLine.Info) para obtener una lnea. El siguiente cdigo usa la subclase DataLine.Info para obtener y abrir una lnea de datos destino: TargetDataLine line; DataLine.Info info= new DataLine.Info (TargeTDataLine.class, format); // format es un objeto AudioFormat If (!AudioSystem.isLineSupported (info)) { //manipular el error } //obtener y abrir la lnea try { line=(TargetDataLine)AudioSystem.getLine(info) ; line.open(format); } catch (LineUnavarialableException ex) { //gestionar el error
} El cdigo anterior obtiene un objeto TargetDataLine sin especificar ningn atributo que no sea la clase y el formato del audio. Puede usar cdigo semejante para obtener otro tipo de lneas. Para un SourceDataLine o un clip, solo sustituya la clase TargetDataLine como la clase de la lnea variable, y tambin en el primer argumento del constructor DataLine.Info . Para puerto, puede usar instancia esttica de Port.Info semejante a lo siguiente: If (AudioSystem.isLineSupported(Port.Info.MICROPHONE) { try { line=(Port)AudioSystem.getLine(Port.Info.MICROPHONE); } } Observar el uso del mtodo isLineSupported para saber si el mezclador aun tiene una lnea del tipo deseado. Puede usar los siguientes mtodos de AudioSystem para aprender ms acerca de las lneas fuente y destino del tipo especificado que
(ya REVISADO)
son soportados por cualquier mezclador instalado. static Line.Info[] getSourceLineInfo(Line.Info info) static Line.Info[] getTargetLineInfo(Line.Info info)
Observe que los arreglos devueltos para cada uno de estos mtodos indican tipos nicos de lneas, no necesariamente todos las lneas. Por ejemplo si dos lneas de un mezclador o dos lneas de diferentes mezcladores, tienen objetos idnticos Line.Info, las dos lneas sern representadas por un solo Line.Info en el arreglo devuelto. Obteniendo una Lnea desde un Mezclador. La interface Mixer incluye variaciones en los mtodos acceso de AudioSystem para lneas fuente y destino. Los mtodos de Mixer incluyen los que toman el argumento Line.Info como lo hacen los mtodos de AudioSystem. Sin embargo, Mixer tambin incluye sus variantes, los cuales no toman argumentos: Line.Info[] getSourceLineInfo() Line.Info[] getTargetLineInfo() Estos metodos regresan arreglos de todos los objetos Line.Info para mezcladores particulares. Una vez que ha obtenido los arreglos, puede iterar sobre ellos, llamando el mtodo getLine de Mixer para obtener cada lnea, seguido por el mtodo de apertura de lnea para reservar el uso de cada lnea para su programa. Seleccionando Puertos de Entrada y Salida. Se pueden obtener todos los puertos de entrada y salida pasando el objeto Port.Info a los mtodos de AudioSystem (o Mixer) getSourceLineInfo y getTargetLineInfo que toman el argumento Line.Info. Para iterar el arreglo de los objetos devuelto e invocar al mtodo getLine de Mixer para obtener cada puerto. Puede abrir cada puerto llamado al mtodo open de la Linea. Al abrir el puerto le permitir tomar o enviar sonido al puerto.
Se recomienda no abrir o cerrar puertos a menos que el programa responda a las necesidades de los usuarios, respetando la configuracin que el usuario o sistema operativo tiene previamente seleccionado.
(ye revisado)
No es necesario abrir o cerrar puertos antes de que el mezclador est conectado para trabajar correctamente. Por ejemplo puede empezar a reproducir sonido hacia la salida de audio del mezclador, aun cuando todos los puertos estn cerrados. Los datos fluirn hacia el mezclador, la reproduccin no ser bloqueada, el usuario no escuchara nada, tan pronto como el usuario abra el puerto, el sonido ser escuchado a travs del puerto en la posicin que haya alcanzado la reproduccin en ese momento. Puede invocar al mtodo getTargetLineInfo para ver si tiene puertos de salida, no hay razn para acceder a los puertos a menos que desee cambiar su configuracin (tal como cambiar su estado abierto o cerrado, o la configuracin de cualquier otro control que puedan tener). Permiso para Usar los Recursos de Audio. La API de sonido de java incluye una clase AudioPermission que indica los tipos de acceso de una applet (o una aplicacin que este corriendo de forma segura) pueda tener muestras de audio del sistema. El permiso para grabar audio es controlado de forma separada. Este permiso debera ser garantizado con cuidado, para llegar a prevenir escuchas a escondidas no autorizadas. Por default, los applets y aplicaciones tienen los permisos siguientes: Un applet corriendo con el manejador de seguridad puede reproducir pero no puede grabar audio. Una aplicacin corriendo sin el manejador de seguridad puede reproducir y grabar audio.
Una aplicacin corriendo con el manejador de seguridad default puede reproducir pero no grabar audio En general, los applets corren bajo el escrutinio de un manejador de
seguridad que no les permite grabar sonido. Las aplicaciones por otro lado no instalan automticamente un manejador de seguridad y son capaces de grabar sonido. Sin embargo, si el manejador de seguridad de default es invocado explcitamente por una aplicacin a la aplicacin no se le permitir grabar sonido. Las aplicaciones y applets pueden grabar sonido aun cuando corran con el manejador de seguridad si
(ya revisado)
les ha sido garantizado explcitamente el permiso de hacerlo. Su un programa tiene permiso para grabar o reproducir sonido, una excepcin ser lanzada cuando intente abrir una lnea. Su programa no tendr nada que hacer ms que atrapar la excepcin y reportar el problema al usuario porque los permisos no pueden ser combinados desde la API(si esta pudiera hacerse desde la API nadie estara seguro). Generalmente los permisos son establecidos en una o ms de las polticas de configuracin de archivos, las cuales un usuario o administrador del sistema pueden editar usando un editor de texto o el programa PolicyTool. REPRODUCCIENDO AUDIO La API de sonido de java est diseada para ayudar a los programas de aplicacin a reproducir sonidos suavemente y de forma continua, aunque sean sonidos muy grandes. Existen dos tipos de lneas que pueden usar para reproducir sonido: un Clip y un SourceDataLine.
La primera diferencia entre las dos es que con un Clip puede especificar todos los datos del sonido a la vez, antes de su reproduccin; mientras que con el SourceDataLine. Tendra que escribir nuevos buffers de datos continuamente durante la reproduccin. Hay varias situaciones en las cuales usted debera usar un clip o un SourceDataLine, los siguientes criterios le ayudaran a identificar cual tipo de lnea es mejor para una situacin particular: *Use un Clip cuando no tenga datos de sonido en tiempo real que puedan ser precargados en la memoria. Por ejemplo si usted leera un archivo pequeo de sonido dentro de un Clip, si desea repetir o colocar en una posicin arbitraria, etc. La interface Clip ofrece mtodos para realizar esto fcilmente en otras palabras, porque los sonidos son precargados dentro de un Clip, la reproduccin puede empezar inmediatamente en lugar de tener que esperar a que un buffer este lleno. *Usar un SoucerDataLine. Para un archivo de sonido el cual es
ADAN 19-21
(ya revisado)
tan grande que no se pueda ajustar en la memoria, o un sonido en el cual los datos no pueden ser conocidos durante el avance de la reproduccin, ejemplo, suponga que est monitoreando un sonido de entrada y la reproduccin del sonido est siendo capturada, si no tiene un mezclador que pueda enviar la entrada de audio a un puerto de salida, su programa de aplicacin tiene que tomar los datos capturados y enviarlos a una salida de audio del mezclador. En este caso una SourDataLine es ms apropiada que un Clip. Usando un Clip Construya un objeto DataLine.Info con Clip.class para el primer argumento y pase es DataLine.Info como un argumento del mtodo getLine de AudioSystem o Mixer.
Obtener una lnea solo le permitir una forma de referenciarla, getLine actualmente no reservara la lnea para usted; debido a que un mezclador podra tener un nmero limitado de lneas disponibles del tipo deseado, y puede suceder que despus de que haya invocado a getLine para obtener el Clip, otro programa de aplicacin salta y atrapa el clip antes de que usted est listo para empezar la reproduccin. Para que usted pueda usar el clip, necesita reservarlo de forma exclusiva para su programa, usando los siguientes mtodos de clip: Void open(AudioInputStream stream) Void open(AudioFormat format, byte[]data, int offset, in buffersize) Clip (semejante a SourceDataLine) no incluye mtodos para escribir nuevos datos en el buffer. El argumento buffersize solo especifica la cantidad de bytes que se pueden cargar dentro del clip. No es un buffer donde se puedan continuamente cargar ms datos, tal como se puede con un buffer de SourceDataLine. Despus de abrir un clip, puede especificar el punto dentro de los datos donde deseara empezar la reproduccin, usando los mtodos de Clip setFramePosition o setMicroSecondPosition, de otro modo empezara desde el inicio. Puede configurar la reproduccin para repetirla continuamente usando el mtodo SetLoopPoints. Cuando est listo para reproducir, simplemente llame al mtodo start, existen otros mtodos como stop, rewind, etc. El volumen de un Clip y su actividad o estado pueden ser monitoreados llamando a los mtodos de DataLine, getLevel
Un SourceDataLine se obtiene de forma semejante a la obtencin de un Clip tambin la apertura de un SourceDataLine es semejante a la apertura de Clip, el propsito es otra vez reservar la lnea. Sin embargo se usan mtodos diferentes incluidos en DataLine: Void open (AudioFormat format). Cuando se abre una SourceDataLine, no se asocia ningn dato a la lnea, solo se especifica el formato del audio que se desea reproducir. El sistema seleccionado por default la longitud del buffer. O tambin si lo desea puede indicar la longitud del buffer usando el mtodo: Void open (AudioFormat format, int buffersize) donde buffersize debe ser indicado en bytes, pero pudiera corresponder a un nmero entero de muestras (frames). Tambin es posible abrir un SourceDataLine usando el mtodo open() de Line, sin argumentos, en este caso la lnea es abirta con el formato de audio y tamao de buffer por default. En este caso no se podrn hacer cambios, solo podr invocar a los mtodos de DataLine getFormat y getBuffersize antes de que la lnea haya sido abierta. Una vez que SourceDataLine es abierta, puede empezar a tocar sonido, invocando al mtodo start de DataLine y tambin escribiendo repetidamente los datos en el buffer para su reproduccin. El siguiente mtodo permite colocar datos en el buffer: Int write(byte[] b, int offset, int length) offset y length se indican en bytes. La reproduccin se llevara a cabo solo si el buffer tiene datos, si se invoca al mtodo start en un SourceDataLine pero nunca escribe datos en el buffer, el mtodo start podra nunca ser enviado y sin embargo en este caso solo el mtodo isRunning de DataLine podra retornar verdadero. En el siguiente ejemplo se leen trozos de datos desde un flujo, se escribe un trozo a la vez en SourceDataLine para su reproduccin. line
(ya revisado)
Si no desea usar el mtodo de escritura por bloques, puede invocar primero al grupo available(dentro del ciclo) para saber cuntos bytes pueden ser escritos sin bloquear y asignar este lmite variable a numBytesToRead antes de leer desde el flujo. Probablemente deseara invocar este ciclo de reproduccin en un thread separado para que el resto de los programas de aplicacin no parezcan congelarse cuando se reproduce un sonido (archivo) grande. En cada iteracin del ciclo, debe probar si el usuario ha solicitado detener la reproduccin. Para poner el booleano stopped a verdadero en el ciclo anterior. Dado que write regresa antes de que todos los datos hayan terminado de reproducirse, cmo saber cundo la reproduccin se ha completado?
Una forma es llamar al mtodo drain de DataLine despus de escribir el ltimo buffer de datos. Este mtodo bloquea hasta que todos los datos hayan sido reproducidos. Cuando el control regresa al programa, puede liberar la lnea si lo desea, sin cortar prematuramente la reproduccin de cualquier muestra de audio. line.write(b,offset,numBytesToWrite) //esta es la llamada final de write line.drain(); line.stop(); line.close(); line=null;
Tambin puede detener prematuramente la reproduccin en curso, por ejemplo pulsando el botn stop el cual invocara al mtodo stop de DataLine para detener la reproduccin inmediatamente aun a la mitad del buffer, esto deja cualquier dato en el buffer, de modo que si se invoca start la reproduccin continua, si esto no es lo que desea puede descartar los datos del buffer llamando a flush.
Un SourceDataLine genera un evento STOP cuando el flujo de datos ha sido detenido, de cualquier forma incluyendo que se alcanzo el final de la reproduccin. Es importante realizar los eventos START y STOP con isActive, no con isRunning.
ESEQUIEL 28-20
Monitoreando el estado de la lnea. Las notificaciones son generadas en forma de objetos LineEvent, los cuales pueden ser de los siguientes cuatro tipos: OPEN, CLOSE,START y STOP. Cualquier objeto en el programa que implementa la interface LineListener se puede registrar para recibir tales notificaciones. Para implementar la interface LineListener, el objeto simplemente necesita actualizar el mtodo que tomara como argumento LineEvent, para registrar un objeto con alguno de estos eventos invoque el siguiente mtodo de Line: public void addLineListerner(LineListener listener) cuando ocurra cualquiera de los 4 eventos, se enva un mensaje update a todos sus Listeners. El objeto puede preguntar a LineEvent que recibi. Primero debe invocar a LineEvent.getLine para estar seguro que la lnea fue detenida. Sincronizacin de mltiples Lneas de reproduccin. Si de sea reproducir mltiples pistas de audio simultneamente, puede desear que todas inicien y terminen al mismo tiempo, algunos mescladores facilitan este proceso con su mtodo Synchoronize el cual se aplica a las operaciones open, close, start y stop como un grupo de lneas de datos usando un simple comando, en lugar de tener que controlar cada Lnea individualmente. Para saber si un mezclador particular ofrece esta caracterstica para especificar grupos de lneas de datos, llamar al mtodo: Boolean isSynchronizationSuported(Line[] lines, Boolean sincro)de la interface Mixer.
El primer argumento indica el grupo de Lneas y el Segundo parmetro indica la exactitud con la cual la sincronizacin podra ser mantenida. Si el segundo parmetro es verdadero se le estara preguntando al mezclador si es capaz de mantener precisin en todas las lneas a la vez.