adaptive sync
This commit is contained in:
@@ -35,3 +35,4 @@ export PATH="$HOME/.local/bin:$PATH"
|
|||||||
alias ls='ls --color=auto'
|
alias ls='ls --color=auto'
|
||||||
alias doc='docker-compose'
|
alias doc='docker-compose'
|
||||||
alias cla='cd /home/nnduc/.cache/ && claude'
|
alias cla='cd /home/nnduc/.cache/ && claude'
|
||||||
|
alias wa="watch -n1 "sensors | grep -E 'Tctl|edge|junction|mem:|Composite'""
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Shift_R+F12 shows/hides the HUD
|
||||||
|
no_display
|
||||||
|
toggle_hud=Shift_R+F12
|
||||||
|
fps
|
||||||
|
frametime
|
||||||
|
frame_timing
|
||||||
|
gpu_stats
|
||||||
|
cpu_stats
|
||||||
|
# diagnostics: log starts 20s after launch, Shift_L+F2 toggles logging
|
||||||
|
output_folder=/home/nnduc/mangologs
|
||||||
|
autostart_log=20
|
||||||
|
log_interval=0
|
||||||
|
toggle_logging=Shift_L+F2
|
||||||
|
gpu_core_clock
|
||||||
|
gpu_mem_clock
|
||||||
|
vram
|
||||||
|
ram
|
||||||
|
cpu_mhz
|
||||||
|
# fps
|
||||||
|
fps_limit=80,60,120,0
|
||||||
|
fps_limit_method=early
|
||||||
|
toggle_fps_limit=Shift_L+F1
|
||||||
@@ -75,8 +75,51 @@ echo 3 | sudo tee /sys/class/drm/card*/device/pp_dpm_mclk
|
|||||||
with `adaptive_sync off` games run without it.
|
with `adaptive_sync off` games run without it.
|
||||||
- To turn off FreeSync for a single game (Xorg): `adaptive_sync=false %command%`
|
- To turn off FreeSync for a single game (Xorg): `adaptive_sync=false %command%`
|
||||||
(Steam launch options).
|
(Steam launch options).
|
||||||
|
- Login greeters (SDDM, LightDM, ...) are fullscreen and mostly static, so VRR
|
||||||
|
drops to the bottom of the range and flickers. `mesa/drirc` disables it for
|
||||||
|
any `*greeter*` executable; install system-wide (greeters don't read `~/.drirc`):
|
||||||
|
```bash
|
||||||
|
sudo cp xorg/20-amdgpu.conf /etc/X11/xorg.conf.d/
|
||||||
|
sudo cp mesa/drirc /etc/drirc
|
||||||
|
```
|
||||||

|

|
||||||
|
|
||||||
|
## Shader cache (Steam)
|
||||||
|
|
||||||
|
With Steam's *Shader Pre-caching* off (it re-downloads caches for every game
|
||||||
|
almost daily), Steam points Mesa at a temporary
|
||||||
|
`~/.local/share/Steam/shader_cache_temp_dir_*` and deletes it when the game
|
||||||
|
exits, so every session recompiles shaders (hitches everywhere, every time).
|
||||||
|
Steam only sets the legacy `MESA_GLSL_CACHE_DIR`, so the newer variable wins.
|
||||||
|
Set it session-wide (i3 is started by SDDM, `environment.d` doesn't reach
|
||||||
|
Steam). The cache lives in `/var/cache` so `~/.cache` cleaners don't wipe it,
|
||||||
|
with one private subdir per user: Mesa creates its dirs `0700`, so a single
|
||||||
|
shared dir can't work (and would let users poison each other's shaders).
|
||||||
|
`/etc/environment` can't expand `$USER`, so use `/etc/profile.d` (SDDM's
|
||||||
|
X11/Wayland sessions and TTY logins source it). Run as your normal user, not
|
||||||
|
from a root shell (`~` and `$USER` must be yours), with Steam closed:
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /var/cache/mesa_shader_cache
|
||||||
|
sudo chmod 1777 /var/cache/mesa_shader_cache # like /tmp: anyone creates own subdir
|
||||||
|
mv ~/.cache/mesa_shader_cache /var/cache/mesa_shader_cache/$USER # no sudo: keeps ownership
|
||||||
|
sudo sed -i '/^MESA_SHADER_CACHE_/d' /etc/environment
|
||||||
|
sudo tee /etc/profile.d/mesa-shader-cache.sh >/dev/null <<'EOF'
|
||||||
|
export MESA_SHADER_CACHE_DIR="/var/cache/mesa_shader_cache/$USER"
|
||||||
|
export MESA_SHADER_CACHE_MAX_SIZE=10G
|
||||||
|
export PRESSURE_VESSEL_FILESYSTEMS_RW=/var/cache/mesa_shader_cache
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
The last line matters: Steam runs games (native and Proton) in the Steam
|
||||||
|
Linux Runtime container, which shares `$HOME` but gives the game its own empty
|
||||||
|
`/var`. Without it the cache is written to a tmpfs inside the container and
|
||||||
|
thrown away when the game exits.
|
||||||
|
Re-login, then check it's yours and persists after playing (should print > 0):
|
||||||
|
```bash
|
||||||
|
echo $MESA_SHADER_CACHE_DIR; ls -ld $MESA_SHADER_CACHE_DIR # owner must be you
|
||||||
|
find $MESA_SHADER_CACHE_DIR -mmin -60 -type f | wc -l
|
||||||
|
```
|
||||||
|
Deleting the cache is harmless: shaders just recompile (stutter) on first use.
|
||||||
|
|
||||||
## Installing dependencies
|
## Installing dependencies
|
||||||
|
|
||||||
Package availability differs between distros — Arch has everything below in the
|
Package availability differs between distros — Arch has everything below in the
|
||||||
@@ -191,9 +234,9 @@ sudo emerge --ask games-util/gamemode
|
|||||||
|
|
||||||
Adaptive sync (sway): the desktop runs at a fixed 240 Hz with VRR off, because
|
Adaptive sync (sway): the desktop runs at a fixed 240 Hz with VRR off, because
|
||||||
sway only renders on change and idle frame rates fall below the panel's 48 Hz
|
sway only renders on change and idle frame rates fall below the panel's 48 Hz
|
||||||
floor (out of LFC range → flicker). `sway/scripts/vrr-follow` turns VRR on for
|
floor (out of LFC range → flicker). gamemode turns VRR on for DP-1 while a
|
||||||
DP-1 only while the visible workspace has a fullscreen window; `lock-now` turns
|
game runs and off when it exits (install `gamemode/gamemode.ini` to
|
||||||
it off while locked. Needs `jq`.
|
`~/.config/gamemode.ini`); `lock-now` turns it off while locked.
|
||||||
|
|
||||||
### GPU monitoring & tuning
|
### GPU monitoring & tuning
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ font pango:NotoSans 12
|
|||||||
# text rendering and scalability on retina/hidpi displays (thanks to pango).
|
# text rendering and scalability on retina/hidpi displays (thanks to pango).
|
||||||
#font pango:DejaVu Sans Mono 8
|
#font pango:DejaVu Sans Mono 8
|
||||||
|
|
||||||
|
# Clear leftover Wayland env (e.g. from a previous Hyprland/sway session) out of
|
||||||
|
# systemd/dbus so dbus-activated apps like Thunar don't try to use a dead compositor.
|
||||||
|
# Must run before anything dbus-activated starts.
|
||||||
|
exec --no-startup-id sh -c "systemctl --user unset-environment WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE SWAYSOCK; dbus-update-activation-environment --systemd DISPLAY XAUTHORITY XDG_CURRENT_DESKTOP=i3 XDG_SESSION_TYPE=x11; pkill -x Thunar"
|
||||||
|
|
||||||
# Start XDG autostart .desktop files using dex. See also
|
# Start XDG autostart .desktop files using dex. See also
|
||||||
# https://wiki.archlinux.org/index.php/XDG_Autostart
|
# https://wiki.archlinux.org/index.php/XDG_Autostart
|
||||||
exec --no-startup-id dex --autostart --environment i3
|
exec --no-startup-id dex --autostart --environment i3
|
||||||
@@ -58,6 +63,7 @@ exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
|||||||
exec --no-startup-id ~/.config/i3/scripts/wallpaper-rotate $wallpaper_dir
|
exec --no-startup-id ~/.config/i3/scripts/wallpaper-rotate $wallpaper_dir
|
||||||
exec --no-startup-id pasystray
|
exec --no-startup-id pasystray
|
||||||
exec --no-startup-id polybar
|
exec --no-startup-id polybar
|
||||||
|
exec --no-startup-id ~/.config/i3/scripts/guide-freeze
|
||||||
|
|
||||||
set $refresh_i3status killall -SIGUSR1 i3status
|
set $refresh_i3status killall -SIGUSR1 i3status
|
||||||
|
|
||||||
@@ -99,7 +105,7 @@ floating_modifier $mod
|
|||||||
#xrandr --output HDMI-2 --auto --right-of eDP1
|
#xrandr --output HDMI-2 --auto --right-of eDP1
|
||||||
# High refresh rates can flicker on AMD (VRAM clock switching), so run the
|
# High refresh rates can flicker on AMD (VRAM clock switching), so run the
|
||||||
# desktop at 120Hz. See README "High refresh rate flicker".
|
# desktop at 120Hz. See README "High refresh rate flicker".
|
||||||
exec --no-startup-id xrandr --output DisplayPort-0 --mode 1920x1080 --rate 120
|
exec --no-startup-id xrandr --output DisplayPort-0 --mode 1920x1080 --rate 240
|
||||||
|
|
||||||
# start a terminal
|
# start a terminal
|
||||||
#bindsym $mod+Return exec i3-sensible-terminal
|
#bindsym $mod+Return exec i3-sensible-terminal
|
||||||
@@ -108,6 +114,9 @@ bindsym $mod+Return exec $terminal
|
|||||||
# kill focused window
|
# kill focused window
|
||||||
bindsym $mod+Shift+q kill
|
bindsym $mod+Shift+q kill
|
||||||
|
|
||||||
|
# freeze / resume focused window (SIGSTOP / SIGCONT)
|
||||||
|
bindsym $mod+m exec --no-startup-id ~/.config/i3/scripts/freeze-toggle
|
||||||
|
|
||||||
# start dmenu (a program launcher)
|
# start dmenu (a program launcher)
|
||||||
#bindsym $mod+d exec --no-startup-id j4-dmenu-desktop
|
#bindsym $mod+d exec --no-startup-id j4-dmenu-desktop
|
||||||
#bindsym $mod+d exec --no-startup-id dmenu
|
#bindsym $mod+d exec --no-startup-id dmenu
|
||||||
|
|||||||
Executable
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Freeze / resume the focused window's process tree (SIGSTOP / SIGCONT).
|
||||||
|
pid=$(xdotool getactivewindow getwindowpid 2>/dev/null) || exit 1
|
||||||
|
|
||||||
|
# collect pid plus all descendants (Wine/Proton games spawn several)
|
||||||
|
descendants() {
|
||||||
|
local p
|
||||||
|
for p in $(pgrep -P "$1"); do
|
||||||
|
echo "$p"
|
||||||
|
descendants "$p"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
pids="$pid $(descendants "$pid")"
|
||||||
|
name=$(ps -o comm= -p "$pid")
|
||||||
|
|
||||||
|
case "$(ps -o state= -p "$pid")" in
|
||||||
|
T*) kill -CONT $pids && notify-send -t 1500 "Resumed" "$name ($pid)" ;;
|
||||||
|
*) kill -STOP $pids && notify-send -t 1500 "Frozen" "$name ($pid)" ;;
|
||||||
|
esac
|
||||||
Executable
+50
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Freeze/resume the focused window on the controller's Home/guide button (BTN_MODE).
|
||||||
|
# Stdlib only: reads raw evdev events. Gamepads are readable by the seat user.
|
||||||
|
import glob, os, select, signal, struct, subprocess, time
|
||||||
|
|
||||||
|
EV_KEY, BTN_MODE = 1, 0x13c
|
||||||
|
EVENT = struct.Struct('llHHi') # struct input_event
|
||||||
|
LONG_BITS = struct.calcsize('l') * 8
|
||||||
|
CMD = [os.path.expanduser('~/.config/i3/scripts/freeze-toggle')]
|
||||||
|
|
||||||
|
signal.signal(signal.SIGCHLD, signal.SIG_IGN) # auto-reap child processes
|
||||||
|
|
||||||
|
def has_btn_mode(path):
|
||||||
|
try:
|
||||||
|
with open(f'/sys/class/input/{os.path.basename(path)}/device/capabilities/key') as f:
|
||||||
|
words = f.read().split()
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
bits = 0
|
||||||
|
for w in words:
|
||||||
|
bits = bits << LONG_BITS | int(w, 16)
|
||||||
|
return bits >> BTN_MODE & 1
|
||||||
|
|
||||||
|
fds = {} # fd -> device path
|
||||||
|
last = 0.0
|
||||||
|
rescan = 0.0
|
||||||
|
while True:
|
||||||
|
if time.monotonic() >= rescan: # pick up hotplugged controllers
|
||||||
|
for path in glob.glob('/dev/input/event*'):
|
||||||
|
if path not in fds.values() and has_btn_mode(path):
|
||||||
|
try:
|
||||||
|
fds[os.open(path, os.O_RDONLY)] = path
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
rescan = time.monotonic() + 2
|
||||||
|
ready, _, _ = select.select(list(fds), [], [], 2)
|
||||||
|
for fd in ready:
|
||||||
|
try:
|
||||||
|
data = os.read(fd, EVENT.size * 64)
|
||||||
|
except OSError: # controller unplugged
|
||||||
|
os.close(fd)
|
||||||
|
del fds[fd]
|
||||||
|
continue
|
||||||
|
for sec, usec, type_, code, value in EVENT.iter_unpack(data):
|
||||||
|
if type_ == EV_KEY and code == BTN_MODE and value == 1:
|
||||||
|
now = sec + usec / 1e6
|
||||||
|
if now - last < 0.4: # GuliKit's Home button double-fires ~10ms apart
|
||||||
|
continue
|
||||||
|
last = now
|
||||||
|
subprocess.Popen(CMD, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<driconf>
|
||||||
|
<device>
|
||||||
|
<application name="Login greeters" executable_regexp=".*greeter.*">
|
||||||
|
<option name="adaptive_sync" value="false" />
|
||||||
|
</application>
|
||||||
|
</device>
|
||||||
|
</driconf>
|
||||||
+6
-6
@@ -2,19 +2,19 @@
|
|||||||
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
|
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
|
||||||
"coq.artifacts": { "branch": "artifacts", "commit": "d545035d06408f2d68cd03bc401425e42c298fc4" },
|
"coq.artifacts": { "branch": "artifacts", "commit": "d545035d06408f2d68cd03bc401425e42c298fc4" },
|
||||||
"coq.thirdparty": { "branch": "3p", "commit": "a021e24f1ff538d339aece0de80d621b68862701" },
|
"coq.thirdparty": { "branch": "3p", "commit": "a021e24f1ff538d339aece0de80d621b68862701" },
|
||||||
"coq_nvim": { "branch": "coq", "commit": "df4eb27b425568cea17f01a25a07cf447066ce81" },
|
"coq_nvim": { "branch": "coq", "commit": "0cdbf99893729c5ffa74064382efc53364d7045d" },
|
||||||
"fzf-lua": { "branch": "main", "commit": "05e44d38de0a79c11fba5f7bf8138791b1dbdd1e" },
|
"fzf-lua": { "branch": "main", "commit": "78b85d2a522b1e6a2d154216b3e532a1df1ad6d7" },
|
||||||
"gruvbox.nvim": { "branch": "main", "commit": "154eb5ff5b96d0641307113fa385eaf0d36d9796" },
|
"gruvbox.nvim": { "branch": "main", "commit": "154eb5ff5b96d0641307113fa385eaf0d36d9796" },
|
||||||
"julia-vim": { "branch": "master", "commit": "52b30547346b21bc93acda28d626795667f9e087" },
|
"julia-vim": { "branch": "master", "commit": "52b30547346b21bc93acda28d626795667f9e087" },
|
||||||
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||||
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
|
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
|
||||||
"nvim-autopairs": { "branch": "master", "commit": "430522f95fe4fb7c511ec64f8c1a90cc6a66c05c" },
|
"nvim-autopairs": { "branch": "master", "commit": "430522f95fe4fb7c511ec64f8c1a90cc6a66c05c" },
|
||||||
"nvim-bqf": { "branch": "main", "commit": "c282a62bec6c0621a1ef5132aa3f4c9fc4dcc2c7" },
|
"nvim-bqf": { "branch": "main", "commit": "c282a62bec6c0621a1ef5132aa3f4c9fc4dcc2c7" },
|
||||||
"nvim-lspconfig": { "branch": "master", "commit": "16286347bdba1333c7d124d9de9fe6630731b2b2" },
|
"nvim-lspconfig": { "branch": "master", "commit": "a9bb4d5f4276aa5cddc015faa3ecc5a7b5a26b14" },
|
||||||
"nvim-tree.lua": { "branch": "master", "commit": "b2aadda94b107480c48e548d6db51c6840b7b33c" },
|
"nvim-tree.lua": { "branch": "master", "commit": "478c69c0fe253caea88de9c5e138bfa77395a59a" },
|
||||||
"nvim-web-devicons": { "branch": "master", "commit": "5f032a85be210cd1c6ac98861eb3b187ff3bd5eb" },
|
"nvim-web-devicons": { "branch": "master", "commit": "58447c1fca354bbf184425e4a8d01deecbd6f3c4" },
|
||||||
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
|
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
|
||||||
"vim-ime": { "branch": "master", "commit": "79e3b02eb50a57305113550be7ca163b267b5e30" },
|
"vim-ime": { "branch": "master", "commit": "79e3b02eb50a57305113550be7ca163b267b5e30" },
|
||||||
"viml-surround": { "branch": "master", "commit": "98358bad347aa2b8a180c2edde84c3bd8a51fdd1" },
|
"viml-surround": { "branch": "master", "commit": "98358bad347aa2b8a180c2edde84c3bd8a51fdd1" },
|
||||||
"vimtex": { "branch": "master", "commit": "cb81778aee678b513af3de7f1ca5943e7ee31b2f" }
|
"vimtex": { "branch": "master", "commit": "16a5609d17a436db7f48046d91747fd6a9d75c74" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,476 +0,0 @@
|
|||||||
# Simple daemon config file for PipeWire version "1.2.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/minimal.conf.d/ for system-wide changes or in
|
|
||||||
# ~/.config/pipewire/minimal.conf.d/ for local changes.
|
|
||||||
#
|
|
||||||
|
|
||||||
context.properties = {
|
|
||||||
## Configure properties in the system.
|
|
||||||
#library.name.system = support/libspa-support
|
|
||||||
#context.data-loop.library.name.system = support/libspa-support
|
|
||||||
#support.dbus = true
|
|
||||||
#link.max-buffers = 64
|
|
||||||
link.max-buffers = 16 # version < 3 clients can't handle more
|
|
||||||
#mem.warn-mlock = false
|
|
||||||
#mem.allow-mlock = true
|
|
||||||
#mem.mlock-all = false
|
|
||||||
#clock.power-of-two-quantum = true
|
|
||||||
#log.level = 2
|
|
||||||
#cpu.zero.denormals = false
|
|
||||||
|
|
||||||
core.daemon = true # listening for socket connections
|
|
||||||
core.name = pipewire-0 # core name and socket name
|
|
||||||
|
|
||||||
## Properties for the DSP configuration.
|
|
||||||
default.clock.rate = 48000
|
|
||||||
#default.clock.allowed-rates = [ 48000 ]
|
|
||||||
#default.clock.quantum = 1024
|
|
||||||
#default.clock.min-quantum = 32
|
|
||||||
#default.clock.max-quantum = 2048
|
|
||||||
#default.clock.quantum-limit = 8192
|
|
||||||
#default.clock.quantum-floor = 4
|
|
||||||
#default.video.width = 640
|
|
||||||
#default.video.height = 480
|
|
||||||
#default.video.rate.num = 25
|
|
||||||
#default.video.rate.denom = 1
|
|
||||||
#
|
|
||||||
settings.check-quantum = true
|
|
||||||
settings.check-rate = true
|
|
||||||
|
|
||||||
# This config can use udev or hardcoded ALSA devices. Make sure to
|
|
||||||
# change the alsa device below when disabling udev
|
|
||||||
minimal.use-udev = true
|
|
||||||
|
|
||||||
# Load the pulseaudio emulation daemon
|
|
||||||
minimal.use-pulse = true
|
|
||||||
}
|
|
||||||
|
|
||||||
context.properties.rules = [
|
|
||||||
{ matches = [ { cpu.vm.name = !null } ]
|
|
||||||
actions = {
|
|
||||||
update-props = {
|
|
||||||
# These overrides are only applied when running in a vm.
|
|
||||||
default.clock.min-quantum = 1024
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
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
|
|
||||||
audio.adapt = audioconvert/libspa-audioconvert
|
|
||||||
api.alsa.* = alsa/libspa-alsa
|
|
||||||
support.* = support/libspa-support
|
|
||||||
}
|
|
||||||
|
|
||||||
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. This uses
|
|
||||||
# RTKit if the user doesn't have permission to use regular realtime
|
|
||||||
# scheduling.
|
|
||||||
{ name = libpipewire-module-rt
|
|
||||||
args = {
|
|
||||||
nice.level = -11
|
|
||||||
rt.prio = 88
|
|
||||||
#rt.time.soft = -1
|
|
||||||
#rt.time.hard = -1
|
|
||||||
}
|
|
||||||
flags = [ ifexists nofail ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# The native communication protocol.
|
|
||||||
{ name = libpipewire-module-protocol-native }
|
|
||||||
|
|
||||||
# The profile module. Allows application to access profiler
|
|
||||||
# and performance data. It provides an interface that is used
|
|
||||||
# by pw-top and pw-profiler.
|
|
||||||
{ name = libpipewire-module-profiler }
|
|
||||||
|
|
||||||
# Allows applications to create metadata objects. It creates
|
|
||||||
# a factory for Metadata objects.
|
|
||||||
{ name = libpipewire-module-metadata }
|
|
||||||
|
|
||||||
# Creates a factory for making nodes that run in the
|
|
||||||
# context of the PipeWire server.
|
|
||||||
{ name = libpipewire-module-spa-node-factory }
|
|
||||||
|
|
||||||
{ name = libpipewire-module-spa-device-factory }
|
|
||||||
|
|
||||||
# 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 }
|
|
||||||
|
|
||||||
# The access module can perform access checks and block
|
|
||||||
# new clients.
|
|
||||||
{ name = libpipewire-module-access
|
|
||||||
args = {
|
|
||||||
# access.allowed to list an array of paths of allowed
|
|
||||||
# apps.
|
|
||||||
#access.allowed = [
|
|
||||||
# /usr/bin/pipewire-media-session
|
|
||||||
#]
|
|
||||||
|
|
||||||
# An array of rejected paths.
|
|
||||||
#access.rejected = [ ]
|
|
||||||
|
|
||||||
# An array of paths with restricted access.
|
|
||||||
#access.restricted = [ ]
|
|
||||||
|
|
||||||
# Anything not in the above lists gets assigned the
|
|
||||||
# access.force permission.
|
|
||||||
#access.force = flatpak
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Makes a factory for wrapping nodes in an adapter with a
|
|
||||||
# converter and resampler.
|
|
||||||
{ name = libpipewire-module-adapter }
|
|
||||||
|
|
||||||
# Makes a factory for creating links between ports.
|
|
||||||
{ name = libpipewire-module-link-factory }
|
|
||||||
|
|
||||||
{ name = libpipewire-module-protocol-pulse
|
|
||||||
condition = [ { minimal.use-pulse = true } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
pulse.properties = {
|
|
||||||
# the addresses this server listens on
|
|
||||||
server.address = [
|
|
||||||
"unix:native"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.properties = {
|
|
||||||
adapter.auto-port-config = { mode = dsp }
|
|
||||||
}
|
|
||||||
|
|
||||||
context.objects = [
|
|
||||||
#{ factory = <factory-name>
|
|
||||||
# ( args = { <key> = <value> ... } )
|
|
||||||
# ( flags = [ ( nofail ) ] )
|
|
||||||
# ( condition = [ { <key> = <value> ... } ... ] )
|
|
||||||
#}
|
|
||||||
#
|
|
||||||
# Creates an object from a PipeWire factory with the given parameters.
|
|
||||||
# If nofail is given, errors are ignored (and no object is created).
|
|
||||||
#
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
|
|
||||||
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
|
|
||||||
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
|
|
||||||
#{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } }
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
|
||||||
|
|
||||||
# Make a default metadata store
|
|
||||||
{ factory = metadata
|
|
||||||
args = {
|
|
||||||
metadata.name = default
|
|
||||||
# metadata.values = [
|
|
||||||
# { key = default.audio.sink value = { name = somesink } }
|
|
||||||
# { key = default.audio.source value = { name = somesource } }
|
|
||||||
# ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# A default dummy driver. This handles nodes marked with the "node.always-process"
|
|
||||||
# property when no other driver is currently active. JACK clients need this.
|
|
||||||
{ factory = spa-node-factory
|
|
||||||
args = {
|
|
||||||
factory.name = support.node.driver
|
|
||||||
node.name = Dummy-Driver
|
|
||||||
node.group = pipewire.dummy
|
|
||||||
priority.driver = 20000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{ factory = spa-node-factory
|
|
||||||
args = {
|
|
||||||
factory.name = support.node.driver
|
|
||||||
node.name = Freewheel-Driver
|
|
||||||
priority.driver = 19000
|
|
||||||
node.group = pipewire.freewheel
|
|
||||||
node.freewheel = true
|
|
||||||
#freewheel.wait = 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# This creates a ALSA udev device that will enumerate all
|
|
||||||
# ALSA devices. Because it is using ACP and has the auto-profile
|
|
||||||
# property set, this will enable a profile and create associated
|
|
||||||
# nodes, which will be automatically configured to their best
|
|
||||||
# configuration with the auto-port-config settings.
|
|
||||||
# Extra node and device params can be given with node.param and
|
|
||||||
# device.param prefixes.
|
|
||||||
{ factory = spa-device-factory
|
|
||||||
args = {
|
|
||||||
factory.name = api.alsa.enum.udev
|
|
||||||
alsa.use-acp = true
|
|
||||||
device.object.properties = {
|
|
||||||
api.acp.auto-profile = true
|
|
||||||
api.acp.auto-port = true
|
|
||||||
device.object.properties = {
|
|
||||||
node.adapter = audio.adapt
|
|
||||||
resample.disable = false
|
|
||||||
adapter.auto-port-config = {
|
|
||||||
mode = dsp
|
|
||||||
monitor = false
|
|
||||||
control = false
|
|
||||||
position = preserve # unknown, aux
|
|
||||||
}
|
|
||||||
#node.param.Props = {
|
|
||||||
# channelVolumes = [ 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6 ]
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
#device.param.Profile = {
|
|
||||||
# #idx = 0
|
|
||||||
# name = pro-audio
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
condition = [ { minimal.use-udev = true } ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# This creates a single PCM source device for the given
|
|
||||||
# alsa device path hw:0. You can change source to sink
|
|
||||||
# to make a sink in the same way.
|
|
||||||
{ factory = adapter
|
|
||||||
args = {
|
|
||||||
factory.name = api.alsa.pcm.source
|
|
||||||
node.name = "system"
|
|
||||||
node.description = "system"
|
|
||||||
media.class = "Audio/Source"
|
|
||||||
api.alsa.path = "hw:4"
|
|
||||||
#api.alsa.period-size = 0
|
|
||||||
#api.alsa.period-num = 0
|
|
||||||
#api.alsa.headroom = 0
|
|
||||||
#api.alsa.start-delay = 0
|
|
||||||
#api.alsa.disable-mmap = false
|
|
||||||
#api.alsa.disable-batch = false
|
|
||||||
#api.alsa.use-chmap = false
|
|
||||||
#api.alsa.multirate = true
|
|
||||||
#latency.internal.rate = 0
|
|
||||||
#latency.internal.ns = 0
|
|
||||||
#clock.name = api.alsa.0
|
|
||||||
node.suspend-on-idle = false
|
|
||||||
#audio.format = "S32"
|
|
||||||
#audio.rate = 48000
|
|
||||||
#audio.allowed-rates = [ ]
|
|
||||||
#audio.channels = 4
|
|
||||||
#audio.position = [ FL FR RL RR ]
|
|
||||||
#resample.quality = 4
|
|
||||||
resample.disable = true
|
|
||||||
#monitor.channel-volumes = false
|
|
||||||
#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
|
|
||||||
#channelmix.disable = false
|
|
||||||
#dither.noise = 0
|
|
||||||
#node.param.Props = {
|
|
||||||
# params = [
|
|
||||||
# audio.channels 6
|
|
||||||
# ]
|
|
||||||
#}
|
|
||||||
adapter.auto-port-config = {
|
|
||||||
mode = dsp
|
|
||||||
monitor = false
|
|
||||||
control = false
|
|
||||||
position = unknown # aux, preserve
|
|
||||||
}
|
|
||||||
#node.param.PortConfig = {
|
|
||||||
# direction = Output
|
|
||||||
# mode = dsp
|
|
||||||
# format = {
|
|
||||||
# mediaType = audio
|
|
||||||
# mediaSubtype = raw
|
|
||||||
# format = F32
|
|
||||||
# rate = 48000
|
|
||||||
# channels = 4
|
|
||||||
# position = [ FL FR RL RR ]
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
#node.param.Props = {
|
|
||||||
# channelVolumes = [ 0.5 0.4 0.3 0.5 ]
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
condition = [ { minimal.use-udev = false } ]
|
|
||||||
}
|
|
||||||
{ factory = adapter
|
|
||||||
args = {
|
|
||||||
factory.name = api.alsa.pcm.sink
|
|
||||||
node.name = "system"
|
|
||||||
node.description = "system"
|
|
||||||
media.class = "Audio/Sink"
|
|
||||||
api.alsa.path = "hw:4"
|
|
||||||
#api.alsa.period-size = 0
|
|
||||||
#api.alsa.period-num = 0
|
|
||||||
#api.alsa.headroom = 0
|
|
||||||
#api.alsa.start-delay = 0
|
|
||||||
#api.alsa.disable-mmap = false
|
|
||||||
#api.alsa.disable-batch = false
|
|
||||||
#api.alsa.use-chmap = false
|
|
||||||
#api.alsa.multirate = true
|
|
||||||
#latency.internal.rate = 0
|
|
||||||
#latency.internal.ns = 0
|
|
||||||
#clock.name = api.alsa.0
|
|
||||||
node.suspend-on-idle = false
|
|
||||||
#audio.format = "S32"
|
|
||||||
#audio.rate = 48000
|
|
||||||
#audio.allowed-rates = [ ]
|
|
||||||
#audio.channels = 2
|
|
||||||
#audio.position = "FL,FR"
|
|
||||||
#resample.quality = 4
|
|
||||||
resample.disable = true
|
|
||||||
#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
|
|
||||||
#channelmix.disable = false
|
|
||||||
#dither.noise = 0
|
|
||||||
#node.param.Props = {
|
|
||||||
# params = [
|
|
||||||
# audio.format S16
|
|
||||||
# ]
|
|
||||||
#}
|
|
||||||
adapter.auto-port-config = {
|
|
||||||
mode = dsp
|
|
||||||
monitor = false
|
|
||||||
control = false
|
|
||||||
position = unknown # aux, preserve
|
|
||||||
}
|
|
||||||
#node.param.PortConfig = {
|
|
||||||
# direction = Input
|
|
||||||
# mode = dsp
|
|
||||||
# monitor = true
|
|
||||||
# format = {
|
|
||||||
# mediaType = audio
|
|
||||||
# mediaSubtype = raw
|
|
||||||
# format = F32
|
|
||||||
# rate = 48000
|
|
||||||
# channels = 4
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
#node.param.Props = {
|
|
||||||
# channelVolumes = [ 0.5 0.4 0.3 0.5 ]
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
condition = [ { minimal.use-udev = false } ]
|
|
||||||
}
|
|
||||||
# This creates a new Source node. It will have input ports
|
|
||||||
# that you can link, to provide audio for this source.
|
|
||||||
#{ factory = adapter
|
|
||||||
# args = {
|
|
||||||
# factory.name = support.null-audio-sink
|
|
||||||
# node.name = "my-mic"
|
|
||||||
# node.description = "Microphone"
|
|
||||||
# media.class = "Audio/Source/Virtual"
|
|
||||||
# audio.position = "FL,FR"
|
|
||||||
# monitor.passthrough = true
|
|
||||||
# adapter.auto-port-config = {
|
|
||||||
# mode = dsp
|
|
||||||
# monitor = true
|
|
||||||
# position = preserve # unknown, aux, preserve
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
# This creates a new link between the source and the virtual
|
|
||||||
# source ports.
|
|
||||||
#{ factory = link-factory
|
|
||||||
# args = {
|
|
||||||
# link.output.node = system
|
|
||||||
# link.output.port = capture_1
|
|
||||||
# link.input.node = my-mic
|
|
||||||
# link.input.port = input_FL
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
#{ factory = link-factory
|
|
||||||
# args = {
|
|
||||||
# link.output.node = system
|
|
||||||
# link.output.port = capture_2
|
|
||||||
# link.input.node = my-mic
|
|
||||||
# link.input.port = input_FR
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
]
|
|
||||||
|
|
||||||
context.exec = [
|
|
||||||
#{ path = <program-name>
|
|
||||||
# ( args = "<arguments>" | [ <arg1> <arg2> ... ] )
|
|
||||||
# ( condition = [ { <key> = <value> ... } ... ] )
|
|
||||||
#}
|
|
||||||
#
|
|
||||||
# Execute the given program with arguments.
|
|
||||||
#
|
|
||||||
# You can optionally start the pulseaudio-server here as well
|
|
||||||
# but it is better to start it as a systemd service.
|
|
||||||
# It can be interesting to start another daemon here that listens
|
|
||||||
# on another address with the -a option (eg. -a tcp:4713).
|
|
||||||
#
|
|
||||||
##{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" }
|
|
||||||
]
|
|
||||||
|
|
||||||
node.rules = [
|
|
||||||
{ matches = [
|
|
||||||
{
|
|
||||||
# all keys must match the value. ! negates. ~ starts regex.
|
|
||||||
#alsa.card_name = "ICUSBAUDIO7D"
|
|
||||||
#api.alsa.pcm.stream = "playback"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
actions = {
|
|
||||||
update-props = {
|
|
||||||
#node.name = "alsa_playback.ICUSBAUDIO7D"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
device.rules = [
|
|
||||||
{ matches = [
|
|
||||||
{
|
|
||||||
#alsa.card_name = "ICUSBAUDIO7D"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
actions = {
|
|
||||||
update-props = {
|
|
||||||
#device.name = "alsa_card.ICUSBAUDIO7D"
|
|
||||||
#api.acp.auto-profile = false
|
|
||||||
#api.acp.auto-port = false
|
|
||||||
#device.param.Profile = {
|
|
||||||
# #idx = 0
|
|
||||||
# name = off
|
|
||||||
#}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,345 +0,0 @@
|
|||||||
# Daemon config file for PipeWire version "1.2.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/pipewire.conf.d/ for system-wide changes or in
|
|
||||||
# ~/.config/pipewire/pipewire.conf.d/ for local changes.
|
|
||||||
#
|
|
||||||
|
|
||||||
context.properties = {
|
|
||||||
## Configure properties in the system.
|
|
||||||
#library.name.system = support/libspa-support
|
|
||||||
#context.data-loop.library.name.system = support/libspa-support
|
|
||||||
#support.dbus = true
|
|
||||||
#link.max-buffers = 64
|
|
||||||
link.max-buffers = 16 # version < 3 clients can't handle more
|
|
||||||
mem.warn-mlock = true # Gentoo should have good RLIMITs now
|
|
||||||
#mem.allow-mlock = true
|
|
||||||
#mem.mlock-all = false
|
|
||||||
#clock.power-of-two-quantum = true
|
|
||||||
#log.level = 2
|
|
||||||
#cpu.zero.denormals = false
|
|
||||||
|
|
||||||
#loop.rt-prio = -1 # -1 = use module-rt prio, 0 disable rt
|
|
||||||
#loop.class = data.rt
|
|
||||||
#thread.affinity = [ 0 1 ] # optional array of CPUs
|
|
||||||
#context.num-data-loops = 1 # -1 = num-cpus, 0 = no data loops
|
|
||||||
#
|
|
||||||
#context.data-loops = [
|
|
||||||
# { loop.rt-prio = -1
|
|
||||||
# loop.class = [ data.rt audio.rt ]
|
|
||||||
# #library.name.system = support/libspa-support
|
|
||||||
# thread.name = data-loop.0
|
|
||||||
# #thread.affinity = [ 0 1 ] # optional array of CPUs
|
|
||||||
# }
|
|
||||||
#]
|
|
||||||
|
|
||||||
core.daemon = true # listening for socket connections
|
|
||||||
core.name = pipewire-0 # core name and socket name
|
|
||||||
|
|
||||||
## Properties for the DSP configuration.
|
|
||||||
default.clock.rate = 44100
|
|
||||||
default.clock.rates = [ 44100 96000 192000 384000]
|
|
||||||
default.clock.allowed-rates = [ 44100 96000 192000 384000]
|
|
||||||
#default.clock.quantum = 1024
|
|
||||||
#default.clock.min-quantum = 32
|
|
||||||
#default.clock.max-quantum = 2048
|
|
||||||
#default.clock.quantum-limit = 8192
|
|
||||||
#default.clock.quantum-floor = 4
|
|
||||||
#default.video.width = 640
|
|
||||||
#default.video.height = 480
|
|
||||||
#default.video.rate.num = 25
|
|
||||||
#default.video.rate.denom = 1
|
|
||||||
#
|
|
||||||
#settings.check-quantum = false
|
|
||||||
#settings.check-rate = false
|
|
||||||
|
|
||||||
# keys checked below to disable module loading
|
|
||||||
module.x11.bell = true
|
|
||||||
# enables autoloading of access module, when disabled an alternative
|
|
||||||
# access module needs to be loaded.
|
|
||||||
module.access = true
|
|
||||||
# enables autoloading of module-jackdbus-detect
|
|
||||||
module.jackdbus-detect = true
|
|
||||||
}
|
|
||||||
|
|
||||||
context.properties.rules = [
|
|
||||||
{ matches = [ { cpu.vm.name = !null } ]
|
|
||||||
actions = {
|
|
||||||
update-props = {
|
|
||||||
# These overrides are only applied when running in a vm.
|
|
||||||
default.clock.min-quantum = 1024
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
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
|
|
||||||
avb.* = avb/libspa-avb
|
|
||||||
api.alsa.* = alsa/libspa-alsa
|
|
||||||
api.v4l2.* = v4l2/libspa-v4l2
|
|
||||||
api.libcamera.* = libcamera/libspa-libcamera
|
|
||||||
api.bluez5.* = bluez5/libspa-bluez5
|
|
||||||
api.vulkan.* = vulkan/libspa-vulkan
|
|
||||||
api.jack.* = jack/libspa-jack
|
|
||||||
support.* = support/libspa-support
|
|
||||||
video.convert.* = videoconvert/libspa-videoconvert
|
|
||||||
#videotestsrc = videotestsrc/libspa-videotestsrc
|
|
||||||
#audiotestsrc = audiotestsrc/libspa-audiotestsrc
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
# If condition is given, the module is loaded only when the context
|
|
||||||
# properties all match the match rules.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Uses realtime scheduling to boost the audio thread priorities. This uses
|
|
||||||
# RTKit if the user doesn't have permission to use regular realtime
|
|
||||||
# scheduling. You can also clamp utilisation values to improve scheduling
|
|
||||||
# on embedded and heterogeneous systems, e.g. Arm big.LITTLE devices.
|
|
||||||
{ name = libpipewire-module-rt
|
|
||||||
args = {
|
|
||||||
nice.level = -11
|
|
||||||
rt.prio = 88
|
|
||||||
#rt.time.soft = -1
|
|
||||||
#rt.time.hard = -1
|
|
||||||
#uclamp.min = 0
|
|
||||||
#uclamp.max = 1024
|
|
||||||
}
|
|
||||||
flags = [ ifexists nofail ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# The native communication protocol.
|
|
||||||
{ name = libpipewire-module-protocol-native
|
|
||||||
args = {
|
|
||||||
# List of server Unix sockets, and optionally permissions
|
|
||||||
#sockets = [ { name = "pipewire-0" }, { name = "pipewire-0-manager" } ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# The profile module. Allows application to access profiler
|
|
||||||
# and performance data. It provides an interface that is used
|
|
||||||
# by pw-top and pw-profiler.
|
|
||||||
{ name = libpipewire-module-profiler }
|
|
||||||
|
|
||||||
# Allows applications to create metadata objects. It creates
|
|
||||||
# a factory for Metadata objects.
|
|
||||||
{ name = libpipewire-module-metadata }
|
|
||||||
|
|
||||||
# Creates a factory for making devices that run in the
|
|
||||||
# context of the PipeWire server.
|
|
||||||
{ name = libpipewire-module-spa-device-factory }
|
|
||||||
|
|
||||||
# Creates a factory for making nodes that run in the
|
|
||||||
# context of the PipeWire server.
|
|
||||||
{ name = libpipewire-module-spa-node-factory }
|
|
||||||
|
|
||||||
# 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 }
|
|
||||||
|
|
||||||
# The portal module monitors the PID of the portal process
|
|
||||||
# and tags connections with the same PID as portal
|
|
||||||
# connections.
|
|
||||||
{ name = libpipewire-module-portal
|
|
||||||
flags = [ ifexists nofail ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# The access module can perform access checks and block
|
|
||||||
# new clients.
|
|
||||||
{ name = libpipewire-module-access
|
|
||||||
args = {
|
|
||||||
# Socket-specific access permissions
|
|
||||||
#access.socket = { pipewire-0 = "default", pipewire-0-manager = "unrestricted" }
|
|
||||||
|
|
||||||
# Deprecated legacy mode (not socket-based),
|
|
||||||
# for now enabled by default if access.socket is not specified
|
|
||||||
#access.legacy = true
|
|
||||||
}
|
|
||||||
condition = [ { module.access = true } ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Makes a factory for wrapping nodes in an adapter with a
|
|
||||||
# converter and resampler.
|
|
||||||
{ name = libpipewire-module-adapter }
|
|
||||||
|
|
||||||
# Makes a factory for creating links between ports.
|
|
||||||
{ name = libpipewire-module-link-factory }
|
|
||||||
|
|
||||||
# Provides factories to make session manager objects.
|
|
||||||
{ name = libpipewire-module-session-manager }
|
|
||||||
|
|
||||||
# Use libcanberra to play X11 Bell
|
|
||||||
{ name = libpipewire-module-x11-bell
|
|
||||||
args = {
|
|
||||||
#sink.name = "@DEFAULT_SINK@"
|
|
||||||
#sample.name = "bell-window-system"
|
|
||||||
#x11.display = null
|
|
||||||
#x11.xauthority = null
|
|
||||||
}
|
|
||||||
flags = [ ifexists nofail ]
|
|
||||||
condition = [ { module.x11.bell = true } ]
|
|
||||||
}
|
|
||||||
{ name = libpipewire-module-jackdbus-detect
|
|
||||||
args = {
|
|
||||||
#jack.library = libjack.so.0
|
|
||||||
#jack.server = null
|
|
||||||
#jack.client-name = PipeWire
|
|
||||||
#jack.connect = true
|
|
||||||
#tunnel.mode = duplex # source|sink|duplex
|
|
||||||
source.props = {
|
|
||||||
#audio.channels = 2
|
|
||||||
#midi.ports = 1
|
|
||||||
#audio.position = [ FL FR ]
|
|
||||||
# extra sink properties
|
|
||||||
}
|
|
||||||
sink.props = {
|
|
||||||
#audio.channels = 2
|
|
||||||
#midi.ports = 1
|
|
||||||
#audio.position = [ FL FR ]
|
|
||||||
# extra sink properties
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flags = [ ifexists nofail ]
|
|
||||||
condition = [ { module.jackdbus-detect = true } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
context.objects = [
|
|
||||||
#{ factory = <factory-name>
|
|
||||||
# ( args = { <key> = <value> ... } )
|
|
||||||
# ( flags = [ ( nofail ) ] )
|
|
||||||
# ( condition = [ { <key> = <value> ... } ... ] )
|
|
||||||
#}
|
|
||||||
#
|
|
||||||
# Creates an object from a PipeWire factory with the given parameters.
|
|
||||||
# If nofail is given, errors are ignored (and no object is created).
|
|
||||||
# If condition is given, the object is created only when the context properties
|
|
||||||
# all match the match rules.
|
|
||||||
#
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
|
|
||||||
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
|
|
||||||
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
|
|
||||||
#{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } }
|
|
||||||
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
|
||||||
|
|
||||||
# A default dummy driver. This handles nodes marked with the "node.always-process"
|
|
||||||
# property when no other driver is currently active. JACK clients need this.
|
|
||||||
{ factory = spa-node-factory
|
|
||||||
args = {
|
|
||||||
factory.name = support.node.driver
|
|
||||||
node.name = Dummy-Driver
|
|
||||||
node.group = pipewire.dummy
|
|
||||||
node.sync-group = sync.dummy
|
|
||||||
priority.driver = 200000
|
|
||||||
#clock.id = monotonic # realtime | tai | monotonic-raw | boottime
|
|
||||||
#clock.name = "clock.system.monotonic"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{ factory = spa-node-factory
|
|
||||||
args = {
|
|
||||||
factory.name = support.node.driver
|
|
||||||
node.name = Freewheel-Driver
|
|
||||||
priority.driver = 190000
|
|
||||||
node.group = pipewire.freewheel
|
|
||||||
node.sync-group = sync.dummy
|
|
||||||
node.freewheel = true
|
|
||||||
#freewheel.wait = 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# This creates a new Source node. It will have input ports
|
|
||||||
# that you can link, to provide audio for this source.
|
|
||||||
#{ factory = adapter
|
|
||||||
# args = {
|
|
||||||
# factory.name = support.null-audio-sink
|
|
||||||
# node.name = "my-mic"
|
|
||||||
# node.description = "Microphone"
|
|
||||||
# media.class = "Audio/Source/Virtual"
|
|
||||||
# audio.position = "FL,FR"
|
|
||||||
# monitor.passthrough = true
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
|
|
||||||
# This creates a single PCM source device for the given
|
|
||||||
# alsa device path hw:0. You can change source to sink
|
|
||||||
# to make a sink in the same way.
|
|
||||||
#{ factory = adapter
|
|
||||||
# args = {
|
|
||||||
# factory.name = api.alsa.pcm.source
|
|
||||||
# node.name = "alsa-source"
|
|
||||||
# node.description = "PCM Source"
|
|
||||||
# media.class = "Audio/Source"
|
|
||||||
# api.alsa.path = "hw:0"
|
|
||||||
# api.alsa.period-size = 1024
|
|
||||||
# api.alsa.headroom = 0
|
|
||||||
# api.alsa.disable-mmap = false
|
|
||||||
# api.alsa.disable-batch = false
|
|
||||||
# audio.format = "S16LE"
|
|
||||||
# audio.rate = 48000
|
|
||||||
# audio.channels = 2
|
|
||||||
# audio.position = "FL,FR"
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Use the metadata factory to create metadata and some default values.
|
|
||||||
#{ factory = metadata
|
|
||||||
# args = {
|
|
||||||
# metadata.name = my-metadata
|
|
||||||
# metadata.values = [
|
|
||||||
# { key = default.audio.sink value = { name = somesink } }
|
|
||||||
# { key = default.audio.source value = { name = somesource } }
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
]
|
|
||||||
|
|
||||||
context.exec = [
|
|
||||||
#{ path = <program-name>
|
|
||||||
# ( args = "<arguments>" | [ <arg1> <arg2> ... ] )
|
|
||||||
# ( condition = [ { <key> = <value> ... } ... ] )
|
|
||||||
#}
|
|
||||||
#
|
|
||||||
# Execute the given program with arguments.
|
|
||||||
# If condition is given, the program is executed only when the context
|
|
||||||
# properties all match the match rules.
|
|
||||||
#
|
|
||||||
# You can optionally start the session manager here,
|
|
||||||
# but it is better to start it as a systemd service.
|
|
||||||
# Run the session manager with -h for options.
|
|
||||||
#
|
|
||||||
#{ path = "/usr/bin/pipewire-media-session" args = ""
|
|
||||||
# condition = [ { exec.session-manager = null } { exec.session-manager = true } ] }
|
|
||||||
#
|
|
||||||
# You can optionally start the pulseaudio-server here as well
|
|
||||||
# but it is better to start it as a systemd service.
|
|
||||||
# It can be interesting to start another daemon here that listens
|
|
||||||
# on another address with the -a option (eg. -a tcp:4713).
|
|
||||||
#
|
|
||||||
#{ path = "/usr/bin/pipewire" args = [ "-c" "pipewire-pulse.conf" ]
|
|
||||||
# condition = [ { exec.pipewire-pulse = null } { exec.pipewire-pulse = true } ] }
|
|
||||||
]
|
|
||||||
@@ -39,7 +39,6 @@ exec --no-startup-id ~/.config/sway/scripts/wallpaper-rotate $wallpaper_dir
|
|||||||
# adaptive_sync on the desktop makes sway stutter/flicker; 120Hz avoids AMD
|
# adaptive_sync on the desktop makes sway stutter/flicker; 120Hz avoids AMD
|
||||||
# VRAM clock flicker at high refresh (see README).
|
# VRAM clock flicker at high refresh (see README).
|
||||||
output DP-1 mode 1920x1080@240Hz adaptive_sync off allow_tearing yes
|
output DP-1 mode 1920x1080@240Hz adaptive_sync off allow_tearing yes
|
||||||
exec_always pkill -xf '/bin/sh /home/nnduc/.config/sway/scripts/vrr-follow'; ~/.config/sway/scripts/vrr-follow
|
|
||||||
#output DP-1 mode 1920x1080@240Hz adaptive_sync on allow_tearing yes
|
#output DP-1 mode 1920x1080@240Hz adaptive_sync on allow_tearing yes
|
||||||
|
|
||||||
### Idle configuration
|
### Idle configuration
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ wall_dir="${1:?wallpaper directory required}"
|
|||||||
img=$(find "$wall_dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | shuf -n1)
|
img=$(find "$wall_dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | shuf -n1)
|
||||||
swaymsg -q output DP-1 adaptive_sync off # lock screen redraws rarely: fixed 240 Hz
|
swaymsg -q output DP-1 adaptive_sync off # lock screen redraws rarely: fixed 240 Hz
|
||||||
swaylock -f ${img:+-i "$img"}
|
swaylock -f ${img:+-i "$img"}
|
||||||
# once unlocked, let vrr-follow decide again (in background so swayidle/suspend aren't held up)
|
# once unlocked, turn VRR back on if a game (gamemode) is still running
|
||||||
( while pgrep -x swaylock >/dev/null; do sleep 1; done
|
( while pgrep -x swaylock >/dev/null; do sleep 1; done
|
||||||
~/.config/sway/scripts/vrr-follow once ) &
|
gamemoded -s | grep -q 'is active' && swaymsg -q output DP-1 adaptive_sync on ) &
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# adaptive_sync on DP-1 only while the visible workspace shows a fullscreen window
|
|
||||||
OUT=DP-1
|
|
||||||
update() {
|
|
||||||
if [ "$(swaymsg -t get_tree | jq --arg o "$OUT" '
|
|
||||||
.nodes[] | select(.name==$o) as $out | $out.nodes[]
|
|
||||||
| select(.name==$out.current_workspace)
|
|
||||||
| [.. | objects | select((.fullscreen_mode? // 0) > 0)] | length')" -gt 0 ]
|
|
||||||
then s=on; else s=off; fi
|
|
||||||
[ "$s" != "$last" ] && swaymsg -q output "$OUT" adaptive_sync "$s" && last=$s
|
|
||||||
}
|
|
||||||
[ "$1" = once ] && { update; exit; }
|
|
||||||
update
|
|
||||||
swaymsg -t subscribe -m '["workspace","window"]' | while read -r _; do update; done
|
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"clock": {
|
"clock": {
|
||||||
// "timezone": "America/New_York",
|
// "timezone": "America/New_York",
|
||||||
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
||||||
|
"format": "{:%Y-%m-%d %H:%M}",
|
||||||
"format-alt": "{:%Y-%m-%d %H:%M}"
|
"format-alt": "{:%Y-%m-%d %H:%M}"
|
||||||
},
|
},
|
||||||
"bluetooth": {
|
"bluetooth": {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Section "Device"
|
||||||
|
Identifier "AMD"
|
||||||
|
Driver "amdgpu"
|
||||||
|
Option "VariableRefresh" "true"
|
||||||
|
EndSection
|
||||||
Reference in New Issue
Block a user