FAILURE MAP
← Case archive

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.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

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 fixtureActualExpectedOutcome
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 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

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 fixtureActualExpectedOutcome
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 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

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 fixtureActualExpectedOutcome
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 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

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