Fork me on GitHub

PyTheory Playground

Music theory for humans — every result below is computed live by pytheory on the server.

PyTheory is music theory for humans — a Python library that models tones, scales, chords, keys, fretboards, and rhythm in a way people can actually read. It speaks twelve-tone Western harmony fluently, but it isn't limited to it: Indian rāgas, Arabic maqāmāt, gamelan slendro & pelog, 19-TET, and a dozen other tonal systems are first-class citizens, complete with microtonal synthesis.

This playground

Everything on this site is computed live by pytheory on the server — no music theory is re-implemented in JavaScript. Each card cites the API call behind it. Explore:

  • Guitar Tab — chord diagrams for six fretted instruments, with custom tunings, capo, and a click-to-edit fretboard that names whatever you finger. Charted chords keep their curated shapes; anything else (F♯m7♭5, Gadd9, C7sus4…) gets a voicing computed from its notes.
  • Chord Lab — voicings, inversions, tension, pitch-class set theory, and tritone substitutions for any chord symbol.
  • Scales — every scale and mode across sixteen tonal systems, harmonized and playable.
  • Keys & Progressions — diatonic chords, borrowed chords, secondary dominants, named progressions, and a modulation planner.
  • Ragas — fifty-four rāgas across the Hindustani and Carnatic traditions: aroha & avaroha, pakad, thaat or melakarta, and true shruti just intonation, played on a sitar.
  • Maqamat — ten Arabic maqāmāt with their ajnas and seyir, tuned to real quarter-tones — the half-flat neutral intervals a piano can't play, rendered where they actually sit.
  • Songwriter — sketch a whole arrangement from a vibe: sections, one hundred drum grooves with fills, chord styles, bass, and fade-out, rendered as audio, MIDI, or engraved sheet music.
  • Tools — identify chords from fret positions, analyze progressions, detect keys, transcribe hummed or whistled recordings into notation, and convert MIDI to LilyPond (with PDF engraving), ABC, MusicXML, or tab — complete with a key-detected, Roman-numeral chord timeline of the file.

Install it

Not familiar with uv? It's the fast Python package manager — install it here.

$ uv add pytheory

Then, in a REPL:

>>> from pytheory import Fretboard, CHARTS
>>> print(CHARTS["western"]["Cmaj7"].tab(fretboard=Fretboard.guitar()))

Links

1fr

How it’s built root.interval_to(…)

Click the diagram to build your own voicing — clicks above the nut toggle open / muted strings, and a second click on a dot clears it. Whatever you finger, pytheory names it and keeps everything else in sync.

More voicings NamedChord.fingerings(…)

ASCII tab NamedChord.tab(fretboard=…)


        

On the neck TonedScale / Chord + fretboard, same tuning & capo

Root notes in red. Click any note to hear it. Follows the instrument, tuning, and capo above.

Tuner pytheory.tuner.Tuner · analyze_frame(…)

Tap the stream from your own JS — three lines
const tuner = new EventSource("http://localhost:8123/stream");
tuner.onmessage = (e) => {
  const { freq, note, octave, cents, in_tune } = JSON.parse(e.data);
};
listening for a note…
-50¢0+50¢

Open strings click to hear a reference tone

Allow microphone access, play one string at a time, and tune until the needle centers. Strings light up as you get close.

intervals
pitch classes
Forte number
figured bass
tension
dissonance

Voicings chord.inversion() · .drop2() · .open_voicing()

Substitutions chord.tritone_sub() · .extensions()

Negative harmony chord.negative_harmony(key)

Mirror the chord across the key's tonic–dominant axis (Ernst Levy / Jacob Collier).

Reharmonize reharmonize(chord, key)

Substitution ideas — tritone sub, diatonic swaps, the secondary dominant that tonicises it, and its negative-harmony mirror.

Neo-Riemannian chord.parallel() · .leading_tone_exchange() · .relative()

The P / L / R transformations — each moves one voice a step to a closely related triad (the moves behind Romantic and film harmony).

Tuning & beats chord.beat_frequencies · Score(temperament=…)

The same chord in four temperaments — equal splits the octave evenly, just locks to pure ratios; listen for the beating.

Beat frequencies

Voice leading chord.voice_leading(other)

Solo over it scale.recommend(…) · chord_scales() · avoid_notes()

Scales that fit this chord's tones — improv starting points.

Harmonized scale.harmonize()

On the fretboard fretboard.scale_diagram(scale)


        

Circle of fifths Key(…).signature · key.relative

Click a key to explore it.

Chords by function key.chords_by_function()

Chords in the same family do the same harmonic job — swap one for another.

Circle neighbours key.circle_of_fifths()

A fifth either way shares all but one note — the smoothest places to modulate.

Progression key.progression(…)

Beyond the key key.borrowed_chords · key.secondary_dominant(…)

Borrowed (modal interchange)

Secondary dominants

What next? key.suggest_next(…)

Modulation planner key.modulation_path(…) · key.pivot_chords(…)

Songwriter Score.section(…) · part.arpeggio · part.fade_out · score.drums

One click sketches a whole arrangement — sections, grooves, chords, and a bass line — that you can rework below. pytheory renders the band.

mixer — part levels, reverb, drum feel Part(volume=…, reverb=…) · Score(drum_humanize=…)

Note inspector Tone.solfege · .helmholtz · .overtones(…)

Chord identifier Fingering.identify()

Progression analyzer analyze_progression · find_cadences · check_voice_leading

Non-chord tones analyze_non_chord_tones(melody, chord)

Twelve-tone row ToneRow · .matrix() · .all_forms()

Key detector Key.detect(…)

Audio → LilyPond / ABC / Tab Score.from_wav(…)

Hum a melody, whistle a hook, or record a bass line — monophonic transcription via YIN pitch tracking. WAV, m4a voice memos, and mp3 all work.

or choose a file:

MIDI → LilyPond / ABC / Tab Score.from_midi(…)

No MIDI handy? Grab one from the Keys & Progressions tab with the MIDI button.

aroha ascending
avaroha descending
pakad catch-phrase
vadi · samvadi

Shruti intonation raga.shruti_table(sa) — just vs 12-TET

Each swara's just ratio and how far it sits from the equal-tempered piano (in cents).

ajnas building blocks
seyir melodic journey
degrees

A degree is a half-flat — the neutral 2nds, 3rds, 6ths and 7ths a piano can't play, sitting a quarter-tone low. The note names above are only the nearest 12-TET approximations; the table below is the real tuning.

Quarter-tone intonation maqam.maqam_table(tonic) — just vs 12-TET

Each degree's just ratio and how far it sits from the equal-tempered piano (in cents) — Rast's neutral third floats ~45¢ under the tempered E.

Accented downbeat. Runs in your browser with the Web Audio clock.

Tempo trainer pytheory.metronome.Metronome(end_bpm=…)

Ramp the tempo while you practise — start slow, speed up automatically.