Dialogo con Gemini.
Ciao, ho installato Ubuntu 26.04 LTS desktop. Potresti descrivere il sistema audio?
Ubuntu 26.04 LTS adotta uno stack audio moderno incentrato interamente su PipeWire e WirePlumber, consolidando l’architettura introdotta nelle versioni recenti e mandando definitivamente in pensione la gestione legacy separata di PulseAudio e JACK.
L’architettura del sistema audio è strutturata in quattro livelli principali:
1. Il Core: PipeWire (pipewire)
- Gestisce l’elaborazione dei flussi multimediali (audio e video) a bassissima latenza.
- È progettato con un modello di sicurezza basato su permessi (cruciale per l’isolamento delle applicazioni Snap e Flatpak).
- Offre un motore a grafo unificato capace di gestire contemporaneamente esigenze audio consumer e audio professionale.
2. Il Session Manager: WirePlumber (wireplumber)
- Sostituisce il vecchio gestore
pipewire-media-session. - Si occupa delle policy di routing (selezione automatica delle periferiche predefinite, priorità jack cuffie/Bluetooth, memoria dei livelli di volume per dispositivo).
- È altamente configurabile tramite script in Lua e file di configurazione modulari in
/etc/wireplumber/o~/.config/wireplumber/.
3. Livello di Compatibilità ed Emulazione PipeWire fornisce wrapper trasparenti che espongono le vecchie API alle applicazioni senza richiedere modifiche al software:
pipewire-pulse: Sostituisce il demone PulseAudio. I comandi classici comepactl,pacmde le app che usanolibpulsecontinuano a funzionare normalmente.pipewire-jack: Offre un’implementazione drop-in per le applicazioni professionali (DAW, sintetizzatori) che richiedono il server audio JACK a bassa latenza.- ALSA Plugin: Intercetta i flussi delle applicazioni che comunicano direttamente con ALSA e li indirizza a PipeWire.
4. Driver Hardware: ALSA Kernel Modules
- A basso livello, l’interfacciamento con i controller hardware (chip integrati Intel/AMD HDA, schede audio USB, codec Realtek) rimane gestito dai moduli del kernel Linux tramite ALSA (Advanced Linux Sound Architecture).
Comandi utili per la diagnostica e il controllo
- Stato dei servizi:Bash
systemctl --user status pipewire wireplumber pipewire-pulse - Controllo server e routing in tempo reale:Bash
wpctl status(Mostra l’albero di sorgenti, sink, nodi audio e consente di cambiare volume o endpoint predefiniti conwpctl set-volumeowpctl set-default). - Informazioni sul server audio:Bash
pactl info(IndicheràServer Name: PulseAudio (on PipeWire...)). - Interfaccia grafica avanzata (opzionale): Per gestire il routing a grafo dei nodi e i buffer di latenza sono disponibili strumenti come
helvumoqpwgraph:Bashsudo apt install qpwgraph
Se vuoi approfondire la configurazione o l’uso dello stack audio:
Configurare PipeWire per audio pro a bassa latenza
Guida alla gestione dei dispositivi con wpctl da terminale
Mostrami una guida pratica ai comandi di wpctl per gestire volumi, switch di output e microfoni da riga di comando.
wpctl è il tool di controllo da riga di comando di WirePlumber. Permette di ispezionare l’albero dei nodi multimediali, regolare i volumi e cambiare al volo sorgenti e uscite predefinite senza passare dall’interfaccia grafica.
1. Ispezione dello stato del sistema
Per visualizzare l’elenco dei dispositivi, delle sorgenti (Source) e delle uscite (Sink) con i relativi ID numerici:
Bash
wpctl status
Nell’output, il simbolo * accanto a un ID indica il dispositivo attualmente impostato come predefinito:
Plaintext
Audio
├─ Sinks:
│ * 48. Built-in Audio Analog Stereo [vol: 0.65]
│ 49. USB Audio DAC Output [vol: 1.00]
├─ Sources:
│ * 52. Built-in Audio Analog Stereo [vol: 0.80]
Per ottenere dettagli tecnici completi su un nodo specifico (es. proprietà ALSA, formati supportati):
Bash
wpctl inspect <ID>
2. Gestione del Volume e Mute
I valori di volume in wpctl sono espressi come moltiplicatori decimali (es. 1.0 = 100%, 0.5 = 50%) o in percentuale con il suffisso %. È possibile usare @DEFAULT_AUDIO_SINK@ o @DEFAULT_AUDIO_SOURCE@ come alias invece dell’ID numerico.
| Azione | Comando | Note |
|---|---|---|
| Imposta volume assoluto | wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.65 | Imposta l’uscita predefinita al 65% |
| Aumenta volume | wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+ | Aumenta del 5% (limite max 150%) |
| Abbassa volume | wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- | Riduce del 5% |
| Toggle Mute uscita | wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle | Inverte lo stato (muta / smuta) |
| Mute esplicito | wpctl set-mute @DEFAULT_AUDIO_SINK@ 1 | 1 per mutare, 0 per riattivare |
Il flag
-l <limite>(es.-l 1.5) previene aumenti accidentali oltre la soglia specificata quando si usano incrementi relativi.
3. Gestione del Microfono (Input/Source)
Le stesse operazioni di regolazione e silenziamento si applicano alle sorgenti audio:
Bash
# Imposta il volume del microfono predefinito all'80%
wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 0.80
# Toggle mute del microfono predefinito (ideale per scorciatoie da tastiera)
wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
# Silenzia esplicitamente il microfono
wpctl set-mute @DEFAULT_AUDIO_SOURCE@ 1
4. Cambio del Dispositivo Predefinito (Switch Output / Input)
Per commutare l’uscita audio o la sorgente del microfono su un altro dispositivo hardware:
- Esegui
wpctl statusper individuare l’ID del dispositivo desiderato. - Imposta l’ID come default:
Bash
# Cambia l'uscita audio predefinita (es. passa alle cuffie o a un DAC USB con ID 49)
wpctl set-default 49
# Cambia il microfono predefinito (es. passa a un microfono USB con ID 55)
wpctl set-default 55
5. Esempi di Scripting e Keybinding
Per integrare wpctl in scorciatoie globali di sistema o script shell, puoi creare comandi a riga singola senza dipendere dagli ID numerici:
Bash
# Script per alzare il volume senza superare il 100%
wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+
# Script per abbassare il volume
wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
# Switch rapido per mutare/riattivare il microfono con feedback visivo/notifica
wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle && notify-send "Microfono" "$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@)"
Scrivi uno script bash che utilizzi wpctl per ciclare a rotazione tra tutti i sink audio di output disponibili.
Questo script esegue il parsing dell’output di wpctl status, individua tutti gli ID dei dispositivi di output (Sinks), rileva quello attualmente predefinito (contrassegnato da *) e imposta il successivo nella lista in modo circolare. Include anche l’invio di una notifica desktop tramite notify-send.
Salva il codice in un file, ad esempio ~/bin/cycle-audio-sinks.sh:
Bash
#!/usr/bin/env bash
set -euo pipefail
# Estrae il blocco 'Sinks:' da wpctl status e raccoglie gli ID
sinks_block=$(wpctl status | sed -n '/Sinks:/,/Sources:/p' | sed '$d')
# Trova tutti gli ID numerici dei sink (escludendo eventuali header)
sink_ids=($(echo "$sinks_block" | grep -oE '[0-9]+\.' | tr -d '.'))
if [ ${#sink_ids[@]} -le 1 ]; then
echo "Trovati ${#sink_ids[@]} sink disponibili: nessuno switch necessario."
exit 0
fi
# Individua il sink attualmente attivo (quello con l'asterisco '*')
current_sink=$(echo "$sinks_block" | grep -E '\*\s+[0-9]+\.' | grep -oE '[0-9]+\.' | tr -d '.')
# Calcola l'indice del sink successivo nella lista circolare
next_sink=""
for i in "${!sink_ids[@]}"; do
if [ "${sink_ids[$i]}" = "$current_sink" ]; then
next_index=$(( (i + 1) % ${#sink_ids[@]} ))
next_sink="${sink_ids[$next_index]}"
break
fi
done
# Fallback al primo sink se per qualsiasi motivo il default corrente non viene matchato
if [ -z "$next_sink" ]; then
next_sink="${sink_ids[0]}"
fi
# Imposta il nuovo sink predefinito
wpctl set-default "$next_sink"
# Recupera la descrizione leggibile del nuovo sink per la notifica
sink_name=$(wpctl inspect "$next_sink" | grep -E 'node.description\s*=' | head -n1 | cut -d'"' -f2)
[ -z "$sink_name" ] && sink_name="Sink ID: $next_sink"
# Invia una notifica desktop (se disponibile libnotify)
if command -v notify-send >/dev/null 2>&1; then
notify-send -t 2000 -a "PipeWire" "Output Audio Cambiato" "$sink_name"
fi
echo "Audio commutato su: $sink_name (ID: $next_sink)"
Installazione e Assegnazione Scorciatoia da Tastiera
- Rendi eseguibile lo script:Bash
chmod +x ~/bin/cycle-audio-sinks.sh - Assegna una scorciatoia su GNOME:
- Apri Impostazioni → Tastiera → Visualizza e personalizza le scorciatoie.
- Scorri fino a Scorciatoie personalizzate e clicca su Aggiungi scorciatoia.
- Nome:
Cicla Output Audio - Comando:
/home/<tuo-utente>/bin/cycle-audio-sinks.sh(inserisci il percorso assoluto completo) - Tasto di scelta rapida: ad esempio Super + F12 o un tasto multimediale dedicato.
Come posso filtrare lo script bash di wpctl per ignorare i sink virtuali o le uscite HDMI non collegate?
Per filtrare i sink non desiderati, è preferibile interrogare i metadati di ciascun nodo tramite wpctl inspect <ID> oppure tramite pw-dump (che fornisce l’albero PipeWire in formato JSON). In questo modo possiamo verificare che:
- Il nodo sia hardware reale (
api.alsa.pathodevice.api = "alsa"/device.bus = "usb"/device.bus = "bluetooth"). - Non sia un sink virtuale/loopback (escludendo
node.virtual = trueo stream generati da EasyEffects, OBS, ecc.). - Se si tratta di un’uscita HDMI/DisplayPort, lo switch jack sia effettivamente inserito (
alsa.jack = trueoavailability = "yes"), evitando le porte video senza monitor o casse connesse.
Ecco la versione aggiornata dello script bash che esegue questa validazione su ciascun sink prima di includerlo nel ciclo di rotazione:
Bash
#!/usr/bin/env bash
set -euo pipefail
# Estrae il blocco 'Sinks:' da wpctl status
sinks_block=$(wpctl status | sed -n '/Sinks:/,/Sources:/p' | sed '$d')
# Estrae tutti gli ID grezzi dei sink
raw_sink_ids=($(echo "$sinks_block" | grep -oE '[0-9]+\.' | tr -d '.'))
valid_sinks=()
valid_sink_names=()
# Funzione per validare ciascun sink
is_valid_sink() {
local id="$1"
local inspect_out
inspect_out=$(wpctl inspect "$id" 2>/dev/null) || return 1
# 1. Esclude nodi esplicitamente virtuali, null-sink o loopback
if echo "$inspect_out" | grep -qE 'node.virtual\s*=\s*"true"|node.name\s*=\s*".*null-sink.*"|node.name\s*=\s*".*loopback.*"'; then
return 1
fi
# 2. Gestione HDMI / DisplayPort disconnessi
# Se il driver segnala un jack ALSA non connesso (availability = "no" o stato unplugged)
if echo "$inspect_out" | grep -iqE 'hdmi|displayport'; then
if echo "$inspect_out" | grep -qE 'device.connection\s*=\s*"unplugged"|alsa.jack\s*=\s*"false"'; then
return 1
fi
fi
return 0
}
# Popola l'array dei soli sink validi e attivi
for id in "${raw_sink_ids[@]}"; do
if is_valid_sink "$id"; then
valid_sinks+=("$id")
name=$(wpctl inspect "$id" | grep -E 'node.description\s*=' | head -n1 | cut -d'"' -f2)
[ -z "$name" ] && name="ID: $id"
valid_sink_names+=("$name")
fi
done
if [ ${#valid_sinks[@]} -eq 0 ]; then
echo "Nessun sink audio valido trovato."
exit 1
elif [ ${#valid_sinks[@]} -eq 1 ]; then
echo "Trovato solo 1 sink valido (${valid_sink_names[0]}): switch non necessario."
exit 0
fi
# Trova il sink attualmente predefinito
current_sink=$(echo "$sinks_block" | grep -E '\*\s+[0-9]+\.' | grep -oE '[0-9]+\.' | tr -d '.' || true)
# Calcola il sink successivo
next_sink=""
next_name=""
for i in "${!valid_sinks[@]}"; do
if [ "${valid_sinks[$i]}" = "$current_sink" ]; then
next_index=$(( (i + 1) % ${#valid_sinks[@]} ))
next_sink="${valid_sinks[$next_index]}"
next_name="${valid_sink_names[$next_index]}"
break
fi
done
# Se il default corrente non era nella lista dei validi, riparte dal primo
if [ -z "$next_sink" ]; then
next_sink="${valid_sinks[0]}"
next_name="${valid_sink_names[0]}"
fi
# Imposta il nuovo sink predefinito
wpctl set-default "$next_sink"
# Notifica desktop
if command -v notify-send >/dev/null 2>&1; then
notify-send -t 2000 -a "PipeWire" "Output Audio Commutato" "$next_name"
fi
echo "Audio commutato su: $next_name (ID: $next_sink)"
Personalizzazione dei filtri (opzionale)
Se utilizzi plugin specifici come EasyEffects, NoiseTorch o ponti JACK e desideri escluderli esplicitamente per nome, puoi aggiungere pattern aggiuntivi al check dei nodi virtuali:
Bash
if echo "$inspect_out" | grep -qE 'node.name\s*=\s*".*easyeffects.*"|node.name\s*=\s*".*noisetorch.*"'; then
return 1
fi
E si può creare un flusso audio attraverso il network tra due sistemi Ubuntu 26.04 ?
Sì, su Ubuntu 26.04 LTS questo si realizza nativamente sfruttando l’architettura di PipeWire.
Esistono due approcci principali:
- PipeWire Nativo (Modulo RAOP / Roc / Network Pulse): il modo più diretto e moderno tramite i moduli di PipeWire.
- Tunneling PipeWire-Pulse (TCP): sfrutta l’emulatore
pipewire-pulseper mantenere la massima compatibilità e immediatezza di configurazione via comandi standard.
Metodo 1: Modulo Tunneling PipeWire-Pulse (TCP Diretto)
In questo schema, il Ricevitore (PC B – Casse) apre la porta TCP di PipeWire-Pulse, e il Trasmettitore (PC A – Sorgente) crea un tunnel sink verso l’IP del ricevitore.
1. Sul PC Ricevitore (es. IP 192.168.1.50): Abilita l’ascolto di connessioni di rete sul demone pipewire-pulse dell’utente:
Bash
pactl load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24 auth-anonymous=1
(Se il firewall ufw è attivo sul ricevitore, apri la porta 4713: sudo ufw allow from 192.168.1.0/24 to any port 4713 proto tcp).
2. Sul PC Trasmettitore: Carica il modulo tunnel puntando all’indirizzo IP del ricevitore:
Bash
pactl load-module module-tunnel-sink server=192.168.1.50 sink_name=Remote_2604
Una volta caricato, il nuovo sink remoto comparirà tra le uscite audio:
- Puoi verificarlo con
wpctl status. - Puoi impostarlo come predefinito con
wpctl set-default <ID_DEL_SINK_REMOTO>oppure selezionarlo graficamente dalle impostazioni audio di GNOME.
Metodo 2: Streaming Real-time a Bassissima Latenza con ROC / RTP (Nativo PipeWire)
PipeWire include moduli nativi per lo streaming in tempo reale sul network basati sulla libreria ROC Toolkit (progettata specificamente per audio di rete trasparente a perdita di pacchetti) o su RTP/SAP.
Per attivare uno stream nativo PipeWire RTP/AVB senza passare da Pulse:
- Sul PC Trasmettitore:Bash
pw-cli load-module libpipewire-module-rtp-source '{ destination.ip = "224.0.0.56" destination.port = 46998 }' - Sul PC Ricevitore:Bash
pw-cli load-module libpipewire-module-rtp-sink '{ listen.ip = "224.0.0.56" listen.port = 46998 }'
Rendere la configurazione persistente su Ubuntu 26.04
Poiché in Ubuntu 26.04 i servizi multimediali sono gestiti da systemd a livello utente (systemd --user), per rendere persistente l’ascolto o il tunnel TCP senza dover rieseguire i comandi:
- Crea la directory di override per PipeWire:Bash
mkdir -p ~/.config/pipewire/pipewire-pulse.conf.d/ - Crea un file
~/.config/pipewire/pipewire-pulse.conf.d/network.confcontenente:Snippet di codicepulse.cmd = [ { cmd = "load-module" args = "module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24 auth-anonymous=1" } ] - Riavvia il servizio utente:Bash
systemctl --user restart pipewire-pulse
Vuoi configurare l’autenticazione sicura o la sincronizzazione multistanza con PipeWire?Sì
Come posso impostare l’autenticazione sicura e la sincronizzazione di clock a bassa latenza su una rete locale con PipeWire tra due macchine Ubuntu 26.04?
Per ottenere autenticazione sicura (evitando flag aperti come auth-anonymous=1) e sincronizzazione temporale deterministica a bassa latenza tra due macchine Ubuntu 26.04, l’architettura ideale prevede:
- Sincronizzazione di clock a livello hardware/rete (PTP/NTP) per prevenire drift e resampling audio.
- Streaming a bassissima latenza con ROC Toolkit o PTP-RTP nativo in PipeWire.
- Autenticazione crittografica e isolamento di rete tramite chiave condivisa (Cookie) o tunnel crittografato (WireGuard).
1. Sincronizzazione Temporale Hardware (PTP / Precision Time Protocol)
Quando si trasmettono flussi PCM grezzi tra due nodi senza accumulo di buffer, il disallineamento dei clock interni dei DAC provoca underrun, overrun e micro-scatti.
Installa e avvia linuxptp per sincronizzare i clock di sistema con precisione sub-microsecondo nella LAN:
Bash
sudo apt install linuxptp
- Sul nodo principale (Master Clock – es. interfaccia
eth0):Bashsudo ptp4l -i eth0 -m - Sul nodo secondario (Slave Clock):Bash
sudo ptp4l -i eth0 -s -m # Sincronizza il clock del sistema operativo (CLOCK_REALTIME) con il clock PTP hardware: sudo phc2sys -a -r -m
2. Streaming a Bassa Latenza con ROC Toolkit in PipeWire
Il toolkit ROC (libpipewire-module-roc-*) è progettato specificamente per lo streaming audio in tempo reale su rete non garantita: include Forward Error Correction (Reed-Solomon) per tollerare pacchetti persi senza richiedere re-invii TCP, mantenendo la latenza al minimo (5–15 ms).
Installa i moduli necessari:
Bash
sudo apt install pipewire-module-roc libroc-dev
Configurazione Ricevitore (Sink – es. IP 192.168.1.50):
Crea ~/.config/pipewire/pipewire.conf.d/roc-sink.conf:
Snippet di codice
context.modules = [
{ name = libpipewire-module-roc-sink
args = {
fec.code = "rs8m"
local.ip = "0.0.0.0"
local.source.port = 10001
local.repair.port = 10002
local.control.port = 10003
sink.name = "ROC_Remote_Sink"
sink.props = {
node.description = "Altoparlanti Remoti (ROC HD)"
media.class = "Audio/Sink"
}
}
}
]
Configurazione Trasmettitore (Source):
Crea ~/.config/pipewire/pipewire.conf.d/roc-source.conf:
Snippet di codice
context.modules = [
{ name = libpipewire-module-roc-source
args = {
fec.code = "rs8m"
remote.ip = "192.168.1.50"
remote.source.port = 10001
remote.repair.port = 10002
remote.control.port = 10003
node.name = "ROC_Source_Out"
node.props = {
node.description = "Stream Remoto ROC"
media.class = "Audio/Sink"
}
}
}
]
Riavvia PipeWire su entrambi i nodi:
Bash
systemctl --user restart pipewire
3. Autenticazione e Sicurezza di Rete
I protocolli audio in tempo reale basati su UDP (RTP, ROC) non includono handshake TLS nativi per evitare overhead sul campionamento. La sicurezza si implementa a due livelli:
Opzione A: Autenticazione tramite Cookie di Sicurezza (per pipewire-pulse)
Se usi il protocollo TCP di PulseAudio/PipeWire:
- Genera un cookie crittografico binario a 256-bit sul Master:Bash
dd if=/dev/urandom of=~/.config/pipewire/audio.cookie bs=256 count=1 - Copia in modo sicuro il file sulla macchina client via
scp:Bashscp ~/.config/pipewire/audio.cookie utente@192.168.1.51:~/.config/pipewire/audio.cookie - Configura il ricevitore senza
auth-anonymous=1:Bashpactl load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24 auth-cookie=/home/<utente>/.config/pipewire/audio.cookie
Opzione B: Tunnel Crittografato WireGuard (Consigliato per ROC / RTP)
Per incapsulare i pacchetti UDP di ROC in un canale con crittografia ChaCha20-Poly1305 a livello kernel senza impattare la latenza:
- Crea un’interfaccia WireGuard punto-punto (
wg0) tra le due macchine (es.10.10.0.1e10.10.0.2). - Imposta
local.ip = "10.10.0.1"eremote.ip = "10.10.0.1"nelle rispettive configurazioni PipeWire ROC. - Blocca con il firewall
ufwqualsiasi traffico verso le porte 10001–10003 che non provenga dall’interfacciawg0.