Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

Это, безусловно, достижимо с 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 байта был довольно близок к идеальному для низкой задержки.

  1. Вторая и часто упускаемая из виду причина задержки звука - это любое другое действие, выполняемое в потоках захвата или воспроизведения.Например, протоколирование сообщений на консоль может привести к задержке в 10 мс.Выключи его.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top