FreeRDP: звук, заикания, OSS вместо ALSA

в 3:56, , рубрики: alsa, freebsd, FreeRDP, open source, oss, underrun occurred, Программирование, Работа со звуком, Сетевые технологии, метки: ,

image

FreeRDP довольно популярный инструмент для доступа к Windows машинам с не windows систем.
Не смотря на свою популярность у проекта документация отвратительная: актуально и полно освещены только вопросы как собрать из исходников и как начать кодить и слать патчи.
Если требуется что то чуть подробнее узнать про использование то лучше сразу идти на IRC канал к разработчикам или лезть в исходники, всё остальное слухи и/или устарело.

У меня были проблемы со звуком во FreeBSD:

ALSA lib pcm.c:7905:(snd_pcm_recover) underrun occurred

впрочем, далеко не у меня одного и не только во FreeBSD.


Какие только бредовые варианты не гуглятся по по поводу опустошения очереди ALSA, но все они бесполезны (почему — ниже). Разве что перейти на Pulse.

Под капотом

RDP

Клиент подключается к серверу, они договариваются какие виртуальные каналы (звук, буфер обмена, ком порт и тп) они будут использовать и с какими параметрами.
В случае звука выбирается частота дискретизации, количество каналов (моно/стерео), кодек, один из следующих: PCM, ADPCM, ALAW, MULAW, DVI_ADPCM.
Когда появляется звук — он отправляется клиенту небольшими блоками, клиент посылает подтверждение и таймстемп.
Некоторые плагины вычисляют таймстепм самостоятельно, например ALSA.

ALSA

Как и многие другие звуковые плагины (Pulse, mac и пр) ALSA сама не умеет декодировать форматы ADPCM и DVI_ADPCM, вместо этого она их конвертирует в PCM средствами FreeRDP и воспроизводит.
ADPCM/DVI_ADPCM — сжимают звук в 4 раза относительно PCM. Качество теряется не сильно, обычный пользователь на слепом тесте вряд ли заметит разницу.

Решение 1

Код всех звуковых плагинов (ALSA, Pulse, mac, winmm) был компактным, это вдохновило написать поддержку OSS, родной звуковой системы FreeBSD.
тыц и готово
самое важное забыл :)
После не продолжительной отладки оно заработало.

Решение 2

После приобретения положительного опыта с OSS я решил разобраться что же не так в ALSA.
Тыц патчик
Функция rdpsnd_alsa_wave_play() отвечает за то чтобы отправлять данные в звуковое устройство, ещё она занимается некоторыми вычислениями временных интервалов — сколько звук воспроизводится.
Функция snd_pcm_htimestamp() возвращает некоторые значения того что есть и сколько будет проигрываться, дальше была небольшая обёртка.
Считало оно совсем не правильно.
Уж не знаю почему, но у оригинального кода получалось 9-11, а у оригинального кода из rdpsnd_main.c получалось более 200.
Мой код давал практический такой же результат как rdpsnd_main.c (разница в единицы, я более грубо считал), поэтому поставил код из rdpsnd_main.c.
Дополнительно немного изменил параметры инициализации и почистил код.
Думаю там ещё можно было повыкидывать, но я сплю и вижу как бы удалить библиотеку для ALSA из системы :)

Решение 3

Для ленивых :)
Если бы оно нагуглилось… то было бы единственным.
Дело в том, что даже не патченный плагин для ALSA работает отлично если выставить руками формат звука PCM.
Но чтобы узнать что его вообще можно выставлять проще смотреть в исходники, заодно там обнаруживаются другие скрытые параметры.

Документация пишет как выбрать звуковую подсистему:

/sound:alsa

или старый вариант, с выставлением latency

--plugin rdpsnd --data latency:50 --

Страшная тайна в том, что параметров сильно больше, и документация не говорит как вводить больше одного в новом варианте командной строки.
rdpsnd — название плагина, в новой версии ком строки к нему обращаются через /sound.

"sys": звуковая подсистема: asla, pulse, oss (с моими патчами), mac, winmm, opensles, ios
"dev": устройство. Для ALSA это путь вида /dev/УСТРОЙСТВО для OSS номер устройства (те для /dev/dsp2 нужно указывать 2)
"format": формат звука, число: PCM — 1, ADPCM — 2, ALAW — 6, MULAW — 7, DVI_ADPCM — 17.
"rate": частота. Скорее всего 48000, 44100 и тп.
"channel": число каналов. 1 — моно, 2 — стерео.
"latency": число.
"quality": качество, текст или число. «dynamic» — 0 (частота будет меняться в зависимости от задержек канала), «medium» — 1, «high» — 2.

Целебные параметры командной строки для ALSA:

/sound:sys:alsa,format:1,quality:high

(для интернета скорее всего не лучший вариант, особенно мобильного PCM — не сжатый звук)

Параметры командной строки для OSS:

/sound:sys:oss,format:1,quality:high

Плюшки

Теперь FreeRDP можно тянуть с гитхаба и собирать под FreeBSD, всё исправлено.
Патчи которые были в портах — частично устарели, остальное добавил, и добавил свои для сборки без ошибок.

Ложка дёгтя

1. OSS по прежнему не доступен в tsmf (/multimedia) и audin (/microphone) плагинах.
2. В основную ветку на момент публикации все патчи перечисленные выше не попали.
3. underrun occurred — полностью не исчезли, в начале воспроизведения они проскакивают, но уже через 5 секунд звук перестаёт заикаться. Возможно стоит поиграться с latency, с константами (65) из кода или посмотреть tcpdump как ходят пакеты. 5-10 заиканий в начале воспроизведения легко не заметить, раньше они были постоянно.
4. Заикания есть и в OSS, просто он не пишет ошибок.

Автор: Ivan_83

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js