FAILURE MAP
← Case archive

FA-81766 / MIDI event timing / Open access

Time Signature meta event decoding: bar length counted in quarter notes · case 01

A 6/8 bar is reported as 2880 ticks (six quarters) instead of 1440.

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

ROOT CAUSE

The bar length multiplies ppq by the numerator, ignoring the beat unit.

VERIFIED REPAIR

Restore the bar length step so that it reads `ppq * 4 * nn // den`.

Unsuccessful approach: Dividing before multiplying by the numerator truncates the beat length for resolutions that do not divide evenly.

Case contract

Input [bytes, ppq]. bytes must be FF 58 04 nn dd cc bb with nn > 0, dd <= 6 and bb > 0. The denominator is 2**dd; the metronome click is cc MIDI clocks (24 per quarter) converted to ticks as ppq*cc//24; the bar length in ticks is ppq*4*nn//denominator. Return [nn, denominator, click_ticks, bar_ticks] or 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

N = 1
observations = []
def solve(x):
    if not isinstance(x, list) or len(x) != 2:
        return None
    data, ppq = x
    if len(data) != 7 or data[0] != 0xFF or data[1] != 0x58 or data[2] != 4:
        return None
    nn, dd, cc, bb = data[3:7]
    if nn == 0 or dd > 6 or bb == 0 or ppq <= 0:
        return None
    den = 2 ** dd
    click = ppq * cc // 24
    bar = ppq * nn
    return [nn, den, click, bar]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None)], [([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None), ([[255, 88, 5, 4, 2, 24, 8], 480], None), ([[255, 88, 3, 4, 2, 24, 8], 480], None)], [([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 3, 4, 2, 24, 8], 480], None), ([[255, 89, 4, 4, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 2, 24, 0], 480], None)], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])]]
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[4, 4, 480, 1920][4, 4, 480, 1920]Passed
oracle 1[6, 8, 720, 2880][6, 8, 720, 1440]Failed
oracle 2[3, 4, 100, 300][3, 4, 100, 300]Passed
oracle 3[5, 16, 22, 450][5, 16, 22, 112]Failed
oracle 4[3, 16, 22, 270][3, 16, 22, 67]Failed
oracle 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

SHA-256 / 653b17b5cf87caf9c139600c190455ee09625d1d33faec1400e39e7286ef5fc2

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    if not isinstance(x, list) or len(x) != 2:
        return None
    data, ppq = x
    if len(data) != 7 or data[0] != 0xFF or data[1] != 0x58 or data[2] != 4:
        return None
    nn, dd, cc, bb = data[3:7]
    if nn == 0 or dd > 6 or bb == 0 or ppq <= 0:
        return None
    den = 2 ** dd
    click = ppq * cc // 24
    bar = ppq * 4 // den * nn
    return [nn, den, click, bar]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None)], [([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None), ([[255, 88, 5, 4, 2, 24, 8], 480], None), ([[255, 88, 3, 4, 2, 24, 8], 480], None)], [([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 3, 4, 2, 24, 8], 480], None), ([[255, 89, 4, 4, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 2, 24, 0], 480], None)], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])]]
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[4, 4, 480, 1920][4, 4, 480, 1920]Passed
oracle 1[6, 8, 720, 1440][6, 8, 720, 1440]Passed
oracle 2[3, 4, 100, 300][3, 4, 100, 300]Passed
oracle 3[5, 16, 22, 110][5, 16, 22, 112]Failed
oracle 4[3, 16, 22, 66][3, 16, 22, 67]Failed
oracle 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

SHA-256 / 54c0d47964d8ef9a047da11679891af5ad1b4bda695dcd1fd0a93163241c7e67

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    if not isinstance(x, list) or len(x) != 2:
        return None
    data, ppq = x
    if len(data) != 7 or data[0] != 0xFF or data[1] != 0x58 or data[2] != 4:
        return None
    nn, dd, cc, bb = data[3:7]
    if nn == 0 or dd > 6 or bb == 0 or ppq <= 0:
        return None
    den = 2 ** dd
    click = ppq * cc // 24
    bar = ppq * 4 * nn // den
    return [nn, den, click, bar]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None)], [([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 0, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 7, 24, 8], 480], None), ([[255, 88, 5, 4, 2, 24, 8], 480], None), ([[255, 88, 3, 4, 2, 24, 8], 480], None)], [([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 3, 4, 2, 24, 8], 480], None), ([[255, 89, 4, 4, 2, 24, 8], 480], None), ([[255, 88, 4, 4, 2, 24, 0], 480], None)], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 6, 3, 36, 8], 480], [6, 8, 720, 1440]), ([[255, 88, 4, 7, 3, 12, 8], 90], [7, 8, 45, 315]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])], [([[255, 88, 4, 4, 2, 24, 8], 480], [4, 4, 480, 1920]), ([[255, 88, 4, 3, 2, 24, 8], 100], [3, 4, 100, 300]), ([[255, 88, 4, 5, 4, 6, 8], 90], [5, 16, 22, 112]), ([[255, 88, 4, 2, 1, 48, 8], 96], [2, 2, 192, 384]), ([[255, 88, 4, 3, 4, 6, 8], 90], [3, 16, 22, 67]), ([[255, 88, 4, 4, 2, 24, 8], 0], None), ([[255, 88, 4, 9, 3, 18, 8], 100], [9, 8, 75, 450]), ([[255, 88, 4, 4, 0, 96, 8], 120], [4, 1, 480, 1920])]]
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[4, 4, 480, 1920][4, 4, 480, 1920]Passed
oracle 1[6, 8, 720, 1440][6, 8, 720, 1440]Passed
oracle 2[3, 4, 100, 300][3, 4, 100, 300]Passed
oracle 3[5, 16, 22, 112][5, 16, 22, 112]Passed
oracle 4[3, 16, 22, 67][3, 16, 22, 67]Passed
oracle 5NoneNonePassed
oracle 6NoneNonePassed
oracle 7NoneNonePassed

SHA-256 / b023fefe9dc9b0904b5a891454784fdc2e20b5407592de9105a95126cd207db5

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:06.014597+00:00.

Case digest / c7c5ec812f43e7db1cf39792077d3e46df91d6689e4c793197e2f5b597641492