User guide3 min read

Karaoke File Formats Overview: NCN Trio & Single Package Formats

Comprehensive guide on how MIDI (.mid), Lyrics (.lyr/.lrc), Cursor (.cur), and unified packages (.nkm/.nkmx) structure karaoke music data.

Overview of Karaoke File Ecosystem

In standard karaoke systems, song data is represented either through a legacy 3-file system (NCN Format: .mid + .lyr + .cur) or modern unified compressed single-file packages (.nkm and .nkmx). Understanding these specifications is essential for building media processing, timing synchronization, and audio synthesis software.

Core Format Comparison

Audio & Sequence
MIDI (.mid)

Contains polyphonic instrument notes, pitch bends, velocity, tempo map, and optional embedded compressed XML lyric metadata.

Text & Metadata
LYR (.lyr) / LRC (.lrc)

Text files containing song title, artist, key signature, and lyrics text line-by-line encoded in Windows-874 (TIS-620) or UTF-8.

Timing Sync
CUR (.cur)

16-bit binary cursor track storing compressed 24 PPQ reference ticks for syllable-by-syllable lyric highlighting.

NCN Karaoke 3-File Mapping Pipeline (.mid + .lyr + .cur)

  1. 1
    1. Extract PPQ from MIDI (.mid): Read ticksPerBeat (PPQ resolution) from the MIDI header to use as the timing base.
  2. 2
    2. Convert Cursor (.cur) to MIDI Ticks: Read 16-bit binary integers (Little-Endian) until 0xFF marker, then convert each cursor value using tick = Math.round((cur * ticksPerBeat) / 24) into absolute MIDI ticks.
  3. 3
    3. Read & Decode Lyric File (.lyr): Decode text using Windows-874 / TIS-620 charset. Skip lines 0-2 (Title, Artist, Key Header). Extract lines from index 3 onwards as song lyric verses.
  4. 4
    4. 1-to-1 Character-by-Character Sequential Mapping: For each lyric line, append a trailing space and split into characters. Sequentially pair EVERY character (including Thai tone marks, vowels, and spaces) 1-to-1 with entry ticks from the converted cursor array: LyricEvent { text: char, tick: ticks[i] }.
  5. 5
    5. Real-Time Highlight Rendering: As Web Audio playback progresses, the UI renderer compares currentTick >= event.tick to highlight and wipe lyric character colors in real time.