Skip to content

Make the transform a Fourier transform - #48

Merged
ibrahimweng merged 1 commit into
mainfrom
claude/the-transform
Aug 31, 2026
Merged

Make the transform a Fourier transform#48
ibrahimweng merged 1 commit into
mainfrom
claude/the-transform

Conversation

@ibrahimweng

Copy link
Copy Markdown
Owner

listen.ts is how the app reads sounds out of a recording — find where they are, then say whether two are the same kind of thing. Underneath all of it is a Fourier transform, and it was not one.

What was wrong

The angle it multiplies by was turned once per block instead of once per butterfly:

for (let k = 0; k < len / 2; k++) { ...butterflies using cr, ci... }
const nr = cr * wr - ci * wi;   // ← outside the loop

So every butterfly in a block used the angle it started at, which is no angle at all. What that computes is a Walsh–Hadamard transform.

A five-cycle cosine, which belongs in bin 5 and nowhere else:

naive DFT non-zero bins: 5
this fft non-zero bins:  1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
                         peak at 15

Only one kind of test could find it

Every test that compares one fingerprint against another passes on a transform that is merely consistent — and this one was. It scrambled every spectrum the same way, so two takes of a sound still matched and nothing above it ever complained. What was lost was every comparison between sounds that are not the same, which is the whole of what this file does.

It took a naive DFT, written straight from the definition and slow enough that nobody would ship it. After the fix, the two agree to 4.6e-13.

The comment above it says why this matters

The four pages under tools/ have the same transform with the line in the right place. This copy is the one that moved, and its own comment reads:

moved here so that the app and the pages that measure it cannot come to disagree about what a sound looks like

They had come to disagree.

Thirteen tests

The DFT comparison, a tone landing in its own bin at five frequencies, silence staying silent, a constant living entirely in bin zero, and what the fingerprint is actually for — taking out what a set of sounds have in common pushes two of the same kind apart, 0.95 → 0.45.

Three of those tests were mine and wrong first, which is worth saying: mono doesn't take the centre out, ordinary averages the logs rather than the prints, and a quieter take of a sound isn't identical to it (half a print is how loud each slice was) — so that one now asks whether it's nearer to itself than to something else, rather than asking for a number I picked.

333 unit tests (was 320), 88 browser tests, build clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi


Generated by Claude Code

`listen.ts` is how the app reads sounds out of a recording: find where they
are, then say whether two of them are the same kind of thing. Underneath all
of it is a Fourier transform, and it was not one.

The angle it multiplies by was turned once per block instead of once per
butterfly, so every butterfly in a block used the angle it started at, which
is no angle at all. What that computes is a Walsh-Hadamard transform. A five
cycle cosine, which belongs in bin five and nowhere else, came out spread
across every odd bin with its peak in bin fifteen.

Found by comparing against a transform written straight from the definition.
Nothing else could have found it. Every test that compares one fingerprint
against another passes on a transform that is merely consistent, and this
one was: it scrambled every spectrum the same way, so two takes of a sound
still matched and nothing above ever complained. What was lost was every
comparison between sounds that are not the same, which is the whole of what
this file does.

The four pages under `tools/` have the same transform with the line in the
right place. This copy is the one that moved, and the comment above it says
why that matters -- "moved here so that the app and the pages that measure
it cannot come to disagree about what a sound looks like". They had come to
disagree.

After the fix it matches the definition to 4.6e-13.

Thirteen tests, including that comparison, a tone landing in its own bin at
five different frequencies, silence staying silent, a constant living
entirely in the bin that means no change, and what the fingerprint is for:
that taking out what a set of sounds have in common pushes two of the same
kind apart, 0.95 to 0.45, which is the thing the ordinary exists to do.

Three of those tests were mine and wrong first. `mono` does not take the
centre out, `ordinary` averages the logs rather than the prints, and a
quieter take of a sound is not identical to it -- half of a print is how
loud each slice was -- so that one asks whether it is nearer to itself than
to something else rather than asking for a number.

333 unit tests, 88 browser tests, build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi
@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beat-studio Ready Ready Preview Aug 31, 2026 11:15am

@ibrahimweng
ibrahimweng merged commit c9a36a1 into main Aug 31, 2026
5 checks passed
@ibrahimweng
ibrahimweng deleted the claude/the-transform branch August 31, 2026 13:13
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