В настоящее время я экспериментирую с обработкой сигналов в реальном времени, поэтому я пошел и попробовал PortAudio (от C).PortAudio ненадежный: выражение «...» не выполнено
У меня есть два аудиоинтерфейса на моем компьютере, встроенный звук (Intel HD Audio) и аудиоинтерфейс USB. Оба они отлично работают под управлением ALSA на Linux. Я также попробовал USB-аудио интерфейс под JACK на Linux, и это также отлично работает.
Что я делаю:
Мой код просто инициализирует Portaudio, открывает и запускает поток (один канал, paInt32
формат образца, defaultLowInputLatency
/defaultLowOutputLatency
, хотя я попытался изменить к paFloat32
или defaultHighInputLatency
/defaultHighOutputLatency
, которое ничем ничего не улучшилось).
При каждом вызове обратного вызова он копирует sizeof(int32_t) * frameCount
байтов через memcpy
из ввода в выходной буфер, а затем возвращает paContinue
. В обратном вызове он ничего не делает. Нет распределения памяти, нет системных вызовов, ничего не может заблокировать. Он просто выводит то, что он прочитал. Код очень прост, но я не могу его запустить.
Замена memcpy
с помощью циклического копирования frameCount
Элементы типа int32_t
от входа в выходной буфер ничего не изменили.
Что я пробовал:
Следующие сценарии были опробованы с Portaudio.
- Вход и выход через аудиоинтерфейс USB, механизм обратного вызова на PortAudio, сервер ALSA.
- Вход и выход через аудиоинтерфейс USB, блокирование ввода/вывода в PortAudio с 1024 буфером выборки, ALSA-сервер.
- Вход через аудиоинтерфейс через USB, выход через встроенный звук, механизм обратного вызова на PortAudio, сервер ALSA.
- Вход через аудиоинтерфейс через USB, выход через встроенный звук, блокирование ввода/вывода на PortAudio с 1024 размерами буфера выборки, бэкэнд ALSA.
- Вход и выход через аудиоинтерфейс USB, механизм обратного вызова на PortAudio, JACK-сервер.
- Вход и выход через аудиоинтерфейс USB, блокирование ввода/вывода на PortAudio с 1024 буфером выборки, JACK-бэкэнд.
Проблемы я столкнулся:
Результаты были следующими. (Числа представляют собой сценарии, описанные выше.)
- Отсутствие выхода с устройства.
- Выход из устройства нестационарный (прерывается). Все время много буферов подрывается.
- Нет выхода с устройства.
- Выход с устройства нереализуемый. Иногда это работает, иногда это не так. (Не меняя ничего, просто запуская исполняемый файл несколько раз.) Когда он работает, латентность начинается с низкого уровня, но со временем увеличивается и становится очень заметной.
- Нет выхода с устройства.
- Нет выхода с устройства.
Между каждую попытку, ALSA был испытан, если он по-прежнему реагирует (иногда это было полностью «заточено», так что ни одно приложение не может звучать выход больше) и перезагрузил систему в случае ALSA получил «заперт» , затем продолжил тестирование.
Более подробной информации, которые могут быть полезны при отслеживании проблемы вниз:
В сценариях, где нет никакого вывода вообще, я получаю следующее сообщение об ошибке при использовании ALSA в качестве внутреннего интерфейса.
Expression 'err' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3350
Expression 'ContinuePoll(self, StreamDirection_In, &pollTimeout, &pollCapture)' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3876
Expression 'PaAlsaStream_WaitForFrames(stream, &framesAvail, &xrun)' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4248
При использовании JACK в качестве backend появляется следующее сообщение об ошибке.
Cannot lock down 42435354 byte memory area (Cannot allocate memory)
Кроме того, независимо от того, какой метод я использую, я всегда получаю эти предупреждения.
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2267:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:867:(find_matching_chmap) Found no matching channel map
При использовании ALSA у меня также есть одна или две жалобы на недоходы.
ALSA lib pcm.c:7905:(snd_pcm_recover) underrun occurred
Функции Portaudio, что я называю (Pa_Initialize
, Pa_OpenStream
, Pa_StartStream
, Pa_StopStream
, Pa_CloseStream
, Pa_Terminate
, в таком порядке), возвращают paNoError
.
paex_read_write_wire.c
(блокирующий ввод-вывод), который поставляется с PortAudio, обычно может обращаться к устройству, но также испытывает множество недоработок (например, мой тестовый пример 2).
В любом случае нет ничего интересного в dmesg
. (Только что проверил, что, так как ALSA имеет компонент на уровне ядра.)
Мой вопрос:
Любой знает, что здесь проблема и как я могу это исправить? Или, по крайней мере, как я мог сузить его немного больше?
Пожалуйста, покажите свой код. –
Здесь вы идете! Большое спасибо за ваше время и усилия! /// PortAudio (на основе обратного вызова): http://pastebin.com/MrHpkXEA /// PortAudio (блокирование ввода-вывода): http://pastebin.com/MDdUZ8W3 /// RtAudio (callback- основанный): http://pastebin.com/YCQ0JpSR –
FWIW, я получаю такую же проблему на Ubuntu 16.04.1 с простым приложением PortAudio. Я получаю эту ошибку с перерывами. Очень расстраивает! –