Als stereo-installatie gebruik ik een Raspberry Pi die eveneens als domotica-controller dienst doet, uitgebreid met een DigiAMP+ eindversterker. Radio luisteren we nu via internet. En TV kijken we al lang via internet op de monitor van de computer. Maar hoe koppel je alles aan elkaar, jawel via het netwerk.
Er bestaat verschillende software om geluid via een netwerk naar andere apparaten te sturen. Maar bij het kijken naar TV en/of video moet je letten op latency (vertraging). Een te hoge latency zorgt dat de lippen van sprekende mensen reeds bewegen voor je het geluid hoort. M.a.w. het geluid loopt niet synchroon met het beeld, het geluid loopt namelijk achter op de beelden.
Na lang zoeken kon enkel Roc Streaming de latency zo laag houden dat het niet meer opvalt.
Eerst werd de versterker uitbreiding (HAT) op de Raspberry Pi geïnstalleerd. De luidsprekers aangesloten. Raspberry Pi OS geconfigureerd om de versterker te gebruiken. MPD software (of iets dergelijks) geïnstalleerd en geconfigureerd om radio te beluisteren. De Raspberry Pi kan dus al als radiotuner en versterker fungeren.
Computers met eenvoudige audio hardware hebben meestal geen mogelijkheid om het geproduceerde geluid op te nemen. En dus ook niet de mogelijkheid om geluid via het netwerk om te leiden naar een ander apparaat. Gelukkig bestaat er een software oplossing: PipeWire.
PipeWire is een nieuw multimedia-systeem. Het is bedoeld om zowel audio als video op te nemen en af te spelen met een minimale vertraging (latency) en biedt ondersteuning voor PulseAudio, JACK, ALSA en GStreamer-applicaties. Daarenboven wordt het in Debian Trixie standaard gebruikt als geluidsverwerker en ondersteund het standaard Roc Streaming.
De Roc Toolkit zijn op een computer met Debian Trixie en KDE Plasma standaard geïnstalleerd. Je moet de Roc Toolkit enkel in PipeWire activeren. De computer wordt de geluidsbron, de Raspberry Pi de ontvanger. M.a.w. De op de computer geproduceerde geluiden moeten via het netwerk worden verzonden waarbij deze door de Raspberry Pi worden ontvangen en afgespeeld.
Je activeert de computer als geluidsbron door de volgende configuratiemap aan te maken:
dany@pindabook:~$ mkdir -p ~/.config/pipewire/pipewire.conf.d
Daarna kan je het configuratiebestand voor de Roc Toolkit aanmaken:
dany@pindabook:~$ nano ~/.config/pipewire/pipewire.conf.d/roc-sink.conf
Met de volgende inhoud:
context.modules = [
{ name = libpipewire-module-roc-sink
args = {
fec.code = rs8m
remote.ip = 192.168.129.2
remote.source.port = 10001
remote.repair.port = 10002
sink.name = "Roc Sink"
sink.props = {
node.name = "roc-sink"
}
}
}
]
Zorg ervoor dat je de instelling remote.ip aanpast naar het IP adres van de Raspberry Pi (ROC afspeelapparaat).
De overige instellingen zijn standaard en kan je zonder problemen overnemen.
Raadpleeg voor meer configuratiemogelijkheden de volledige online documentatie.
Sla de configuratie op (Ctrl+s) en sluit nano af (Ctrl+x). Om Roc Streaming onder PiweWire effectief te activeren, herstart je de computer.
Naast PipeWire wordt in Debian Trixie met KDE Plasma het PulseAudio geluidssysteem gebruikt. PulseAudio informatie vraag je op met:
dany@pindabook:~$ pactl info
Server String: /run/user/1000/pulse/native
Library Protocol Version: 35
Server Protocol Version: 35
Is Local: yes
Client Index: 133
Tile Size: 65472
User Name: dany
Host Name: pindabook
Server Name: PulseAudio (on PipeWire 1.4.2)
Server Version: 15.0.0
Default Sample Specification: float32le 2ch 48000Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.pci-0000_00_1b.0.analog-stereo
Default Source: alsa_input.pci-0000_00_1b.0.analog-stereo
Cookie: b50b:d184
De beschikbare afspeelapparaten geef je weer met:
dany@pindabook:~$ pactl list sources short
37 roc-sink.monitor PipeWire float32le 2ch 44100Hz SUSPENDED
60 alsa_output.pci-0000_00_1b.0.analog-stereo.monitor PipeWire s32le 2ch 48000Hz SUSPENDED
61 alsa_input.pci-0000_00_1b.0.analog-stereo PipeWire s32le 2ch 48000Hz SUSPENDED
Zonder de short optie krijg je meer informatie.
Ook in de Systeeminstellingen bij het onderdeel Geluid merk je het ROC Sink Afspeelapparaat op. Doordat we de Raspberry Pi nog niet als ontvangende ROC Streaming apparaat hebben geconfigureerd, zal dit nog niet werken.

We gaan daarbij op dezelfde manier te werk, het aanmaken van de configuratiemap:
pi@raspberrypi:~ $ mkdir -p ~/.config/pipewire/pipewire.conf.d
En deze keer het aanmaken van de instellingen voor de ROC Streaming ontvanger:
pi@raspberrypi:~ $ nano .config/pipewire/pipewire.conf.d/roc-source.conf
Met de inhoud:
context.modules = [
{ name = libpipewire-module-roc-source
args = {
local.ip = 0.0.0.0
resampler.profile = medium
fec.code = rs8m
sess.latency.msec = 50
local.source.port = 10001
local.repair.port = 10002
source.name = "Roc Source"
source.props = {
node.name = "roc-source"
}
}
}
]
Waarvan de volgende opties de belangrijkste zijn:
local.ip = in het voorbeeld ingesteld op het volledige IPv4 LAN netwerk. M.a.w. alle op het thuis netwerk aangesloten apparaten kunnen er gebruik van maken.sess.latency.msec = bepaalt de maximale toegelaten latenty in milliseconden. Indien dit niet gehaald wordt, worden geluidsfragmenten niet afgespeeld om toch de maximaal toegelaten vertraging te bereiken en dat hoor je.
Er ontstaan daardoor storende geluidsonderbrekingen.
Deze kunnen te wijten zijn aan overbelaste hardware (wat zelden het geval is) of, wat het meest voorkomt, storingen op het netwerk.
WiFi netwerken zijn veel storingsgevoeliger dan bekabelde netwerken.
sess.latency.msec hoe beter de synchronisatie tussen beeld en geluid, maar hoe groter de kans op hoorbare onderbrekingen ten gevolge van storingen.
Dit heeft alles te maken met het bufferen van de audiogegevens.
In de online documentatie wordt in het gegeven voorbeeld 5000 ms gebruikt.
M.a.w. 5 seconden vertraging tussen beeld en geluid, wat nergens op lijkt.
Bij een vertraging (latentie) van 50 ms zal je op een bekabeld netwerk geen onderbrekingen horen en zal de beeld- en geluidssynchronisatie zo klein zijn dat je ze niet opmerkt.
Sla de configuratie op (Ctrl+s) en sluit nano af (Ctrl+x). Om Roc Streaming ontvanger onder PiweWire effectief te activeren, herstart je de Raspberry Pi:
pi@raspberrypi:~ $ sudo systemctl reboot
[sudo] password for pi:
pi@raspberrypi:~ $ Read from remote host raspberrypi: Connection reset by peer
Connection to raspberrypi closed.
client_loop: send disconnect: Broken pipe
Om de beschikbare PipeWire modules weer te geven, gebruik je de opdracht:
pi@raspberrypi:~ $ pw-cli ls Module
id 1, type PipeWire:Interface:Module/3
object.serial = "1"
module.name = "libpipewire-module-rt"
id 2, type PipeWire:Interface:Module/3
object.serial = "2"
module.name = "libpipewire-module-protocol-native"
id 4, type PipeWire:Interface:Module/3
object.serial = "4"
module.name = "libpipewire-module-profiler"
id 6, type PipeWire:Interface:Module/3
object.serial = "6"
module.name = "libpipewire-module-metadata"
id 8, type PipeWire:Interface:Module/3
object.serial = "8"
module.name = "libpipewire-module-spa-device-factory"
id 10, type PipeWire:Interface:Module/3
object.serial = "10"
module.name = "libpipewire-module-spa-node-factory"
id 12, type PipeWire:Interface:Module/3
object.serial = "12"
module.name = "libpipewire-module-client-node"
id 14, type PipeWire:Interface:Module/3
object.serial = "14"
module.name = "libpipewire-module-client-device"
id 16, type PipeWire:Interface:Module/3
object.serial = "16"
module.name = "libpipewire-module-portal"
id 17, type PipeWire:Interface:Module/3
object.serial = "17"
module.name = "libpipewire-module-access"
id 18, type PipeWire:Interface:Module/3
object.serial = "18"
module.name = "libpipewire-module-adapter"
id 20, type PipeWire:Interface:Module/3
object.serial = "20"
module.name = "libpipewire-module-link-factory"
id 22, type PipeWire:Interface:Module/3
object.serial = "22"
module.name = "libpipewire-module-session-manager"
id 29, type PipeWire:Interface:Module/3
object.serial = "29"
module.name = "libpipewire-module-jackdbus-detect"
id 30, type PipeWire:Interface:Module/3
object.serial = "30"
module.name = "libpipewire-module-roc-source"
De configuratie is geslaagd als de libpipewire-module-roc-source aanwezig is (laatste in het voorbeeld). De Roc Streamer ontvanger is klaar, maar voor je deze test, controleer en regel je de geluidsweergave op de Raspberry Pi met bijvoorbeeld de volgende opdracht om een testgeluid af te spelen:
pi@raspberrypi:~ $ aplay /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
Dank zij het in PipeWire ingebouwde mengpaneel kan zowel lokaal als streaming geluid tegelijkertijd afgespeeld worden. Omschakelen hoeft dus niet langer.
Testen doe je dus vanaf de audio bron computer. Opnieuw kan dat via de Geluid Systeeminstellingen:

Je kunt daarbij zowel het linker als rechter kanaal testen. Indien de test mislukt, zal je alle configuratiebestanden moeten overlopen en controleren op fouten. Vergeet daarbij niet telkens te herstarten.
Sluit na een geslaagde test het test venster. Selecteer het ROC Sink Afspeelapparaat en test het afspelen van muziek, video, enz. via verschillende applicaties. Let bij het afspelen van gesprekken in video's op de lipsynchronisatie.
Je kunt eventuele foutmeldingen en afspeelonderbrekingen (in WiFi netwerken) weergeven door het systeemlogboek te raadplegen:
pi@raspberrypi:~ $ sudo dmesg -T | pipewire
[E][10:22:21.011243] mod.protocol-native | [module-protocol-: 803 lock_socket()] server 0x5590f940d0: unable to lock lockfile '/run/user/1000/pipewire-0.lock': Resource temporarily unavailable (maybe another daemon is running)
[E][10:22:21.012963] pw.conf | [ conf.c: 602 load_module()] 0x5590f72230: could not load mandatory module "libpipewire-module-protocol-native": Resource temporarily unavailable
[E][10:22:21.015690] default | [ pipewire.c: 124 main()] failed to create context: Resource temporarily unavailable
Als het streamen werkt, kan je het gebruiksvriendelijk maken met behulp van een script om te schakelen tussen lokaal afspelen en via het netwerk afspelen (handig voor laptops). Daarvoor hebben we de afspeelmogelijkheden van de computer nodig, geef deze weer met:
dany@pindabook:~$ pactl list sinks short
37 roc-sink PipeWire float32le 2ch 44100Hz SUSPENDED
60 alsa_output.pci-0000_00_1b.0.analog-stereo PipeWire s32le 2ch 48000Hz SUSPENDED
Daarna kunnen we de in het voorbeeld gevonden afspeelmogelijkheden omschakelen door een script aan te maken:
dany@pindabook:~$ nano HiFi.sh
Met de volgende inhoud:
# HiFi.sh
# List devices: pactl list sinks short
# Omschakelen audio uitgangen
# Welke uitgang is nu actief?
current=$(pactl get-default-sink)
if [ $current == "roc-sink" ]; then # Roc-sink is actief
# activeer de lokale audio-uitgang
pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
sleep 1
pactl -- set-sink-volume 0 75%
else # Roc-sink is niet actief
# activeer Roc-sink uitgang
pactl set-default-sink roc-sink
sleep 1
pactl -- set-sink-volume 0 60%
fi
Pas daarin de lokale audio-uitgang aan op de op jouw computer gevonden lokale afspeelmogelijkheid. Let ook op de opdrachten waarbij ik telkens een standaard volume per afspeelapparaat instel. Sla het script op en test het tijdens het afspelen van audio:
dany@pindabook:~$ bash HiFi.sh
Werk dit verder uit door bijvoorbeeld een Programmastarter menu aan te maken en deze desnoods aan de taakbalk toe te voegen. Ik gebruik een dergelijk script ook om bij het afsluiten (Afmeldscript in de Systeeminstellingen bij Autostart) van de laptop, het standaard audio afspeelapparaat in te stellen. Wat natuurlijk ook kan bij het opstarten (Aanmeldscript) van de laptop.
Aangezien we deze keer geen extra software geïnstalleerd hebben, moeten we enkel de configuratiebestanden verwijderen.
dany@pindabook:~$ rm ~/.config/pipewire/pipewire.conf.d/roc-sink.conf
dany@pindabook:~$ rm HiFi.sh
pi@raspberrypi:~ $ rm .config/pipewire/pipewire.conf.d/roc-source.conf