2010-09-20 2 views
13

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

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

+1

Мне не нравится это спрашивать, но эта проблема возникает на Mac OSX, Linux или Windows? Я знаю, что Java - это однократная запись, работающая в любом месте, но факт в том, что эти операционные системы имеют радикально разные MIDI-системы, и сама среда выполнения Java может оказаться неспособной корректно взаимодействовать с ней. –

+0

Спасибо, что спросили об этом так, что Google нашел его. –

ответ

7

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

список провайдеров МИДИСОВ извлекает из JDK нижележащего класса com.sun.media.sound.JDK13Services, через статического метод getProviders()

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

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

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

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

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

+1

com.sun.media.sound.JDK13Services.setCachingPeriod (..), похоже, был удален где-то между 1.7_51 и 1.7_67. Если кто-нибудь найдет альтернативный метод ускорения кеширования, мне было бы интересно его услышать. – crig

+0

1) этот код все еще компилируется и запускается 'com.sun.media.sound.JDK13Services.setCachingPeriod (1);' 2) на OSX. Я почти уверен, что это вообще не помогает. –

+0

Я могу подтвердить это * НЕ РАБОТАЕТ * на OS X 10.5.5. Не пробовал ни на что другое. Кроме того, кажется, что период кеша неограничен? Я ждал целую минуту, но он все еще не поднимает новое устройство. – phreakhead

-1

Это звучит так, как будто это может быть ошибка OS specificx, но я могу подумать обойти.

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

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

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

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

+0

Мне нужна Java, чтобы иметь возможность подключиться к устройствам. Я могу только подключиться к ним из результатов MidiSystem.getMidiDeviceInfo(). – tybro0103

+1

Это возможно, если вы сделаете возвращаемый объект/сериализуемым. Я бы предложил использовать что-то еще, кроме Java, если вы хотите постоянно звонить и использовать более низкую информацию о ОС, это не лучший язык для этого. Особенно учитывая, что Mac и Java не всегда ладят друг с другом. Вы уже пробовали это на другой ОС? – binarycreations

+0

Я еще не пробовал другую ОС. Мне нужно, чтобы он работал на OS X и на Java. – tybro0103

3

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

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

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

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

+0

+1: мы достигли очень похожих выводов –

+0

Итак, мы сделали примерно ровно то же время :) – Zetten

Смежные вопросы