Neural Audio Quantiser

Year
2026

Role
Solo

Built with
Python, NumPy, PyTorch

Team
Solo

Links
Repository is private

Two waveforms of the same drum hit on one timeline. Before the edit, the hit starts 38.7 milliseconds after the beat. After the model’s edit it starts 0.29 milliseconds from it. The waveform is moved, not stretched.

Before38.7 ms late
the beat 38.7 ms late
After the model’s edit0.29 ms from the beat
-25 ms0 ms+25 ms+50 ms+75 ms+100 ms+125 ms+150 ms+175 ms

Read the write-up Three held-out clips, before and after the model’s edit, on a shared timeline around the beat (time in milliseconds from the beat). The model moves the audio; it doesn’t stretch it. Each clip has a click track mixed in, so you can hear the timing. Repository is private

A drum hit that lands a few milliseconds early or late makes a performance sound loose. Quantising moves it onto the beat, but the usual tools stretch the audio to do it, and you can hear that. I’m building a model that uses the same tools a human engineer would: cut the audio and move it, so nothing is stretched.

Why I started again

I have tried this before. An earlier attempt, from December 2025, went straight to the deep end. So this version starts again from the simplest data I can make, one hit per clip, and only gets harder once the model has earned it.

What I built

I’ve built a data synthesis engine that makes training pairs with exact labels: a clip with the hit off the beat, and the same clip with it on the beat. I’m using it to train a model that uses the same tools a human engineer would, starting with the simplest one: cut the hit and move it. The model predicts how far each hit should move, in milliseconds, forwards or back. A fixed cut-and-move step then applies that move to the waveform.

Figure 2. The task, drawn schematically: a hit that lands early is cut and moved onto the beat.
The task: cut and moveSchematic. A drum hit starts just before a vertical line marking the beat. An arrow moves it forward until its start sits on the line. BeforeAfter the beat cut move hit lands earlyhit lands on the beat The task: cut and moveSchematic. A drum hit starts just before a vertical line marking the beat. An arrow moves it forward until its start sits on the line. BeforeAfter the beat cut move hit lands earlyhit lands on the beat

What it showed

The test is deliberately narrow. There are 512 held-out clips, each with a single hit, and one question: after the model’s edit, how many hits sit within one millisecond of the beat? I set the pass mark at 95% before running the experiment.

The best model, trained for 30,000 steps, puts 98.4% ± 0.9 of hits within a millisecond, the mean of three training seeds. Doing nothing leaves the median hit 30.3 ms from the beat. After the model’s edit it is 0.29 ms. Only one model setup cleared the pass mark. The next best reached 94.8%. Training longer mattered: the same setup scored 79.4% after 3,000 steps and 91.4% after 10,000.

Figure 1. Share of 512 held-out synthetic clips, one hit each, whose hit ends up within 1 ms of the beat after the edit. Learned model: mean of three training seeds after 30,000 steps (dots are the individual seeds; ± is the standard deviation across seeds). The classical method is still better on this clean data.
Hits within 1 ms of the beat, after the editBar chart. Share of hits within 1 millisecond of the beat after the edit, on 512 held-out clips. Learned model: 98.4 percent, plus or minus 0.9, mean of three training seeds. Classical grid-snap method: 100 percent. Doing nothing leaves the median hit 30.3 milliseconds from the beat. A dashed line marks the 95 percent pass mark. The classical method is better on this data. Hits within 1 ms of the beat, after the edit (%) 0255075100 Learned model: 98.4% ± 0.9 of hits within 1 ms (mean of three training seeds) Classical grid-snap: 100% of hits within 1 ms pass mark: 95%, set in advance 98.4% ± 0.9 100% Do nothingLearned modelClassical grid-snap median 30.3 ms from the beatmedian 0.29 ms from the beatmedian 0.016 ms from the beat Hits within 1 ms of the beat, after the editBar chart. Share of hits within 1 millisecond of the beat after the edit, on 512 held-out clips. Learned model: 98.4 percent, plus or minus 0.9, mean of three training seeds. Classical grid-snap method: 100 percent. Doing nothing leaves the median hit 30.3 milliseconds from the beat. A dashed line marks the 95 percent pass mark. The classical method is better on this data. Do nothing median 30.3 ms from the beat Learned model 98.4% ± 0.9 median 0.29 ms from the beat Classical grid-snap 100% median 0.016 ms from the beat pass mark 95% 0255075100 % of hits within 1 ms of the beat

What it did not show

A classical method still does better. A hand-written signal-processing routine that finds each hit and snaps it to the nearest beat gets every one of the 512 hits within a millisecond, with a median of 0.016 ms. So this rung passes my gate, but it is not solved.

The data is also clean and synthetic, and I haven’t tried a real recording.

What’s next

The point of this stage is to find out what lets a network hear exactly where a hit starts, before I make the data harder. Matching the classical method on clean data is the bar for the next rung. Real drum one-shots are that rung, and I haven’t started it.