A text editor for chord notation. Write chord symbols above your lyrics and Chord Notepad detects them, highlights them and plays them back, voiced the way a real musician would on piano or guitar. The sound is real MIDI synthesis through FluidSynth.
Watch the demo · Read how it was built
- macOS version has had limited testing; feedback welcome.
Writing chords
- Highlights chord symbols as you type, and tells chord lines apart from lyric lines on its own
- Three notations you can switch between: American (
C,Am,Bb7), European solfège (Do,Re,Mi), and roman numerals (I,V,vi) - Roman numerals follow the key: write
I V vi IV, set{key: D}, and hear it in D; change the key and the same lines play anywhere - Understands the full range, from plain triads to slash chords and altered jazz voicings (
C/E,C7b9,Cmaj7#5(9),Cm7b5)
Playing them back
- Click any chord to hear it, or press play to run the whole song with each chord lighting up as it sounds
- Chords are voiced like a player, not stacked mechanically: the piano voicing moves smoothly from one chord to the next (voice leading), and the guitar voicing finds real, playable fingerings on the fretboard
- Or voice for an ensemble instead of one instrument: Choir (SATB), Male Choir (TTBB), Treble Choir (SSA), and String Quartet presets voice each chord as independent parts with real voice leading (custom ensembles too), and MIDI export writes them out one track per voice
- Choose the instrument: piano, or guitar in standard, Drop D, DADGAD, or Open G tuning, plus a ukulele preset (any custom fretted instrument or custom piano voicing too, built with the Tools → Settings voicing editor)
- Real MIDI synthesis through FluidSynth, with a soundfont bundled in
- A metronome you can switch on and off mid-playback
- A chord sheet strip (View → Chord Sheet) shows the song's voiced chords left to right as they'll actually play, follows along during playback, and switches between keyboard, staff, chord box, and tab views
A small format for songs
- Hold a chord longer with
C*2(two beats), rest withNC, comment with// - Inline directives drive the player:
{bpm: 120},{bpm: +20},{time: 3/4},{key: G},{label: verse},{loop: verse 4} - Tempo and key can change partway through a song, and loops replay a labelled section
Also
- A reverse tool: click notes on a keyboard and it names the chord, inversions and slash spellings included
- File operations, recent files, adjustable font size
- Export the song as a standard MIDI file, for use in DAWs or notation software
-
Linux: FluidSynth library (
libfluidsynthpackage)# Fedora/RHEL sudo dnf install fluidsynth # Ubuntu/Debian sudo apt install libfluidsynth3 # Arch sudo pacman -S fluidsynth
-
Windows: No additional dependencies needed (FluidSynth DLL will be bundled with the executable)
- Python 3.10+
- Pipenv for dependency management
Download the latest release from the Releases page:
- Linux:
ChordNotepad-linux-x64(standalone executable) - Windows:
ChordNotepad-windows-x64.exe - macOS:
ChordNotepad-macos-x64
All releases are automatically built and tested using GitHub Actions.
-
Clone the repository:
git clone https://github.com/yourusername/chord-notepad.git cd chord-notepad -
Install dependencies:
pipenv install
-
Run the application:
make run # or pipenv run python src/main.py
Install development dependencies:
pipenv install --devBuild a standalone executable for your current platform:
make buildThe executable will be created in the dist/ directory:
- Linux:
dist/ChordNotepad - Windows:
dist/ChordNotepad.exe
Building on Linux for Linux:
make build
# Output: dist/ChordNotepadBuilding on Windows for Windows:
pipenv install --dev
pipenv run pyinstaller --clean chord-notepad.spec
REM Output: dist\ChordNotepad.exeNote: PyInstaller creates platform-specific executables. To build for Windows, you must run the build on a Windows machine. To build for Linux, run on a Linux machine.
-
Create or Open a File: Use File > New or File > Open
-
Write Lyrics with Chords: Type chord symbols above lyrics
C Am F G This is a simple song Dm7 G7 Cmaj7 With jazz chords too -
Click Chords: Click any highlighted chord to hear it
-
Auto-Play: Click the Play button to auto-play all chords sequentially
-
Configure Settings:
- Settings > BPM: Adjust playback speed (default: 120)
- Settings > Font Size: Adjust editor font size
- Major: C, D, E, F, G, A, B
- Minor: Cm, Dm, Em, Am
- Seventh: C7, Dm7, Gmaj7, Am7
- Diminished: C°, Ddim, Cdim7
- Augmented: C+, Daug
- Suspended: Csus2, Csus4, Dsus
- Extended: C9, D11, E13
- Alterations: C7b5, D7#9, Em7b5
- Half-diminished: Cø7, Dm7b5
- Add chords: Cadd9, Dadd11
- Slash chords / inversions: C/E, Am/G, G/B
Ctrl+N: New fileCtrl+O: Open fileCtrl+S: Save fileCtrl+Shift+S: Save AsCtrl+Q: QuitCtrl+MouseWheel: Zoom in/out
chord-notepad/
├── src/
│ ├── main.py # Application entry point
│ ├── ui/
│ │ ├── main_window.py # Main window with menu and toolbar
│ │ └── text_editor.py # Custom text editor widget
│ ├── audio/
│ │ ├── player.py # FluidSynth playback engine
│ │ ├── chord_picker.py # Piano voice-leading picker
│ │ └── guitar_chord_picker.py # Guitar fingering search
│ ├── services/ # Song parsing, playback, event production
│ ├── viewmodels/ # MVVM view-models
│ └── chord/
│ ├── helper.py # Symbol -> notes, notes -> chord name
│ └── detector.py # Line classification and detection
├── resources/
│ └── soundfont/
│ └── GeneralUser-GS.sf2 # Bundled soundfont
├── chord-notepad.spec # PyInstaller spec file
├── Pipfile # Python dependencies
├── Makefile # Build commands
└── README.md
make testmake cleanThe project uses standard Python conventions with:
- 4-space indentation
- Clear, descriptive variable names
- Docstrings for all public methods
- Main thread: Tkinter GUI event loop
- Producer thread: walks the song ahead of time and pushes a single merged, timestamped stream of events (chord notes plus metronome ticks) into a bounded buffer
- Player thread: pops events, waits for each one's moment, and fires FluidSynth; the GUI stays out of the timing loop and is signalled through a queue
- FluidSynth MIDI synthesis, both for click-to-play and full-song playback
- Every event is anchored to an absolute time, so tempo and key can change mid-song without drift
- Chord durations are set per chord in the text (a bare chord is one beat,
C*2is two)
pyfluidsynth: Python bindings for FluidSynthpychord: fast chord parsing (the first-pass parser)music21: fallback parser for more exotic chord spellingspillow: image handlingtkinter: GUI framework (included with Python)
pyinstaller: creates standalone executablespytest: test runnerhypothesis: property-based tests (fuzzes the voicing, asserting it never plays a note outside the chord)sphinx/rinohtype: build the user guide
Licensed under GNU Affero General Public License v3.0.
Contributions are welcome! Please feel free to submit a Pull Request.
- FluidSynth for MIDI synthesis
- PyChord for chord parsing
- GeneralUser GS soundfont by S. Christian Collins