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