FA-81561 / MIDI event timing / Open access
Eighth-note swing time remapping: beats split at eighth-note boundaries · case 01
Every offbeat is treated as a downbeat of its own, so swing never delays anything and positions double.
ROOT CAUSE
The tick is decomposed by half-beats instead of beats.
VERIFIED REPAIR
Restore the beat decomposition step so that it reads `divmod(t, ppq)`.
Unsuccessful approach: Taking the beat from ppq but the position modulo half a beat never reaches the second-half branch.
Case contract
Input [ticks, ppq, swing] with even ppq > 0 and swing 50..75 percent. Within each beat, positions in the first half [0, ppq/2) scale linearly onto [0, split) and positions in the second half onto [split, ppq), where split = ppq*swing/100. The remapped position is floored. Invalid parameters return None.
Why this case matters
MIDI sequencers, file readers and synth drivers depend on exact event ordering and tick/time arithmetic.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 3:
return None
ticks, ppq, swing = x
if ppq <= 0 or ppq % 2 or not 50 <= swing <= 75:
return None
half = ppq // 2
split = Fraction(ppq * swing, 100)
out = []
for t in ticks:
beat, pos = divmod(t, half)
if pos < half:
new = pos * split / half
else:
new = split + (pos - half) * (ppq - split) / half
out.append(beat * ppq + int(new))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None)], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318])], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67])], [([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])], [([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[100, 300], 480, 55], [110, 318]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [0, 480, 960, 1440] | [0, 240, 480, 720] | Failed |
| oracle 1 | [0, 480, 960, 1440] | [0, 316, 480, 796] | Failed |
| oracle 2 | [480, 559, 795] | [316, 357, 479] | Failed |
| oracle 3 | [144, 624] | [144, 384] | Failed |
| oracle 4 | [1920, 2400, 2580] | [960, 1320, 1380] | Failed |
| oracle 5 | None | None | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 9c748af361f5836d3b4514894ece978033d90a679e74d9b437a5c0a755a758bf
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 3:
return None
ticks, ppq, swing = x
if ppq <= 0 or ppq % 2 or not 50 <= swing <= 75:
return None
half = ppq // 2
split = Fraction(ppq * swing, 100)
out = []
for t in ticks:
beat, pos = (t // ppq, t % half)
if pos < half:
new = pos * split / half
else:
new = split + (pos - half) * (ppq - split) / half
out.append(beat * ppq + int(new))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None)], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318])], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67])], [([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])], [([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[100, 300], 480, 55], [110, 318]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [0, 0, 480, 480] | [0, 240, 480, 720] | Failed |
| oracle 1 | [0, 0, 480, 480] | [0, 316, 480, 796] | Failed |
| oracle 2 | [0, 79, 315] | [316, 357, 479] | Failed |
| oracle 3 | [144, 144] | [144, 384] | Failed |
| oracle 4 | [960, 960, 1140] | [960, 1320, 1380] | Failed |
| oracle 5 | None | None | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 0ac1d0f5907c1af76bac3d4e7877785aef0ad32b578ad4d0d02a45690be23ec9
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
if not isinstance(x, list) or len(x) != 3:
return None
ticks, ppq, swing = x
if ppq <= 0 or ppq % 2 or not 50 <= swing <= 75:
return None
half = ppq // 2
split = Fraction(ppq * swing, 100)
out = []
for t in ticks:
beat, pos = divmod(t, ppq)
if pos < half:
new = pos * split / half
else:
new = split + (pos - half) * (ppq - split) / half
out.append(beat * ppq + int(new))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None)], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318])], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67])], [([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])], [([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[100, 300], 480, 55], [110, 318]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470]), ([[30, 100], 120, 67], [40, 106])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | [0, 240, 480, 720] | [0, 240, 480, 720] | Passed |
| oracle 1 | [0, 316, 480, 796] | [0, 316, 480, 796] | Passed |
| oracle 2 | [316, 357, 479] | [316, 357, 479] | Passed |
| oracle 3 | [144, 384] | [144, 384] | Passed |
| oracle 4 | [960, 1320, 1380] | [960, 1320, 1380] | Passed |
| oracle 5 | None | None | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 57cd2be83e9c3467654e1da13eda88bdd3aee8230edc375a7b7aedbfb5c711eb
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it is not a complete Standard MIDI File or MIDI 1.0/2.0 implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:50:04.095328+00:00.
Case digest / 41bbf1f604b684b32ad42d9fba2dcdc60b45a3fed72d90219b11fd9835de49cc