Java sound api - Сканирование для устройств midi - PullRequest
13 голосов
/ 20 сентября 2010

Я работаю над проектом Java, который получает события midi от оборудования midi, используя библиотеку javax.sound.midi.В документации сказано, что MidiSystem.getMidiDeviceInfo() возвращает список всего подключенного миди-оборудования.Это работает для меня, но проблема в том, что это работает только один раз.Первый раз требуется мгновенное сканирование для поиска устройств, но каждый раз после этого он немедленно возвращает тот же список, даже если были подключены новые устройства.Есть ли способ заставить его повторно сканировать?Он будет пересканирован, если приложение будет перезапущено, но я не хочу, чтобы мои пользователи перезагружались, если они подключают новое миди-устройство.

Кстати, я использую Mac OS X ... это было указаноЭто поведение может быть различным для разных ОС.

Ответы [ 4 ]

7 голосов
/ 29 сентября 2010

MidiSystem.getMidiDeviceInfo() получает полный список поставщиков и извлекает информацию об устройстве у каждого поставщика.

Список провайдеров MIDI восстанавливается из базового класса JDK com.sun.media.sound.JDK13Services , через статический метод getProviders()

открытый статический синхронизированный список getProviders (класс serviceClass) Получает список, содержащий установленные экземпляры поставщиков для запрошенная услуга. Список провайдеры кэшируются на период время, указанное cachingPeriod. В течение этот период, тот же экземпляр списка возвращается за тот же тип поставщик. После этого периода новый экземпляр построен и возвращен. Возвращенный список является неизменным.

Итак, похоже, этот класс содержит список провайдеров в кеше, который будет перезагружен через определенный период времени. Вы можете установить этот период в пользовательское значение, используя метод setCachingPeriod(int seconds). Насколько я знаю, период кэширования по умолчанию установлен на 60 секунд.

Например, чтобы обновлять этот кэш каждую секунду, вы можете добавить эту строку в свой код:

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

Обратите внимание, что в этом решении используется класс пропиетарии Sun, поэтому он не может быть на 100% переносимым.

3 голосов
/ 29 сентября 2010

Не имея каких-либо MIDI-устройств на моем рабочем ПК или даже любом другом Mac, я сомневаюсь, что смогу проверить это должным образом, но ...

Класс MidiSystem, кажется, использует com.sun.media.sound.JDK13Services.getProviders(Class providerClass), чтобы найти список устройств в системе. Документация API для этого класса гласит, что список воссоздается при последовательном вызове за пределами cachingPeriod, что может быть удобно установлено путем вызова setCachingPeriod(int seconds).

Если повезет, вы можете просто вызвать это один раз в начале вашего приложения и установить его на 5 секунд или около того, и это будет волшебным образом работать. Однако в документах также указано «Этот метод предназначен только для тестирования», поэтому я не совсем уверен, насколько эффективным будет этот подход.

Надеюсь, этого достаточно, чтобы вы начали, а я тем временем продолжу ковыряться в поисках более чистого способа сделать это.

0 голосов
/ 24 июля 2018

Я ответил, что это Обновите список Midi Devices в Java , но для тех, кто сюда попал, теперь есть библиотека, которая поддерживает это правильно: https://github.com/DerekCook/CoreMidi4J

библиотека выступает в роли поставщика устройств для подсистемы MIDI, так что это, по сути, дроп-ин, и весь ваш существующий код будет работать.

Я не автор, но она хорошо работает для моих нужд, и потребоваланемного поиска, чтобы найти, поэтому я публикую его здесь для тех, кто сталкивается с проблемой.

0 голосов
/ 24 сентября 2010

Звучит так, как будто это может быть ошибка в спецификации ОС, но я могу придумать, как обойтись.

В Java вы можете запускать внешние команды для ОС. (Быстрый Google, дал мне этот пример http://www.javafaq.nu/java-example-code-186.html, он выглядит нормально и дает вам идею).

При проверке новых устройств вы можете отправить внешнюю команду для запуска простой Java-программы, которая быстро запрашивает устройства midi с помощью MidiSystem.getMidiDeviceInfo () и выводит результаты в текстовый файл, или вы можете получить выходные данные из объекта BufferedReader .

Также помните, что внешняя программа, используемая для запроса устройств midi, не должна быть написана на Java, в то время как Java вызывает у вас больше проблем. В качестве альтернативы вы можете просто запросить ОС для подключенных устройств и использовать grep для фильтрации результатов.

Надеюсь, это поможет.

...