Site Tools


software:freerdp:sound

Качественный звук в FreeRDP на FreeBSD

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

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

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

и не у меня одного и не только во FreeBSD.

Как это работает

RDP

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

ALSA

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

Решение 1

Для FreeBSD: я добавил поддержку OSS для воспроизведения звука (rdpsnd плагин):

Патчи включены в основную ветку, поэтому нужно убедится что freerdp собран с поддержкой OSS и принудительно включить вывод звука через OSS:

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

Решение 2

После OSS я пропатчил ALSA:
https://github.com/ivan-83/FreeRDP/commit/8d5825ee007a7889992d5a01e482d1589dd6a7ee - тоже уже в основной ветке.

Почему не работало

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

Решение 3

Не патченный плагин для ALSA работает отлично если выставить руками формат звука PCM.

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

Параметры командной строки

Только то что касается вывода звука.

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.

PS

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

  • * исправлена сборка под FreeBSD
  • + OSS в rdpsnd (воспроизведение звука)
  • + OSS в audin (запись звука)
  • + OSS в tsmf (воспроизведение мультимедиа), работает только с ffmpeg
  • * tsmf исправления для работы под FreeBSD (не воспроизводилось видео)
  • * ALSA исправлено воспроизведение звука и почищен код
  • + devd поддержка в urbdrc (перенаправление USB) и работа urbdrc во FreeBSD (не проверялось)
  • + добавлены отладочные сообщения
  • * патч для правильного определения временной зоны
  • * исправлена работа динамических каналов (в тч audin)

Исправления смотреть тут: https://github.com/ivan-83/FreeRDP/commits/master (начиная с 09 марта 2015 по 02 мая 2015)

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

В основной ветке

software/freerdp/sound.txt · Last modified: 2022/02/07 18:40 by root