2010-09-20 19 views
13

Estoy trabajando en un proyecto java que recibe eventos midi desde hardware midi utilizando la biblioteca javax.sound.midi. En la documentación, dice que MidiSystem.getMidiDeviceInfo() devuelve una lista de todos los hardware midi conectados. Funciona para mí, pero el problema es que solo funciona una vez. Se necesita un momento la primera vez para escanear realmente los dispositivos, pero cada vez que eso devuelva inmediatamente la misma lista, incluso si se han conectado nuevos dispositivos. ¿Hay alguna manera de obligarlo a volver a explorar? Volverá a escanear si la aplicación se reinicia, pero no quiero que mis usuarios tengan que reiniciarse si conectan un nuevo dispositivo midi.Java sound api - Escaneo para dispositivos midi

BTW, estoy usando Mac OS X ... se ha señalado que el comportamiento puede ser diferente para diferentes sistemas operativos.

+1

Odio preguntar esto, pero ¿este problema ocurre en Mac OSX, Linux o Windows? Sé que Java es de escritura única, ejecutable en cualquier lugar, pero el hecho es que estos sistemas operativos tienen sistemas MIDI radicalmente diferentes, y es posible que el tiempo de ejecución de Java no pueda interactuar correctamente con él. –

+0

Gracias por preguntar esto de tal manera que Google lo encontró. –

Respuesta

7

El MidiSystem.getMidiDeviceInfo() obtiene la lista completa de proveedores y extrae la información del dispositivo de cada proveedor.

La lista de proveedores MIDIs se recupera de la clase underlaying JDK com.sun.media.sound.JDK13Services, a través del método estático getProviders()

getProviders públicos estáticos sincronizados lista (Clase ServiceClass) obtiene una lista que contiene instalados instancias de los proveedores para el servicio solicitado . La lista de proveedores se almacena en caché durante el período de que otorga cachingPeriod. Durante este período, la misma instancia de lista es devuelta para el mismo tipo de proveedor .Después de este período, se construye y devuelve una nueva instancia de . La lista devuelta es inmutable.

Por lo tanto, parece que esta clase tiene la lista de Proveedores en un caché, que se volverá a cargar después de un cierto período de tiempo. Puede establecer este período en un valor personalizado utilizando el método setCachingPeriod(int seconds). Mientras sepa, el período de caché predeterminado se establece en 60 segundos.

A modo de ejemplo, para volver a cargar esta caché cada segundo, se baremo añadir esta línea a su código:

com.sun.media.sound.JDK13Services.setCachingPeriod(1); 

Por favor, tenga en cuenta que esta solución hace uso de una clase propietaria Sol, por lo que no podría ser 100% portátil.

+1

com.sun.media.sound.JDK13Services.setCachingPeriod (..) parece haberse eliminado en algún lugar entre 1.7_51 y 1.7_67. Si alguien encuentra un método alternativo para acelerar el período de almacenamiento en caché, estaría interesado en escucharlo. – crig

+0

1) este código todavía compila y ejecuta 'com.sun.media.sound.JDK13Services.setCachingPeriod (1);' 2) en OSX Estoy bastante seguro de que no ayuda en absoluto –

+0

Puedo confirmar esto * DOES NO FUNCIONA * en OS X 10.5.5. No he probado nada más. Además, parece que el período de caché es indefinido? Esperé un minuto entero pero todavía no recoge el nuevo dispositivo. – phreakhead

-1

Parece que esto podría ser un error específico del sistema operativo, pero puedo pensar en una solución.

En java puede ejecutar comandos externos al sistema operativo. (Un Google rápido, me dio este ejemplo http://www.javafaq.nu/java-example-code-186.html se ve bien y te da la idea).

Al buscar nuevos dispositivos, puede enviar un comando externo para ejecutar un programa java simple que consulta rápidamente los dispositivos midi utilizando MidiSystem.getMidiDeviceInfo() y muestra los resultados en un archivo de texto o puede obtener el resultado del BufferedReader objeto.

Recuerde también que el programa externo utilizado para consultar dispositivos midi no tiene que escribirse en Java en caso de que Java le cause más problemas. Alternativamente, puede consultar el sistema operativo para los dispositivos conectados y usar grep para filtrar los resultados.

Espero que esto ayude.

+0

Necesito Java para realmente poder conectarme a los dispositivos. Solo puedo conectarme a ellos a partir de los resultados de MidiSystem.getMidiDeviceInfo(). – tybro0103

+1

Esto aún es posible si hace que los objetos devueltos se puedan serializar. Sugeriría utilizar algo más que Java si desea llamar continuamente y utilizar más información de bajo nivel del sistema operativo, no es el mejor lenguaje para usar para esto. Sobre todo teniendo en cuenta que Macs y Java no siempre se llevan bien. ¿Has probado esto en un sistema operativo diferente todavía? – binarycreations

+0

No he probado con otro sistema operativo. Necesito que funcione en OS X y en Java. – tybro0103

3

A falta de cualquier dispositivo MIDI en mi PC de trabajo, o de hecho cualquier tipo de Mac, no creo que voy a ser capaz de probar de forma adecuada, pero ...

La clase MidiSystem parece utilizar para encontrar el com.sun.media.sound.JDK13Services.getProviders(Class providerClass) lista de dispositivos en el sistema. El API docs for this class indica que la lista se recrea en una llamada sucesiva fuera de un cachingPeriod, que se puede configurar convenientemente llamando al setCachingPeriod(int seconds).

Con un poco de suerte, puede llamar esto una vez al inicio de su aplicación y configurarlo en 5 segundos o algo así, y funcionará mágicamente. Sin embargo, los documentos también dicen "Este método solo está destinado a ser probado", por lo que no estoy seguro de cuán efectivo será este enfoque.

Espero que esto sea suficiente para comenzar, y mientras tanto seguiré hurgando para ver si puedo encontrar una manera más limpia de hacerlo.

+0

+1: hemos llegado a conclusiones muy similares –

+0

Así que lo hicimos, exactamente a la misma hora :) – Zetten