Skip to main content

Pipewire experiments

Architettura di OSS

diagramma OSS

Open Sound System offriva un'interfaccia in puro stile "è tutto un file": le applicazioni OSS utilizzavano /dev/dsp e /dev/audio, esposti dal modulo kernel, per accedere direttamente all'hardware, in modo esclusivo e in formato grezzo. Niente mixing software, niente volume... niente, insomma.

Architettura di ALSA

diagramma OSS

ALSA (Advanced Linux Sound Architecture) aggiunge un livello di astrazione allo stack audio Linux: le applicazioni possono usare una libreria per parlare con l'interfaccia esposta dal kernel (una API, in gergo tecnico), che a sua volta comunica con l'hardware audio.

Supporta hardware MIDI, fino a 8 schede audio simultaneamente e un sistema di plugin che lo rende molto più versatile del predecessore.

Demo: ALSA riconosce una scheda audio

su Debian Testing, installa i pacchetti libasound2, alsa-tools e alsa-utils.

Poi esegui

$ aplay -l

Demo: registrazione e playback con aplay/arecord

$ arecord -f cd > prova.wav
$ aplay prova.wav

Mettiamo che io voglia avere più applicazioni che riproducono audio nello stesso momento: uno scenario piuttosto normale, e.g. un player musicale e una scheda del browser, o una notifica del sistema.

Demo: (tentativo di) riproduzione di due file audio in contemporanea

Per riprodurre l'esperimento occorre bypassare il plugin dmix (mixing software, attivo di default).

Crea il file /etc/asound.conf:

pcm.!default {
type plug
slave.pcm hw
}

Ora prova ad eseguire aplay prova.wav in due sessioni parallele

PulseAudio e JACK

La principale novità dei server audio è nell'architettura.

diagramma OSS

C'è un processo principale, il server appunto, che esegue in background, e i diversi client (le applicazioni) vi si connettono per avere accesso alle risorse audio.

Il server si interfaccia a sua volta con il backend audio, come ALSA, per parlare con l'hardware. In questo modo c'è un singolo processo che parla con l'hardware, e il problema di mixare insieme l'audio di più applicazioni si sposta nel server audio.

Le due implementazioni di server audio più diffuse sono PulseAudio e JACK, e non a caso si concentrano su priorità differenti.

PulseAudio è più per il consumer [il comune mortale]. Offre diversi tool grafici per gestire al volo le applicazioni connesse, con funzionalità comode come la regolazione del volume per ogni processo.

Demo: interfaccia grafica di `pavucontrol` per il controllo del volume dei singoli processi

Attraverso i moduli, PulseAudio implementa anche qualche funzionalità in più, come il supporto al bluetooth e la creazione di input/output audio virtuali.

Demo: modulo loopback di PA per collegare tra loro un source e un sink

Ottenere il source da usare (e.g. un microfono):

$ pactl list sources short

55	alsa_output.pci-0000_05_00.6.HiFi__Speaker__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
56	alsa_input.pci-0000_05_00.6.HiFi__Mic2__source	PipeWire	s32le 2ch 48000Hz	SUSPENDED
57	alsa_input.pci-0000_05_00.6.HiFi__Mic1__source	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4506	alsa_output.pci-0000_05_00.1.HiFi__HDMI4__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4507	alsa_output.pci-0000_05_00.1.HiFi__HDMI3__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4508	alsa_output.pci-0000_05_00.1.HiFi__HDMI2__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4509	alsa_output.pci-0000_05_00.1.HiFi__HDMI1__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4804	bluez_input.80:C3:BA:4B:D9:88	PipeWire	float32le 1ch 48000Hz	SUSPENDED
4807	bluez_output.80_C3_BA_4B_D9_88.1.monitor	PipeWire	s24le 2ch 48000Hz	RUNNING

...in questo caso sarebbe alsa_input.pci-0000_05_00.6.HiFi__Mic2__source

Ottenere il sink da usare (e.g. altoparlanti/cuffie):

$ pactl list sinks short

55	alsa_output.pci-0000_05_00.6.HiFi__Speaker__sink	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4506	alsa_output.pci-0000_05_00.1.HiFi__HDMI4__sink	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4507	alsa_output.pci-0000_05_00.1.HiFi__HDMI3__sink	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4508	alsa_output.pci-0000_05_00.1.HiFi__HDMI2__sink	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4509	alsa_output.pci-0000_05_00.1.HiFi__HDMI1__sink	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4807	bluez_output.80_C3_BA_4B_D9_88.1	PipeWire	s24le 2ch 48000Hz	RUNNING

...in questo caso sarebbe alsa_output.pci-0000_05_00.6.HiFi__Speaker__sink

Collegarli tra loro (in questo caso ottenendo l'effetto echo/feedback):

$ pactl load-module module-loopback source=alsa_input.pci-0000_05_00.6.HiFi__Mic2__source sink=alsa_output.pci-0000_05_00.6.HiFi__Speaker__sink

JACK è un altro sound server e si rivolge al mondo del pro-audio. è incentrato su bassa latenza e gestione patchbay dei dispositivi (ovvero con modello a grafo).

Demo: grafo di JACK

Puoi mostrare il grafo di JACK con qjackctl

PipeWire: l'anello di congiunzione

PipeWire nasce nel 2015 da un progetto già iniziato in precedenza chiamato PulseVideo, che prometteva di uniformare la gestione audio e video su Linux.

L'architettura di PipeWire è simile a quella di PulseAudio: c'è un processo centrale che fa da server chiamato demone, e i vari processi che vi si connettono fanno da client.

diagramma OSS

I client in questo caso possono essere applicazioni PipeWire native, applicazioni PulseAudio o anche JACK, e tutto sarà gestito dallo stesso server di PipeWire.

La comunicazione client/server di PipeWire viaggia su un socket Unix e i messaggi seguono un protocollo chiamato PipeWire Native Protocol. Questo può incapsulare un messaggio PulseAudio, ALSA, JACK o chicchessia, e verrà poi decodificato dal modulo apposito caricato dal demone PipeWire.

Demo: installazione dei pacchetti pw e output di pactl

  • installare pipewire pipewire-alsa pipewire-pulse pipewire-jack
  • mostrare l'output di pactl list sources short e/o pactl list sinks short
55	alsa_output.pci-0000_05_00.6.HiFi__Speaker__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
56	alsa_input.pci-0000_05_00.6.HiFi__Mic2__source	PipeWire	s32le 2ch 48000Hz	SUSPENDED
57	alsa_input.pci-0000_05_00.6.HiFi__Mic1__source	PipeWire	s32le 2ch 48000Hz	RUNNING
4506	alsa_output.pci-0000_05_00.1.HiFi__HDMI4__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4507	alsa_output.pci-0000_05_00.1.HiFi__HDMI3__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4508	alsa_output.pci-0000_05_00.1.HiFi__HDMI2__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4509	alsa_output.pci-0000_05_00.1.HiFi__HDMI1__sink.monitor	PipeWire	s32le 2ch 48000Hz	SUSPENDED
4804	bluez_input.80:C3:BA:4B:D9:88	PipeWire	float32le 1ch 48000Hz	SUSPENDED
4807	bluez_output.80_C3_BA_4B_D9_88.1.monitor	PipeWire	s24le 2ch 48000Hz	RUNNING
Demo: grafo PipeWire

Dipendenze da installare: pipewire, pipewire-pulse, pipewire-jack, pipewire-alsa e helvum o qpwgraph

Per mostrare il grafo di PipeWire, usiamo Helvum o qpwgraph:

Demo: lancio di una applicazione JACK e cambiamento del grafo PW

Installa e lancia qtractor

PipeWire si è configurato come se fosse una scheda audio fisica, e come server PulseAudio a tutti gli effetti, quindi è pronto per scambiare audio in modo trasparente con client nativi ALSA e PulseAudio, che non si accorgeranno neanche della differenza.

Demo: alsamixer mostra una scheda audio pw

  • eseguire alsamixer e se necessario switchare scheda audio con F6, fino a mostrare una scheda chiamata PipeWire

Sotto la scocca, PipeWire mantiene una lista di oggetti che rappresentano tutte le entità che abbiamo visto nel grafo e le relazioni tra di loro.

Session management

Il session manager ha il compito di rilevare i dispositivi e i client connessi e configurarli per poterli usare con PipeWire. Collateralmente, è la componente che può implementare il un sistema di permessi per decidere quali processi possono avere accesso a quali risorse.

Esiste un'implementazione dimostrativa [un po' come Weston per Wayland] chiamata pipewire-session-manager, e ognuno è libero di utilizzare la propria. Lo standard de facto è wireplumber.

Demo: il session manager crea nodi, porte e link quando si collega un nuovo dispositivo

Teniamo d'occhio l'output di pw-cli mentre Firefox riproduce dell'audio e colleghiamo un nuovo dispositivo audio, in questo caso degli auricolari Bluetooth.

PipeWire rileva un nuovo device e WirePlumber inizia il suo "sporco lavoro" di configurazione: si collega a PipeWire come client e crea i nodi per il nuovo dispositivo, e infatti eccoli qui anche nel grafo.

Portals e sistema di permessi

Diversamente dai suoi cugini più datati, in PipeWire ogni client può avere o non avere il permesso di accedere a ogni singolo oggetto. Questo almeno in teoria. In pratica, allo stato attuale, ci sono solo due casi:

  1. Accesso diretto, senza restrizioni, che funziona un po' come PulseAudio ["sulla fiducia"], e
  2. Accesso da sandbox, per le applicazioni Snap, Flatpak e compagnia.

È per risolvere il 2' problema che gli sviluppatori di PipeWire hanno introdotto il supporto ai portals, che danno accesso a svariate risorse del SO, dal filesystem al network, fino alla cattura dello schermo.

In questo modo le app isolate si rivolgono al portal, che può gestire come vuole i permessi per ciascuna applicazione.

PipeWire per il video

Ritroviamo il meccanismo dei portals anche per la gestione del video in PipeWire.

Demo: C'è un nodo webcam nel grafo

Apri Helvum/qpwgraph e nota la presenza di un nodo relativo a una webcam, inizialmente non connesso ad altri nodi

Demo: Firefox chiede il permesso di usare la webcam

Il supporto per la camera via PipeWire è ancora opt-in in Firefox, così come in Chrome/Chromium.

Firefox è generalmente nativa e non esegue in sandbox, ma può essere configurato per accedere a webcam e schermo tramite portal

  • Visita about:config in FF e imposta la variabile media.webrtc.camera.allow-pipewire a true
  • Visita una pagina web che richiede l'accesso alla webcam, come quella di test di Mozilla
  • Nota che viene richiesto il permesso all'uso di una webcam
  • Torna su Helvum/qpwgraph e nota il collegamento del nodo webcam a FF

Quando una pagina richiede l'accesso alla webcam, Firefox fa una richiesta D-Bus al camera portal.

Se l'utente accetta, il portal comunica a PipeWire di creare un link tra il nodo della webcam e Firefox, in modo che quest'ultimo riceva lo stream video.

Demo: Impostare FF per usare pw per la webcam

Notare come si imposta la variabile media.webrtc.camera.allow-pipewire a true in about:config, come sopra

Demo: Condivisione schermo con FF

In questo caso, PipeWire già il default: è l'unico modo per convidividere lo schermo su Wayland.

Anche in questo caso l'accesso avviene tramite portal, stavolta un desktop portal, che tra le altre cose gestisce la possibilità di catturare lo schermo.

Qui purtroppo si apre una parentesi piuttosto ampia sulla compatibilità dei diversi compositor/DE alla condivisione delle risorse tramite portal.

Ogni compositor/DE implementa il proprio backend per il desktop portal, e diversi backend supportano diverse funzionalità di condivisione: alcuni permettono la condivisione di singole finestre, altri solo dell'intero schermo o di una porzione.

Fonti e Risorse