GENERATED-MIDI COUNTEREXAMPLE / OCTOBER 14, 2026
MP3 to MIDI.
A gap is not intent.
Joining erased separate events in these constructed controls. Three intentional same-pitch events touching end-to-start became one under the zero-gap rule. A one-tick gap survived at zero but was joined at 30. This tests editing logic on generated MIDI, not audio transcription, musical accuracy or a recommended tolerance.
Touching events
can still be separate.
| Generated source | Off | 0 | 30 | 120 |
|---|---|---|---|---|
| Same pitch / gap 0 | 3 | 1 | 1 | 1 |
| Same pitch / gap 1 | 3 | 3 | 1 | 1 |
| Same pitch / gap 30 | 3 | 3 | 1 | 1 |
| Same pitch / gap 31 | 3 | 3 | 3 | 1 |
| Same pitch / gap 120 | 3 | 3 | 3 | 1 |
| Same pitch / gap 121 | 3 | 3 | 3 | 3 |
| Different pitches / touching | 3 | 3 | 3 | 3 |
Same pitch / gap 0
Off / tolerance 0 / 30 / 120: 3 / 1 / 1 / 1.
Same pitch / gap 1
Off / tolerance 0 / 30 / 120: 3 / 3 / 1 / 1.
Same pitch / gap 30
Off / tolerance 0 / 30 / 120: 3 / 3 / 1 / 1.
Same pitch / gap 31
Off / tolerance 0 / 30 / 120: 3 / 3 / 3 / 1.
Same pitch / gap 120
Off / tolerance 0 / 30 / 120: 3 / 3 / 3 / 1.
Same pitch / gap 121
Off / tolerance 0 / 30 / 120: 3 / 3 / 3 / 3.
Different pitches / touching
Off / tolerance 0 / 30 / 120: 3 / 3 / 3 / 3.
Every source has three explicit events, each 96 ticks long. Six controls repeat pitch 60 with gaps of 0, 1, 30, 31, 120 or 121 ticks between successive events. A seventh uses pitches 60, 62 and 64 with touching boundaries. This is a deliberately constructed MIDI counterexample: we know the source-event intent because we defined it, not because an extractor recovered a musician's intent.
At zero tolerance, only the touching same-pitch fixture joins. At 30, the one-tick and 30-tick fixtures also join, but the 31-tick fixture does not. At 120, the 31-tick and 120-tick fixtures join; the 121-tick fixture still retains three. Different-pitch events remain separate at every tested tolerance. These exact boundaries follow the inclusive comparison in the disclosed rule, not an empirically discovered safe threshold for music.
A union can fill silence
without knowing why it exists.
The touching source adds zero positive gap ticks even when its three events become one. The one-tick fixture fills two ticks when it joins, because there are two gaps. The 30-tick fixture fills 60. The 31-tick fixture fills 62 only under the 120-tick allowance, and the 120-tick fixture fills 240. The 121-tick fixture and different-pitch control fill zero in all cases.
All source duration sums are 288 ticks. A joined same-pitch event lasts 288 plus twice its source gap; an unjoined file retains three 96-tick events. The selected tempo is 120 BPM and the resolution is 480 ticks per quarter. Seconds equal ticks * 60 / (120 * 480). Neither that time conversion nor a shorter event list establishes whether repeated attacks should be removed.
First velocity is a choice,
not a reconstruction.
The generator requests velocities 0.4, 0.8 and 0.6 for the three source events. The saved source MIDI is parsed before editing, so the result JSON keeps its actual quantized velocities rather than assuming those decimal requests survived byte-for-byte. The join rule retains the first member's parsed velocity. When a source joins into one event, the later two velocities no longer remain as separate note velocities.
When the rule leaves three events, all three parsed velocities remain. We compare full pitch, start, duration and velocity tuples from the re-parsed output with the intended groups. This does not simulate an instrument envelope or prove how the file sounds. It shows exactly what information this declared union rule retains and discards.
The same rule.
A different kind of input.
The source script defines all three events as separate, constructs Standard MIDI, saves it, hashes it, then parses it. Each case starts with those actual parsed source notes. Off disables joining. Active cases group by pitch, sort starts, and join when nextStart - currentUnionEnd <= tolerance. The group keeps the first start and velocity, extends its end to the largest member end and can absorb subsequent eligible events transitively.
The joining function is exactly the implementation used on the retained fragment controls. This run asserts its source text matches and records its SHA-256. That prior page measures actual generated-audio transcription exports. This page starts instead with intentionally constructed MIDI, so it must not be described as another MP3 conversion or an audio evaluation.
There are seven original MIDI files and twenty-eight actual re-exports. Every result records original event identities, grouped members, parsed output fields, event counts, positive gap ticks and file hashes. The actual Node and MIDI package versions are recorded. Different-pitch controls validate eligibility; the 30/31 and 120/121 pairs check inclusive boundaries. No prior evidence file or live converter setting is changed.
The condition is belonging,
not merely closeness.
MP3MIDITool's repair guidance describes merging fragments that belong to one held note. This counterexample tests a limited mechanical substitute for that condition. Same pitch and short gap can be compatible with both a fragmented hold and separate repeated events. Our controls establish the latter by construction; they do not infer it from arbitrary recordings.
This is not a test of that site's converter, an instrument sound, a DAW editor or a physical phone. No audio model or visitor file is used. We cannot give a universal safe joining tolerance from these results, and we do not rate transcription accuracy. The source-event definition, not a listening claim, is the reference for this counterexample.
Inspect the source and the union.
Full results include all source notes, groups, velocities and hashes. Reproduction code runs as node scripts/measure-repeated-note-joins.cjs in this project and checks the prior join implementation. All inputs are authored MIDI fixtures, not uploaded recordings.
- Same pitch / gap 0 sourceSHA-256:
b79f67e4e946434f2cd0b13fe9fb941e036741b2768b9396f777cdfa33486b4f. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Same pitch / gap 1 sourceSHA-256:
4f806fe44c34f731d34d1e5ab9a7ab7146ec2e2d1ae76be005f7db3a866c4173. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Same pitch / gap 30 sourceSHA-256:
3930cdcafeedca2c35f37e228d51897a044366d3d6a95369aa563de859f1e28d. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Same pitch / gap 31 sourceSHA-256:
90eb0553071b964138d6446d2124ad589464ffc16e3d15a93df116d0aa925dea. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Same pitch / gap 120 sourceSHA-256:
c4729ab3c593471cb417e1ff5d917875ff0092f33025abe692e0457a79f7b6ce. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Same pitch / gap 121 sourceSHA-256:
a610dfc52e780d2f501567545104b37a770f0b768dc46caaee82b175707c82f2. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120. - Different pitches / touching sourceSHA-256:
0c2ee7f773ae2ebbd6fecc6a22916edbde7386d291f0782d84ceea10ef3290de. Exports: Off / Tolerance 0 / Tolerance 30 / Tolerance 120.