Files
kennethreitz b396f42f84 Add REPL guide: theory scratchpad, composition, effects, complete example
Covers the prompt, theory commands, composition flow, effects,
automation, LFOs, playback, export, and a full start-to-finish session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:26:11 -04:00

277 lines
6.3 KiB
ReStructuredText

Interactive REPL
================
PyTheory includes an interactive scratchpad for exploring music theory,
hearing ideas instantly, and building arrangements — all without writing
a Python script.
::
$ pytheory repl
The REPL is two things at once: a **theory calculator** (what chords
are in this key? what's the interval between these notes?) and a
**composition sketchpad** (add drums, layer parts, tweak effects, hear
it, export MIDI). Use whichever side you need.
Getting Started
---------------
The welcome screen tells you everything you need::
♫ PyTheory REPL
════════════════════════════════════════
try: key Am — set a key
chords — see its chords
prog I V vi IV — hear a progression
drums bossa nova
play_score — hear it all
help for all commands, quit to exit
Type those five things in order and you'll have music playing in
30 seconds.
The Prompt
----------
The prompt shows your current state — key, tempo, drums, active part,
and effects. It starts compact and grows as you add context::
pytheory[key=C | bpm=120]>
pytheory[key=Am | bpm=140]>
pytheory[key=Am | bpm=140 | drums=bossa nova]>
pytheory[key=Am | bpm=140 | drums=bossa nova | →lead(saw)]>
When it gets long, it stacks into two lines::
key=Am | bpm=140 | drums=bossa nova | →lead(saw) rev=0.3 lp=2000
♫>
You always know where you are.
Theory Commands
---------------
These work without any audio setup. Pure theory exploration.
Set a key and explore it::
pytheory> key Am
A minor: A B C D E F G A
pytheory> chords
i A minor
ii° B diminished
III C major
iv D minor
v E minor
VI F major
VII G major
pytheory> modes
ionian A B C# D E F# G# A
dorian A B C D E F# G A
phrygian A Bb C D E F G A
...
pytheory> scales
major A B C# D E F# G# A
minor A B C D E F G A
harmonic minor A B C D E F G# A
...
Build progressions::
pytheory> prog I V vi IV
Am → Em → F → Dm
pytheory> progression i iv V i
Am → Dm → E → Am
Explore intervals and chords::
pytheory> interval C4 G4
C4 → G4: perfect 5th
7 semitones
pytheory> identify C E G
C major
symbol: C
pytheory> identify F#m7b5
F# half-diminished 7th
symbol: F#m7b5
tones: F#4 A4 C5 E5
intervals: [3, 3, 4]
Circle of fifths::
pytheory> circle
fifths: A → E → B → F# → C# → G# → D# → A# → F → C → G → D
fourths: A → D → G → C → F → A# → D# → G# → C# → F# → B → E
Other musical systems::
pytheory> system indian
system: indian
scales: chromatic, bilawal, khamaj, kafi, ...
pytheory> system arabic
system: arabic
scales: chromatic, ajam, nahawand, kurd, hijaz, ...
Guitar::
pytheory> fingering Am
Am
E|--0--
B|--1--
G|--2--
D|--2--
A|--0--
E|--x--
pytheory> diagram minor 5
0 1 2 3 4 5
E| E | F | - | G | - | A |
...
Composition Commands
--------------------
When you're ready to make sound, add drums and parts.
Drums::
pytheory> drums bossa nova
score.drums("bossa nova", repeats=4)
pytheory> drums
(lists all 58 presets)
Parts — each with its own synth and envelope::
pytheory> part lead saw pluck
score.part("lead", synth="saw", envelope="pluck")
pytheory> part chords fm pad
score.part("chords", synth="fm", envelope="pad")
pytheory> part bass sine pluck
score.part("bass", synth="sine", envelope="pluck")
pytheory> part
lead: synth=saw envelope=pluck vol=0.5 ←
chords: synth=fm envelope=pad vol=0.5
bass: synth=sine envelope=pluck vol=0.5
The arrow (````) shows which part is active. Switch with
``part <name>``.
Add notes, chords, arpeggios::
pytheory> add C5 1
.add("C5", 1.0)
pytheory> add Am 4
.add(Chord.from_symbol("Am"), 4.0)
pytheory> add E5 0.67 110
.add("E5", 0.67, velocity=110)
pytheory> rest 2
.rest(2.0)
pytheory> arp Am updown 2 2
.arpeggio("Am", pattern="updown", bars=2.0, octaves=2)
pytheory> prog i iv V i
Am → Dm → E → Am
Effects
-------
Set effects on the active part — mirrors the Python API::
pytheory> reverb 0.4
pytheory> delay 0.3 0.375
pytheory> lowpass 2000 3
pytheory> dist 0.5
pytheory> chorus 0.3
pytheory> sidechain 0.8
pytheory> humanize 0.3
pytheory> legato on
pytheory> glide 0.04
pytheory> volume 0.4
Automation — change effects mid-song::
pytheory> set lowpass 3000
.set(lowpass=3000)
LFO modulation::
pytheory> lfo lowpass 0.5 400 3000 8 sine
.lfo("lowpass", rate=0.5, min=400, max=3000, bars=8, shape="sine")
Playback and Export
-------------------
Hear your work::
pytheory> play_score
♫ play_score()
pytheory> play_pattern
♫ play_pattern("bossa nova")
Export::
pytheory> save_midi sketch.mid
save_midi("sketch.mid")
pytheory> render sketch.wav
saved: sketch.wav
Session management::
pytheory> show
<Score 4/4 140bpm 3 parts 8.0 measures>
lead: saw+pluck 32 notes reverb=0.3 delay=0.25 ←
chords: fm+pad 8 notes
drums: bossa nova (76 hits)
pytheory> status
key=A minor bpm=140 swing=0.0
drums=bossa nova parts=[lead, chords, bass] active=lead
pytheory> clear
cleared (C major, 120 bpm)
Complete Example
----------------
A full session from start to playable track::
pytheory[key=C | bpm=120]> key Am
pytheory[key=Am | bpm=120]> bpm 140
pytheory[key=Am | bpm=140]> drums bossa nova
pytheory[key=Am | bpm=140 | drums=bossa nova]> part chords fm pad
pytheory[...| →chords(fm)]> prog i iv V i
pytheory[...| →chords(fm)]> part lead saw pluck
pytheory[...| →lead(saw)]> reverb 0.3
pytheory[...| →lead(saw) rev=0.3]> delay 0.25
pytheory[...| →lead(saw) rev=0.3 del=0.25]> arp Am updown 4 2
pytheory[...]> play_score
♫ play_score()
pytheory[...]> save_midi my_bossa.mid
save_midi("my_bossa.mid")
Every command you typed maps 1:1 to the Python API. When you're
ready to move from the REPL to a script, the translation is direct.