Fisch´s Projekte-Seite

Project start: November 2020

Last updated: July 2021

Language: German

Multiroom Audio




Stellen wir uns folgendes Szenario einmal vor: Du h¨rst im Wohnzimmer Musik (Lokales Netzwerk, Spotify, Schallplatte, Kassette) oder guckst einen Livestream und hast plötzlich das Bedürfnis etwas zu Essen zu machen. In der Küche stehend fällt dir der Lautstärkeverlust auf. Nicht jeder hat dann die Option den Verstärker entsprechend aufzudrehen.
Eine Lösung ist hier ein Multiroom Audio Player, welcher im besten Fall noch die Geräte synchronisiert. Für mich war Snapcast genau die Software, die ich suchte. Der Snapcast Server läuft auf einer im lokalen Netzwerk erreichbaren Maschine und kümmert sich um das Verteilen und die Snychronisation der verbundenen Clients.
Die Snapcast Clients wollte ich so standalone wie möglich halten und habe dazu das platz- und preistechnische Minimum gewählt: Raspberry Pi Zero.
Dieser hat keinen onboard Audioanschluss, die Klinkenbuchse der Raspberry Pi 1 bis 4 offenbart jedoch auch keine gute Audioqualität. Hier kommen Digital zu Analogkonverter (kurz DAC) Module zum Einsatz, welche PCM kodierte Audiodaten aus den I²S Pins des Raspberry Pi GPIO Headers in ein Analoges Audiosignal umwandeln.
Die Synchronisierung der abspielenden Geräte erfordert eine Pufferung des Audiosignals. Auch, wenn sich diese optimieren Lässt ist dies nicht für Echtzeitanwendungen wie Spiele gedacht. Für Filme könnte das Videosignal an anderer Stelle entsprechend verzögert werden, damit habe ich mich jedoch bisher nicht befasst und schalte einfach zwischen direkter Wiedergabe und Snapcast um.



Nachfolgend ein reduzierter Einblick auf die Verbindungen zwischen Hardware und Software (Stand Juli 2021). Beide Clients werde ich nachfolgend bebildert näher beschreiben.


Client 1



Dieses Gerät habe ich als erstes gebaut, da es möglichst einfach funktioniert und daher gut zum Testen war. Es besteht aus einem Pi Zero und einem Wondom TAS230DI MkII. Dieser Digitalverstärker beinhaltet einen I²S DAC und eine Class D Stereoendstufe.


In das aus 4mm Pappelsperrholz geschnittene Gehäuse kam noch ein Spannungsregler und ein Taster als Power on/off schalter. Dieser ist an GPIO 3 / Physical Pin 5 angeschlossen und verbindet bei Betätigung diesen mit GND (Pin 6). Das Script pi-power-button von Howchoo macht das Herunterfahren dann möglich.


Strom kommt aus einem 19V Netzteil, da das Verstärkermodul etwas mehr Fluff als der Pi benötigt. Ein Pololu Stepdown auf 5V kümmert sich dann um den Raspberry.


Dieses Gerät kam so nun auf einen Küchenschrank und wurde mit einem Paar JBL Control One verbunden. Irgendetwas muss aber mit meinem Wondom TAS230DI nicht in Ordnung sein. Die Tiefen waren deutlich zu leise. Abhilfe schaffte libasound2-plugin-equal als Equalizer Plugin für den Alsamixer.
Auch hatte ich zu Anfang oft Probleme mit kurzen Aussetzern. Hier war die onboard W-Lan Antenne des Pi Zero Schuld. Empfehlen kann ich den "Edimax EW-7612UAn V2" WiFi USB Stick, da dieser Treiberseitig gut unterstützt wird. Gefolgt bin ich der Anleitung von datenreise.de.
In der /etc/modprobe.d/8192cu.conf folgende Zeile einfügen:

options 8192cu rtw_power_mgnt=0 rtw_enusbss=0


Die WiFi Credentials eintragen in /etc/wpa_supplicant/wpa_supplicant.conf
Un das Onboard WiFi und Bluetooth deaktivieren in /boot/config.txt mit:

dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt


Danach Reboot und der Stick sollte als z.B. wlan0 erkannt sein.


Client 2



Während Client 1 versteckt in der Küche wohnt sollte für das Wohnzimmer etwas ansprechenderes gebaut werden. Dort habe ich auch die Möglichkeit ein Lankabel zu nutzen. Als Hat für den Pi Zero funktionierte das Waveshare 16595 Ethernet und USB Modul hervorragend. Draufstecken, Micro USB Brücke für USB dran und läuft.
Weiter ist ein HifiBerry DAC+ ADC Pro für die digital zu analog und analog zu digital Konvertierung zuständig. Diesen habe ich gewählt, da er Ausgänge sowie Eingänge hat und recht schmerzfrei am Raspberry Pi unterstützt werden sollte, was ich von der zuerst gekauften AudioInjector Ultra Sound Card nicht behaupten kann. (Tipps dazu nehme ich gerne an) Hier reichte ein "dtoverlay=hifiberry-dacplusadcpro" in der /boot/config.txt aus. Siehe: Datasheet DAC+ ADC Pro.
Audio kann auf Mikrofon oder Line Level rein gehn, entweder durch eine 3,5 mm Stereo Klinkenbuchse oder Symmetrisch über einen Pinheader dahinter. Diesen habe ich mit zwei XLR/6,35 mm Kombi Neutrikbuchsen verbunden. Gehäusetechnisch war der Lasercutter wieder Gold wert. 3 mm dickes grau getöntes Plexiglas lässt die ganzen roten LED's im Betrieb leicht durchschimmern. Da mit der Soundkarte und dem Ethernet Hat der Pi Stack etwas zu hoch würde musste das Hifiberry zur Seite weichen. Ein altes IDE Kabel eignet sich super als Verbindung der beiden Komponenten.

Während die Tonübertragung für die Wiedergabe durch die Snapcast Server- und Clientsoftware implementiert wird musste ich den Input von PC/TV, Schallplattenspieler, etc. selber weiterleiten. Hierbei hatte ich Erfolg mit GStreamer, welches die Audiorohdaten per TCP an den Snapcast Server sendet, welcher sie von dort synchronisiert an alle Clients zurück verteilt. Nach installation der benötigen Pakete mit:

sudo apt-get install libgstreamer1.0-0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-alsa

setzt folgende Zeile setzt dies in die Tat um:

gst-launch-1.0 alsasrc ! audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! tcpclientsink host= port=4953


Dem Snapcast Server teilt man dies in der /etc/snapcastserver.conf wie folgt mit:

stream = tcp://:4953?name=aux_tcp


GStreamer an sich lässt sich nicht als Deamon betreiben, was ein Autostart nicht so einfach möglich macht. Hierzu habe ich GStreamer Deamon "GstD" nach der Anleitung gebaut und installiert.
Besagten Autostart realisierte ich durch ein systemd service unter /etc/systemd/system/gstd.service mit dem Inhalt:

[Unit]
Description=GStreamer Daemon
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=pi
ExecStart=/usr/local/bin/gstd

[Install]
WantedBy=multi-user.target


Aktivieren mit "systemctl enable gstd" bzw starten mit start.

Der gst-launch Befehl von oben muss dann in GstD als Pipeline erstellt werden. Da die Pipelines nach einem Reboot nicht erhalten bleiben brauchte ich zwei Scripts und einen weiteren Service.
Eins zum Starten unter /home/pi/start-gst-client.sh:

#!/bin/sh
gst-client pipeline_create snapcastaux alsasrc ! audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wa$
gst-client pipeline_play snapcastaux


Eins zum Stoppen unter /home/pi/stop-gst-client.sh:

#!/bin/sh
gst-client pipeline_stop snapcastaux
gst-client pipeline_delete snapcastaux


Nicht vergessen ausführbar zu machen:

chmod u+x start-gst-client.sh
chmod u+x stop-gst-client.sh


Und der service unter /etc/systemd/system/gst-client.service hier als Link, da der Codeanteil hier sonst Überhand nimmt: gst-client.service
Das "ExecStartPre=/bin/sleep 5" sorgt dafür, dass GstD zuerst läuft. Nicht besonders elegant, funktioniert aber. "systemctl enable gst-client.service", dann Reboot und Daumen drücken.


Mit dem leicht transparenten Gehäse als Vorlage konnte ich es nicht lassen eine LED Anzeige dahinter zu verbauten. Da hier Beispielsweise Songtitel angezeigt werden sollen musste es etwas Alphanumerisches sein. Zwei 4-Stellen 14-Segment Displays mit ht16k33 I²C Treiberchip waren günstig und genau das was ich suchte.
Mit python3 und pip3 installiert nutze ich adafruit-circuitpython-ht16k33 als python package für die Ansteuerung des Displays.
Auch zwei Touch Buttons sind links und rechts hinter die Front geklebt. Display und Buttons kommunizieren durch den Pi mit dem MQTT Server. Der Code dazu hier: repos.ctdo.de/interfisch/mqtt_pi_led-display
An dem rechten Display habe ich die Lötbrücke A0 gesetzt, damit bekommt es 0x71 statt 0x70 als I²C Adresse. Ansonsten sind beide Displays parallel an 3v3, GND, SCL und SDA am Pi GPIO Header angelötet. Hier hatte ich keine Probleme mit dem I²C Device auf dem Hifiberry. Die Touch Sensoren sind kleine Platinen von Reichelt namens Debo Touch. Diese habe ich bereits erfolgreich bei meiner IoT Waage verwendet. GPIO 23 und 24 waren dafür noch frei. Welche GPIO Pins vom Hifiberry belegt sind lässt sich unter hifiberry.com/docs/hardware/gpio-usage-of-hifiberry-boards/ nachlesen.


Jetzt ist die Box aber auch gut voll.


Oft finde ich es bei Projekten schade, nicht mehr das Innere sehen zu können in das 99 Prozent der Arbeit gegangen ist. Hier finde ich ist mit ein guter Kompromiss gelungen.


Die roten LED's der 14-Segment Anzeige passen gut zu den roten SMD LED's auf den Platinen. Auch das Berühren des Touch Tasters wird mit einer roten LED auf dessen Rückseite Quittiert.
Für die Anzeige habe ich bisher statischen Text und Scrolltext in verschiedenen Animationen implementiert. Artist und Titel bekomme ich in Node-Red beispielsweise über die MPD API.