mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-07-21 18:19:30 +00:00
33b0636cc4
A full freshness + quality pass across the documentation, with every code example verified by actually running it against v0.57.8. Content / accuracy: - Fixed stale and broken examples throughout: SymPy-based "symbolic pitch" (SymPy was removed), the case-sensitive progression parser (I/V/vi/IV vs i/iv), analog_drift -> analog, Key.relative/parallel returning Key objects, Tone.from_string validation needing a system, stale tab()/scale_diagram() output, and many counts (74 drum sounds, 100 patterns, 37 fills, 19 chord types, 16 systems, 25 fretboard instruments, 56 waveforms, 83 presets). - Documented major recent features that were missing: Maqam (quarter-tone Arabic maqamat) and Raga (Hindustani + Carnatic, shruti just intonation) in the systems guide and the CLI; SVG/PNG diagram export; progression / cadence / secondary-dominant analysis and reharmonization; notation export to LilyPond/MusicXML/ABC incl. lyrics; from_wav transcription; render_scores batch rendering; CLI raga/maqam and `analyze song.mid`. Navigation / presentation: - Added sphinx-design + sphinx-copybutton to the docs deps and conf. - Rebuilt the homepage "Why would I want this?" into a sphinx-design persona card grid with CTA buttons and a badge row; wired the brand logo into the sidebar (and suppressed the now-redundant project-name text). - Added API-reference pages for the public Raga and Maqam classes. Also: removed a duplicate `jati` attribute line from the Raga docstring so autodoc no longer double-documents it. Sphinx build is clean (0 warnings).
294 lines
9.5 KiB
ReStructuredText
294 lines
9.5 KiB
ReStructuredText
Quickstart
|
|
==========
|
|
|
|
PyTheory works at two levels — pick the one that fits what you need:
|
|
|
|
1. **Music theory** — explore scales, chords, keys, intervals, and
|
|
harmony. No audio required. Works anywhere Python runs.
|
|
|
|
2. **Composition** — build multi-part arrangements with drums, synths,
|
|
effects, and export to MIDI. Needs PortAudio for live playback.
|
|
|
|
Both are first-class. You can use PyTheory purely as a theory
|
|
reference and never touch the audio side, or you can jump straight
|
|
into composing. This guide covers both paths.
|
|
|
|
Installation
|
|
------------
|
|
|
|
::
|
|
|
|
$ pip install pytheory
|
|
|
|
(Don't want to install anything yet? Try PyTheory in your browser at
|
|
the `playground <https://playground.pytheory.org>`_.)
|
|
|
|
For audio playback through your speakers, you'll also need
|
|
`PortAudio <http://www.portaudio.com/>`_:
|
|
|
|
- macOS: ``brew install portaudio``
|
|
- Ubuntu: ``apt install libportaudio2``
|
|
- Windows: included with the ``sounddevice`` package
|
|
|
|
PortAudio is only needed for live playback. MIDI export, WAV export,
|
|
and all theory functions work without it.
|
|
|
|
Two optional extras unlock the performance features::
|
|
|
|
$ pip install "pytheory[live]" # MIDI input (python-rtmidi)
|
|
$ pip install "pytheory[link]" # Ableton Link sync (LinkPython-extern)
|
|
|
|
``[live]`` lets the live engine take input from a MIDI keyboard or
|
|
controller; ``[link]`` lets it lock tempo and beat grid to an
|
|
`Ableton Link <https://www.ableton.com/link/>`_ session (Ableton
|
|
Live, most iOS music apps). They're independent — install either or
|
|
both. ``[link]`` compiles Ableton's C++ Link library on first
|
|
install, so expect the install to take a minute. See :doc:`live`
|
|
for what they unlock.
|
|
|
|
Hear Something Immediately
|
|
--------------------------
|
|
|
|
::
|
|
|
|
$ pytheory demo
|
|
|
|
This generates and plays a random track — different every time. It's
|
|
the fastest way to hear what PyTheory can do.
|
|
|
|
Explore Music Theory
|
|
--------------------
|
|
|
|
The theory layer is where most people start. No audio setup needed —
|
|
this works everywhere Python runs. Every concept in Western music
|
|
theory — and fifteen other tuning systems — has a clean Python API.
|
|
|
|
Tones and intervals:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import Tone
|
|
|
|
>>> c4 = Tone.from_string("C4", system="western")
|
|
>>> c4.frequency
|
|
261.6255653005986
|
|
>>> c4.midi
|
|
60
|
|
|
|
>>> c4 + 7
|
|
<Tone G4>
|
|
>>> c4.interval_to(c4 + 7)
|
|
'perfect 5th'
|
|
|
|
>>> Tone.from_frequency(440)
|
|
<Tone A4>
|
|
>>> Tone.from_midi(69)
|
|
<Tone A4>
|
|
|
|
Keys, scales, and chords:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import Key, Chord
|
|
|
|
>>> key = Key("C", "major")
|
|
>>> key.chords
|
|
['C major', 'D minor', 'E minor', 'F major', 'G major', 'A minor', 'B diminished']
|
|
|
|
>>> [c.symbol for c in key.progression("I", "V", "vi", "IV")]
|
|
['C', 'G', 'Am', 'F']
|
|
|
|
>>> key.signature
|
|
{'sharps': 0, 'flats': 0, 'accidentals': []}
|
|
|
|
>>> Key("F", "major").signature
|
|
{'sharps': 0, 'flats': 1, 'accidentals': ['Bb']}
|
|
|
|
>>> Chord.from_symbol("Am7").identify()
|
|
'A minor 7th'
|
|
|
|
>>> Chord.from_tones("G", "B", "D", "F").analyze("C")
|
|
'V7'
|
|
|
|
Harmonic analysis and modulation:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> Key("C", "major").pivot_chords(Key("G", "major"))
|
|
['A minor', 'C major', 'E minor', 'G major']
|
|
|
|
>>> Key("C", "major").relative
|
|
<Key A minor>
|
|
|
|
>>> key.suggest_next(key.triad(4)) # what follows V?
|
|
[<Chord C major>, <Chord A minor>, <Chord F major>]
|
|
|
|
Scales across 16 tuning systems:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import TonedScale
|
|
|
|
>>> TonedScale(tonic="Sa4", system="indian")["bhairav"].note_names
|
|
['Sa', 'komal Re', 'Ga', 'Ma', 'Pa', 'komal Dha', 'Ni', 'Sa']
|
|
|
|
>>> TonedScale(tonic="Do4", system="arabic")["hijaz"].note_names
|
|
['Do', 'Reb', 'Mi', 'Fa', 'Sol', 'Solb', 'Sib', 'Do']
|
|
|
|
>>> TonedScale(tonic="C4", system="japanese")["hirajoshi"].note_names
|
|
['C', 'D', 'Eb', 'G', 'Ab', 'C']
|
|
|
|
Those ``TonedScale`` spellings are 12-tone-equal-tempered
|
|
approximations. For the real thing — just-intonation Indian *ragas*
|
|
and quarter-tone Arabic *maqamat* with their authentic tunings — reach
|
|
for the dedicated ``Raga`` and ``Maqam`` classes (see :doc:`systems`):
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import Raga, Maqam
|
|
|
|
>>> Raga.get("yaman").note_names(sa="C")
|
|
['C', 'D', 'E', 'F#', 'G', 'A', 'B']
|
|
|
|
>>> Maqam.get("rast").degree_names() # the down arrow marks a quarter-flat
|
|
['Do', 'Re', 'Mi↓', 'Fa', 'Sol', 'La', 'Si↓']
|
|
|
|
Guitar fingerings:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import Fretboard
|
|
|
|
>>> fb = Fretboard.guitar()
|
|
>>> fb.chord("Am")
|
|
Fingering(E=x, A=0, D=2, G=2, B=1, e=0)
|
|
|
|
All of the above works without PortAudio, without sounddevice,
|
|
without any audio setup at all. It's pure Python music theory.
|
|
|
|
Compose a Track
|
|
---------------
|
|
|
|
This is where it gets fun. A ``Score`` is your arrangement — drums,
|
|
chords, melody, bass, each with their own synth and effects:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Score, Key, Duration, play_score
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.drums("rock", repeats=8, fill="rock", fill_every=4)
|
|
|
|
piano = score.part("piano", instrument="piano", reverb=0.3)
|
|
lead = score.part("lead", synth="saw", envelope="pluck",
|
|
delay=0.2, reverb=0.2, lowpass=4000)
|
|
bass = score.part("bass", synth="triangle", lowpass=900)
|
|
|
|
for chord in Key("G", "major").progression("I", "V", "vi", "IV") * 2:
|
|
piano.add(chord, Duration.WHOLE)
|
|
|
|
lead.add("D5", 1).add("B4", 0.5).add("D5", 0.5)
|
|
lead.add("G5", 1).add("E5", 1)
|
|
lead.add("D5", 0.5).add("B4", 0.5).add("A4", 1)
|
|
lead.add("G4", 2).rest(2)
|
|
|
|
for n in ["G2", "G2", "D2", "D2", "E2", "E2", "C2", "C2"] * 2:
|
|
bass.add(n, Duration.HALF)
|
|
|
|
play_score(score)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/quickstart.wav" type="audio/wav"></audio>
|
|
|
|
Export to Your DAW
|
|
------------------
|
|
|
|
The whole point: sketch in Python, finish in Logic / Ableton / Reaper.
|
|
|
|
.. code-block:: python
|
|
|
|
score.save_midi("my_sketch.mid")
|
|
|
|
Open that file in any DAW and you'll see all the notes laid out on
|
|
the timeline, ready to assign to real instruments and mix.
|
|
|
|
You can also save rendered audio:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import save, Chord
|
|
save(Chord.from_symbol("Am7"), "am7.wav", t=2_000)
|
|
|
|
Prefer sheet music? Export the same arrangement to notation — ABC,
|
|
LilyPond, or MusicXML — and open it in MuseScore, Frescobaldi, or any
|
|
engraver:
|
|
|
|
.. code-block:: python
|
|
|
|
with open("my_sketch.musicxml", "w") as f:
|
|
f.write(score.to_musicxml(title="My Sketch"))
|
|
|
|
See :doc:`playback` for the full export story, and :doc:`listening` to
|
|
go the other way — transcribe a recording straight back into a ``Score``.
|
|
|
|
What's in the Box
|
|
-----------------
|
|
|
|
**Theory** — tones, scales (40+ across 16 tuning systems, including
|
|
just-intonation Indian ragas and quarter-tone Arabic maqamat), chords
|
|
(19 types, Roman numeral analysis with secondary dominants, figured
|
|
bass, tension scoring, voice leading, pitch class sets with Forte
|
|
numbers), keys (detection, signatures, modulation paths, borrowed
|
|
chords), cadence detection, reharmonization, and scale recommendation.
|
|
|
|
**Sequencing** — Score, Part, Duration, TimeSignature. Arpeggiator
|
|
with 5 patterns. Legato with pitch glide. Per-note velocity. Swing.
|
|
Tempo changes. Fade in/out. Song sections with repeat. Humanize.
|
|
|
|
**Synthesis** — 56 waveforms, from the classic four (sine, saw,
|
|
square, triangle) through FM, supersaw, pulse, and wavefolding to 39
|
|
dedicated instrument synths modeled from scratch — plus 83 ready-to-play
|
|
instrument presets that bundle a synth, envelope, and effects. 10 ADSR
|
|
envelopes. Detune. Stereo pan and spread.
|
|
|
|
**Effects** — distortion, chorus, lowpass filter (with resonance),
|
|
delay, reverb (algorithmic + 7 stereo convolution presets including
|
|
Taj Mahal with 12-second tail). All per-part with automation and
|
|
LFO modulation. Sidechain compression. Master bus compressor/limiter.
|
|
|
|
**Drums** — 100 pattern presets (rock, jazz, salsa, bossa nova,
|
|
afrobeat, house, trap, and 90+ more). 37 fill presets. 74 synthesized
|
|
drum voices with stereo panning.
|
|
|
|
**Instruments** — 25 fretted and bowed string instruments (guitar
|
|
with 8 tunings, bass, ukulele, mandolin family, violin family, banjo,
|
|
harp, oud, sitar, erhu, and more) with chord-fingering generation,
|
|
ASCII tab, and SVG/PNG fretboard diagrams.
|
|
|
|
**Output** — stereo playback, WAV export, MIDI import/export, and
|
|
notation export to ABC, LilyPond, and MusicXML. Plus audio-to-score
|
|
transcription: drop in a recording and get the notes back.
|
|
|
|
**Interface** — REPL with tab completion (``pytheory repl``) and a CLI
|
|
with 24 commands: ``pytheory demo``, ``pytheory key``, ``pytheory
|
|
chord``, ``pytheory identify``, ``pytheory midi``, ``pytheory play``,
|
|
``pytheory raga``, ``pytheory maqam``, ``pytheory tune``, and more.
|
|
|
|
Where to Go Next
|
|
-----------------
|
|
|
|
- :doc:`theory` — music theory fundamentals
|
|
- :doc:`tones` — working with individual notes
|
|
- :doc:`scales` — scales, modes, and keys
|
|
- :doc:`systems` — world tunings: ragas, maqamat, gamelan, and microtonal grids
|
|
- :doc:`chords` — chord construction, analysis, and progressions
|
|
- :doc:`fretboard` — guitar, bass, and string-instrument fingerings and tabs
|
|
- :doc:`sequencing` — composing multi-part arrangements
|
|
- :doc:`synths` — the 56 waveforms and 10 envelopes
|
|
- :doc:`effects` — reverb, delay, distortion, chorus, lowpass, automation
|
|
- :doc:`drums` — 100 patterns, 37 fills, drum synthesis
|
|
- :doc:`playback` — play, save, export
|
|
- :doc:`listening` — transcribe recordings, the browser studio, the tuner
|
|
- :doc:`live` — real-time MIDI performance, Ableton Link
|