Skip to content

Latest commit

Β 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎡 Whistle Melody

Whistle a tune β€” get sheet-ready notes and a playable MIDI file.

A tiny native macOS app: whistle into the microphone, watch your melody appear as notes on a piano roll, play it back, fix the parts you missed by re-whistling them, and export a standard .mid file that opens in GarageBand or Logic.

Pure SwiftUI + AVFoundation. No dependencies, no cloud β€” everything runs on your Mac.

Whistled melody detected as notes on the piano roll

✨ Features

  • πŸŽ™ Whistle-to-notes β€” real-time pitch detection tuned for whistling (YIN algorithm, 350–5000 Hz)
  • 🎹 Piano roll β€” detected notes with names (A5, C6…), live note indicator while you whistle
  • πŸ” Re-whistle a fragment β€” select the notes you got wrong, whistle them again, and the new take is spliced in seamlessly
  • ▢️ Instant playback β€” whole melody or just the selection, through the built-in GM synth
  • πŸ’Ύ MIDI export β€” standard MIDI file (GM "Whistle" instrument) for any DAW or notation app

Selected notes (orange) are ready to be replaced by a new take β€” hit Re-whistle Selection and whistle just that fragment again:

Selected notes ready to be re-whistled

πŸ“¦ Install

Grab WhistleMelody-x.y.z.zip from the latest release, unzip and move WhistleMelody.app to Applications.

First launch: the app is not notarized yet (no Apple Developer subscription), so macOS will refuse to open it at first. Two ways around it:

  • Try to open the app once, then go to System Settings β†’ Privacy & Security, scroll down and click Open Anyway. On macOS 13–14 you can simply right-click the app β†’ Open β†’ Open.
  • Or clear the quarantine flag in Terminal: xattr -d com.apple.quarantine /Applications/WhistleMelody.app

This is a one-time step. Building from source (below) needs no workarounds at all.

πŸš€ Build & run

Requires macOS 14+ and Xcode command line tools (Swift 5.9+).

./scripts/build_app.sh
open build/WhistleMelody.app

For quick development iterations: swift run (the mic permission is then attributed to your terminal app).

🎼 Usage

  1. Record (Space) β€” start recording, whistle, press again to stop. Detected notes appear on the piano roll.
  2. Click notes to select them (click empty area to deselect).
  3. Re-whistle Selection β€” record a replacement take; new notes are spliced into the selected range, the rest of the melody shifts to stay continuous.
  4. Play / Play Selection β€” playback through the system GM synth.
  5. Save MIDI… β€” export a .mid file.

πŸ”¬ How it works

  • Pitch detection β€” YIN algorithm over an AVAudioEngine mic tap (window 2048, hop 1024, whistle band 350–5000 Hz, RMS noise gate).
  • Segmentation β€” median-smoothed pitch track split into notes on semitone jumps (> 0.7 st) or silence (> 60 ms); fragments < 90 ms are dropped as noise.
  • MIDI β€” hand-written SMF format 0 (480 tpq, 120 BPM, GM program 79 "Whistle"), played via AVMIDIPlayer.

Design decisions live in features/whistle-melody.md.

πŸ“ Project layout

Sources/WhistleMelody/
  App.swift            – entry point
  ContentView.swift    – toolbar, status bar, layout
  PianoRollView.swift  – note visualization and selection
  MelodyStore.swift    – app state: record/play/splice/export
  AudioRecorder.swift  – mic capture, framing, RMS gate
  PitchDetector.swift  – YIN pitch detection
  NoteSegmenter.swift  – pitch track β†’ discrete notes
  MidiFile.swift       – Standard MIDI File writer
  MidiPlayer.swift     – playback via AVMIDIPlayer
scripts/               – .app bundling (Info.plist + build_app.sh)

About

🎡 Whistle a melody into the mic β€” get notes on a piano roll and a playable MIDI file. Native macOS app: SwiftUI, YIN pitch detection, zero dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages