npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ncn-to-kar

v1.2.0

Published

Convert NCN karaoke files (.mid + .lyr + .cur) to KAR format and play KAR files with lyrics display

Readme

ncn-to-kar

Convert NCN karaoke files (.mid + .lyr + .cur) to KAR format (MIDI with embedded karaoke tracks).

Features

  • Converts NCN-style karaoke files to standard KAR format
  • Supports TIS-620 encoded lyric files (Thai encoding)
  • Preserves timing information from cursor files
  • Creates karaoke tracks with proper grapheme cluster handling
  • Generates compatible KAR files for karaoke software
  • KAR Player: Play and display lyrics from KAR files with timing

Installation

npm install ncn-to-kar

Usage

Command Line

ncn-to-kar <midi-file> <lyric-file> <cursor-file> <output-kar-file>

Example:

ncn-to-kar song.mid song.lyr song.cur song.kar

Programmatic API

const { convertNcnToKar } = require('ncn-to-kar');

const result = convertNcnToKar({
  midiFile: 'song.mid',
  lyricFile: 'song.lyr',    // TIS-620 encoded
  cursorFile: 'song.cur',
  outputFile: 'song.kar'
}, {
  onWarn: (msg) => console.warn(msg)
});

console.log('Converted:', result.outputFile);
console.log('Title:', result.songTitle);
console.log('Artist:', result.artistName);

KAR Player

Play and display lyrics from KAR files:

const { KarPlayer } = require('ncn-to-kar');

const player = new KarPlayer('song.kar');

// Load the file
const data = player.load();
console.log('Title:', data.songTitle);
console.log('Artist:', data.artistName);

// Set up callbacks
player
  .onTitleChange((title) => {
    console.log('Title:', title);
  })
  .onArtistChange((artist) => {
    console.log('Artist:', artist);
  })
  .onLyricChange((text, time, index) => {
    // Display lyrics as they come
    process.stdout.write(text);
  });

// Start playing
player.play();

// Get metadata
const metadata = player.getMetadata();
console.log('Duration:', metadata.duration, 'seconds');

File Format

Input Files

  • MIDI file (.mid): Standard MIDI file with music data

    • Must use ticks-per-beat timing (SMPTE timing not supported)
  • Lyric file (.lyr): Text file with lyrics in TIS-620 encoding

    • Line 1: Song title
    • Line 2: Artist name
    • Line 3: Musical key (discarded)
    • Line 4: Blank (discarded)
    • Line 5+: Lyrics (one line per lyric line)
  • Cursor file (.cur): Binary file with timing information

    • 2-byte little-endian values for each character
    • Terminated with 0xFF

Output File

  • KAR file (.kar): Standard MIDI file with embedded karaoke tracks
    • Track 0: Original MIDI tracks
    • Track 1: "Words" - Karaoke timing and text
    • Track 2: "Lyric" - Full lyrics
    • Track 3: "Artist" - Artist name
    • Track 4: "SongTitle" - Song title

API Reference

convertNcnToKar(options, callbacks)

Converts NCN files to KAR format.

Parameters:

  • options (Object):

    • midiFile (string): Path to MIDI file
    • lyricFile (string): Path to lyric file (TIS-620 encoded)
    • cursorFile (string): Path to cursor file
    • outputFile (string): Path to output KAR file
  • callbacks (Object, optional):

    • onWarn (Function): Callback for warning messages

Returns:

  • Object:
    • outputFile (string): Path to created KAR file
    • songTitle (string): Extracted song title
    • artistName (string): Extracted artist name

Throws:

  • Error: If conversion fails (file not found, invalid format, etc.)

KarPlayer

Plays KAR files and displays lyrics with timing.

Constructor:

  • new KarPlayer(karFilePath) - Create a new player instance

Methods:

  • load() - Load and parse the KAR file
  • play() - Start playing (triggers lyric callbacks)
  • stop() - Stop playing
  • pause() - Pause playing
  • resume() - Resume playing
  • onLyricChange(callback) - Set callback for lyric events: (text, timeInSeconds, index) => void
  • onTitleChange(callback) - Set callback for title: (title) => void
  • onArtistChange(callback) - Set callback for artist: (artist) => void
  • getLyricsAtTime(timeInSeconds) - Get all lyrics up to a specific time
  • getAllLyrics() - Get all lyrics with timing
  • getMetadata() - Get song metadata (title, artist, duration, etc.)

Example:

const player = new KarPlayer('song.kar');
player.load();

player.onLyricChange((text, time, index) => {
  console.log(`[${time.toFixed(2)}s] ${text}`);
});

player.play();

parseKarFile(karFilePath)

Parse a KAR file and extract karaoke information.

Returns:

  • Object:
    • midi - Parsed MIDI data
    • ticksPerBeat - MIDI ticks per beat
    • songTitle - Song title
    • artistName - Artist name
    • lyrics - Array of lyric events with timing
    • wordsTrack, lyricTrack, artistTrack, titleTrack - Track references

CDN Configuration

Get CDN URLs for SpessaSynth libraries from .env file:

const { getCdnUrls, getCdnUrl } = require('ncn-to-kar');

// Get all CDN URLs
const urls = getCdnUrls();
console.log(urls.spessasynth_lib);
console.log(urls.spessasynth_core);

// Get specific URL
const libUrl = getCdnUrl('spessasynth_lib');

The .env file should contain:

SPESSASYNTH_LIB_URL=https://cdn.jsdelivr.net/npm/spessasynth_lib@latest/dist/index.js
SPESSASYNTH_CORE_URL=https://cdn.jsdelivr.net/npm/spessasynth_core@latest/dist/index.js

Requirements

  • Node.js >= 12.0.0

Dependencies

  • grapheme-splitter: For proper grapheme cluster handling
  • iconv-lite: For TIS-620 encoding/decoding
  • midi-file: For MIDI file parsing and writing

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.