FA-81556 / MIDI event timing / Open access
Eighth-note swing time remapping: offbeat half stretched by the downbeat factor · case 01
With 66% swing a note late in the beat (tick 479 of a 480-tick beat) lands after the next downbeat.
ROOT CAUSE
The second half of the beat is scaled by the first-half factor split/half instead of (ppq-split)/half.
VERIFIED REPAIR
Restore the second half scale step so that it reads `(ppq - split) / half`.
Unsuccessful approach: Using an unscaled second half shifts it by the swing offset without compressing it, overrunning the beat.
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, ppq)
if pos < half:
new = pos * split / half
else:
new = split + (pos - half) * 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]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None)], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None), ([[100, 300], 480, 55], [110, 318]), ([[250, 470], 480, 50], [250, 470])], [([[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]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[30, 100], 120, 67], [40, 106])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[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, 396, 632] | [316, 357, 479] | Failed |
| oracle 3 | [960, 1320, 1500] | [960, 1320, 1380] | Failed |
| oracle 4 | [1, 334, 337] | [1, 334, 336] | Failed |
| oracle 5 | [0, 69] | [0, 69] | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 9429660f5867870e0f68ab85279bca4ae2eea517e1976f79d655725c02e4237d
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 = divmod(t, ppq)
if pos < half:
new = pos * split / half
else:
new = split + (pos - half) * (ppq - half) / 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]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None)], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None), ([[100, 300], 480, 55], [110, 318]), ([[250, 470], 480, 50], [250, 470])], [([[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]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[30, 100], 120, 67], [40, 106])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[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, 376, 555] | [316, 357, 479] | Failed |
| oracle 3 | [960, 1320, 1440] | [960, 1320, 1380] | Failed |
| oracle 4 | [1, 334, 337] | [1, 334, 336] | Failed |
| oracle 5 | [0, 69] | [0, 69] | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 772afb3888b83081f836b89d2797d1c2eaa93e23d500c77982fc7a3b1776daa7
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]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None)], [([[240, 300, 479], 480, 66], [316, 357, 479]), ([[120, 360], 480, 60], [144, 384]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[0, 240], 480, 49], None), ([[0, 240], 480, 76], None), ([[0, 240], 481, 60], None), ([[100, 300], 480, 55], [110, 318]), ([[250, 470], 480, 50], [250, 470])], [([[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]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[250, 470], 480, 50], [250, 470])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[960, 1200, 1320], 480, 75], [960, 1320, 1380]), ([[1, 239, 241], 480, 70], [1, 334, 336]), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[30, 100], 120, 67], [40, 106])], [([[0, 240, 480, 720], 480, 50], [0, 240, 480, 720]), ([[0, 240, 480, 720], 480, 66], [0, 316, 480, 796]), ([[0, 60], 120, 58], [0, 69]), ([[0, 240], 480, 49], None), ([[100, 300], 480, 55], [110, 318]), ([[90], 120, 62], [97]), ([[5, 55], 100, 64], [6, 67]), ([[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 | [960, 1320, 1380] | [960, 1320, 1380] | Passed |
| oracle 4 | [1, 334, 336] | [1, 334, 336] | Passed |
| oracle 5 | [0, 69] | [0, 69] | Passed |
| oracle 6 | None | None | Passed |
| oracle 7 | None | None | Passed |
SHA-256 / 2d1bbbfb48c68b12b8c9286a896b5caa275c9f43d6980f6c1f5e0a0dac222d26
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.082891+00:00.
Case digest / 174dced850b17f78953e70c80ef9bda9985c830016cebbb741ab7bff4dd99f37