mostly improvements
authorIan Kelling <ian@iankelling.org>
Wed, 7 May 2025 19:01:43 +0000 (15:01 -0400)
committerIan Kelling <ian@iankelling.org>
Wed, 7 May 2025 19:01:43 +0000 (15:01 -0400)
17 files changed:
.xsession
beetag
brc
brc2
distro-end
distro-pkgs
filesystem/etc/needrestart/conf.d/iank.conf
filesystem/usr/local/bin/btrbk-run
filesystem/usr/local/bin/mount-latest-subvol
filesystem/usr/local/bin/myupgrade
filesystem/usr/local/bin/switch-mail-host
fsf-script-lib
machine_specific/frodo/subdir_files/.config/pipewire/pipewire-pulse.conf [new file with mode: 0644]
machine_specific/frodo/subdir_files/.config/pipewire/pipewire.conf [new file with mode: 0644]
pkgs
schrootupdate
subdir_files/.config/mpv/mpv.conf

index dcb4a0b676d1e43de75a491c08c89204882a24d5..89548f6fdc6e81b388c39fe4369dfd74208a32f9 100755 (executable)
--- a/.xsession
+++ b/.xsession
@@ -9,5 +9,5 @@
 # note, in xmonad we had to do this:
 # xsetroot -cursor_name left_ptr
 
-
+/a/exe/myx >/tmp/myx.log 2>&1
 exec i3
diff --git a/beetag b/beetag
index 2816f7c608d42d9f170320f12d19003c94ac1c6a..efc3c5f634fcb1332e4370b8d390af4ccd601bd7 100755 (executable)
--- a/beetag
+++ b/beetag
@@ -445,14 +445,35 @@ beetag()  {
   beetag-head-playlist
 
   #{ mpv --profile=a --volume=$volume --idle 2>&1 & } 2>/dev/null # todo: consider using again
+
+  # Notes on preventing
+  # stuttering with error message "Audio device underrun detected."
+  # during high IO load. Things I tried which did not work:
+  #
+  # * mpv --audio-buffer=2. (Default is 0.2) --pipewire-buffer=2000 --pulse-buffer=2000 --cache=yes --cache --cache-secs=30
+  # * mpv without loading scripts. mpv with the default gui.
+  # *s chrt -a -r -p 99 MPV_PID. and -p 80 on pipwire and pipewire-pulse.
+  #
+  # # moved on to configuring pipewire but didn't finish.
+  #
+  # * read the troubleshooting section: https://wiki.archlinux.org/title/PipeWire
+  # command to see
+  #
+  # * After changing configs: systemctl --user restart pipewire pipewire-pulse pipewire-pulse.socket
+  #
+  # * According to docs, to get started: cp /usr/share/pipewire/pipewire.conf ~/.config/pipewire/pipewire.conf
+  # cp /usr/share/pipewire/pipewire-pulse.conf ~/.config/pipewire/pipewire-pulse.conf
+  #
   mpv --profile=a --volume=$volume --idle &
   sleep .1 # or else: socat[1103381] E connect(5, AF=1 "/tmp/mpvsock", 14): Connection refused
 
+  # loop to play files.
   while true; do
     id=${ids[j]}
     path="${ls_paths[$j]}"
     ls_out="${ls_lines[j]}"
     tags=( ${ls_out%%,*} )
+    # Spamming the help text at this point is pretty useful.
     beetag-help
     printf "██ %s\n" "$ls_out"
     beetag-nostatus 1
diff --git a/brc b/brc
index 43aaadb0f69f6b226895c947301d0d3caf93f573..4b69d765dce5c9e773b3715ed0ee92632a41c8ff 100644 (file)
--- a/brc
+++ b/brc
@@ -634,6 +634,11 @@ bl() {
 # like running cl <enter> a <enter>
 cla() {
   local line cdirs
+  if [[ $DOT_CDIRS ]]; then
+    cdirs="$DOT_CDIRS"
+  else
+    cdirs=~/.cdirs
+  fi
   mapfile -t lines <"$cdirs"
   start=$(( ${#lines[@]} - 1 ))
   for (( j=start; j >= 0; j-- )); do
diff --git a/brc2 b/brc2
index 0c6745e36bb93e93eff3aa4b6211f91b668ceff4..87f54518aab0a95476724d42688588ed0e14ab29 100644 (file)
--- a/brc2
+++ b/brc2
@@ -247,6 +247,7 @@ rm-docker-iptables() {
 # Defaults always_set_home
 # Defaults !umask
 # EOF
+
 # sd /nocow/schroot/flidas//etc/locale.gen <<'EOF'
 # en_US.UTF-8 UTF-8
 # EOF
@@ -517,7 +518,7 @@ brains() {
   _iki-convert brains.fsf.org/wiki "$@"
 }
 glue() {
-  _iki-convert gluestick.office.fsf.org "$@"
+  _iki-convert gluestick.fsf.org "$@"
 }
 
 # usage: see above
@@ -2022,7 +2023,7 @@ ilog() {
   tmpf=$(mktemp)
   chan="${1:-#fsfsys}"
   # use * instead of -r since that does sorted order
-  sl root@li.b8.nz ilog-local "$chan" > $tmpf
+  sl root@li.b8.nz ilog-local "${chan@Q}" > $tmpf
   less +G $tmpf
   rm -f $tmpf
 }
@@ -4820,7 +4821,37 @@ url-decode() {
 
 osimain() {
   i push && i push gh main
-  }
+}
+
+# osi merge codeberg. after checking out a pr branch.
+om() {
+  local br
+  GIT_EDITOR=true m i rebase --continue
+  br=$(sed -r 's,^.*/,,' .git/HEAD )
+  e br=$br
+  m i co main
+  m i merge $br
+  m osimain
+}
+
+# osi github. checkout next pr
+og() {
+  gh_pr_num=$(gh pr ls --json number -q '.[].number' | tail -n1)
+  m gh pr checkout $gh_pr_num -b $gh_pr_num
+  m i rebase main
+}
+
+# continue og after fixing rebase
+o2() {
+  GIT_EDITOR=true m i rebase --continue
+  m i co main
+  m i merge $gh_pr_num
+  m osimain
+  m gh pr close $gh_pr_num --comment "I merged your signature into the petition. Thank you for signing!
+
+We'd much appreciate if you promote the petition further!
+Thanks again!"
+}
 
 export BASEFILE_DIR=/a/bin/fai-basefiles
 
index 79a75bdfd3800986b621e35d042c9084f3e36745..88db7cbc16bea73bd798a3c4f1bc6ebffe1abb49 100755 (executable)
@@ -253,7 +253,7 @@ esac
 
 
 
-##### begin automatic upgrades (after checkrestart has been installed) ####
+##### begin automatic upgrades (after needrestart has been installed) ####
 # if apt-config-auto-update is installed,
 # it also has similar config, in a file 10something,
 # but i think this overrides it since its higher number.
@@ -1355,8 +1355,15 @@ sgo schrootupdate.timer
 # for testing firefox specific issues
 case $distro in
   trisquel|ubuntu)
+    schroot_name=bookworm
     m mkschroot -s /a/bin/fai/fai/config/files/etc/apt/sources.list.d/bookworm.list/BOOKWORM_FREE \
-      debian bookworm chromium fonts-noto-color-emoji fonts-recommended
+      debian $schroot_name chromium fonts-noto-color-emoji fonts-recommended locales
+    sd /nocow/schroot/$schroot_name/etc/locale.gen <<'EOF'
+en_US.UTF-8 UTF-8
+EOF
+    s schroot -c $schroot_name locale-gen
+    s schroot -c $schroot_name update-locale LANG=en_US.UTF-8
+
     ;;
   debian)
     # fonts are for emojis, which tend to get used as buttons on the web.
@@ -1697,6 +1704,10 @@ DEVICESCAN -a -o on -S on -n standby,q $sched \
 ########### misc stuff
 
 
+# x200 on t12, this unit fails on boot. no idea why, but it seems harmless
+systemctl mask wacom-inputattach@ttyS4.service
+
+
 # see current with:
 # xdg-settings get default-web-browser
 # not sure this is needed.
index bd60d0f4374ad4066e6b2a5410ac21fba30b0bf4..5960bf8409ec5011475008915f15c83c6c0ef208 100755 (executable)
@@ -75,11 +75,6 @@ case $distro in
   *) : ;; # other distros come with cron.
 esac
 
-case $distro in
-  arch) e tk ;;
-  *) : ;; # other distros come with tk from git
-esac
-
 case $distro in
   arch) e the_silver_searcher ;;
   debian|trisquel|ubuntu) e silversearcher-ag ;;
@@ -102,11 +97,18 @@ case $HOSTNAME in
     ;;
 esac
 
+
+case $distro in
+  arch) e tk ;;
+  *) : ;; # other distros come with tk from git
+esac
+
 case $distro in
-  debian) e gnome-session-flashback ;;
-  # flidas is missing dependency gnome-panel. others unknown
+  trisquel) e icedove ;;
+  *) e thunderbird ;;
 esac
 
+
 case $distro in
   debian)
     e cpio-doc ;;
index 7e9988fb4d173004306c4d71edcf1c9ef2297d84..b1025fad98027d2a55948935584b650eb2fc72fc 100644 (file)
@@ -1,6 +1,15 @@
+#!/usr/bin/perl
+# shebang is just for highlighting
+
 # Restart mode: (l)ist only, (i)nteractive or (a)utomatically.
 $nrconf{restart} = 'a';
 #  0: disable microcode checks completely
 # On my systems, the default makes the nagios check return 3, unknown.
 # I don't have any systems which need microcode update detection.
 $nrconf{ucodehints} = 0;
+
+# note, we can verify this works as expected by adding
+# print join(", ", @{$nrconf{blacklist}}), "\n";
+# and running it with perl. @{} dereferences the array reference.
+push(@{$nrconf{blacklist}}, qr(^/usr/local/bin/emacs$));
+push(@{$nrconf{blacklist}}, qr(^/usr/local/bin/emacsclient$));
index 172de8e118a94ae67ca30cd9655997350bca65be..7f5ee3f9e5248bd7d026ce78b5dacf0c52aeb35b 100755 (executable)
@@ -441,7 +441,7 @@ while true; do
     -3) conf_suf=3 ;;
     -a)
       # all moiuntpoints
-      mountpoints=(/a /o /qr /qd /q)
+      mountpoints=(/a /o /qr /q)
       ;;
     # only creates the config file, does not run btrbk
     -c) conf_only=true ;;
@@ -648,24 +648,24 @@ else
             prospective_mps+=(/o)
           fi
           if [[ $source_host == "$HOST2" ]]; then
-            prospective_mps+=(/a /qr /qd /q)
+            prospective_mps+=(/a /qr /q)
           fi
         else
           if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
             prospective_mps+=(/o)
           fi
           if [[ $HOSTNAME == "$HOST2" ]]; then
-            prospective_mps+=(/a /qr /qd /q)
+            prospective_mps+=(/a /qr /q)
           fi
           if $kd_spread; then
-            prospective_mps=(/a /o /qr /qd /q)
+            prospective_mps=(/a /o /qr /q)
           fi
         fi
         # If the above conditions didnt add any mountpoints, and host
         # status is empty, then add all mointpoints. This is a case of
         # doing something like kd_spread manually.
         if [[ ! ${prospective_mps[0]} && $source_host != "$HOST2" && $source_host != "$MAIL_HOST" && $HOSTNAME != "$MAIL_HOST" && $HOSTNAME != "$HOST2"  ]]; then
-          prospective_mps=(/a /o /qr /qd /q)
+          prospective_mps=(/a /o /qr /q)
         fi
 
         # note: put q last just in case its specific retention options were to
index 1a55c886c00e83ec41d4fea6554d8f9eac0673fc..9207364dfdd7af37c6d2e388a43816b7ede5cb7a 100755 (executable)
@@ -241,12 +241,6 @@ mv-vol-to-leaf() {
     return 0
   fi
 
-  # no leaf volumes for qd
-  if [[ $vol == qd ]]; then
-    w b btrfs sub del qd || return 0
-    return 0
-  fi
-
   date=$(date +%Y-%m-%dT%H:%M:%S%z)
   leaf=$vol.leaf.$date
   b mv $vol $leaf
@@ -351,7 +345,6 @@ EOF
   if [[ -e $f ]]; then
     fstab <<EOF
 $crypt_dev  /q  btrfs  noatime,subvol=q$mopts  0 0
-$crypt_dev  /qd  btrfs  noatime,subvol=qd$mopts  0 0
 /q/p  /p  none  bind$mopts  0 0
 EOF
   fi
@@ -575,7 +568,7 @@ readonly verbose force
 if (( $# )); then
   all_vols=( "$@" )
 else
-  all_vols=(q a o i qd qr)
+  all_vols=(q a o i qr)
   ar_snaps=(/mnt/root/btrbk/ar.*)
   if [[ -e /mnt/root/ar ]] || (( ${#ar_snaps[@]} > 0 )); then
     all_vols+=(ar)
index 361bf3c8b6c93ba291ac4f1353480bdf4cb9325b..a1cc684e87f8d686aba4b395d30f6b5bf2dc472d 100755 (executable)
@@ -105,7 +105,7 @@ sleep 1
 # But, I'd rather something gets messed up than things not get
 # restarted.
 if ! /sbin/needrestart -p &>/dev/null; then
-  if [[ $hn == "$MAIL_HOST" || $hn == kd ]]; then
+  if [[ $hn == "$MAIL_HOST" || $hn == kd || $hn == frodo ]]; then
     # send us an email so we can decide what to do
     needrestart -r l
   else
index 21227f71f1f06cc988e65819a53bdcea488b9a6f..be1f9dd8c0b3daa5d3645b9f7ec00c77cbaf0d67 100755 (executable)
@@ -85,7 +85,7 @@ host2_only=false
 force=false
 force_arg=
 pull_reexec=false
-mp_args="-m /o,/a,/q,/qd,/qr"
+mp_args="-m /o,/a,/q,/qr"
 check_installed=false
 orig_args=("$@")
 if ! temp=$(getopt -l check-installed,force,pull-reexec,help 2afioh "$@"); then
@@ -144,7 +144,7 @@ fi
 if $mail_only; then
   mp_args="-m /o"
 elif $host2_only; then
-  mp_args="-m /a,/q,/qd,/qr"
+  mp_args="-m /a,/q,/qr"
 fi
 
 
index 7fa83184bd50fcd6875cde91347511c1e9628bc1..d24e751ffb4f62a97ac32847543360e74f434f65 100644 (file)
@@ -50,7 +50,9 @@ int_regex='^-?[0-9]+$'
 # unsigned int, no negative.
 # shellcheck disable=SC2034
 uint_regex='^[0-9]+$'
-
+# graphical chars: no [:space:], no newline. good for various string checks.
+# shellcheck disable=SC2034
+graph_regex='^[[:graph:]]+$'
 
 # horizontal row. used to break up output
 # shellcheck disable=SC2120 # not a big deal.
diff --git a/machine_specific/frodo/subdir_files/.config/pipewire/pipewire-pulse.conf b/machine_specific/frodo/subdir_files/.config/pipewire/pipewire-pulse.conf
new file mode 100644 (file)
index 0000000..77110b9
--- /dev/null
@@ -0,0 +1,173 @@
+# PulseAudio config file for PipeWire version "1.0.5" #
+#
+# 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-pulse.conf.d/ for system-wide changes or in
+# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes.
+#
+
+context.properties = {
+    ## Configure properties in the system.
+    #mem.warn-mlock  = false
+    #mem.allow-mlock = true
+    #mem.mlock-all   = false
+    #log.level       = 2
+
+    #default.clock.quantum-limit = 8192
+}
+
+context.spa-libs = {
+    audio.convert.* = audioconvert/libspa-audioconvert
+    support.*       = support/libspa-support
+}
+
+context.modules = [
+    { name = libpipewire-module-rt
+        args = {
+            nice.level   = -11
+            #rt.prio      = 83
+            #rt.time.soft = -1
+            #rt.time.hard = -1
+            #uclamp.min = 0
+            #uclamp.max = 1024
+        }
+        flags = [ ifexists nofail ]
+    }
+    { name = libpipewire-module-protocol-native }
+    { name = libpipewire-module-client-node }
+    { name = libpipewire-module-adapter }
+    { name = libpipewire-module-metadata }
+
+    { name = libpipewire-module-protocol-pulse
+        args = {
+           # contents of pulse.properties can also be placed here
+           # to have config per server.
+        }
+    }
+]
+
+# Extra scripts can be started here. Setup in default.pa can be moved in
+# a script or in pulse.cmd below
+context.exec = [
+    #{ path = "pactl"        args = "load-module module-always-sink" }
+    #{ path = "pactl"        args = "upload-sample my-sample.wav my-sample" }
+    #{ path = "/usr/bin/sh"  args = "~/.config/pipewire/default.pw" }
+]
+
+# Extra commands can be executed here.
+#   load-module : loads a module with args and flags
+#      args = "<module-name> <module-args>"
+#      ( flags = [ nofail ] )
+pulse.cmd = [
+    { cmd = "load-module" args = "module-always-sink" flags = [ ] }
+    #{ cmd = "load-module" args = "module-switch-on-connect" }
+    #{ cmd = "load-module" args = "module-gsettings" flags = [ nofail ] }
+]
+
+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
+}
+
+pulse.properties = {
+    # the addresses this server listens on
+    server.address = [
+        "unix:native"
+        #"unix:/tmp/something"              # absolute paths may be used
+        #"tcp:4713"                         # IPv4 and IPv6 on all addresses
+        #"tcp:[::]:9999"                    # IPv6 on all addresses
+        #"tcp:127.0.0.1:8888"               # IPv4 on a single address
+        #
+        #{ address = "tcp:4713"             # address
+        #  max-clients = 64                 # maximum number of clients
+        #  listen-backlog = 32              # backlog in the server listen queue
+        #  client.access = "restricted"     # permissions for clients
+        #}
+    ]
+    #server.dbus-name       = "org.pulseaudio.Server"
+    #pulse.min.req          = 128/48000     # 2.7ms
+    #pulse.default.req      = 960/48000     # 20 milliseconds
+    #pulse.min.frag         = 128/48000     # 2.7ms
+    #pulse.default.frag     = 96000/48000   # 2 seconds
+    #pulse.default.tlength  = 96000/48000   # 2 seconds
+    # iank. ran out of time to test this to prevent io stuttering
+    # I set this in the pipewire config too. I don't understand quite how they interact.
+    #pulse.min.quantum      = 1024/44100
+
+    #pulse.min.quantum      = 128/48000     # 2.7ms
+    #pulse.idle.timeout     = 0             # don't pause after underruns
+    #pulse.default.format   = F32
+    #pulse.default.position = [ FL FR ]
+    # These overrides are only applied when running in a vm.
+    vm.overrides = {
+        pulse.min.quantum = 1024/48000      # 22ms
+    }
+}
+
+# client/stream specific properties
+pulse.rules = [
+    {
+        matches = [
+            {
+                # all keys must match the value. ! negates. ~ starts regex.
+                #client.name                = "Firefox"
+                #application.process.binary = "teams"
+                #application.name           = "~speech-dispatcher.*"
+            }
+        ]
+        actions = {
+            update-props = {
+                #node.latency = 512/48000
+            }
+            # Possible quirks:"
+            #    force-s16-info                 forces sink and source info as S16 format
+            #    remove-capture-dont-move       removes the capture DONT_MOVE flag
+            #    block-source-volume            blocks updates to source volume
+            #    block-sink-volume              blocks updates to sink volume
+            #quirks = [ ]
+        }
+    }
+    {
+        # skype does not want to use devices that don't have an S16 sample format.
+        matches = [
+             { application.process.binary = "teams" }
+             { application.process.binary = "teams-insiders" }
+             { application.process.binary = "skypeforlinux" }
+        ]
+        actions = { quirks = [ force-s16-info ] }
+    }
+    {
+        # firefox marks the capture streams as don't move and then they
+        # can't be moved with pavucontrol or other tools.
+        matches = [ { application.process.binary = "firefox" } ]
+        actions = { quirks = [ remove-capture-dont-move ] }
+    }
+    {
+        # speech dispatcher asks for too small latency and then underruns.
+        matches = [ { application.name = "~speech-dispatcher.*" } ]
+        actions = {
+            update-props = {
+                pulse.min.req          = 512/48000      # 10.6ms
+                pulse.min.quantum      = 512/48000      # 10.6ms
+                pulse.idle.timeout     = 5              # pause after 5 seconds of underrun
+            }
+        }
+    }
+    #{
+    #    matches = [ { application.process.binary = "Discord" } ]
+    #    actions = { quirks = [ block-source-volume ] }
+    #}
+]
diff --git a/machine_specific/frodo/subdir_files/.config/pipewire/pipewire.conf b/machine_specific/frodo/subdir_files/.config/pipewire/pipewire.conf
new file mode 100644 (file)
index 0000000..c66bc2b
--- /dev/null
@@ -0,0 +1,333 @@
+# Daemon config file for PipeWire version "1.0.5" #
+#
+# 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                        = 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
+
+    # iank: adding this made us output at the same sample rate as the audio we were playing, which seems like a good thing. from arch wiki: "PipeWire can also change dynamically the output sample rates supported by your DAC", find them with:
+    # grep -E 'Codec|Audio Output|rates' /proc/asound/card*/codec#*
+    # get currently used rate:
+    # grep rate: /proc/asound/card?/pcm??/sub?/hw_params
+    # or pw-top
+    #
+    #
+    default.clock.allowed-rates = [ 44100 48000 88200 96000 192000 ]
+
+    #default.clock.allowed-rates = [ 48000 ]
+    #default.clock.quantum       = 1024
+    # iank. ran out of time to test this to prevent io stuttering
+    #default.clock.min-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
+    #
+    # These overrides are only applied when running in a vm.
+    vm.overrides = {
+        default.clock.min-quantum = 1024
+    }
+
+    # 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.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
+    #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
+            priority.driver = 20000
+            #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 = 19000
+            node.group      = pipewire.freewheel
+            node.freewheel  = true
+        }
+    }
+
+    # 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>" )
+    #    ( 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 } ] }
+]
diff --git a/pkgs b/pkgs
index 9e00cb443ea81853393de532361e602ebaa1a6d6..e56d2bee3be677e67705098d172fd9da87c417cd 100644 (file)
--- a/pkgs
+++ b/pkgs
@@ -200,6 +200,7 @@ p3=(
   i3status
   icecast2
   iftop
+  imapfilter
   iotop
   info
   inotify-tools
index df3cfe0dbd1f94c034e84e0498366a5f1eedd6b1..2692c2e11b613a0d2972e337edba01916b915952 100755 (executable)
@@ -28,7 +28,7 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
 # used to have more than one, leaving commented in case we do
 #for n in bullseye; do
-n=bullseye
+n=bookworm
 if [[ -e /etc/schroot/chroot.d/$n.conf ]]; then
   cd /
   schroot -c $n -- apt-get -y update
index f91c63d0323a2515133ca9ec72cfb80bec714462..3aee05dd77d8dd509e7d8d834d871c417c05722f 100644 (file)
@@ -45,10 +45,16 @@ player-operation-mode=cplayer
 audio-display=no
 # dont display any tags
 display-tags=
-#really-quiet
+# this gets rid of lines like:
+# [ipc_398] Write error (Broken pipe)
+#
+# which I suspect are happening because we do 2 socats too fast. But it
+# never seems to cause any other problem, so whatever, just hide it.
+really-quiet
+
 # note, useful cli option:
 # --script-opts=osc-visibility=always
-
+#
 # gets rid of lines like:
 # (+) Audio --aid=1 (flac 2ch 44100Hz)
 # AO: [pulse] 44100Hz stereo 2ch s16