412 lines
12 KiB
Bash
412 lines
12 KiB
Bash
#!/usr/bin/env bash
|
||
|
||
PIPEWIRE_HOME=/etc/pipewire
|
||
WIREPLUMBER_HOME=/usr/share/wireplumber
|
||
|
||
# https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/home
|
||
#
|
||
# with-alsa: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA
|
||
sudo apt -y install \
|
||
libfdk-aac2 \
|
||
libldacbt-{abr,enc}2 \
|
||
libopenaptx0
|
||
|
||
sudo apt -y install \
|
||
gstreamer1.0-pipewire \
|
||
libpipewire-0.3-{0,dev,modules} \
|
||
libspa-0.2-{bluetooth,dev,jack,libcamera,modules} \
|
||
pipewire \
|
||
pipewire-{alsa,jack,v4l2,libcamera}
|
||
|
||
sudo apt install \
|
||
pipewire-audio-client-libraries \
|
||
pipewire \
|
||
pipewire-alsa \
|
||
pipewire-audio \
|
||
pipewire-jack
|
||
|
||
## For WirePlumber - pipewire session manager
|
||
sudo apt-get install wireplumber{,-doc}
|
||
|
||
## Other management tools
|
||
sudo apt-get install qpwgraph vlc-plugin-pipewire
|
||
|
||
# Copy conffiles to /etc
|
||
sudo cp -vRa /usr/share/pipewire /etc/
|
||
sudo mkdir -p ${PIPEWIRE_HOME}/pipewire.conf.d
|
||
|
||
# Wireplumber now expects configuration files in /usr/share and no more lua.
|
||
# sudo cp -vRa /usr/share/wireplumber /etc/
|
||
# sudo mkdir -p ${WIREPLUMER_HOME}/wireplumber.conf.d
|
||
|
||
# WirePlumber has profile auto-switching enabled by default. It can
|
||
# automatically switch between HSP/HFP and A2DP profiles whenever an
|
||
# input stream is detected. You can disable it with:
|
||
conf_print_wireplumber_bt_autoswitch() {
|
||
cat <<-EOF
|
||
wireplumber.settings = {
|
||
bluetooth.autoswitch-to-headset-profile = false
|
||
}
|
||
EOF
|
||
}
|
||
# conf_print_wireplumber_bt_autoswitch | sudo tee ${WIREPLUMBER_HOME}/wireplumber.conf.d/11-bluetooth-policy.conf
|
||
# conf_print_wireplumber_bt_autoswitch | sudo tee ~/.config/wireplumber/wireplumber.conf.d/11-bluetooth-policy.conf
|
||
|
||
sudo touch ${PIPEWIRE_HOME}/media-session.d/with-alsa
|
||
|
||
sudo cp /usr/share/doc/pipewire/examples/ld.so.conf.d/pipewire-jack-x86_64-linux-gnu.conf /etc/ld.so.conf.d/
|
||
|
||
sudo ldconfig
|
||
|
||
# sudo cp /usr/share/doc/pipewire/examples/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d/
|
||
sudo ln -s /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d/99-pipewire-default.conf
|
||
#conf_print_pipewire_default() {
|
||
#cat <<-EOF
|
||
#pcm.!default {
|
||
# type pipewire
|
||
# playback_node "-1"
|
||
# capture_node "-1"
|
||
# hint {
|
||
# show on
|
||
# description "Default ALSA Output (currently PipeWire Media Server)"
|
||
# }
|
||
#}
|
||
#
|
||
#ctl.!default {
|
||
# type pipewire
|
||
#}
|
||
#EOF
|
||
#}
|
||
# conf_print_pipewire_default | sudo tee /etc/alsa/conf.d/99-pipewire-default.conf
|
||
|
||
conf_print_pipewire_desktop() {
|
||
cat <<-EOF
|
||
[Desktop Entry]
|
||
Version=1.0
|
||
Name=PipeWire Media System
|
||
Comment=Start the PipeWire Media System
|
||
Exec=/usr/bin/pipewire
|
||
Terminal=false
|
||
Type=Application
|
||
X-GNOME-Autostart-Phase=Initialization
|
||
X-KDE-autostart-phase=1
|
||
EOF
|
||
}
|
||
conf_print_pipewire_desktop | sudo tee /etc/xdg/autostart/pipewire.desktop
|
||

|
||
conf_print_wireplumber_desktop() {
|
||
cat <<-EOF
|
||
[Desktop Entry]
|
||
Version=1.0
|
||
Name=WirePlumber PipeWire Media System
|
||
Comment=Start the WirePlumber
|
||
Exec=/usr/bin/wireplumber
|
||
Terminal=false
|
||
Type=Application
|
||
X-GNOME-Autostart-Phase=Initialization
|
||
X-KDE-autostart-phase=1
|
||
EOF
|
||
}
|
||
conf_print_wireplumber_desktop | sudo tee /etc/xdg/autostart/wireplumber.desktop
|
||
|
||
# don't use this we make incremental changes to conf.d/<file>.conf
|
||
#
|
||
# conf_print_pipewire_conf() {
|
||
# cat <<-EOF
|
||
# # PipeWire ALSA configuration
|
||
# context.properties = {
|
||
# # ALSA settings
|
||
# alsa.jack.device = "hw:0"
|
||
# alsa.jack.autoconnect = true
|
||
# alsa.jack.autoconnect-ports = true
|
||
# alsa.jack.latency = 100000
|
||
# }
|
||
# EOF
|
||
#}
|
||
# conf_print_pipewire_conf | sudo tee /etc/pipewire/pipewire.conf
|
||
|
||
# https://davejansen.com/disable-wireplumber-pipewire-suspend-on-idle-pops-delays-noise/
|
||
conf_print_alsa_conf_suspend-timeout() {
|
||
cat <<-EOF
|
||
alsa_monitor.enabled = true
|
||
|
||
alsa_monitor.properties = {
|
||
-- Your existing properties configuration
|
||
}
|
||
|
||
alsa_monitor.rules = {
|
||
{
|
||
matches = {
|
||
{
|
||
-- This matches all cards.
|
||
{ "device.name", "matches", "alsa_card.*" },
|
||
},
|
||
},
|
||
apply_properties = {
|
||
-- Your existing apply_properties configuration
|
||
["session.suspend-timeout-seconds"] = 0, -- Add this line
|
||
},
|
||
},
|
||
{
|
||
matches = {
|
||
{
|
||
-- Matches all sources.
|
||
{ "node.name", "matches", "alsa_input.*" },
|
||
},
|
||
{
|
||
-- Matches all sinks.
|
||
{ "node.name", "matches", "alsa_output.*" },
|
||
},
|
||
},
|
||
apply_properties = {
|
||
-- Your existing apply_properties configuration
|
||
["session.suspend-timeout-seconds"] = 0, -- Add this line
|
||
},
|
||
},
|
||
}
|
||
EOF
|
||
}
|
||
# no more lua for wireplumber
|
||
# conf_print_alsa_conf_suspend-timeout | sudo tee ${WIREPLUMBER_HOME}/main.lua.d/60-alsa_suspend-timeout.conf
|
||
|
||
# improved crackling in fullscreen
|
||
conf_print_pipewire_quantum() {
|
||
cat <<-EOF
|
||
conf_print_pipewire_quantum() {
|
||
default.clock.quantum = "32"
|
||
default.clock.min-quantum = "64"
|
||
default.clock.max-quantum = "768"
|
||
EOF
|
||
}
|
||
conf_print_pipewire_quantum | sudo tee ${PIPEWIRE_HOME}/pipewire.conf.d/clock_quantum.conf
|
||
|
||
# default.clock.allowed-rates = [ 44100 48000 96000 192000 ]
|
||
conf_print_pipewire_quantum() {
|
||
cat <<-EOF
|
||
default.clock.rate = 44100
|
||
default.clock.allowed-rates = 44100
|
||
default.clock.quantum = 512
|
||
default.clock.min-quantum = 16
|
||
default.clock.max-quantum = 2048
|
||
default.clock.quantum-limit = 512
|
||
settings.check-quantum = false
|
||
settings.check-rate = false
|
||
EOF
|
||
}
|
||
conf_print_pipewire_quantum | sudo tee ${PIPEWIRE_HOME}/pipewire.conf.d/clock_quantum.conf
|
||
|
||
conf_print_pipewire_alsa-api() {
|
||
cat <<-EOF
|
||
# See: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA#alsa-buffer-properties
|
||
api.alsa.headroom = 1024
|
||
api.alsa.period-size = 256
|
||
EOF
|
||
}
|
||
conf_print_pipewire_alsa-api | sudo tee ${PIPEWIRE_HOME}/pipewire.conf.d/alsa-api.conf
|
||
|
||
conf_print_pipewire_clock-rate() {
|
||
cat <<-EOF
|
||
context.properties = {
|
||
default.clock.rate = [ 44100 48000 ]
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_pipewire_clock-rate | sudo tee ${PIPEWIRE_HOME}/pipewire.conf.d/alsa-dmix.conf
|
||
|
||
conf_print_pipewire_alsa-dmix() {
|
||
cat <<EOF
|
||
|
||
EOF
|
||
}
|
||
conf_print_pipewire_alsa-dmix | sudo tee ${PIPEWIRE_HOME}/pipewire.conf.d/alsa-dmix.conf
|
||
|
||
## with-jack: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-JACK:
|
||
# sudo apt -y install libspa-0.2-jack
|
||
#
|
||
#sudo touch /etc/pipewire/media-session.d/with-jack
|
||
#
|
||
## Either run JACK clients using the pw-jack wrapper, or copy:
|
||
# cp /usr/share/doc/pipewire/examples/ld.so.conf.d/pipewire-jack-*.conf /etc/ld.so.conf.d/
|
||
|
||
# ldconfig
|
||
|
||
# /usr/share/pipewire/client-rt.conf /etc/pipewire/client-rt.conf.d/
|
||
mkdir -p ${PIPEWIRE_HOME}/client-rt.conf.d/
|
||
|
||
# Real-time Client config file for PipeWire version "1.0.3" #
|
||
#
|
||
# Copy and edit this file in /etc/pipewire for system-wide changes
|
||
# or in ~/.config/pipewire for local changes.
|
||
#
|
||
# It is also possible to place a file with an updated section in
|
||
# /etc/pipewire/client-rt.conf.d/ for system-wide changes or in
|
||
# ~/.config/pipewire/client-rt.conf.d/ for local changes.
|
||
#
|
||
|
||
conf_print_client-rt_context_property() {
|
||
cat <<-EOF
|
||
context.properties = {
|
||
## Configure properties in the system.
|
||
#mem.warn-mlock = false
|
||
#mem.allow-mlock = true
|
||
#mem.mlock-all = false
|
||
log.level = 0
|
||
|
||
#default.clock.quantum-limit = 8192
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_client-rt_context_property | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_context_property.conf >/dev/null
|
||
|
||
conf_print_client-rt_context_spa-libs() {
|
||
cat <<-EOF
|
||
context.spa-libs = {
|
||
#<factory-name regex> = <library-name>
|
||
#
|
||
# Used to find spa factory names. It maps an spa factory name
|
||
# regular expression to a library name that should contain
|
||
# that factory.
|
||
#
|
||
audio.convert.* = audioconvert/libspa-audioconvert
|
||
support.* = support/libspa-support
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_client-rt_context_spa-libs | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_context_spa-libs.conf >/dev/null
|
||
|
||
conf_print_client-rt_context_modules() {
|
||
cat <<-EOF
|
||
context.modules = [
|
||
#{ name = <module-name>
|
||
# ( args = { <key> = <value> ... } )
|
||
# ( flags = [ ( ifexists ) ( nofail ) ] )
|
||
# ( condition = [ { <key> = <value> ... } ... ] )
|
||
#}
|
||
#
|
||
# Loads a module with the given parameters.
|
||
# If ifexists is given, the module is ignored when it is not found.
|
||
# If nofail is given, module initialization failures are ignored.
|
||
#
|
||
# Uses realtime scheduling to boost the audio thread priorities
|
||
{ name = libpipewire-module-rt
|
||
args = {
|
||
#rt.prio = 88
|
||
#rt.time.soft = -1
|
||
#rt.time.hard = -1
|
||
}
|
||
flags = [ ifexists nofail ]
|
||
}
|
||
|
||
# The native communication protocol.
|
||
{ name = libpipewire-module-protocol-native }
|
||
|
||
# Allows creating nodes that run in the context of the
|
||
# client. Is used by all clients that want to provide
|
||
# data to PipeWire.
|
||
{ name = libpipewire-module-client-node }
|
||
|
||
# Allows creating devices that run in the context of the
|
||
# client. Is used by the session manager.
|
||
{ name = libpipewire-module-client-device }
|
||
|
||
# Makes a factory for wrapping nodes in an adapter with a
|
||
# converter and resampler.
|
||
{ name = libpipewire-module-adapter }
|
||
|
||
# Allows applications to create metadata objects. It creates
|
||
# a factory for Metadata objects.
|
||
{ name = libpipewire-module-metadata }
|
||
|
||
# Provides factories to make session manager objects.
|
||
{ name = libpipewire-module-session-manager }
|
||
]
|
||
EOF
|
||
}
|
||
conf_print_client-rt_context_modules | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_context_modules.conf >/dev/null
|
||
|
||
conf_print_client-rt_filter_properties() {
|
||
cat <<-EOF
|
||
filter.properties = {
|
||
#node.latency = 1024/48000
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_client-rt_filter_properties | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_filter_properties.conf >/dev/null
|
||
|
||
conf_print_client-rt_stream_properties() {
|
||
cat <<-EOF
|
||
stream.properties = {
|
||
#node.latency = 1024/48000
|
||
#node.autoconnect = true
|
||
#resample.quality = 4
|
||
#channelmix.normalize = false
|
||
#channelmix.mix-lfe = true
|
||
#channelmix.upmix = true
|
||
#channelmix.upmix-method = psd # none, simple
|
||
#channelmix.lfe-cutoff = 150
|
||
#channelmix.fc-cutoff = 12000
|
||
#channelmix.rear-delay = 12.0
|
||
#channelmix.stereo-widen = 0.0
|
||
#channelmix.hilbert-taps = 0
|
||
#dither.noise = 0
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_client-rt_stream_properties | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_stream_properties.conf >/dev/null
|
||
|
||
conf_print_client-rt_stream_rules() {
|
||
cat <<-EOF
|
||
stream.rules = [
|
||
{ matches = [
|
||
{
|
||
# all keys must match the value. ! negates. ~ starts regex.
|
||
#application.name = "pw-cat"
|
||
#node.name = "~Google Chrome$"
|
||
}
|
||
]
|
||
actions = {
|
||
update-props = {
|
||
#node.latency = 512/48000
|
||
}
|
||
}
|
||
}
|
||
]
|
||
EOF
|
||
}
|
||
conf_print_client-rt_stream_rules | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_stream_rules.conf >/dev/null
|
||
|
||
conf_print_client-rt_alsa_properties() {
|
||
cat <<-EOF
|
||
alsa.properties = {
|
||
#alsa.deny = false
|
||
# ALSA params take a single value, an array [] of values
|
||
# or a range { min=.. max=... }
|
||
#alsa.access = [ MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED ]
|
||
#alsa.format = [ FLOAT S32 S24 S24_3 S16 U8 ]
|
||
#alsa.rate = { min=1 max=384000 } # or [ 44100 48000 .. ]
|
||
#alsa.channels = { min=1 max=64 } # or [ 2 4 6 .. ]
|
||
#alsa.period-bytes = { min=128 max=2097152 } # or [ 128 256 1024 .. ]
|
||
#alsa.buffer-bytes = { min=256 max=4194304 } # or [ 256 512 4096 .. ]
|
||
|
||
#alsa.volume-method = cubic # linear, cubic
|
||
}
|
||
EOF
|
||
}
|
||
conf_print_client-rt_alsa_properties | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_alsa_properties.conf >/dev/null
|
||
|
||
conf_print_client-rt_alsa_rules() {
|
||
cat <<-EOF
|
||
# client specific properties
|
||
alsa.rules = [
|
||
{ matches = [ { application.process.binary = "resolve" } ]
|
||
actions = {
|
||
update-props = {
|
||
alsa.buffer-bytes = 131072
|
||
}
|
||
}
|
||
}
|
||
]
|
||
EOF
|
||
}
|
||
conf_print_client-rt_alsa_rules | sudo tee ${PIPEWIRE_HOME}/client-rt.conf.d/client-rt_alsa_rules.conf >/dev/null
|