Ищете Java-оболочку для Windows DirectSound/WASAPI/? аудио

Потратив довольно много времени на то, чтобы обойти существующую библиотеку javax.sound.sampled для простого (но относительно точного по времени) захвата/рендеринга звука, я пришел к выводу, что мне действительно нужно добраться до родного звука. API. Проблема, которую я обнаружил, заключается в том, что мне нужно иметь возможность получить положение кадра звука (которое я визуализирую, записывая в SourceDataLine) с шагом 20 или 50 миллисекунд, с точностью до 1 или 2 миллисекунд. Другими словами, я хочу синхронизировать некоторые графические события с воспроизводимым звуком, с частотой кадров видео от 20 до 50 кадров в секунду, с дрожанием не более 1 или 2 миллисекунд. Кажется, что реализация JavaSound слишком далека от аппаратного обеспечения (цена за независимость от платформы?) для этого. После долгих «переделок» с размерами буфера SDL/TDL, аудиоформатами, размером буферов SDL.write() и TDL.read(), частотой записи и т. д. я не могу найти способ избежать изменения в кадре сообщаемое положение по сравнению с системными часами (с разрешением 1 миллисекунда, а не микросекунды).

[Дополнительное уточнение: я мог бы просто позволить графическому рендерингу работать с фиксированной скоростью, основанной на системных часах, что было бы достаточно точным для моих нужд. Однако, если это должно быть синхронизировано со звуковой дорожкой, к тому времени, когда обычная звуковая дорожка (длиной, например, 5 минут) приблизится к концу, даже небольшая разница во времени будет накапливаться до заметной разницы во времени между звуком и графикой. Я думал просто проверять синхронизацию каждую секунду (или 2, или 5), но «дрожание» от сообщаемой позиции звукового кадра приведет к исправлениям, которые затем будут заметны.]

Я изучал, какие библиотеки уже могут быть доступны. Похоже, что многие из существующих пакетов предназначены для поддержки сообщества разработчиков игр. Однако мне не нужен 3D-звук, аппаратное ускорение эффектов, синтез, обработка — просто способ прочитать положение кадра того, что слышится, с постоянной задержкой. Если бы задержка составляла целых 100 миллисекунд, но была постоянной, я мог бы спроектировать вокруг этого.

Я был бы признателен за рекомендации для библиотек Java, предоставляющих такие возможности. Я предполагаю, что это будут JNI-обертки собственного аудио API. На данный момент мне нужно только поддерживать Windows7. Я видел OpenAL (похоже, это «открытый» способ Creative для поддержки аппаратного ускорения звука, поскольку теперь он больше не поддерживается в Vista — ориентирован на игры и больше, чем мне нужно), JSyn (сосредоточение внимания на синтезе, MIDI, а не на простом сэмплировании). интерфейс) и JAsioHost (самый многообещающий на данный момент).

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

Спасибо.


person ags    schedule 02.05.2012    source источник
comment
Для такого рода звука с малой задержкой единственное, что может сделать это, — это ASIO, поэтому вы можете использовать JAsioHost, но вам понадобится звуковая карта с драйвером ASIO, которая в основном представляет собой профессиональное звуковое оборудование.   -  person Jakub Zaverka    schedule 03.05.2012
comment
@JakubZaverka Да, я смотрю ASIO. Я также нашел драйверы ASIO4ALL (которые работают даже для моего крошечного тестового ноутбука), но все же это больше усложняет установку. Я также наблюдаю некоторое странное поведение с новыми драйверами. Я бы предпочел простую предсказуемость/наблюдаемость положения кадра без этой сложности. Мне на самом деле не нужна низкая задержка (мне нужно иметь возможность измерять постоянную задержку, чтобы справиться с ней), но мне нужно иметь возможность синхронизировать мое приложение с воспроизводимым звуком.   -  person ags    schedule 03.05.2012


Ответы (2)


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

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

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

Само воспроизведение может быть выполнено функциями WaveOut в Windows (ссылка здесь, вы можете искать руководства). Вы можете получить доступ к этим функциям из Java, используя JNI. WaveOut воспроизводит звук в формате Wav, что означает, что вы можете открыть устройство с помощью простой модуляции LPC и отправить необработанные сэмплы.

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

person Jakub Zaverka    schedule 03.05.2012

Я еще не пробовал ни один из них, но, возможно, стоит изучить:

person Leif Gruenwoldt    schedule 01.04.2017