Research · 2026-09-29

How close does the sync land? Sixteen real piano recordings, measured

SheetVideo lines a score up with a recording of it by listening: no tapping, no metronome, no markers. This is how it does that, and how close it gets on 16 public-domain piano recordings (60 minutes, 1,448 bars) by different pianists, from Bach to Joplin, measured note by note against the recordings themselves.

7.9 msmedian distance from a synced note to its attack in the recording
81%of notes within one video frame (33 ms at 30 fps)
90%within two frames
29of 1,448 bars flagged for a second look

Summary

Across the 14 recordings where attacks can be measured, the median synced note lands 7.9 ms from the attack we find in the recording, 81% land within one frame of a 30 fps video and 90% within two. Our way of finding attacks is itself off by a median of 4.9 ms when the truth is known (section 4), so part of that spread is the ruler, not the sync. In 3 of the recordings the pianist does not play the score as the file writes it (repeats taken or skipped); the sync finds the order they played it in by itself.

The earlier figures on our home page (a median under 5 ms, 43 ms at worst) come from a synthetic test, where a score is played back under a known tempo warp. This is the harder test: real pianos, real rooms, real rubato, and no answer key.

1 · The test set

Every recording here is in the public domain or CC0 (Wikimedia Commons, most of them from Musopen), and every score is an edition from the Mutopia Project, read as MIDI, the way someone would import it into SheetVideo: all in the public domain but the Nocturne's, which is CC BY-SA 3.0. We chose them for range: slow and fast, sparse and dense, a 1902 piano roll, a twelve-minute ballade, and three pieces whose recordings do not follow their score's repeats.

PieceRecordingLengthBarsTempo range
Frédéric Chopin
Étude Op. 10 No. 12 Revolutionary
Edward Neeman, piano (public domain)2:45840.61–0.98× written
Frédéric Chopin
Étude Op. 10 No. 1 Waterfall
Edward Neeman, piano (public domain)1:51790.84–1.22× written
Frédéric Chopin
Étude Op. 10 No. 5 Black Keys
Edward Neeman, piano (public domain)1:51850.72–1.09× written
Frédéric Chopin
Étude Op. 25 No. 1 Aeolian Harp
Musopen recording (public domain)3:01500.53–0.96× written
Frédéric Chopin
Waltz Op. 64 No. 1 Minute Waltz
Olga Gurevich, piano (public domain)1:471400.55–1.17× written
Frédéric Chopin
Fantaisie-Impromptu, Op. 66
Musopen recording (CC0)5:271380.62–1.11× written
Frédéric Chopin
Prelude Op. 28 No. 15 Raindrop
Musopen recording (CC0)4:55890.71–1.07× written
Frédéric Chopin
Prelude Op. 28 No. 6 in B minor
Musopen recording (CC0)1:48260.77–1.24× written
Ludwig van Beethoven
Pathétique Sonata, II. Adagio cantabile
Musopen recording (CC0)4:58730.70–1.02× written
Ludwig van Beethoven
Pathétique Sonata, III. Rondo
Musopen recording (CC0)4:352100.67–1.00× written
Johann Sebastian Bach
Prelude in C major, BWV 846
Musopen recording (CC0)2:19350.92–1.11× written
Robert Schumann
Träumerei, Op. 15 No. 7
Musopen recording (public domain)3:2333 played 33 of 25 written*0.51–0.93× written
Robert Schumann
Of Foreign Lands and Peoples, Op. 15 No. 1
Musopen recording (public domain)1:5244 played 44 of 22 written*0.52–0.81× written
Scott Joplin
The Entertainer
Scott Joplin's 1902 piano roll (public domain)2:3785 played 85 of 152 written*0.70–1.20× written
Frédéric Chopin
Ballade No. 4 in F minor, Op. 52
Musopen recording (CC0)12:422390.62–1.69× written
Frédéric Chopin
Nocturne in E-flat major, Op. 9 No. 2
Peter Johnston, piano (CC0)4:19380.68–1.69× written

* The recording repeats or skips sections: the bar count is of the score as played. Tempo range: the 5th to 95th percentile of each bar's tempo against the tempo the file gives.

2 · How the sync works

2.1 What is compared

The recording is read at 22.05 kHz and cut into overlapping frames 23 ms apart (a 4096-sample window, so the bass is still resolved to the semitone). Each frame becomes two short vectors: a chroma vector, the energy in each of the twelve pitch classes, and an onset vector, which pitch classes just got louder, with one more channel for broadband hits. The score is not rendered to audio for this: the same two vectors are written straight from its notes, so nothing depends on how a synthesiser happens to sound.

CDEFGABthe recordingCDEFGABthe score, laid onto the recording by the sync123
Figure 1. The first twelve seconds of Chopin's Prelude in B minor. Top: the chroma of the recording, C at the bottom, B at the top. Bottom: the chroma written from the score, laid onto the recording by the sync. Numbers are bar lines. The melody is in the left hand, and the score's pattern lines up with the recording's bar by bar.

2.2 The cost of pairing two moments

For score frame i and recording frame j, with chroma vectors xi, yj, onset directions oi, pj and onset strengths ai, bj:

c(i,j)=α(1−⟨xi,yj⟩)+(1−α)12(ai2+bj2−2aibj⟨oi,pj⟩)

with α=0.4: the harmony counts, and so does whether a note is struck at that moment or only still ringing. Both vectors are unit length, so a perfect match costs 0 and nothing in common costs about 1.

2.3 The path, and what it may leave out

The sync is a monotone path through the matrix of these costs (figure 3), from the first note of the score to its last, found by dynamic programming. A recording holds more than the score: silence, a breath, someone talking before the first chord, a take that stops early. Rather than letting the path start and end anywhere for free, every frame of recording the path leaves unexplained is charged at one rate, κ, the cost a matched frame of this piece typically has. With U the number of sounding frames of recording the path leaves out and B the number of bent steps it takes, a path's total is

C=∑(i,j)∈Pc(i,j)+κU+βκB

Nothing is normalised by the path's length, so a path that stops short of a slow ending does not look better for having covered less. A bent step (the score moving at two or three times the recording's pace, or the reverse) is charged βκ, so the path follows the tempo it has found rather than wandering to whichever chord matches best locally.

2.4 Coarse to fine, twice

A four-minute piece is a matrix of about 108 cells, too many to search directly. The sync first fits a straight line (a global tempo and offset) at a coarse resolution, searches a band around it that allows 35% of cumulative rubato, and then refines only a narrow tube round the coarse path at the full 23 ms resolution. It then does this a second time with the score laid out at the tempo curve the first pass found, so a long ritardando becomes part of the layout and the step charges only ever fall on note-level timing.

The editor while it syncs: the score and the recording as colour fingerprints, joined by the path it has found
Figure 2. The editor while it syncs Of Foreign Lands and Peoples. Top: the score's fingerprint (its chroma, twelve rows); bottom: the recording's. Each thread joins a moment of the score to the moment of the recording the path has matched it to. It is the alignment as it runs, not an animation.
the score as written, at its written tempo →the recording →
Figure 3. Of Foreign Lands and Peoples (Schumann). The cost matrix of the score as the file writes it (left to right, at its written tempo) against the recording (bottom to top); bright where they agree. The path is the sync, bar by bar. The pianist takes both repeats, so the path runs through the first eight bars, jumps back (dashed) to play them again, runs on to the end, then jumps back to bar 9 and plays the second half again.

2.5 When the pianist does not play the score as written

A MIDI file has no repeat signs, so a minuet or a waltz is written once and played with its repeats; a file that writes them out meets a pianist who skips some. Before the fine pass, the sync finds the order the bars are played in, with a coarse pass (about 4 frames per second) where the path may also jump at a bar line to the start of any other bar, back or ahead (after Fremerey, Müller and Clausen's JumpDTW):

D(sa,j)=c(sa,j)+min{D(sa−1,j−1),minbD(eb,j−1)+J,…}

where sa is the first frame of bar a, eb the last of bar b, and J the price of a jump: three seconds' worth of unexplained recording. A repeat the score lacks is cheaper to jump back for than to leave unexplained; a bar that only resembles another is cheaper to walk through. The order is kept only if it saves more than one more jump's worth over playing the score straight through; otherwise the score is left as it is. Of the sixteen recordings, three came back with a different order (table 1), and they are the three that do not follow their file: both repeats in the Schumann, the first repeat only in Träumerei, and a 1902 piano roll of The Entertainer which, by the sync's reading, leaves out the last two strains and goes from the return of the first straight to the final bar. The editor says so when the sync is done (figure 4).

The editor after the sync: the bar timeline and the message that the recording plays bars 1–8 twice, then 9–22 twice
Figure 4. After the sync of the same piece: the timeline now has 44 bars, and the editor says what it found and did.

2.6 From the path to the notes

The path gives a time for every bar line and every note onset. Each onset is then moved onto an attack detected in the recording, if there is one within 80 ms, so the note lights on the attack you hear rather than on a smoothed estimate of it. Finally every bar is checked: how well its notes matched, whether the path stood still or skipped there, and whether its tempo leaps against its neighbours. Bars that fail are flagged in the editor for a person to look at, and can be fixed by dragging one note onto its attack.

The editor's list of bars worth a listen after a sync
Figure 5. The bars flagged in that sync, each with where it is in the recording and how sure the sync is. One click plays it; another says it sounds right.

3 · The tempo the pianists took

None of these recordings holds the tempo its file gives, and most do not hold any tempo. Figure 6 shows each pianist's tempo, bar by bar, against the written one; the sync is never told any of it. The widest, Chopin · Ballade No. 4 in F minor, moves between 0.62× and 1.69× the written tempo; the steadiest, Bach · Prelude in C major, BWV 846, stays between 0.92× and 1.11×.

Chopin · Étude Op. 10 No. 12 Revolutionary
0:002:37
Chopin · Étude Op. 10 No. 1 Waterfall
0:001:42
Chopin · Étude Op. 10 No. 5 Black Keys
0:001:41
Chopin · Étude Op. 25 No. 1 Aeolian Harp
0:002:35
Chopin · Waltz Op. 64 No. 1 Minute Waltz
0:001:41
Chopin · Fantaisie-Impromptu
0:004:55
Chopin · Prelude Op. 28 No. 15 Raindrop
0:004:45
Chopin · Prelude Op. 28 No. 6 in B minor
0:001:39
Beethoven · Pathétique Sonata, II. Adagio cantabile
0:004:42
Beethoven · Pathétique Sonata, III. Rondo
0:004:31
Bach · Prelude in C major, BWV 846
0:002:08
Schumann · Träumerei
0:003:04
Schumann · Of Foreign Lands and Peoples
0:001:44
Joplin · The Entertainer
0:002:26
Chopin · Ballade No. 4 in F minor
0:0012:29
Chopin · Nocturne in E-flat major
0:004:07
Figure 6. Tempo as a multiple of the written tempo (log scale, 0.4× to 2.5×; the grey line is the written tempo): bar by bar (faint) and as a five-bar running median. Red points are bars the sync flagged.

4 · How we measured

A real recording comes with no answer key: nobody wrote down when each note was struck. So for each synced note we look for its attack in the recording itself, by following the energy at that note's own pitch (its fundamental and first two harmonics) through 2.9 ms steps, and taking the moment it rises fastest. The search stays within half the distance to the neighbouring notes, so it cannot land on another note's attack, and a note is only counted when its attack can be told apart:

  • no other note starts within 120 ms of it;
  • no note within 250 ms shares its partials (the same pitch, a fifth, an octave, an octave and a fifth, two octaves);
  • its rise is at least 6 dB, and 4 dB stronger than any other rise in the window.

Chords count once, by their top note. That leaves 2,777 notes in 14 recordings. In the densest études almost no note has 120 ms to itself (Chopin · Étude Op. 10 No. 1 Waterfall, Chopin · Étude Op. 10 No. 5 Black Keys), so they are synced like any other piece but not scored here.

Checking the ruler. To see how good this detector is, we ran it where the truth is known: on every score of the set rendered by SheetVideo's own piano, starting each search from a guess up to 50 ms off. It finds the true attack with a median error of 4.9 ms; 77% of its answers are within 10 ms, 91% within 20 ms. The rendered piano's attack is cleaner than a real one's, so on the recordings the detector can only do worse, and some of the spread in section 5 is the detector's, not the sync's.

5 · Results

-100-67-3303367100synced time − attack in the recording (ms) · dashed lines: one and two frames at 30 fps0%10%20%30%the sync, 2,777 notes in real recordingsthe detector itself, 3,484 notes, known truth
Figure 7. Where the synced notes land against the attacks in the recordings (bars), and where the detector lands against the known truth (line). The dashed lines mark one and two frames of a 30 fps video. 151 of 2,777 notes lie beyond ±100 ms.
PieceNotes measuredMedian75th pct90th pct≤ 1 frame≤ 2 framesBars flaggedSync time
Chopin · Étude Op. 10 No. 12 Revolutionary49 / 132413.8 ms29 ms58 ms76%94%0 / 8426 s
Chopin · Étude Op. 10 No. 1 Waterfall2 / 1243–––––1 / 7919 s
Chopin · Étude Op. 10 No. 5 Black Keys28 / 981–––––2 / 8527 s
Chopin · Étude Op. 25 No. 1 Aeolian Harp53 / 120114.0 ms40 ms64 ms74%92%1 / 5057 s
Chopin · Waltz Op. 64 No. 1 Minute Waltz89 / 7345.8 ms12 ms47 ms83%96%5 / 14022 s
Chopin · Fantaisie-Impromptu123 / 251920.3 ms51 ms81 ms65%80%1 / 13880 s
Chopin · Prelude Op. 28 No. 15 Raindrop234 / 7428.1 ms29 ms88 ms76%85%1 / 8978 s
Chopin · Prelude Op. 28 No. 6 in B minor75 / 1867.7 ms30 ms119 ms76%83%0 / 2634 s
Beethoven · Pathétique Sonata, II. Adagio cantabile184 / 7288.7 ms46 ms93 ms71%84%2 / 7323 s
Beethoven · Pathétique Sonata, III. Rondo295 / 15678.7 ms24 ms42 ms86%97%3 / 21025 s
Bach · Prelude in C major, BWV 84691 / 54510.0 ms39 ms79 ms71%81%1 / 3522 s
Schumann · Träumerei134 / 2235.5 ms8 ms55 ms88%92%1 / 3323 s
Schumann · Of Foreign Lands and Peoples116 / 2827.1 ms22 ms92 ms83%87%1 / 4418 s
Joplin · The Entertainer282 / 5595.8 ms9 ms12 ms95%98%2 / 8524 s
Chopin · Ballade No. 4 in F minor770 / 27468.4 ms27 ms81 ms78%88%6 / 239100 s
Chopin · Nocturne in E-flat major282 / 5725.5 ms11 ms54 ms86%91%2 / 3816 s
All scored2,7777.9 ms23 ms67 ms81%90%29 / 1,448

Table 2. Error is the distance from a synced note to its attack in the recording. Pieces in grey have too few notes with a measurable attack (fewer than 30) to score. Sync time is for the whole piece, in the browser, on our test machine (a Windows desktop).

6 · What goes wrong

  • The tail. One note in ten lands further than 67 ms from where we find its attack. Some of that is the detector (a pedal swell or a sympathetic string can rise faster than the note itself); some is the sync taking a rolled chord or an ornament as one event. The bars where it matters most are the ones the sync flags.
  • Very dense writing. In the études, notes arrive every 70 ms or less. The sync follows them, but at this resolution a note can be one sixteenth off within a bar without the harmony changing, and our measurement cannot see it either.
  • Noise at the ends. Applause and talking at the start or end of a video can pull the first or last bars onto them. The editor detects applause-like noise and asks for a trim.
  • Scores that differ from the playing. Repeats are found (section 2.5); a cut in the middle of a section, an added cadenza or an ossia are not, and show as flagged bars.

7 · Reproduce it

Everything here comes from the same code the editor runs, driven headless: the recordings and scores are listed with their sources in table 1, the measurement and the figures are made by scripts in our repository, and the numbers on this page are read from their output, not typed in.

Try it on your own recording How to sync a score to a video