Skip to content

fix(export): exported click at the level the app plays it - #837

Merged
thcp merged 1 commit into
big-releasefrom
fix/export-click-level-833
Oct 22, 2026
Merged

thcp merged 1 commit into
big-releasefrom
fix/export-click-level-833

Conversation

@thcp

@thcp thcp commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

Closes #833

What changed

  • The rendered click is mono. Every export now takes it to stereo with an explicit pan=stereo|c0=c0|c1=c0 (CLICK_TO_STEREO), so each channel carries the click at its volume, as the app plays it (Web Audio up-mixes it as L = R = M). Before, amix left the conversion to libswresample's default matrix: -3.01 dB per channel.
  • The stems zip click file uses the same conversion, so the zip still sums to the mix.
  • A cached mix with a click misses the cache (:u in the click part of the key), so nobody is served the old level after upgrading. Mixes without a click keep their keys.

Render paths touched

  • app/pipeline/click_render.py:63 CLICK_TO_STEREO
  • app/api/stems.py:1956 get_mixdown: mix export (all formats), region export, count-in
  • app/api/stems.py:2217 get_video_mixdown (MP4)
  • app/api/stems.py:2385 _render_click_stem (stems zip click file), docstring updated
  • app/api/takes.py:1731 take renders (Streamer Mode video)
  • app/api/stems.py:262 mixdown cache key
  • Phone UI has no click control, so no phone path.

What did not change

  • The click sound: the mono render, Classic's four sha256 fingerprints and tests/fixtures/click_sounds.json all pass untouched. click_levels.json (accent levels, not dB) untouched.
  • Alignment: on a real export, frame counts and onsets are identical to big-release, and after = before x sqrt(2) within 1.1 LSB.
  • The live click.

Levels (Classic, volume 0.6)

  • Export per channel vs live: -3.01 dB before, 0.00 dB after (mix, region, count-in, zip, MP4, take render).
  • Real 20 s song, click only: peak -11.11 to -8.10 dBFS, RMS -37.68 to -34.67 dBFS.
  • Accented click alone at 0.6: peak -7.86 to -4.85 dBFS, still under the -1 dBFS limiter.

Risks

  • Every click export is 3 dB louder than in 0.20. The limiter now engages on a click alone from about volume 0.94 (was 1.32). At volume 4 on loud stems: WAV/FLAC peak -1.00 dBFS, MP3 -1.00 dBTP, no sample at full scale, same as before.
  • On an MP3-stored song, a count-in export on big-release came out mono (stems folded to mono). It is stereo now.

Tests

  • New: the export's per-channel level equals the live buffer times the volume (mix, region, count-in in WAV and FLAC; zip; MP4; take render). Each failed on big-release at -3.01 dB.
  • New: the loudest click (4, accented) on loud stems stays under the ceiling in WAV, FLAC, MP3, OGG, in the mix and the zip.
  • Updated on purpose: UPMIX = 1/sqrt(2) removed from tests/test_click_sounds.py (zip alignment, chosen-sound mix, zip-sums-to-mix tests now expect unity).

Release note: Exported clicks are now 3 dB louder than in 0.20, so they match what you hear in the app. If you set the click level by ear against an export, you may want to turn the click volume down a little.

… app plays it

The click is rendered mono. Live, Web Audio up-mixes it into the stereo
master as L = R = M. In exports, amix left the conversion to
libswresample's default mono-to-stereo matrix, which puts it 3.01 dB
lower on each channel. Every export now converts the click with an
explicit pan=stereo|c0=c0|c1=c0 (CLICK_TO_STEREO): the mix and region
export, the count-in, the stems zip click file, the MP4 export and take
renders. The zip still sums to the mix. The click sound and its timing
are unchanged.

A cached mix with a click misses the cache now (":u" in the click part
of the key), so an upgrade never serves the old level.

Closes #833
@thcp
thcp marked this pull request as ready for review October 22, 2026 18:42
@thcp
thcp merged commit 01be63b into big-release Oct 22, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant