Serveur de son en logiciel libre : état de l'art et utilisabilité en WiFi

Besoin : son sans-fil

J'aimerais que le son joué par mon ordinateur portable voie son rendu déporté* vers mon serveur lui-même relié à une chaîne hi-fi. *

Tout ça à travers le réseau, pour éviter de tirer un périlleux câble à travers la pièce. Il est donc requis que le tout fonctionne en WiFi1.

Mon cas d'utilisation standard est la lecture d'un film/vidéo, la synchronisation précise avec l'image est donc primordiale.

Contexte : Wheezy et logiciel libre

Le laptop est relié au serveur en wifi 802.11G, La latence entre le laptop et le serveur est celle d'un réseau wifi assez moyen :

$ ping -q -c30 marvin.local
--- marvin.local ping statistics ---
30 packets transmitted, 30 received, 0% packet loss, time 29040ms
rtt min/avg/max/mdev = 4.077/5.564/8.724/1.515 ms

On peut supposer que cette latence est suffisament basse et stable pour ne pas générer de décalages audio/vidéo gênants (tout dépend de comment est gérée cette latence sous le capot évidemment).

Plusieurs tests2 m'indiquent une capacité du lien sans fil de ~16Mbps entre le client et le serveur. Un son « qualité CD » (non compressé) a un débit de 1.4Mbps, la bande passante n'est donc a-priori pas un goulot d'étranglement.

Le serveur est sous Debian Wheezy, le laptop aussi... et je n'ai pas envie de me prendre la tête avec une configuration compliquée côté client, pouvant-être ammené à la reproduire sur plusieurs machines.

Accessoirement, une compatibilité cliente pour OSX serait un plus. Voilà pour la liste au Père-FLOSSël.

Technologies envisageables

PulseAudio

… Est un serveur de son pour GNU/Linux3, répandu sur toutes les distributions et installé par défaut avec Gnome et Unity. Il est célèbre pour avoir été fort décrié au moment de son intégration à ubuntu, ayant causé à l'époque plus de mal que de bien. Depuis ? Ça va mieux, merci.

Pulseaudio n'est pas réservé au desktop, peut être installé sur une machine headless. Caractéristique intéressante, il permet de diffuser du son via le réseau :

  • En unicast, via TCP : pour déporter le rendu sonore via le réseau (notre cas) ;
  • En multicast, via UDP : afin de diffuser un même son vers plusieurs systèmes de rendu sonore présents en différents points du réseau (ex: configuration multi-pièce).

Toutes les instances de pulseaudio sont en mesure de se comporter en serveur et/ou en client réseau. C'est à dire de restituer du son sur des enceintes ou bien d'en envoyer sur le réseau.

Le son transmis par pulseaudio n'est pas compressé.

RAOP (Airport, Airplay…)

Les Airport sont des petits boitiers blancs propriétaires et coûteux vendus par Apple, agissant comme un serveur capable de recevoir le son d'autres appareils via le réseau pour le diffuser sur sa propre sortie audio. Un peu ce que je veux bricoler en somme. Pour en avoir vu en action, ça marche bien, et même sur du wifi de qualité médiocre…

@toi-lecteur : Je n'ai par contre pas trop idée de ce que ça vaut au niveau de la synchro audio/vidéo, une expérience ?

Le protocole derrière tout ça se nomme Remote Audio Output Protocol (RAOP). Il est fermé (Apple inside...) mais basique : il s'appuie sur RTSP pour négocier les sessions et RTP pour transmettre le son compressé4 à travers le réseau, le tout de manière chiffrée.

Fort heureusement, RAOP a été rétro-ingéneré et ses clefs de chifrement extraites des logiciels Apple. On trouve donc dans la natures des implémentations de clients et de serveurs open-source utilisant ce protocole.

Tests

Disclaimer : Ces tests ne reflètent pas la valeur intrinsèque des logiciels abordés, mais leur état de fonctionnement "out-of-the-box" pour mon cas d'utilisation, à la date d'aujourd'hui et avec un système Debian Wheezy.

PulseAudio

L'installation du serveur pulseaudio, comme celle du client est d'une simplicité déroutante, je reprends les points essentiels de l'excellent tutoriel de Manu Revah.

Côté serveur

# apt-get install pulseaudio pulseaudio-module-zeroconf avahi-daemon dbus-x11

Dans /etc/default/pulseaudio :

PULSEAUDIO_SYSTEM_START=1

Dans /etc/pulse/system.pa, ajouter (adapter les adresses réseau)

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24
load-module module-zeroconf-publish

Puis

# service pulseaudio restart

Côté client

Si vous utilisez gnome, ceci suffira :

# apt-get install paprefs

Lancer paprefs5. Puis, pour activer la prise en charge du son en réseau :

paprefs: cocher la case "Make discoverable pulseaudio sound-devices available localy"

Et voilà, vous pouvez immédiatement basculer entre votre carte son et celle de votre serveur depuis le contrôleur de son de gnome6 :

Le serveur de son est normalement annoncé en réseau via zeroconf/avahi. Donc pas de configuration réseau à effectuer.

paprefs: cocher la case "contrôleur de son gnome3"

Et… ça marche directement en-dehors-de-la-boîte !

… M'enfin en vérité si la connection filaire donne de supers résultats, ça n'est pas satisfaisant du tout à travers un réseau wifi (voir ci-après).

Tests logiciels

  • VLC avertit que pulse a une trop forte latence et risque d'avoir des soucis7 puis égrenne de petites coupures/sacades toutes les quelques secondes...
  • MPlayer voit bien que quelque-chose cloche et adapte la cadence vidéo pour rester synchronisé : l'image ralentit et accélère en permanence
  • lecteur radio flash (et par extension les lecteurs sus-cités si on ne s'occupe pas de vidéo): quelques sautes toutes les quelques minutes : écoutable mais agaçant.

Bilan

Cette solution semble parfaite de simplicité sur un réseau câblé, tout est au point, y-compris les interfaces graphiques, ce qui mérite d'être signalé… Mais c'est loin d'être utilisable sur du wifi.

  • Le son saute trop pour être agréable ;
  • la synchro audio/vidéo est en revanche respectée.

RAOP : Shairport/Shairplay

Pulseaudio n'ayant pas donné satisfaction sur ces points, voyons avec le protocole lancé par Apple et détourné par de gentils hackers.

Côté client

Très bonne nouvelle, pulseaudio peut se comporter comme un client RAOP, et tout est déjà packagé, sur l'ordinateur portable, il suffit donc d'installer le paquet adapté :

# apt-get install pulseaudio-module-raop

Aller faire un tour dans paprefs (cf avant) puis de cocher "Make discoverable Apple AirTunes sound devices available locally".

La suite se passera exactemment comme pour choisir un serveur de sortie pulseaudio : les serveurs RAOP apparaîtront au sein de la liste du contrôleur de volume Gnome en-dessous des cartes son locales.

Côté serveur

J'ai pu identifier deux implémentations indépendantes8 de serveurs open-source utilisant le protocole RAOP :

  • shairport implémentation historique ;
  • shairplay plus récent, semble moins fini (en fait je n'ai pas bien compris ce qui avait motivé son écriture).

Alors j'ai essayé les deux. Pour voir.

Aucune des deux implémentations n'est empaquetée pour Debian mais ils sont très simples à compiler je ne paraphraserais pas leurs README.md respectifs, qui donnent des instructions concises et fonctionnelles assorties de la liste des dépendances pour Debian/Ubuntu.

En 3 commandes et 5 minutes, on a pour l'un comme pour l'autre un logiciel compilé et fonctionnel.

Shairport

Se démarre d'un

$ ./shairport -v

Tout semble bien se dérouler, mais quand on sélectionne la sortie shairport depuis le client, badaboum sur le serveur !

received request: SETUP rtsp://192.168.33.174/3153376862 RTSP/1.0
sending response: RTSP/1.0 400 Error

et côté client si on essaye de jouer du son :

$ mplayer test.ogg
[...]
AO: [pulse] Init failed: Connection terminated
[...]

Difficile d'en savoir plus mais en tout cas aucun son ne sort et shairport ne semble même pas accéder à la carte son du serveur11. Il se pourrait que ça soit un problème connu de pulseaudio.

En revanche, un iTunes sur OSX arrive à jouer du son vers le serveur… mais c'est plein de craquements pas bien jolis.

Bilan : Pas fonctionnel (pour moi) depuis une machine cliente GNU/Linux, et qualité moyenne sinon (depuis un mac).

Shairplay

Une fois compilée, la bête se lance depuis son dossier avec

$ ./src/shairplay

et c'est tout9.

La sortie apparaît bien dans la liste des sorties audio sur le client… et si on clique dessus… pouf ! ça fonctionne10.

Tests logiciels

J'ai essayé avec plusieurs applications utilisant le son sur l'ordinateur portable, les résultats sont ci-dessous :

  • lecteur radio flash : parfait
  • MPlayer : son haché, inaudible
  • VLC : musique : parfait, vidéo: décalage de ~400/500ms
  • Firefox (vidéo HTML5) : idem vlc, décalage plus important

Bilan : fonctionnel, pas le plus simple à mettre en place non plus côté serveur mais encore une excellente intégration à Gnome.

  • Correct pour de la musique/radio (ne saute pas)
  • Beaucoup moins pour le son d'une vidéo (décalage ~300/400ms, très agaçant)
  • Ne fonctionnait pas avec iTunes/OSX lors de mon test12
  • Fonctionne vraiment trop mal avec mplayer

Conclusion

Je n'ai rien trouvé de satisfaisant pour streamer le son d'une vidéo à travers du wifi de Debian à Debian. Pour de l'audio seul, on peut passer par shairplay13 qui se montre satisfaisant.

En revanche, observant un peu "Linux pour le Desktop" depuis quelques années, j'ai eu l'occasion de noter de bonnes choses :

  • L'autoconfiguration par avahi fonctionne du tonerre
  • Les interfaces sont bien intégrées et permettent un accès à tout

C'est un exemple de fonctionalité avancée bien présentée à l'utilisateur.

En revanche, j'ai été surpris de voir que toute cette autoconfiguration n'essayait jamais de passer par IPv6 au cours de mes expériences.

Il ne reste plus qu'à attendre que pulseaudio (non, je n'ai pas le temps pour un patch) implémente quelque-chose d'un peu robuste pour le son en réseau et ça sera parfait...

Enfin, j'ai été surpris également de voir que le (non)fonctionnement dépendait beaucoup du programme utilisé sur le client, mplayer par exemple semble très à cheval sur la synchro audio/vidéo…

En attendant, quelques pistes non encore explorées :

Bref, la lutte continue !

Merci à tous les développeurs de tous les logiciels abordés !

Bonus track : bande passante

Les bandes passantes mesurées (grossièrement) avec ethstats :

  • RAOP : 1.5Mb/s
  • PulseAudio : 1.7Mb/s

C'est assez surprenant étant donné que le son transmis en RAOP est censé être compressé en ALAC, c'est à dire fondre de 40 à 70%...


  1. Remplacer un câble audio par un câble ethernet me semble d'intérêt limité... 

  2. réalisés avec iperf 

  3. Plus généralement c'est un serveur de son pour les systèmes Posix 

  4. au format ALAC, compressé sans pertes (équivalent au FLAC), et est désormais ouvert

  5. Aussi connu dans les menus sous le nom de "Préférences Pulseaudio" 

  6. Sinon regardez éventuellement du côté de pasytray

  7. VLC conseille d'utiliser pulse3 pour moins souffrir de problèmes liés à la latence, moi je veux bien mais je ne vois pas dans les changelog de Pulseaudio sur quoi se fonde ce conseil, des pistes ? 

  8. C'est à dire qu'elles font serveur audio et pas spécialement le café en plus

  9. des options sont disponibles, voir --help, l'option -v peut se montrer utile. 

  10. En revanche étonnament, sur deux cartes son différentes testées, l'une (Griffin iMic) fonctionnait avec shairplay et l'autre (VIA Vinyl VT1708) restait muette bien qu'active11

  11. astuce rapide pour savoir si un processus utilise la carte son et avec quelques options : $ cat /proc/asound/card*/pcm0p/sub0/hw_params 

  12. apparaît dans la liste des sorties son mais ne peut-être sélectionné 

  13. et probablement via shairport lorsqu'on arrive à le faire fonctionner.