Files
rspektrum/shot_input.sh
tyler ac262505c1 feat: headless PNG render, mLnL annotations, and per-frame sched offset
Commit the accumulated working-tree changes as one snapshot.

- Headless render: `--render OUT.png INPUT.wav` draws the spectrogram
  (full window, or `--pane` for the spectrogram pane only) to a PNG
  with no visible window. Options: `--annotations`/`--no-annotations`,
  `--annotation-opacity`, `--width`/`--height`.
- mLnL annotations: parse the optional `mLnL` RIFF chunk (schema v2)
  and render tx_frame/assertion/control overlays, a timeline lane, and
  a waveform-scope echo, with hover tooltips on the spectrogram,
  timeline, and scope.
- sched_offset_ms: parse the per-frame intent->air latency and surface
  it in the hover tooltips (boxes stay air-anchored upstream).
- Supporting: build wiring (rspektrum.make), shared types/headers,
  web-build and capture-script tweaks, and removal of the old
  synchrosqueezing LaTeX doc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 12:19:37 -07:00

86 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Usage: shot_input.sh <output.png> [action ...]
# Launches rspektrum under Xvfb, runs input actions, captures the screen, cleans up.
#
# Actions (each runs in order):
# "sleep N" sleep N seconds locally (let the app settle / animate).
# Capture at "sleep 12" for a SETTLED render: the background
# high-res STFT fill runs over the first several seconds, so
# earlier grabs are nondeterministic run-to-run.
# "click X Y" left-click at (X,Y): move, press, hold ~0.2s, release.
# "drag X1 Y1 X2 Y2" left-drag from (X1,Y1) to (X2,Y2).
# "rdrag X1 Y1 X2 Y2" same but with Alt held (the app's pan gesture).
# "key NAME" xdotool keysym, e.g. "key F1", "key p", "key Home".
# anything else passed verbatim to xdotool (mousemove, mousedown, ...).
#
# IMPORTANT timing note: a left button's press and release MUST land in different
# 60 Hz frames or raylib's IsMouseButtonPressed edge-detect (current && !previous)
# never fires. The click/drag helpers below insert that gap; a bare "click 1" via
# xdotool is too fast and silently no-ops. Keys reach GLFW fine under Xvfb; so do
# synthetic mouse buttons (the pointer just has to be over a live target).
#
# Layout cheat-sheet at the default 1280x800 window (UI scale = 1.0):
# spectrogram viewport ~ x:[385,1242] y:[50,468] (drags/selections go here)
# sidebar ~ x:[0,320] (buttons; click centers)
# a selection box needs a >5 px drag or it reverts to "no selection".
set -u
OUT="${1:-/tmp/rspek_shot.png}"; shift || true
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DISP=:99
WAV="${RSPEK_WAV:-/tmp/mlink_bulk_drop.wav}"
pkill -f "Xvfb $DISP" 2>/dev/null
sleep 1
Xvfb $DISP -screen 0 1280x800x24 >/tmp/xvfb.log 2>&1 &
XVFB=$!
sleep 1
cd "$REPO" || exit 1
DISPLAY=$DISP ./bin/Debug/rspektrum "$WAV" >/tmp/rspek.log 2>&1 &
APP=$!
sleep 5 # initial load
# Make sure the app window is focused so key events land on it.
WID=$(DISPLAY=$DISP xdotool search --name "Spectrogram" | head -1)
[ -n "$WID" ] && DISPLAY=$DISP xdotool windowactivate "$WID" 2>/dev/null
sleep 0.3
xd() { DISPLAY=$DISP xdotool "$@" 2>>/tmp/xdotool.log; }
for act in "$@"; do
# shellcheck disable=SC2086
set -- $act
case "$1" in
sleep) sleep "$2" ;;
click)
xd mousemove "$2" "$3"; sleep 0.1
xd mousedown 1; sleep 0.2 # hold across >=1 frame
xd mouseup 1; sleep 0.15
;;
drag)
xd mousemove "$2" "$3"; sleep 0.1
xd mousedown 1; sleep 0.1
xd mousemove "$4" "$5"; sleep 0.2
xd mouseup 1; sleep 0.15
;;
rdrag)
xd keydown alt; sleep 0.05
xd mousemove "$2" "$3"; sleep 0.1
xd mousedown 1; sleep 0.1
xd mousemove "$4" "$5"; sleep 0.2
xd mouseup 1; sleep 0.1
xd keyup alt; sleep 0.15
;;
*) xd "$@"; sleep 0.15 ;;
esac
done
sleep 0.3
DISPLAY=$DISP import -window root "$OUT" 2>/tmp/import.log
RC=$?
kill $APP 2>/dev/null
kill $XVFB 2>/dev/null
wait 2>/dev/null
echo "capture rc=$RC -> $OUT"
ls -la "$OUT" 2>/dev/null