← Back to all posts
Tools

OnKey, an Open-Source Mac Singing Trainer, Learns a Song's Melody From One Play

October 24, 2026 · 09:05 UTC · Tools
OnKey, an Open-Source Mac Singing Trainer, Learns a Song's Melody From One Play

TL;DR

OnKey is a free, open-source (MIT) singing trainer for Apple Silicon Macs. You play a song in Spotify, Apple Music or YouTube, and when the song ends OnKey separates the lead vocal, tracks the singer's pitch, turns it into note bars and lines up the lyrics, all on your Mac. Play the song again and you sing against that lane with your pitch drawn on top and a score at the end. Developer Daniel Murrell posted it as a Show HN that reached 221 points, and he says AI coding got the build down to about 10 days. The part worth stealing is the method: an agent shortlisted license-compatible models, an eval set picked the winners, and the docs publish the scores, including the weak ones.


What it does

Most singing apps ship their own catalogue, backing tracks or hand-made note charts. Murrell's Show HN post says the app he had been practicing with filled its song list with covers instead of originals, and he wanted to sing over the actual recording. OnKey never plays, streams or downloads music. It listens to the app that is already playing.

The first play of a song shows lyrics only, and that take is still scored. Once OnKey has heard 70% of the song, it learns it in the background, which took two to three minutes on Murrell's Mac. From the next play, syllable-sized note bars scroll toward a playhead, your live pitch is drawn over them, and you get a per-line report plus a tendency reading that says whether you sit sharp or flat.

Requirements: an M1 or later Mac on macOS 14.2 or newer. Version 14.2 is the first release that lets one app capture another app's audio through Core Audio process taps without an extra driver, and the whole design depends on that.

The pipeline: four open models, run locally

The how-it-works page documents each stage down to the source file. The engine is Rust inside a Tauri window with a React UI, and every model runs through ONNX Runtime, on Core ML where that helps.

learning a song, after its first play ends music app16 kHz mix MDX-Netlead vocal CREPE fullpitch / 10 ms GAMEnote bars syllablelane LRCLIB lyrics, re-timed by wav2vec 2.0 (CTC) then split with the CMU pronouncing dictionary
Separation, pitch, notes, and lyric alignment all run on the Mac. The music is held in memory and never written to disk.
  • Separation: Ultimate Vocal Remover's MDX-Net Karaoke 2 runs on 20-second chunks with 2 seconds of context on each side, after the song ends and at low priority.
  • Pitch: CREPE "full" (via torchcrepe) on the separated vocal, 10 ms hop, 50 to 1100 Hz. A frame counts as sung above 0.45 confidence. The live mic path uses CREPE tiny, ported to Rust.
  • Notes: OpenVPI's GAME transcribes the vocal into notes, and each syllable bar takes the note under it.
  • Lyrics: synced lyrics come from LRCLIB, and a wav2vec 2.0 CTC aligner moves each line to where the words are actually sung.

Lyric timing gets extra work. On first plays, OnKey separates the opening 90 seconds or so live, 5 seconds at a time, just to re-time lyric lines. Across Murrell's library that put 60% of first-play lines within 0.3 seconds of the singing, against 13% using LRCLIB's own timestamps.

The hard part is hearing the singer's tune through a full band mix. Separation does the heavy lifting: it is like asking someone to repeat only what the person at the next table said in a loud bar, after which writing down the notes is the easy job. Murrell said in the HN thread that doing the singer's pitch in real time was where his first Claude Code prototype stalled, which is why OnKey learns after the song ends instead.

How it scores you

The scoring rules are deliberately soft, and the docs say so. Every 10 ms that you and the singer are both singing, your pitch is compared with the singer's line or the note bar, whichever is closer. Within 50 cents (half a semitone) earns full credit, falling linearly to nothing at 150 cents. An octave up or down counts as on the note, each half-second can shift 80 ms to absorb timing slop, and OnKey searches delays from 0.3 seconds early to 1.5 seconds late to cancel your system's latency.

The final score is 100 times pitch accuracy times a participation factor that tops out once you have sung 40% of the singer's part. Someone who just listens scores close to nothing, so you cannot game it by humming one good chorus. Murrell describes the current mode as beginner-level ("I'm one") and says stricter modes are next.

The evals, misses included

The docs include a results table. Note bars are checked against hand-marked notes, lyric timing against hand-timed lyrics, and the score against simulated singers (perfect, wobbly, sharp, and silent with the song leaking into the mic).

OnKey's own checks (% of hand-marked items) note has a bar98 bar on right note92 lyric line within 0.3s91-94 bar starts within 0.1s73 bar with no sung note3
Pitch is solid; note onsets are the weak spot, with about a quarter of bars starting more than 0.1 s off.

He also scored 20 recordings from the PESnQ research set, singers from poor to professional that music experts had already rated, to see whether OnKey ranks them in the same order. Experts agree with each other at 0.88 on the docs' agreement scale. OnKey's "notes hit" metric reaches 0.77, and its headline score only 0.61. The page concludes the score should lean more on notes hit and calls 20 unaccompanied recordings "a good sign more than proof."

agreement with expert ratings, 20 recordings (1 = perfect) expert vs expert0.88 OnKey notes hit0.77 OnKey score0.61
The simpler "notes hit" metric tracks human experts better than the headline score does.

How it got built

Murrell's Show HN post says it started with a question to Claude Code: could it listen to Spotify and to him at the same time and compare pitches? The answer was a Python script drawing his pitch in the terminal. The project then grew from Python with a web frontend into the Rust and Tauri app, written by someone who says in the thread he is new to Rust.

In the thread he estimates the work would have taken "maybe a few months (possibly a year)" without AI and took about 10 days with it. He does have an ML background, but says he barely used it. The agent researched which models existed and which licenses allowed bundling them, and then he "created an eval set and tried the tools against one another until I landed on the best set." That process is reusable for any audio or vision side project: let the agent build the shortlist, keep the final pick for a measured eval.

One HN commenter called it vibe-coded and asked why it is a webview instead of native Swift. Murrell answered with numbers: about 365 MB of the 420 MB download is bundled models, and his agent estimated a Swift rewrite would save 100 to 170 MB out of roughly 1.4 GB in use while models are loaded. He said Tauri makes a later port to other platforms easier.

Privacy and rights, designed in

OnKey keeps no music. Audio is analyzed in memory and only your own mic take is saved (about 0.5 MB per minute). What leaves the machine is listed in the README: a Shazam signature of up to 5 seconds of the music app's sound when nothing else can name the song, artist and title lookups to LRCLIB and iTunes, and a daily update check against GitHub. There is no account and no analytics, and Murrell says in the thread he audits it with Little Snitch.

The README also asks users not to share the learned melody transcriptions and not to modify the app to save music. Sharing a take produces a video of your voice and pitch line only, with no song audio. That is about as polite as an app that listens to Spotify can be.

Limits

  • Mac only: per-app capture and Core ML tie it to Apple Silicon. Linux would need PipeWire and MPRIS in place of the native layer, per the maker, and there is an open platform issue collecting votes.
  • Busy mixes: noisy backing tracks make the vocal hard to isolate, harmonies can pull bars onto the wrong voice, and Murrell says some notes come out an octave off.
  • Speakers leak: echo cancelling removes 20 dB or more of the song on MacBook speakers but only 8 to 14 dB on external ones, so headphones give cleaner scores.
  • Rap and spoken word: pitch scoring barely applies.

Costs on the machine are modest. Singing a learned song used 15 to 19% of one CPU core on Murrell's Mac, and learning peaked around 2.4 GB of memory. The repo went public on October 18 and tagged v0.1.0 on October 22, so expect rough edges.

Key Takeaways

  • OnKey is a free, MIT-licensed Mac app that learns a song's melody from one play in Spotify, Apple Music or YouTube, then scores your pitch on later plays.
  • The on-device pipeline chains UVR MDX-Net separation, CREPE pitch, OpenVPI GAME notes and wav2vec 2.0 lyric alignment through ONNX Runtime on Core ML.
  • Published evals show 92% of hand-marked notes land on the right bar, but only 73% start within 0.1 s, and the headline score agrees with experts at 0.61 against 0.77 for notes hit.
  • The maker credits Claude Code with turning a months-long project into about 10 days, with the agent shortlisting license-safe models and an eval set picking among them.
  • It never stores the music it hears; requirements are an M1 or later Mac on macOS 14.2+.

Sources: OnKey on GitHub, singonkey.app, How OnKey works, Scoring explained, OnKey credits, Show HN thread, CREPE, GAME, Ultimate Vocal Remover, wav2vec 2.0 paper

AIOpen SourceMusicAudio MLApple SiliconClaude CodeShow HN
CONSOLE
$