mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-06-05 14:50:18 +00:00
Trim homepage: two examples, compact feature list, get out of the way
197 → 85 lines. Theory example, composition example, pytheory demo, one-line feature summary per category. No more walls of text before the toctree. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+38
-127
@@ -8,156 +8,67 @@ multi-part arrangements, and exporting them to MIDI for your DAW.
|
||||
|
||||
$ pip install pytheory
|
||||
|
||||
Why Compose in Python?
|
||||
----------------------
|
||||
|
||||
A DAW is great for tweaking sounds. But when you're *thinking about
|
||||
music* — exploring a chord progression, trying every mode of a scale,
|
||||
figuring out which chords two keys share for a modulation — code is
|
||||
faster than clicking.
|
||||
|
||||
PyTheory lets you:
|
||||
|
||||
- **Sketch ideas in seconds**. Type ``Key("A", "minor").progression("i", "iv", "V", "i")``
|
||||
and hear it immediately. Change the key, the mode, the voicing — all
|
||||
in one line. No mouse, no menus.
|
||||
|
||||
- **Build arrangements programmatically**. Layer drums, bass, chords,
|
||||
and leads as named Parts with independent synths, effects, and
|
||||
automation. Then export to MIDI and finish in your DAW.
|
||||
|
||||
- **Generate music algorithmically**. Write a script that picks keys,
|
||||
progressions, and melodies from rules you define — every run produces
|
||||
something new. Use it for inspiration, ear training, or generative art.
|
||||
|
||||
- **Learn theory by doing**. Instead of reading about the circle of
|
||||
fifths, *call* it. Instead of memorizing chord formulas, *build* chords
|
||||
from intervals and hear the result.
|
||||
|
||||
- **Collaborate with AI**. Tools like `Claude Code <https://claude.ai/code>`_
|
||||
can use PyTheory to prototype musical ideas for you. Ask it to "write a
|
||||
bossa nova in A minor with a saw lead and reverb" and it will build the
|
||||
Score, pick the chords, write a melody, choose effects, and play it —
|
||||
all in real Python you can edit and export.
|
||||
|
||||
The workflow: **sketch in Python → hear it instantly → export MIDI → finish in your DAW**.
|
||||
|
||||
Quick Example
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
From idea to MIDI in 10 lines:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> 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, legato=True, glide=0.03)
|
||||
>>> 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
|
||||
|
||||
Theory
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from pytheory import Key, Chord, Tone, Scale, Fretboard
|
||||
>>> from pytheory import Key, Chord, Tone
|
||||
|
||||
>>> key = Key("C", "major")
|
||||
>>> key.chords
|
||||
['C major', 'D minor', 'E minor', 'F major',
|
||||
'G major', 'A minor', 'B diminished']
|
||||
>>> Key("C", "major").chords
|
||||
['C major', 'D minor', 'E minor', 'F major', 'G major', 'A minor', 'B diminished']
|
||||
|
||||
>>> [c.identify() for c in key.progression("I", "V", "vi", "IV")]
|
||||
['C major', 'G major', 'A minor', 'F major']
|
||||
>>> [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'
|
||||
|
||||
>>> c4 = Tone.from_string("C4", system="western")
|
||||
>>> c4.interval_to(c4 + 7)
|
||||
>>> 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
|
||||
-----------
|
||||
|
||||
>>> fb = Fretboard.guitar()
|
||||
>>> fb.chord("G")
|
||||
Fingering(e=3, B=0, G=0, D=0, A=2, E=3)
|
||||
.. code-block:: python
|
||||
|
||||
Highlights
|
||||
----------
|
||||
from pytheory import Score, Pattern, Key, Duration, Chord
|
||||
from pytheory.play import play_score
|
||||
|
||||
**Theory**
|
||||
score = Score("4/4", bpm=140)
|
||||
score.drums("bossa nova", repeats=4)
|
||||
|
||||
- **Tones**: frequencies, MIDI, intervals, transposition, circle of fifths,
|
||||
overtone series, solfege, Helmholtz notation, cents comparison,
|
||||
3 temperaments (equal, Pythagorean, meantone)
|
||||
- **Scales**: 40+ scales across 6 musical systems — Western, Indian,
|
||||
Arabic, Japanese, Blues, Javanese Gamelan. Scale fitness scoring,
|
||||
degree names, parallel modes
|
||||
- **Chords**: 17 types identified automatically, Roman numeral analysis
|
||||
(including borrowed chords: bVI, bVII), tension scoring, voice leading,
|
||||
consonance/dissonance, drop voicings, slash chords, extensions
|
||||
- **Keys**: key detection, signatures, progressions (Roman numerals and
|
||||
Nashville numbers), borrowed chords, secondary dominants, modulation
|
||||
paths, chord suggestions
|
||||
chords = score.part("chords", synth="fm", envelope="pad", reverb=0.4)
|
||||
lead = score.part("lead", synth="saw", envelope="pluck", delay=0.3)
|
||||
bass = score.part("bass", synth="sine", lowpass=500)
|
||||
|
||||
**Instruments**
|
||||
for chord in Key("A", "minor").progression("i", "iv", "V", "i"):
|
||||
chords.add(chord, Duration.WHOLE)
|
||||
|
||||
- 25 instrument presets (guitar, bass, ukulele, mandolin, violin, banjo,
|
||||
oud, sitar, erhu, and more) with fingering generation
|
||||
- 58 drum pattern presets (rock, jazz, salsa, bossa nova, afrobeat, funk,
|
||||
reggae, house, trap, metal, and 48 more)
|
||||
- 21 drum fill presets with auto-fill support
|
||||
lead.arpeggio("Am", bars=4, pattern="updown", octaves=2)
|
||||
|
||||
**Synthesis and Effects**
|
||||
play_score(score)
|
||||
score.save_midi("sketch.mid")
|
||||
|
||||
- 10 synth waveforms: sine, saw, triangle, square, pulse, FM, noise,
|
||||
supersaw, PWM slow, PWM fast
|
||||
- 8 ADSR envelope presets: piano, pluck, pad, organ, bell, strings,
|
||||
staccato, none
|
||||
- 5 audio effects: distortion, chorus, lowpass filter (with resonance),
|
||||
delay, reverb — all per-part with independent settings
|
||||
- Legato mode with pitch glide/portamento
|
||||
- Arpeggiator with 5 patterns and octave spanning
|
||||
- Effect automation via ``.set()`` and LFO modulation via ``.lfo()``
|
||||
- 27 synthesized drum voices (no samples needed)
|
||||
::
|
||||
|
||||
**Export**
|
||||
$ pytheory demo
|
||||
|
||||
- Standard MIDI File export — open in any DAW, notation software, or player
|
||||
- WAV audio export
|
||||
- Real-time playback through speakers
|
||||
What's Inside
|
||||
-------------
|
||||
|
||||
It also works from the command line::
|
||||
|
||||
$ pytheory key G major
|
||||
$ pytheory chord C E G
|
||||
$ pytheory identify Cmaj7
|
||||
$ pytheory progression C major I V vi IV
|
||||
$ pytheory midi C major I V vi IV -o pop.mid
|
||||
$ pytheory play Am7 --synth saw --envelope pluck
|
||||
- **Theory** — tones, scales (40+ across 6 systems), chords (17 types),
|
||||
keys, Roman numeral analysis, modulation, voice leading
|
||||
- **Sequencing** — Score, Parts, arpeggiator, legato/glide, velocity,
|
||||
swing, humanize, tempo changes, song sections
|
||||
- **Synthesis** — 10 waveforms, 8 envelopes, 58 drum patterns, 21 fills
|
||||
- **Effects** — reverb (algorithmic + 7 convolution IRs), delay, lowpass,
|
||||
distortion, chorus, sidechain, automation, LFOs
|
||||
- **Instruments** — 25 presets with fingering generation
|
||||
- **Export** — MIDI, WAV, real-time playback
|
||||
- **CLI** — ``pytheory demo``, ``key``, ``chord``, ``midi``, ``play``, and more
|
||||
- **AI-friendly** — `Claude Code <https://claude.ai/code>`_ can compose
|
||||
and play music through PyTheory from natural language
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
Reference in New Issue
Block a user