Files
midi-playlist/tests/smoke_test.py
T

52 lines
2.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Smoke test: does midikit+songkit produce a valid, parseable, playable file?
Run from repo root: python3 tests/smoke_test.py"""
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
from midikit import MidiFile, Track, MPQN, note, note_name, read, verify
from songkit import bar, melody, arp, bass_drive, drums, vibrato, humanize, parse_score
assert note("A4") == 69 and note("C#5") == 73 and note("Bb3") == 58
assert note_name(69) == "A4" and note_name(60) == "C4"
mf = MidiFile(tpq=480)
mf.time_sig = (4, 2)
mf.key_sig = (-1, True) # D minor
lead = Track("Lead", channel=0)
lead.program(0, "square lead")
melody(lead, 0, "D4 A4-8 D5-8 F5-8 E5-4 D5-2")
vibrato(lead, bar(0), bar(4), channel=0, tempo_bpm=120)
bass = Track("Bass", channel=1)
bass.program(0, "synth bass 1")
bass_drive(bass, 0, [("D", "m"), ("Bb", "")])
acomp = Track("Arp", channel=2)
acomp.program(0, "electric piano 1")
arp(acomp, 0, [("D", "m"), ("Bb", "")])
d = Track("Drums", channel=9)
drums(d, 0, 2, "rock")
mf.add_track(lead); mf.add_track(bass); mf.add_track(acomp); mf.add_track(d)
mf.tempos = [MPQN.from_bpm(0, 120)]
mf.set_loop(bar(0), bar(2)) # loop the whole 2-bar demo
path = "/tmp/midikit_smoke.mid"
mf.write(path)
d = verify(path, min_sec=1, max_sec=30)
print("OK:", path, d["duration_sec"], "sec,",
sum(len(t["notes"]) for t in d["tracks"]), "notes,",
len(d["tracks"]), "tracks")
# loop markers must survive the round-trip in all three conventions
markers = sorted(set(m[1] for t in d["tracks"] for m in t["markers"]))
expected = sorted(["LOOP_START", "LOOP_END", "RPR LOOP START", "RPR LOOP END",
"LoopBegin", "LoopEnd"])
assert markers == expected, "loop markers wrong: %s" % markers
print("loop markers OK:", ", ".join(markers))
# cross-check with mido if present (third-party parser as second opinion)
try:
import mido
m = mido.MidiFile(path)
print("mido agrees:", m.length, "sec,", len(m.tracks), "tracks")
assert abs(m.length - d["duration_sec"]) < 0.5
except ImportError:
print("(mido not installed; skipping cross-check)")