Files
pytheory/docs/guide/playback.rst
T
kennethreitz 119dd2d921 Add conversational prose throughout all 5 guide pages
Sequencing: Score concept, time signatures for non-musicians, Parts as
DAW tracks, arpeggiator/legato/glide context with TB-303 and acid history.
Synths: synthesis philosophy, DX7/Juno/JP-8000 history, practical combos.
Effects: real-music context (The Edge, DJ knobs, shower reverb), why signal
chain order matters, automation as breathing, LFO as repeating automation.
Drums: drums-as-genre foundation, genre group cultural context, fills as
transition signals, drum synthesis as real drum machine techniques.
Playback: three output options context, MIDI as the working musician's path.

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

167 lines
5.3 KiB
ReStructuredText

Playback and Export
===================
This is the output layer. You've built your theory, composed your
arrangement, shaped your sounds -- now you need to hear it. PyTheory
gives you three ways to get your music out: speakers, WAV files, and
MIDI files.
Use **speakers** for immediate feedback while you're sketching and
experimenting. Use **WAV export** when you want to share actual audio
-- post it, send it, drop it into a video. Use **MIDI export** when you
want to bring your sketch into a real DAW and finish it with
professional instruments, mixing, and mastering. Each output serves a
different stage of the creative process.
PyTheory can play audio through your speakers, save to WAV, or export
to MIDI. Everything is synthesized from waveforms -- no samples or
external audio files needed.
.. note::
Audio playback requires `PortAudio <http://www.portaudio.com/>`_ to be
installed on your system. On macOS: ``brew install portaudio``.
On Ubuntu: ``apt install libportaudio2``.
play() -- Single Tones and Chords
---------------------------------
The simplest way to hear something:
.. code-block:: pycon
>>> from pytheory import Tone, Chord, play
>>> play(Tone.from_string("A4"), t=1_000) # A440 for 1 second
>>> play(Chord.from_symbol("Am7"), t=2_000) # chord for 2 seconds
Optional parameters for synth, envelope, and temperament:
.. code-block:: pycon
>>> from pytheory import Synth, Envelope
>>> play(Tone.from_string("C4"), synth=Synth.SAW, envelope=Envelope.PLUCK, t=1_000)
>>> play(Tone.from_string("C4"), temperament="pythagorean", t=1_000)
play_score() -- Full Arrangements
---------------------------------
Plays a ``Score`` with all its parts and drums mixed together:
.. code-block:: pycon
>>> from pytheory import Score, 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="sine", envelope="pad")
>>> for sym in ["Am", "Dm", "E7", "Am"]:
... chords.add(Chord.from_symbol(sym), Duration.WHOLE)
>>> play_score(score)
See :doc:`sequencing` for how to build scores and parts.
render_score() -- Headless Rendering
------------------------------------
Returns a raw audio buffer (numpy float32 array) without playing it.
Useful for saving to WAV or further processing:
.. code-block:: pycon
>>> from pytheory.play import render_score
>>> buf = render_score(score) # numpy float32 array
>>> len(buf)
604800
save() -- WAV Export
--------------------
Render tones or chords to a WAV file. Works without speakers or
PortAudio:
.. code-block:: pycon
>>> from pytheory import save, Chord, Tone, Synth
>>> save(Tone.from_string("A4"), "a440.wav", t=1_000)
>>> save(Chord.from_name("Am7"), "am7.wav", t=2_000)
>>> save(Chord.from_name("C"), "c_triangle.wav",
... synth=Synth.TRIANGLE, temperament="meantone", t=3_000)
save_midi() -- MIDI Export
--------------------------
MIDI export is probably the most useful feature here for working
musicians. The idea is simple: sketch your ideas in Python -- where
iteration is fast, where you can use loops and randomness and music
theory functions -- and then export to MIDI. Open that MIDI file in
Logic, Ableton, Reaper, FL Studio, or whatever you use, and now you've
got your chord progressions, melodies, and bass lines on real tracks.
Swap in your favorite soft synths, add real mixing, finish the track
properly. Python is the sketchpad; the DAW is the canvas.
Export tones, chords, progressions, or full scores as Standard MIDI
Files. MIDI files can be opened in any DAW, edited, transposed, and
assigned to any instrument.
Simple export (single tone, chord, or progression):
.. code-block:: pycon
>>> from pytheory import save_midi, Key, Tone, Chord
>>> save_midi(Tone.from_string("C4"), "middle_c.mid", t=1000)
>>> save_midi(Chord.from_symbol("Am7"), "am7.mid")
>>> chords = Key("C", "major").progression("I", "V", "vi", "IV")
>>> save_midi(chords, "pop.mid", t=500, bpm=120)
Score-based export (with time signature, tempo, and parts):
.. code-block:: pycon
>>> from pytheory import Score, Duration, Key
>>> score = Score("4/4", bpm=140)
>>> for chord in Key("G", "major").progression("I", "IV", "V", "I"):
... score.add(chord, Duration.WHOLE)
>>> score.save_midi("progression.mid")
play_pattern() -- Drum Patterns
-------------------------------
Play a drum pattern through the speakers:
.. code-block:: pycon
>>> from pytheory import Pattern
>>> from pytheory.play import play_pattern
>>> play_pattern(Pattern.preset("rock"), repeats=4, bpm=120)
>>> play_pattern(Pattern.preset("bossa nova"), repeats=4, bpm=140)
See :doc:`drums` for the full list of 58 presets and 21 fills.
play_progression() -- Quick Chord Playback
------------------------------------------
Play a chord progression in sequence with a single call:
.. code-block:: pycon
>>> from pytheory import Key, play_progression
>>> chords = Key("C", "major").progression("I", "V", "vi", "IV")
>>> play_progression(chords, t=800)
Optional synth, envelope, and gap parameters:
.. code-block:: pycon
>>> from pytheory import Synth, Envelope
>>> play_progression(chords, t=1000, synth=Synth.TRIANGLE, gap=200)
>>> play_progression(chords, t=2000, envelope=Envelope.PAD)