Быстрый Аудио Вход / Выход


Вот что я хочу сделать:

Я хочу, чтобы пользователь дал моей программе некоторые звуковые данные (через микрофонный вход), затем подержал его в течение 250 мс,а затем вывел его обратно через динамики.

Я уже сделал это, используя Java Sound API. Проблема в том, что это как-то медленно. Это занимает минимум 1-2 секунды от момента, когда звук сделан, до момента, когда звук снова слышен из динамиков,и я еще даже не пытался реализовать логику задержки. Теоретически есть не должно быть никакой задержки, но есть. Я понимаю, что вы должны ждать, пока звуковая карта заполнит свой буфер или что-то еще, и размер выборки и частота дискретизации имеют какое-то отношение к этому.

Мой вопрос таков: должен ли я продолжать идти по пути Java, пытаясь сделать это? Я хочу, чтобы задержка снизилась до 100 мс, если это возможно. Есть ли у кого-нибудь опыт использования драйвера ASIO с Java? Предположительно, это быстрее..

Кроме того, я парень из .NET. Имеет ли это смысл делать с .NET вместо этого? А как насчет C++? Я ищу правильную технологию для использования здесь, и, возможно, хороший пример того, как читать/записывать в аудио-входные/выходные потоки, используя предложенную вами технологическую платформу. Спасибо за вашу помощь!

5 4

5 ответов:

Я использовал JavaSound в прошлом и нашел его удивительно шелушащимся (и он продолжает меняться между выпусками VM). Если вам нравится C#, используйте его, просто используйте API DirectX. Вот пример того, что вы хотите сделать с помощью DirectSound и C#. Вы можете использовать плагины эффектов для выполнения вашего 250-мс Эхо.

Http://blogs.microsoft.co.il/blogs/tamir/archive/2008/12/25/capturing-and-streaming-sound-by-using-directsound-with-c.aspx

Вы можете посмотреть на JACK, аудио API, предназначенный для обработки звука с низкой задержкой. Кроме того, Google открывает эту отличную презентацию [PDF] об использовании JACK с Java.

Теоретически задержки быть не должно, но она есть.

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

Потенциальная проблема с использованием языка сбора мусора, такого как Java, заключается в том, что GC будет периодически запускаться, прерывая вашу обработку на некоторое произвольное количество времени. Однако я был бы удивлен, если бы это было >100 мс в обычном использовании. Если GC является проблемой, большинство JVM предоставляют альтернативные алгоритмы сбора, которые вы можете попробовать.

Если вы решили пойти по пути C / C++, я настоятельно рекомендую использовать PortAudio ( http://portaudio.com/). Он работает практически со всем на нескольких платформах, и это дает вам низкоуровневое управление звуковыми драйверами, не имея фактически дела с различными технологиями звуковых драйверов, которые есть вокруг.

Я использовал PortAudio в нескольких проектах,и это настоящая радость. И лицензия разрешительная.

Если ваша цель-низкая задержка, вы не можете победить C.

Libsoundio -это низкоуровневая библиотека C для ввода и вывода звука в реальном времени. Он даже поставляется с программойexample , которая делает именно то, что вы хотите - подводит микрофонный вход к выходу динамиков.

Это, безусловно, достижимо с JavaSound , чтобы получить сквозную задержку в пределах 100-150 МС.

  1. Основной причиной задержки являются размеры буферов линий захвата и воспроизведения. Размер устанавливается при открытии строк:
    • захват: TargetDataLine#open(AudioFormat format, int bufferSize)
    • воспроизведение: SourceDataLine#open(AudioFormat format, int bufferSize)

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

Размер буфера по умолчанию можно проверить с помощью DataLine#getBufferSize при вызове #open(AudioFormat format). Размер по умолчанию будет варьироваться в зависимости от AudioFormat и, по-видимому, приспособлен для приложений с высокой задержкой, без заикания воспроизведения (например, потоковое интернет-вещание). Если вы разрабатываете приложение с низкой задержкой, размер буфера по умолчанию слишком велик и должен быть изменен.

В моем тестировании с 16-битным PCM AudioFormat размер буфера 1024 байта был довольно близок идеально подходит для низкой задержки.

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