Fix the visualisers, add a notification icon, bump to v0.11.6 / android-v0.11.5 - #26
Merged
Merged
Conversation
…s an icon
The web display carried three mis-tunings the Android client had already found
and fixed, each recorded in Android's own comments and never ported back:
- fftSize was 1024, so bins are 43 Hz apart. That is wider than the bottom
bands of a log-spaced display, and the lowest dozen bars all landed on the
same one or two bins and drew the same number. 2048 resolves them, which is
most of what "only the left edge moves" was.
- minDecibels/maxDecibels were never set, so the AnalyserNode defaults applied:
-100 to -30. Ordinary mastered speech spends most of a sentence above a -30
ceiling, so band after band sat pinned at 255 — and a clipped bar cannot move.
The window is now -78 to -4, matching Android exactly.
- The tilt was 1.6, the value Android's comment records as lifting the top
bands by 2.6x until they clipped on their own. It is 0.8 here too now.
Both clients also gained the thing neither had: normalisation against what the
display has been hearing rather than against full scale. It is why a quietly
mastered episode drew a flat display while a loud one drew a lively one, and
podcast audio makes it worse than music does — levelling between shows is far
less consistent. Bounded on both ends: it never exceeds 3x and never lifts
silence, so a pause stays empty instead of becoming a wall of room tone.
Measured in a real browser against a synthetic voice with harmonics and
sibilance, comparing the old configuration with the new one over 120 frames:
low bands top bands
before 0.783 1.000
after 0.942 0.465
The top bands were not static there, they were slamming between the rails,
which reads as noise rather than as a spectrum; the bottom moved less than it
does now. An earlier run against a source with no content above 1.7 kHz showed
the opposite for the top bands, because the old settings were amplifying the
noise floor into something that looked like signal. Both numbers are in the
pull request rather than only the flattering one.
The mapping now lives in lib/audio/spectrum.ts so it can be tested without a
browser, which is also how the tilt regression is pinned: at 1.6 more than a
third of the bands clip on a speech-shaped input, and the test fails.
Separately, new-episode notifications used android.R.drawable
.stat_sys_download_done — a download tick for something that is not a download.
There was no suitable glyph in the project, so this adds one: the feed mark,
which is what "new items in a show you follow" means and which survives being
drawn at 24dp. Constructed from exact geometry rather than traced by hand, and
checked by rasterising the paths.
Verified on an emulator: playback runs with the new gain stage on the audio
thread without a crash or an audio-track error, and the drawable is compiled
into the APK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why the web visualiser looked dead
It carried three mis-tunings that the Android client had already diagnosed and fixed. Each one is described in Android's own source comments; none was ported back.
A clipped bar cannot move. At 43 Hz per bin the lowest dozen bars draw the same number. That is the "only the first 10% moves, the rest is static" report.
What both clients were missing
Normalisation against what the display has been hearing, rather than against full scale. It is why a quietly mastered episode drew a flat display while a loud one drew a lively one — and podcast audio makes this worse than music does, because levelling between shows is far less consistent. Bounded on both ends: never more than 3×, and never lifts silence, so a pause stays empty instead of becoming a wall of room tone.
Measured, not asserted
Run in a real browser against a synthetic voice (harmonics + sibilance), old configuration vs new, 120 frames, average peak-to-trough movement per band:
The top bands were not static in the old configuration — they were slamming between the rails, which reads as noise rather than as a spectrum. The bottom third moved less than it does now.
Counter-evidence, included deliberately: an earlier run against a source with no content above 1.7 kHz showed the opposite for the top bands (before 0.559, after 0.104). The reason is that the old settings were amplifying the noise floor into something that looked like signal, and the new window correctly reports an empty band as empty. I am reporting both numbers rather than the flattering one.
The mapping moved to
lib/audio/spectrum.tsso it can be tested without a browser. That is also how the tilt regression is pinned: restoring 1.6 makes more than a third of the bands clip on a speech-shaped input and fails the test — verified by putting the old value back.The notification icon
New-episode notifications used
android.R.drawable.stat_sys_download_done— a download tick, for something that is not a download. There was no suitable glyph in the project, so this adds one.The feed mark rather than a bell: it is what "new items in a show you follow" means, and it survives 24dp in a status bar where a bell's clapper and shoulders do not. Built from exact geometry (a dot plus two annular quarter-sectors sharing an origin) rather than traced by hand, and checked by rasterising the paths before wiring it in. Confirmed compiled into the APK via
aapt2 dump resources.Verification
svelte-checkclean, translations/docs/release-policy gates pass.testDebugUnitTestandtestReleaseUnitTestboth green — the two tasks the release workflow runs.Versions
apps/web→ 0.11.6, Android → versionCode 45 / 0.11.5. This also carries the audit fixes merged in #25, which have not been in a release yet.🤖 Generated with Claude Code