Skip to main content

Music Theory for Humans

Project description

PyTheory: Music Theory for Humans

Explore music theory, compose multi-part arrangements, and export to MIDI — all in Python.

$ pip install pytheory

Sketch Ideas Fast

from pytheory import Score, Pattern, Key, Duration, Chord
from pytheory.play import play_score

score = Score("4/4", bpm=140)
score.drums("bossa nova", repeats=4)

chords = score.part("chords", synth="fm", envelope="pad", reverb=0.4)
lead = score.part("lead", synth="saw", envelope="pluck", delay=0.3, lowpass=3000)
bass = score.part("bass", synth="sine", lowpass=500)

for sym in ["Am", "Dm", "E7", "Am"]:
    chords.add(Chord.from_symbol(sym), Duration.WHOLE)
    chords.add(Chord.from_symbol(sym), Duration.WHOLE)

lead.arpeggio("Am", bars=2, pattern="updown", octaves=2)
lead.arpeggio("Dm", bars=2, pattern="updown", octaves=2)
lead.set(lowpass=5000, reverb=0.4)
lead.arpeggio("E7", bars=2, pattern="up", octaves=2)
lead.arpeggio("Am", bars=2, pattern="updown", octaves=2)

for n in ["A2", "E2", "A2", "C3"] * 4:
    bass.add(n, Duration.QUARTER)

play_score(score)              # hear it now
score.save_midi("sketch.mid")  # open in your DAW

Hear It Instantly

$ pytheory demo

Music Theory

>>> from pytheory import Key, Chord, Tone

>>> Key("C", "major").chords
['C major', 'D minor', 'E minor', 'F major', 'G major', 'A minor', 'B diminished']

>>> [c.symbol for c in Key("G", "major").progression("I", "V", "vi", "IV")]
['G', 'D', 'Em', 'C']

>>> Chord.from_symbol("F#m7b5").identify()
'F# half-diminished 7th'

>>> Tone.from_string("C4").interval_to(Tone.from_string("G4"))
'perfect 5th'

>>> Key("C", "major").pivot_chords(Key("G", "major"))
['A minor', 'B minor', 'C major', 'D major', 'E minor', 'G major']

Composition

score = Score("4/4", bpm=124)
score.drums("house", repeats=16, fill="house", fill_every=8)

pad = score.part("pad", synth="supersaw", envelope="pad",
                 reverb=0.5, chorus=0.3, sidechain=0.85)
lead = score.part("lead", synth="saw", envelope="pluck",
                  legato=True, glide=0.03, humanize=0.3)
bass = score.part("bass", synth="sine", lowpass=300, sidechain=0.7)

# Song structure
score.section("verse")
# ... add notes ...
score.section("chorus")
lead.set(lowpass=5000, reverb=0.3)
# ... add notes ...
score.end_section()

score.repeat("verse")
score.repeat("chorus", times=2)

10 Synth Waveforms

sine, saw, triangle, square, pulse, FM, noise, supersaw, PWM slow, PWM fast

58 Drum Patterns

rock, jazz, bebop, bossa nova, salsa, samba, afrobeat, funk, reggae, house, trap, metal, drum and bass — and 45 more. Plus 21 fill presets.

6 Effects with Automation

lead = score.part("lead", synth="saw",
                  distortion=0.7, lowpass=1000, lowpass_q=5.0,
                  delay=0.3, reverb=0.4, reverb_type="plate",
                  chorus=0.3)

# Automate mid-song
lead.set(lowpass=4000, distortion=0.9)

# LFO modulation
lead.lfo("lowpass", rate=0.5, min=400, max=3000, bars=8)

Signal chain: distortion → chorus → lowpass → delay → reverb

Convolution Reverb

7 synthetic impulse responses: Taj Mahal (12s), cathedral, plate, spring, cave, parking garage, canyon.

pad = score.part("pad", synth="supersaw",
                 reverb=0.85, reverb_type="taj_mahal")

6 Musical Systems

Western, Indian (Hindustani), Arabic (Maqam), Japanese, Blues/Pentatonic, Javanese Gamelan — 40+ scales.

25 Instrument Presets

Guitar (8 tunings), bass, ukulele, mandolin family, violin family, banjo, harp, oud, sitar, erhu, and more — with chord fingering generation.

Command Line

$ pytheory demo                            # hear a generated track
$ pytheory key G major                     # explore a key
$ pytheory identify Cmaj7                  # analyze a chord symbol
$ pytheory progression C major I V vi IV   # build a progression
$ pytheory midi C major I V vi IV -o out.mid
$ pytheory play Am7 --synth saw --envelope pluck
$ pytheory modes C                         # show all modes
$ pytheory circle C                        # circle of fifths

Why Python?

A DAW is great for tweaking sounds. But when you're thinking about music — code is faster than clicking. Sketch ideas, hear them instantly, export MIDI, finish in your DAW.

Tools like Claude Code can use PyTheory to prototype musical ideas from natural language — "write a bossa nova in A minor with a saw lead and reverb" becomes real, playable music.

Documentation

pytheory.kennethreitz.org

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytheory-0.27.1.tar.gz (93.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytheory-0.27.1-py3-none-any.whl (95.5 kB view details)

Uploaded Python 3

File details

Details for the file pytheory-0.27.1.tar.gz.

File metadata

  • Download URL: pytheory-0.27.1.tar.gz
  • Upload date:
  • Size: 93.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pytheory-0.27.1.tar.gz
Algorithm Hash digest
SHA256 d3a8462eec1c103f338dc7cfc68437907e2cbfb21258fe3d8522062a63b89678
MD5 7acfaa9feec956767250862c2d86489c
BLAKE2b-256 c4605c801fc766ff56d6d6816d94faa8f9539428b4c4f8cf53e16910172dfd9b

See more details on using hashes here.

File details

Details for the file pytheory-0.27.1-py3-none-any.whl.

File metadata

  • Download URL: pytheory-0.27.1-py3-none-any.whl
  • Upload date:
  • Size: 95.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pytheory-0.27.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3d40af512d425f6a20dcd3426636fb7c98d858095c36c7924549dd5a9627c03b
MD5 ada1f869f6efc07bf897bb8285b73a7d
BLAKE2b-256 0987879a48b0c135e5c8e23d922303573f81a6b6c1ff79c1c4823a447bcc7c23

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page