ChrisBeWithYouandClaude Fable 5 c86b2c8850 feat(midi): extract lyric meta-events and vocal melody into sidecar payloads
MIDI import previously ignored lyric meta-events entirely, so karaoke
MIDI files lost their lyrics and vocal melody on import.

- new extract_midi_lyrics(midi_path, audio_offset): returns spec 7.1
  lyrics + spec 7.2 vocal_pitch payloads, or None when the file has no
  usable lyrics (existing behavior unchanged)
- collects 0x05 Lyric events, with 0x01 Text as a conservative fallback
  on vocal-ish / Words / Karaoke tracks only (avoids importing copyright
  notices as lyrics)
- .kar conventions handled: '/' and '\' line-break prefixes fold onto
  the previous syllable as 7.1 '+'; '@'/'%' metadata dropped
- per-stream word conventions: hyphen-delimited streams pass '-' joins
  through; space-delimited streams synthesize joins; whole-word streams
  get none; line ends become trailing '+' (stripping a '-' first)
- melody pairing: greedy time-ordered, one note per syllable within
  0.30s; paired syllables snap t/d to the note so both sidecars stay
  mirrored per 7.2; unpaired syllables remain lyrics-only (spec-legal)
- vocal-track selection mirrors the GP importer's idiom (name keywords
  + GM programs 52-54/85-87); SMF type 0 isolates vocal-program
  channels, type 1/2 trusts the lyric-carrying note track
- unpaired lyric durations run to the next syllable, clamped 0.1-2.0s

Callers (the editor plugin's import flow) wire the payloads into the
pak in a follow-up; no manifest keys are written here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
2026-07-23 00:33:36 -05:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-06-16 18:47:13 +02:00
2026-07-03 13:41:50 +02:00
S
Description
No description provided
AGPL-3.0
982 MiB
Languages
JavaScript 56.4%
Python 37.1%
HTML 3.2%
CSS 1.2%
TypeScript 1.1%
Other 1%