Linux Embedded

Le blog des technologies libres et embarquées

Raspaudio : comment diffuser le son de votre PC dans votre salon

La dernière version de buildroot a ajouté un grand nombre d'outils pour faciliter l'intégration dans des projets embarqués complets. Nous avons utilisé ces possibilités pour construire un petit projet libre permettant de diffuser facilement le son de votre PC vers la carte son intégrée de la carte Raspberry Pi.

Présentation de Raspaudio

Le projet Raspaudio (disponible ici) est un projet simple de récepteur de flux venant du framework de diffusion de son Pulseaudio. Pulseaudio est utilisé sur la plupart des distributions bureautique pour  gérer les différents flux sonores, partager la carte son entre différentes applications et, de façon plus générale, gérer l'aspect système du son.

Pulseaudio a la capacité de gérer des cartes son virtuelles qui se font passer pour des cartes son mais sont implémentées de façon logicielle. L'un des types de carte virtuelle est le stream réseau. Pulseaudio est capable de détecter automatiquement des machines sur le réseau local acceptant les flux sonores et de les proposer comme carte son locale. Nous allons configurer une Raspberry Pi pour démarrer automatiquement dans ce mode, puis nous configurerons le PC pour détecter la Raspberry Pi.

Notons que cette solution est une solution basée sur les flux et non sur les fichiers. Contrairement à une solution de type DLNA (qui partage une bibliothèque musicale et joue la musique sur un périphérique distant) le son est décodé sur le PC et envoyé décodé vers la Raspberry pi. Cela présente un certain nombre d'avantages et d'inconvénients

  • Le débit réseau et la qualité nécessaire sont bien plus importants. Le streaming via Wi-Fi peut être problématique
  • Vous pouvez streamer n'importe quel son, dont les son systèmes. La carte son réseau est totalement banalisée.
  • Vous pouvez jouer des son simultanément sur la Raspberry et le PC. Pulseaudio prends un peu de temps pour synchroniser les deux flux mais cela finit par converger.

Compilation du système de fichier pour la Raspberry Pi

Le projet Raspaudio est un projet basé sur buildroot mais il ne contient pas l'ensemble des sources de buildroot. Il utilise un sous-module git pour pointer vers le dépôt officiel. Nous discuterons l'intégration de buildroot dans le projet plus bas dans cet article. Pour obtenir les sources utilisez la commande suivante :

$ git clone --recursive  git@github.com:Openwide-Ingenierie/raspaudio.git

Notez le paramètre --recursive qui permet de cloner non seulement le dépot raspaudio mais également le dépot buildroot qui est inclus en tant que sous-module.

Une fois que vous avez votre clone, il ne vous reste plus qu'à compiler les sources. Cela se fait de façon très classique:

$ cd raspaudio
$ make

Rien de bien compliqué. Comme toutes les premières compilations buildroot, ce sera néanmoins très long. Il faut télécharger et compiler les sources de l'ensemble des applications qui seront embarquées sur le système de fichier.

Une fois la compilation terminée vous trouverez l'ensemble des fichiers à installer sur votre raspberry pi dans le sous répertoire output/images

	output/images/
	├── rootfs.tar
	├── rpi-firmware
	│   ├── bootcode.bin
	│   ├── cmdline.txt
	│   ├── config.txt
	│   ├── fixup.dat
	│   └── start.elf
	└── zImage

Ces fichiers s'installent ensuite de façon classique sur votre Paspberry Pi : le contenu du répertoire rpi-firmware ainsi que le fichier zImage dans la première partition FAT de votre carte SD, le contenu du fichier rootfs.tar dans une seconde partition ext4.

Il ne vous reste plus qu'à vérifier que votre carte démarre correctement. Vous pouvez utiliser ssh depuis la machine qui a compilé buildroot pour vous connecter à la carte. Aucun mot de passe n'est nécessaire car la clé publique de la machine de build a été intégrée au root-filesystem de la carte. La Raspberry Pi utilise une requête DHCP pour configurer son réseau.

configuration du PC

Nous avons donc une Raspberry Pi qui est prête à recevoir un flux réseau. Il ne reste plus qu'à configurer notre PC pour la découvrir et l'utiliser. Tout d'abord le programme graphique paprefs permet de configurer pulseaudio pour gérer le réseau :
tmp

L'option sélectionnée sur la capture d'écran configure pulseaudio pour détecter automatiquement  les machines proposant de recevoir les flux audio et de les afficher comme périphérique local. Vous pouvez également sélectionner l'option du dernier onglet qui permet d'ajouter une carte virtuelle afin d'avoir le son simultanément sur toutes les cartes son.

Notez que paprefs n'est pas toujours installé par défaut. Si ce n'est pas le cas ajoutez le avec votre outil de gestion de paquetage préféré.

Une fois cette option activée vous pouvez aller dans le menu de gestion normale de pulseaudio. Lancez la commande pavucontrol, puis rendez vous dans l'onglet "Périphériques de sortie". Une nouvelle carte son devrait apparaître.

tmp

Lorsque vous lancez une application produisant du son, celle-ci devrait apparaître dans l'onglet "Lecture" de pavucontrol.

tmp

Un menu déroulant (en haut à droite de la ligne de chaque application) permet de sélectionner vers quelle carte son rediriger l'audio.

Sécurisation de l'accès.

Votre Raspberry autorise n'importe quelle machine à envoyer un flux audio vers sa carte son. Cela peut être suffisant sur un réseau personnel et cela simplifie le déploiement, mais sur le long terme il vaut mieux sécuriser cet accès. Pour cela, Raspaudio ajoute un paramètre dans le menu de configuration de buildroot. Rendez vous dans le répertoire de raspaudio et lancez la configuration de buildroot.

$ make menuconfig

Rendez vous dans le dernier sous-menu "User-provided options". vous y trouverez une unique option "pulseaudio access list" qui vous permet d'entrer une liste d'adressses IP autorisées à se connecter. Si vous laissez cette option vide, n'importe qui peut se connecter. Une fois cette option modifiée vous pouvez relancer make (qui sera, cette fois, très rapide) et réinstaller le système.

Détail des paquetages et modifications pour Raspaudio

Nous avons fini la présentation du projet, intéressons nous à sa réalisation. Du point de vue de buildroot, le projet raspaudio est basé sur la configuration par défaut de la Raspberry Pi (située dans buildroot/configs/raspberrypi_defconfig) avec les modifications suivantes :

  • Le nom de la machine a été changé en Raspaudio
  • La chaîne de compilation supporte l'option WCHAR
  • La gestion des device nodes utilise udev
  • Les paquets rpi-userland, pulseaudio et alsa ont été ajoutés pour gérer le son
  • Le paquet avahi  a été ajouté pour permettre la détection automatique du service sur le réseau
  • Le paquet  dbus est nécessaire pour la communication entre avahi  et pulseaudio 
  • Le paquet ntpdate a été ajouté pour régler l'horloge de la carte au démarrage.
  • Le paquet openssh a été ajouté pour permettre la connexion à distance

En plus de ces modifications de configuration, quelques changements plus subtils ont été effectués

Le script add_ssh_key.sh est exécuté après la génération des paquetages ("post-build-script") Il va chercher la clé publique de l'utilisateur faisant la compilation et l'ajoute dans la liste des clés autorisées de l'utilisateur root de la carte. Cela permet à cet utilisateur de se connecter sans mot de passe sur la Raspberry Pi.

Le répertoire raspaudio_overlay remplace un certain nombre de fichiers sur la cible :

raspaudio_overlay/
└── etc
    ├── network
    │   └── interfaces
    └── pulse
        └── daemon.conf
  • Le fichier /etc/network/interfaces ajoute la configuration de l'interface réseau eth0 via DHCP
  • Le fichier /etc/pulse/daemon.conf modifie la configuration de pulseaudio pour autoriser le chargement de modules

Le script raspaudio_adjust.sh modifie le fichier /etc/pulse/system.pa (généré par la compilation de pulseaudio) pour autoriser la connexion réseau et gérer les autorisations d'accès

Enfin nous utilisons une version légèrement modifiée du fichier de configuration de busybox pour modifier les paramètres d'appel de DHCP. Par défaut busybox ne tente qu'une fois de se connecter au serveur DHCP. Notre modification permet de ré-itérer la connexion.

Intégration dans buildroot

Si vous regardez les détails du fichier raspaudio_defconfig vous remarquerez que nous n'avons pas mentionné toutes les différences. Il y a un certain nombre de modifications qui ne concernent pas le système généré mais la façon de le générer.

Ce projet n'est pas qu'une solution pratique pour le multimédia de salon. Il s'agit aussi d'un exemple d'intégration de buildroot comme sous-module d'un projet.

Utiliser un sous-module permet de facilement séparer nos modifications spécifiques du code de buildroot. Nous pouvons sauvegarder nos scripts d'ajustement, nos fichiers de configuration et le répertoire overlay_raspaudio dans notre propre dépôt git sans avoir besoin de travailler sur une branche du dépôt buildroot. Nous pourrions également ajouter nos paquetages dans notre dépot git facilement et garder l'historique du développement du paquetage.

Une fois le paquetage suffisamment mature, il suffit de le déplacer dans l'arborescence buildroot pour générer facilement les patch à envoyer upstream.

Buildroot nous permet également de sauvegarder dans notre dépôt un ensemble de patch à appliquer lors de la construction des paquets. A nouveau, ce n'est pas nécessaire pour Raspaudio.

L'aspect le plus complexe de l'intégration de buildroot dans Raspaudio concerne le fichier de configuration de buildroot. Normalement ce ficher est sauvegardé à la racine du répertoire buildroot/ mais nous ne pouvons pas faire cela car ce fichier étant une partie fondamentale du projet il doit être sauvegardé sous le git principal et ne sera jamais intégré dans le projet buildroot. On ne peut donc pas le garder dans le sous-module.

Buildroot permet également de sauvegarder le fichier .config dans le répertoire output/ qui contient les sources de tous les paquetages. A nouveau, cette solution n'est pas souhaitable pour raspaudio car output est un répertoire "jetable" qui n'est pas géré en configuration.

La solution de Raspaudio consiste à appeler automatiquement, depuis le Makefile, les cibles defconfig et savedefconfig avant les vrai commandes à buildroot. Cela permet de générer et maintenir à jour le fichier raspaudio_defconfig dans le projet. Ce fichier contient une version compressée de la configuration (seuls les champs modifiés sont sauvegardés) qu'il est aisé de comparer, relire et (le cas échéant) fusionner avec git.

Réutiliser les idées de Raspaudio pour vos propres projets

L'intégration fine de buildroot dans Raspaudio mérite d'être réutilisée. En fait, Raspaudio a été pensé comme un exemple de projet à réutiliser pour vos propres besoin. Voici comment créer un projet basé sur buildroot et le sauvegarder dans git.

Création d'un nouveau projet

Tout d'abord, créons notre répertoire de travail et sauvegardons le sous git

$ mkdir mon_projet
$ cd mon_projet
$ git init

Ajoutons buildroot comme sous-module

$ git submodule add git://git.buildroot.net/buildroot buildroot

Vous pouvez utiliser l'option -b tag pour cloner une version particulière de buildroot sinon, c'est la branche master qui sera utilisée.

Nous allons récupérer le fichier Makefile de Raspaudio.

$ wget https://raw.github.com/Openwide-Ingenierie/raspaudio/master/Makefile

Ajoutons quelques fichiers nécessaires à buildroot :

$ touch Config.in
$ touch external.mk
$ wget https://raw.github.com/Openwide-Ingenierie/raspaudio/master/.gitignore

Il faut ensuite éditer le nom de notre projet dans le fichier Makefile. Le champ à modifier s'appelle PROJECT_NAME. Dans la suite de cet exemple nous appellerons ce nouveau projet mon_projet

Nous pouvons sauvegarder cette infrastructure dans git :

$ git add Makefile external.mk Config.in .gitignore
$ git commit -m"Infrastructure projet"

Modification de la configuration de Buildroot

L'infrastructure de notre projet est en place, mais c'est la seul chose que nous avons faite jusqu'à présent.

Tout d'abord les menu de configuration de buildroot fonctionnent parfaitement. Pour initialiser notre projet à partir des options recommandées pour une Raspberry Pi, il suffit d'utiliser la commande suivante :

$ make raspberrypi_defconfig

Un nouveau fichier est créé mon_projet_defconfig qui contient toute la configuration de buildroot. Pensez à l'ajouter à git.

Vous pouvez ensuite modifier le système avec les commandes habituelles :

$ make menuconfig

Utilisation des overlay

La configuration de buildroot permet de sélectionner des logiciels mais un projet complet a généralement besoin de configurer ces logiciels. La façon la plus simple de configurer un logiciel sous buildroot est d'utiliser le mécanisme d'overlay pour remplacer le fichier de configuration. L'infrastructure que nous avons mis en place nous permet de le faire facilement.

Nous allons remplacer le fichier /etc/network/interfaces qui contient la configuration réseau. Pour cela, commençons par créer le répertoire d'overlay :

$ mkdir mon_projet_overlay
$ cd overlay

Dans ce répertoire nous suivons la structure du système de fichiers cible pour ajouter les fichiers à remplacer :

$ mkdir -p etc/network/

Il suffit ensuite d'éditer le fichier de configuration et celui-ci sera utilisé dans le build final :

$ gvim etc/network/interfaces

Enfin, ce fichier faisant partie de la configuration du projet, il ne faut pas oublier de le sauvegarder.

$ git add etc/network/interfaces
$ git commit -m"ajout du fichier de configuration du reseau"

Gestion de plusieurs configurations dans la même arborescence

Généralement un projet buildroot ne comporte qu'une unique configuration mais certains projets peuvent néanmoins en gérer plusieurs en parallel. Vous pouvez garder chaque configuration sur sa propre branche git mais il est également possible d'utiliser plusieurs PROJECT_NAME en parallèle.

Pour invoquer buildroot avec un projet alternatif, utilisez la commande suivante

$ make PROJECT_NAME=<nom du projet> <cible>

Chaque projet aura son propre répertoire output mais ils partageront le répertoire de téléchargement. Vous pouvez facilement gérer des configurations mutliples de cette façon

Autres méthodes de personnalisation

Buildroot offre divers moyens de personnaliser vos projets que nous ne détaillerons pas.

  • Vous pouvez appliquer des patch sur des paquetages déjà intégrés dans buildroot, la méthode est décrite ici
  • Vous pouvez remplacer le code source d'un paquetage intégré dans buildroot par votre propre arborescence, la méthode est décrite ici. Le fichier d'OVERRIDE à utiliser doit s'appeler $(PROJECT_NAME)_local.mk
  • Vous pouvez ajouter votre propre paquet en modifiant les fichiers external.mk et Config.in à la racine de votre projet. La méthode est détaillée ici. Vous pouvez utiliser la variable $(PROJECT_NAME) dans ces deux fichiers pour discriminer entre plusieurs configurations

Conclusion

Raspaudio est un petit projet libre qui vous permettra de résoudre facilement un  problème simple, n'hésitez pas à le cloner sur github, à le modifier pour vos besoins et à ouvrir des pull-requests pour nous permettre d'intégrer vos améliorations...  Mais Raspaudio ce n'est pas que ça.

Raspaudio c'est aussi un exemple de projet Buildroot géré sous git, qui peut facilement suivre les évolutions de buildroot grâce aux sous-modules et qui peut vous servir de base pour vos propres projets. N'hésitez pas à réutiliser cette infrastructure... Mais Raspaudio ce n'est pas que ça.

Raspaudio est surtout le premier projet libre créé par Open Wide Ingénierie. Nous prenons soins de remonter autant que possible nos contributions dans les différents projets libres que nous utilisons (dont, évidemment, buildroot) mais c'est la première fois que nous créons un projet à partir de rien. Raspaudio ne sera jamais un grand projet open-source avec des milliers de contributeurs mais il servira de modèle pour les futurs projets open-source de la société que nous nous ferons un plaisir de présenter sur ce blog.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.