#!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: ./set-pipewire-latency.sh COMMAND [QUANTUM] [RATE] Commands: status Show current PipeWire clock/quantum settings. on [Q] [RATE] Force a low-latency graph quantum. Defaults: Q=128 RATE=48000. off Clear forced quantum/rate and return to normal PipeWire behavior. Useful quantum values at 48 kHz: 256 about 5.3 ms per block, safer 128 about 2.7 ms per block, good stage starting point 64 about 1.3 ms per block, lower latency but higher dropout risk USAGE } metadata() { pw-metadata -n settings "$@" } status() { local output output="$(pw-metadata -n settings)" printf '%s\n' "$output" | grep -E "clock\\.(rate|quantum|min-quantum|max-quantum|force-quantum|force-rate)" || true local rate quantum forced_quantum rate="$(printf '%s\n' "$output" | awk -F"'" '/clock.rate/ { print $4; exit }')" quantum="$(printf '%s\n' "$output" | awk -F"'" '/clock.quantum/ { print $4; exit }')" forced_quantum="$(printf '%s\n' "$output" | awk -F"'" '/clock.force-quantum/ { print $4; exit }')" if [[ -n "$rate" && -n "$quantum" ]]; then awk -v q="$quantum" -v r="$rate" 'BEGIN { printf "\nCurrent block latency: %.2f ms at %s Hz\n", (q / r) * 1000, r }' fi if [[ "${forced_quantum:-0}" != "0" ]]; then printf 'Low-latency override: ON\n' else printf 'Low-latency override: OFF\n' fi } set_low_latency() { local quantum="${1:-128}" local rate="${2:-48000}" if ! [[ "$quantum" =~ ^[0-9]+$ && "$rate" =~ ^[0-9]+$ ]]; then printf 'Quantum and rate must be numeric.\n' >&2 exit 2 fi metadata 0 clock.force-rate "$rate" >/dev/null metadata 0 clock.force-quantum "$quantum" >/dev/null awk -v q="$quantum" -v r="$rate" 'BEGIN { printf "Forced PipeWire quantum %s at %s Hz, about %.2f ms per block\n", q, r, (q / r) * 1000 }' } clear_low_latency() { metadata 0 clock.force-quantum 0 >/dev/null metadata 0 clock.force-rate 0 >/dev/null printf 'Cleared PipeWire forced quantum/rate.\n' } case "${1:-}" in status) status ;; on) set_low_latency "${2:-128}" "${3:-48000}" ;; off) clear_low_latency ;; -h|--help|help|'') usage ;; *) usage >&2 exit 2 ;; esac