From eba299d406200fa8b56365b857aca5baf71d2f85 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Mar 2026 20:59:55 -0400 Subject: [PATCH] Rewrite quickstart with sections for each feature area Breaks the single code block into focused sections: Tones, Scales, Keys and Chords, Guitar Fingerings, Audio Playback, and Command Line. Adds installation notes for PortAudio, shows from_frequency/from_midi, enharmonics, Key class, Chord convenience constructors, tab output, WAV export, and CLI commands. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/guide/quickstart.rst | 171 ++++++++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 24 deletions(-) diff --git a/docs/guide/quickstart.rst b/docs/guide/quickstart.rst index f6df743..357c0e0 100644 --- a/docs/guide/quickstart.rst +++ b/docs/guide/quickstart.rst @@ -8,46 +8,168 @@ Installation $ pip install pytheory -Basic Usage ------------ +For audio playback, you'll also need `PortAudio `_: -Create tones, build scales, and explore music theory: +- macOS: ``brew install portaudio`` +- Ubuntu: ``apt install libportaudio2`` +- Windows: included with the ``sounddevice`` package + +Tones +----- + +A :class:`~pytheory.tones.Tone` is a single musical note: .. code-block:: python - from pytheory import Tone, TonedScale, Fretboard, CHARTS + from pytheory import Tone - # Create a tone — A4 is the tuning standard (440 Hz) + # Create tones — sharps and flats both work a4 = Tone.from_string("A4", system="western") - print(a4.frequency) # 440.0 + a4.frequency # 440.0 Hz — the tuning standard - # Tone arithmetic — add semitones to move up the chromatic scale c4 = Tone.from_string("C4", system="western") - e4 = c4 + 4 # Major third up (4 semitones) - g4 = c4 + 7 # Perfect fifth up (7 semitones) - print(e4, g4) # E4 G4 + c4.midi # 60 — middle C - # Measure intervals between tones - print(g4 - c4) # 7 (semitones — a perfect fifth) + # From a frequency or MIDI number + Tone.from_frequency(440) # + Tone.from_midi(60) # - # Build a C major scale - c_major = TonedScale(tonic="C4")["major"] - print(c_major.note_names) + # Tone arithmetic + c4 + 4 # — major third up + c4 + 7 # — perfect fifth up + + # Interval between two tones + g4 = c4 + 7 + g4 - c4 # 7 semitones + c4.interval_to(g4) # 'perfect 5th' + + # Enharmonics + Tone.from_string("C#4", system="western").enharmonic # 'Db' + +Scales +------ + +Build scales in any key and mode: + +.. code-block:: python + + from pytheory import TonedScale + + c = TonedScale(tonic="C4") + + c["major"].note_names # ['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C'] - # Build diatonic triads from the scale - I = c_major.triad(0) # C E G (C major) - IV = c_major.triad(3) # F A C (F major) - V = c_major.triad(4) # G B D (G major) + c["minor"].note_names + # ['C', 'D', 'D#', 'F', 'G', 'G#', 'A#', 'C'] + + c["dorian"].note_names + # ['C', 'D', 'D#', 'F', 'G', 'A', 'A#', 'C'] + + # Access scale degrees by name or numeral + major = c["major"] + major["tonic"] # C4 + major["dominant"] # G4 + major["V"] # G4 + +Keys and Chords +--------------- + +The :class:`~pytheory.scales.Key` class ties everything together — +scales, chords, and progressions: + +.. code-block:: python + + from pytheory import Key + + key = Key("G", "major") + key.note_names # ['G', 'A', 'B', 'C', 'D', 'E', 'F#', 'G'] + + # All diatonic triads + key.chords + # ['G major', 'A minor', 'B minor', 'C major', + # 'D major', 'E minor', 'F# diminished'] + + # Build progressions from Roman numerals + chords = key.progression("I", "V", "vi", "IV") + [c.identify() for c in chords] + # ['G major', 'D major', 'E minor', 'C major'] + + # Detect the key from notes + Key.detect("C", "E", "G", "A", "D") # + +Build chords directly: + +.. code-block:: python + + from pytheory import Chord + + Chord.from_tones("C", "E", "G") # + Chord.from_name("Am7") # + Chord.from_intervals("G", 4, 7, 10) # + + # Identify any chord + Chord.from_tones("Bb", "D", "F").identify() # 'Bb major' + + # Analyze in a key + Chord.from_name("G7").analyze("C") # 'V7' + +Guitar Fingerings +----------------- + +.. code-block:: python + + from pytheory import Fretboard, CHARTS - # Guitar chord fingerings — labeled with string names fb = Fretboard.guitar() - fingering = CHARTS["western"]["Am"].fingering(fretboard=fb) - print(fingering) # Fingering(e=0, B=1, G=2, D=2, A=0, E=0) + + # Get a labeled fingering from the chord chart + f = CHARTS["western"]["C"].fingering(fretboard=fb) + f # Fingering(e=0, B=1, G=0, D=2, A=3, E=0) + f['A'] # 3 # Identify a chord from fret positions - f = fb.fingering(0, 1, 0, 2, 3, 0) - print(f.identify()) # C major + fb.fingering(0, 0, 0, 2, 2, 0).identify() # 'E minor' + + # ASCII tablature + print(CHARTS["western"]["Am"].tab(fretboard=fb)) + # Am + # E|--0-- + # B|--1-- + # G|--2-- + # D|--2-- + # A|--0-- + # E|--0-- + +Audio Playback +-------------- + +.. code-block:: python + + from pytheory import Tone, Chord, play, save, Synth + + # Play a tone + play(Tone.from_string("A4"), t=1_000) + + # Play a chord with a different waveform + play(Chord.from_name("Am7"), synth=Synth.TRIANGLE, t=2_000) + + # Save to a WAV file + save(Chord.from_name("C"), "c_major.wav", t=2_000) + +Command Line +------------ + +PyTheory also works from the terminal:: + + $ pytheory tone A4 + $ pytheory chord C E G + $ pytheory key G major + $ pytheory scale C dorian + $ pytheory fingering Am + $ pytheory progression C major I V vi IV + $ pytheory detect C E G A D + $ pytheory play Am7 --synth triangle What's Included --------------- @@ -67,3 +189,4 @@ What's Included - **Fingering generation** for 25 instruments with labeled string names, including guitar (8 tunings), bass, ukulele, mandolin, and more - **Audio playback** with sine, sawtooth, and triangle wave synthesis +- **WAV export** for saving rendered audio to disk