
Как контролировать входной сигнал микрофона в Linux?
Примечание: мониторинг — это не то же самое, что запись и воспроизведение записанного.
В Windows я могу прослушивать свой микрофон следующими способами:
С помощью какой-нибудь программы, которая будет захватывать мой микрофон и отправлять его на мою звуковую карту для воспроизведения. Например, с помощью
ffplay
командыffplay -f dshow -i audio="Front panel mic (Realtek High Definition Audio)"
Это приведет к значительной задержке, до нескольких секунд.
С опцией «Прослушать» в свойствах устройства ввода
Это приведет к меньшей задержке — до одной секунды.
С виджетом звуковой карты
Это даст НУЛЕВУЮ задержку. Я думаю, это заставит входящий звук идти на выход, не покидая звуковую карту, но не уверен.
Мне нужна опция №2 в командной строке Linux.
решение1
Вы сможете контролировать свой микрофон с помощью PulseAudioмодуль обратной связи. Модуль должен автоматически создавать петлевые выходы для доступных устройств ввода. Чтобы загрузить модуль вручную
pactl load-module module-loopback
Чтобы сделать изменение постоянным, /etc/pulse/default.pa
добавьте
load-module module-loopback
решение2
Если у вас есть аналоговый вход и аналоговый выход, я бы рекомендовал просто использовать pavucontrol
(PulseAudio Volume Control) для маршрутизации входного звука на выход в микшере. Однако, если у вас есть, например, USB-микрофон, то звук не может быть просто микширован, а некое программное обеспечение должно записать звук, а затем воспроизвести его в выходной поток. И в зависимости от вашего оборудования эта запись + воспроизведение могут вызвать некоторую (или даже большую) задержку.
Вы можете попробовать это:
Сначала получите имена входов и выходов, которые вы хотите использовать:
$ pactl list short | egrep "alsa_(input|output)" | fgrep -v ".monitor"
Для меня результаты выглядят так:
0 alsa_output.pci-0000_00_1b.0.analog-stereo module-alsa-card.c s16le 2ch 44100Hz RUNNING
0 alsa_input.usb-Microsoft_Microsoft___LifeCam_HD-5000-02.analog-mono module-alsa-card.c s16le 1ch 44100Hz SUSPENDED
это означает, что мое выходное устройство называется alsa_output.pci-0000_00_1b.0.analog-stereo
, а моя USB-веб-камера/микрофон называется alsa_input.usb-Microsoft_Microsoft___LifeCam_HD-5000-02.analog-mono
.
Теперь я могу записать звук с USB-микрофона и вывести его на аудиовыход следующим образом:
$ pacat -r --latency-msec=1 -d alsa_input.usb-Microsoft_Microsoft___LifeCam_HD-5000-02.analog-mono | pacat -p --latency-msec=2 -d alsa_output.pci-0000_00_1b.0.analog-stereo
То есть один pacat
процесс считывает данные с микрофона и запрашивает аудиостек, чтобы попытаться получить задержку 1 мс или 0,001 секунды. А другой pacat
процесс записывает аудио на мое выходное устройство и пытается получить задержку 2 мс или 0,002 секунды. Вы также можете попробовать уменьшить задержку вывода до 1 мс, но, по крайней мере, для моего довольно старого оборудования звук в этом случае слишком легко обрезается.
Однако если я оставляю эту комбинацию записи и воспроизведения работающей в течение длительного времени, то, похоже, задержка медленно увеличивается с течением времени. Я предполагаю, что тактовая частота моего USB-микрофона немного быстрее, чем тактовая частота моего выходного аудио, что приводит к медленному увеличению буфера. Я не знаю хорошего способа разрешить этим процессам pactl пропускать аудио, чтобы вывод оставался в реальном времени. Я думаю, мне нужно написать для этого собственное приложение.
Для описанного выше pacat ... | pacat
конвейера наилучшая задержка для моего оборудования составляет около 6 мс от момента попадания звуковых волн в микрофон до момента выхода звуковых волн из выходных динамиков при использовании ядра Linux с включенной функцией PREEMPT (например, linux-lowlatency
ядро Ubuntu).