diff options
Diffstat (limited to 'scripts/normalize-notify-sounds.sh')
| -rwxr-xr-x | scripts/normalize-notify-sounds.sh | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/scripts/normalize-notify-sounds.sh b/scripts/normalize-notify-sounds.sh new file mode 100755 index 0000000..52c1d36 --- /dev/null +++ b/scripts/normalize-notify-sounds.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Normalize notify sound files to a uniform RMS loudness so every notification +# plays at the same perceived level. Re-encodes each file in place (ogg -> ogg). +# Run once after adding or changing a sound in the notify set. +# +# Each file is measured with ffmpeg's volumedetect, then shifted by a constant +# gain so its mean (RMS) volume lands on TARGET_DB. Peaks sit near 0 dB already, +# so the spread was all in the RMS; leveling the RMS makes them match by ear. +# +# Usage: +# normalize-notify-sounds.sh [SOUND_DIR] +# +# Environment: +# TARGET_DB Target mean (RMS) loudness in dB. Default -31 (gentle + even). +# Lower is quieter. The notify script's NOTIFY_VOLUME knob tunes +# the master level at playback time without re-encoding. + +set -euo pipefail + +SOUND_DIR="${1:-$HOME/.local/share/sounds/notify}" +TARGET_DB="${TARGET_DB:--31}" + +command -v ffmpeg >/dev/null || { echo "ffmpeg not found" >&2; exit 1; } +command -v ffprobe >/dev/null || { echo "ffprobe not found" >&2; exit 1; } + +shopt -s nullglob +files=("$SOUND_DIR"/*.ogg) +(( ${#files[@]} )) || { echo "No .ogg files in $SOUND_DIR" >&2; exit 1; } + +for f in "${files[@]}"; do + mean=$(ffmpeg -hide_banner -nostats -i "$f" -af volumedetect -f null /dev/null 2>&1 \ + | grep -oP 'mean_volume: \K[-0-9.]+' || true) + if [ -z "$mean" ]; then + echo "skip (could not measure): $f" >&2 + continue + fi + gain=$(awk -v t="$TARGET_DB" -v m="$mean" 'BEGIN { printf "%.1f", t - m }') + tmp=$(mktemp --suffix=.ogg) + ffmpeg -hide_banner -loglevel error -y -i "$f" \ + -af "volume=${gain}dB" -c:a libvorbis -q:a 6 "$tmp" + # Write through the file rather than mv over it: when SOUND_DIR is the + # stow-symlinked ~/.local copy, mv would replace the symlink with a real + # file and decouple it from the repo. cat preserves the symlink target. + cat "$tmp" > "$f" + rm -f "$tmp" + printf "%-14s mean %7s dB gain %+6s dB -> target %s dB\n" \ + "$(basename "$f")" "$mean" "$gain" "$TARGET_DB" +done |
