downsample - MP3/WAV to 8-bit 15000 Hz WAV (psychoacoustically treated)
======================================================================

What it does
  Decodes an MP3 or WAV, resamples it to exactly 15000 Hz, applies an MPEG-style
  Bark-band psychoacoustic masker to drop inaudible detail, and quantises to
  signed 8-bit - stage one of the audio pipeline, feeding compsample.

    downsample <in.mp3|in.wav> <out.wav> [--duration <s>] [--cutoff <hz>]
               [--psy <n>] [--no-normalize] [--dither]
               [--adjust <regions.csv>] [--frame-hz <hz>]

  --duration time-scales the whole sample (resample, not pad/trim) to a target
  length - a tempo nudge to fit a take.

The two project-specific bits
  --adjust <csv>  The beam-locked replay does not emit its 300 samples/frame at
    a uniform 15000 Hz - it spaces them unevenly (slow top-border decode, fast
    visible lines, the VBL gap; see tools/emitadjaudio).  With --adjust, sample k
    of frame f is taken from the source at its REAL emit time (f + phase[k]) /
    frame_hz, phase[k] from the CSV, so each sample carries the value from the
    instant it is actually heard - cancelling the sample-and-hold timing wobble.
    --frame-hz is the absolute VBL rate (default 50; ~50.056 measured for pitch).

  psy runs before the 8-bit quantise, on the clean band-limited float - so it
  masks against what the listener hears, not quantisation noise, and frequencies
  the resample already discarded can't mask (and delete) audible content.

  15000 Hz = 300 samples/frame = a fixed 20 packets the replay decodes every VBL
  (constant per-frame CPU).

Build
  make            (needs a C++23 compiler and libmpg123)
