Files
pytheory/examples/songs.py
T
kennethreitz 8a4a2df1aa Song #23: Tabla Solo in Raga Yaman (22-shruti)
Tanpura drone intro, quiet sitar Yaman phrases, tabla solo building
from gentle theka through ghost notes to blazing tiri kita with
bayan pitch bends, tihai, dramatic silence, slam finish. Taj Mahal
reverb throughout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:37:34 -04:00

1359 lines
54 KiB
Python

"""Play songs with PyTheory — drums, chords, bass, leads, and effects.
Requires PortAudio: brew install portaudio (macOS)
Each song showcases the full Score API:
- 58 drum pattern presets with genre-matched fills
- 10 synth waveforms (sine, saw, triangle, square, pulse, FM, noise, supersaw, PWM slow/fast)
- 8 ADSR envelope presets
- Per-part effects: reverb, delay, lowpass filter with resonance
- Named parts with independent voices mixed together
Usage:
python examples/song.py
"""
import sounddevice as sd
from pytheory import Chord, Key, Pattern, Duration, Score, Tone, TonedScale, SYSTEMS
from pytheory.rhythm import DrumSound, _Hit
from pytheory.play import render_score, SAMPLE_RATE
def play_song(score, label=""):
"""Render and play. Ctrl-C to skip."""
if label:
print(f" {label}")
print(f" {score}")
print()
try:
buf = render_score(score)
sd.play(buf, SAMPLE_RATE)
sd.wait()
except KeyboardInterrupt:
sd.stop()
print(" (skipped)")
# ── Songs ──────────────────────────────────────────────────────────────────
def bossa_nova_girl():
"""Bossa nova in A minor — Ipanema vibes with reverb-washed chords."""
print(" Bossa Nova in A minor")
print(" bossa nova drums | FM rhodes + reverb | triangle lead + delay")
print(" sine bass + LP 600Hz")
score = Score("4/4", bpm=140)
score.drums("bossa nova", repeats=4)
rhodes = score.part("rhodes", instrument="electric_piano",
volume=0.3, pan=-0.3,
reverb=0.4, reverb_decay=1.8, reverb_type="plate")
lead = score.part("lead", instrument="flute",
volume=0.45, pan=0.3,
delay=0.25, delay_time=0.32, delay_feedback=0.35,
reverb=0.2, reverb_type="plate")
bass = score.part("bass", instrument="upright_bass",
volume=0.45, pan=0.0, lowpass=600)
for sym in ["Am", "Am", "Dm", "Dm", "E7", "E7", "Am", "Am"]:
rhodes.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("E5",.67),("D5",.33),("C5",.67),("B4",.33),("A4",1),("C5",.67),("E5",.33),
("D5",.67),("C5",.33),("A4",1),(None,1),
("F5",.67),("E5",.33),("D5",.67),("C5",.33),("D5",1),("F5",.67),("A5",.33),
("G5",.67),("F5",.33),("D5",1),(None,1),
("G#5",.67),("F5",.33),("E5",.67),("D5",.33),("E5",1),(None,.5),("B4",.5),
("D5",.67),("E5",.33),("G#4",1),(None,1),
("A4",1),("C5",.67),("E5",.33),("A5",1.5),(None,.5),
("G5",.67),("E5",.33),("C5",.67),("A4",.33),("A4",2),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["A2","E2","A2","C3","D2","A2","D2","F2",
"E2","B2","E2","G#2","A2","E2","A2","C3",
"A2","E2","A2","C3","D2","A2","D2","F2",
"E2","B2","E2","G#2","A2","E2","A2","A2"]:
bass.add(n, Duration.QUARTER)
play_song(score)
def bebop_in_bb():
"""Bebop in Bb — horn lead over rhythm changes with walking bass."""
print(" Bebop in Bb major")
print(" bebop drums + fill | saw lead + LP 4kHz | FM rhodes + reverb")
score = Score("4/4", bpm=160)
score.drums("bebop", repeats=8, fill="jazz", fill_every=8)
rhodes = score.part("rhodes", instrument="electric_piano",
volume=0.25, pan=-0.3,
reverb=0.35, reverb_decay=1.2, reverb_type="plate")
lead = score.part("lead", instrument="trumpet",
volume=0.4, pan=0.25,
lowpass=4000, lowpass_q=1.1,
delay=0.15, delay_time=0.19, delay_feedback=0.25,
reverb=0.15, reverb_type="plate")
bass = score.part("bass", instrument="upright_bass",
volume=0.4, pan=0.0, lowpass=500)
for sym in ["Bb", "Gm", "Cm", "F7"] * 2:
rhodes.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("Bb4",.67),("D5",.33),("F5",.67),("D5",.33),
("Bb4",.67),("C5",.33),("D5",.67),("F5",.33),
("G5",.67),("F5",.33),("D5",.67),("Bb4",.33),
("A4",.67),("Bb4",.33),("D5",.67),("G4",.33),
("C5",.67),("Eb5",.33),("G5",.67),("Eb5",.33),
("C5",.67),("D5",.33),("Eb5",.67),("F5",.33),
("A5",.67),("G5",.33),("F5",.67),("Eb5",.33),
("D5",.67),("C5",.33),("A4",.5),(None,.5),
("Bb4",1),("D5",.67),("F5",.33),
("G5",.67),("F5",.33),("D5",.67),("Bb4",.33),
("Bb5",.67),("A5",.33),("G5",.67),("F5",.33),
("Eb5",.67),("D5",.33),("Bb4",.67),("G4",.33),
("C5",.5),(None,.5),("Eb5",.67),("G5",.33),
("F5",.67),("Eb5",.33),("D5",.67),("C5",.33),
("A4",.67),("C5",.33),("Eb5",.67),("F5",.33),
("G5",.67),("A5",.33),("Bb5",1),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["Bb2","D3","F3","A3","G3","F3","D3","Bb2",
"C3","Eb3","G3","Bb3","F3","A3","C4","Eb3",
"Bb2","D3","F3","A3","G3","F3","D3","Bb2",
"C3","Eb3","G3","Bb3","F3","C3","F2","F3"]:
bass.add(n, Duration.QUARTER)
play_song(score)
def salsa_descarga():
"""Salsa descarga in D minor — clave-driven with timbale lead."""
print(" Salsa Descarga in D minor")
print(" salsa drums + fill | saw lead + delay | pulse bass + LP 500Hz")
score = Score("4/4", bpm=180)
score.drums("salsa", repeats=8, fill="salsa", fill_every=4)
pads = score.part("pads", synth="pwm_slow", envelope="pad",
volume=0.2, pan=-0.35,
reverb=0.3, reverb_type="plate", lowpass=2000,
detune=10, humanize=0.2)
lead = score.part("lead", instrument="trumpet",
volume=0.4, pan=0.3,
delay=0.2, delay_time=0.167, delay_feedback=0.3,
reverb=0.15, reverb_type="plate")
bass = score.part("bass", instrument="synth_bass",
volume=0.45, pan=0.0, lowpass=500, lowpass_q=1.3)
for sym in ["Em7b5", "A7", "Dm7", "Bbmaj7"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("E5",.67),("G5",.33),("Bb5",.67),("A5",.33),
("G5",.67),("F5",.33),("E5",.67),("D5",.33),
("C#5",.67),("D5",.33),("E5",.67),("G5",.33),
("F5",.67),("E5",.33),("C#5",.5),(None,.5),
("D5",.5),(None,.17),("F5",.67),("A5",.33),
("G5",.67),("F5",.33),("E5",.67),("D5",.33),
("Bb4",1),("D5",.67),("F5",.33),("A5",1),(None,1),
("E5",.5),("F5",.5),("G5",.67),("A5",.33),
("Bb5",.67),("A5",.33),("G5",.67),("E5",.33),
("C#5",.67),("E5",.33),("A5",.67),("G5",.33),
("F5",.67),("E5",.33),("C#5",.67),("A4",.33),
("D5",1),("F5",.67),("A5",.33),("G5",.67),("F5",.33),("D5",1),(None,1),
("Bb4",.67),("D5",.33),("F5",.67),("Bb5",.33),("A5",1.5),(None,.5),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["E2","E3","A2","A3","D2","D3","Bb2","Bb3"] * 4:
bass.add(n, Duration.QUARTER)
play_song(score)
def afrobeat_groove():
"""Afrobeat in E minor — Fela-inspired hypnotic groove."""
print(" Afrobeat in E minor")
print(" afrobeat drums + fill | saw lead + LP 3kHz | supersaw pads + reverb")
score = Score("4/4", bpm=115)
score.drums("afrobeat", repeats=8, fill="afrobeat", fill_every=8)
pads = score.part("pads", instrument="synth_pad",
volume=0.2, pan=-0.3,
reverb=0.4, reverb_decay=2.0, reverb_type="cathedral",
lowpass=3000)
lead = score.part("lead", instrument="trumpet",
volume=0.4, pan=0.3,
lowpass=3000, lowpass_q=1.0,
delay=0.2, delay_time=0.26, delay_feedback=0.3,
reverb=0.15, reverb_type="plate")
bass = score.part("bass", instrument="bass_guitar",
volume=0.5, pan=0.0, lowpass=500)
for sym in ["Em", "Am", "D", "C"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
riff = [("E5",.5),("G5",.5),("A5",.5),("G5",.5),
("E5",.5),("D5",.5),("E5",1),
("E5",.5),("G5",.5),("A5",.5),("B5",.5),
("A5",.5),("G5",.5),("E5",1),
(None,.5),("A5",.5),("G5",.5),("E5",.5),
("D5",1),("E5",.5),("G5",.5),
("A5",.5),("B5",.5),("A5",.5),("G5",.5),
("E5",1.5),(None,.5)]
for n, d in riff * 2:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["E2","E2","G2","A2","A2","G2","E2","D2",
"D2","D2","F#2","A2","C3","C3","B2","G2"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def reggae_one_drop():
"""Reggae one-drop in G major — roots vibes with dub effects."""
print(" Reggae One-Drop in G major")
print(" reggae drums + fill | triangle lead + delay + reverb")
print(" square chords + reverb | sine bass + LP 400Hz")
score = Score("4/4", bpm=80)
score.drums("reggae", repeats=8, fill="reggae", fill_every=8)
chords = score.part("chords", synth="square", envelope="staccato",
volume=0.2, pan=-0.4,
reverb=0.5, reverb_decay=2.0, reverb_type="cathedral",
lowpass=2000, detune=8,
humanize=0.2)
lead = score.part("lead", instrument="flute",
volume=0.4, pan=0.3,
delay=0.35, delay_time=0.5625, delay_feedback=0.45,
reverb=0.3, reverb_type="cathedral")
bass = score.part("bass", instrument="bass_guitar",
volume=0.55, pan=0.0, lowpass=400, lowpass_q=1.3)
for sym in ["G", "C", "D", "C"] * 2:
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("G5",1.5),(None,.5),("B5",1),("A5",1),
("G5",2),("E5",1),("D5",1),
("C5",1.5),(None,.5),("E5",1),("G5",1),
("A5",1.5),(None,.5),("G5",2),
("D5",1.5),(None,.5),("E5",1),("G5",1),
("A5",2),("B5",1),("A5",1),
("G5",1.5),(None,.5),("E5",1),("D5",1),
("G4",3),(None,1),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["G2","G2","B2","D3","C3","C3","E3","G3",
"D3","D3","F#3","A3","C3","C3","E3","G3",
"G2","G2","B2","D3","C3","C3","E3","G3",
"D3","D3","F#3","A3","C3","G2","C3","D3"]:
bass.add(n, Duration.QUARTER)
play_song(score)
def funk_workout():
"""Funk in E minor — syncopated 16ths with filtered everything."""
print(" Funk Workout in E minor")
print(" funk drums + fill | saw lead + LP 3.5kHz Q=1.5 | pulse bass")
score = Score("4/4", bpm=100)
score.drums("funk", repeats=8, fill="funk", fill_every=4)
chords = score.part("chords", synth="square", envelope="staccato",
volume=0.25, pan=-0.4,
lowpass=2500, reverb=0.15, reverb_type="plate",
sidechain=0.4, humanize=0.2)
lead = score.part("lead", instrument="synth_lead",
volume=0.4, pan=0.35,
lowpass=3500, lowpass_q=1.5,
delay=0.15, delay_time=0.15, delay_feedback=0.25,
reverb=0.1, reverb_type="plate")
bass = score.part("bass", instrument="synth_bass",
volume=0.5, pan=0.0, lowpass=600, lowpass_q=1.2)
for sym in ["Em", "Am", "D", "B7"] * 2:
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("E5",.25),("E5",.25),(None,.25),("G5",.25),
(None,.25),("A5",.25),("G5",.25),("E5",.25),
("D5",.5),("E5",.5),(None,.5),("B4",.5),
("E5",.25),("E5",.25),(None,.25),("G5",.25),
(None,.25),("A5",.25),("B5",.25),("A5",.25),
("G5",.5),("E5",.5),(None,1),
("A4",.25),("C5",.25),("E5",.25),("A5",.25),
("G5",.5),("E5",.5),(None,.5),("C5",.5),
("A4",.5),("C5",.5),("D5",.5),("E5",.5),
("E5",1),(None,1),
("D5",.25),("F#5",.25),("A5",.25),("D5",.25),
("F#5",.5),("D5",.5),("A4",.5),("D5",.5),
("D#5",.5),("F#5",.5),("B4",.5),("D#5",.5),
("F#5",1),(None,1),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["E2","E2","G2","E2","A2","A2","C3","A2",
"D2","D2","F#2","D2","B1","B1","D#2","F#2"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def blues_shuffle():
"""12/8 blues in A — slow shuffle with wailing lead."""
print(" 12/8 Blues Shuffle in A")
print(" 12/8 blues drums | saw lead + reverb + delay | sine bass + LP 500Hz")
score = Score("12/8", bpm=70)
score.drums("12/8 blues", repeats=6)
chords = score.part("chords", instrument="electric_piano",
volume=0.3, pan=-0.3,
reverb=0.3, reverb_decay=1.5, reverb_type="plate")
lead = score.part("lead", instrument="trumpet",
volume=0.45, pan=0.25,
reverb=0.3, reverb_decay=1.2, reverb_type="plate",
delay=0.2, delay_time=0.43, delay_feedback=0.3,
lowpass=3500)
bass = score.part("bass", instrument="upright_bass",
volume=0.5, pan=0.0, lowpass=500)
for sym in ["A", "A", "D", "D", "E7", "A"]:
chords.add(Chord.from_symbol(sym), Duration.DOTTED_HALF)
chords.add(Chord.from_symbol(sym), Duration.DOTTED_HALF)
for n, d in [
("A4",1),("C5",.67),("A4",.33),("E4",1),
(None,.5),("A4",.5),("C5",.67),("D5",.33),
("E5",1.5),("D5",.5),("C5",.5),("A4",.5),
("E4",1.5),(None,.5),("A4",1),
("D5",1),("F5",.67),("D5",.33),("A4",1),
(None,1),("D5",.67),("F5",.33),("A5",1),
("G5",.67),("F5",.33),("D5",1),(None,1),
("E5",.67),("G#4",.33),("B4",.67),("E5",.33),
("D5",1),("A4",1),(None,1),
("A4",.67),("C5",.33),("E5",.67),("A5",.33),
("A5",2),(None,1),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["A1","A1","E2","A2","A1","A1","E2","A2","A1","A1","E2","A2",
"D2","D2","A2","D2","D2","D2","A2","D2",
"E2","E2","B2","E2","A1","A1","E2","A2",
"E2","E2","B2","E2","A1","A1","E2","A2"]:
bass.add(n, Duration.QUARTER)
play_song(score)
def samba_de_janeiro():
"""Samba in G major — carnival energy with shimmering pads."""
print(" Samba in G major")
print(" samba drums + fill | triangle lead + delay | supersaw pads + reverb")
score = Score("4/4", bpm=170)
score.drums("samba", repeats=8, fill="samba", fill_every=8)
pads = score.part("pads", instrument="synth_pad",
volume=0.2, pan=-0.3,
reverb=0.45, reverb_decay=2.0, reverb_type="plate",
lowpass=4000)
lead = score.part("lead", instrument="flute",
volume=0.45, pan=0.3,
delay=0.2, delay_time=0.176, delay_feedback=0.3,
reverb=0.15, reverb_type="plate")
bass = score.part("bass", instrument="bass_guitar",
volume=0.45, pan=0.0, lowpass=500)
for sym in ["G", "Em", "Am", "D7"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("B5",.33),("A5",.33),("G5",.34),("F#5",.5),("E5",.5),
("D5",.5),("G5",.5),("B5",.5),("A5",.5),
("G5",.67),("E5",.33),("D5",.67),("B4",.33),("G4",1),(None,1),
("E5",.5),("G5",.5),("B5",.5),("A5",.5),
("G5",.67),("F#5",.33),("E5",.67),("D5",.33),("E5",1),(None,1),
("A5",.5),("C6",.5),("B5",.5),("A5",.5),
("G5",.67),("E5",.33),("C5",.67),("A4",.33),("A4",1),(None,1),
("D5",.5),("F#5",.5),("A5",.5),("C5",.5),
("B4",.67),("A4",.33),("G4",.67),("F#4",.33),("G4",2),(None,2),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["G2","B2","D3","G2","E2","G2","B2","E2",
"A2","C3","E3","A2","D2","F#2","A2","D3"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def jazz_waltz():
"""Jazz waltz in F major — 3/4 with brushes and space."""
print(" Jazz Waltz in F major")
print(" waltz drums | triangle lead + reverb + delay | FM rhodes")
score = Score("3/4", bpm=150)
score.drums("waltz", repeats=16)
rhodes = score.part("rhodes", instrument="electric_piano",
volume=0.3, pan=-0.3,
reverb=0.4, reverb_decay=2.0, reverb_type="cathedral")
lead = score.part("lead", instrument="flute",
volume=0.4, pan=0.25,
reverb=0.3, reverb_decay=1.5, reverb_type="plate",
delay=0.2, delay_time=0.4, delay_feedback=0.3)
bass = score.part("bass", instrument="upright_bass",
volume=0.4, pan=0.0, lowpass=500)
for _ in range(2):
for sym in ["Fmaj7", "Gm", "C7", "Fmaj7"]:
for _ in range(4):
rhodes.add(Chord.from_symbol(sym), Duration.DOTTED_HALF)
for n, d in [
("A5",1.5),("G5",.5),("F5",1),("E5",1),("C5",1),("F5",1),
("A5",2),(None,1),("G5",2),(None,1),
("Bb5",1),("A5",.5),("G5",.5),("F5",1),("D5",1),("G5",1),
("Bb5",2),(None,1),("A5",1.5),("G5",.5),("F5",1),
("E5",1),("G5",1),("Bb5",1),("A5",1.5),("G5",.5),("E5",1),
("C5",2),(None,1),("E5",1),("G5",1),("C5",1),
("F5",2),("A5",1),("C6",2),(None,1),
("A5",1),("F5",1),("C5",1),("F5",3),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["F2","A2","C3","G2","Bb2","D3","C2","E2","G2","F2","A2","C3"] * 4:
bass.add(n, Duration.QUARTER)
play_song(score)
def house_anthem():
"""House in C minor — four-on-the-floor with acid lead."""
print(" House Anthem in C minor")
print(" house drums + fill | saw acid lead + LP 2kHz Q=2 + delay")
print(" supersaw pads + reverb | sine bass")
score = Score("4/4", bpm=124)
score.drums("house", repeats=8, fill="house", fill_every=8)
pads = score.part("pads", instrument="synth_pad",
volume=0.25, pan=-0.3,
reverb=0.5, reverb_decay=2.5, reverb_type="cathedral",
lowpass=5000,
sidechain=0.6)
lead = score.part("lead", instrument="synth_lead",
volume=0.35, pan=0.3,
lowpass=2000, lowpass_q=2.0,
delay=0.2, delay_time=0.242, delay_feedback=0.35,
reverb=0.15, reverb_type="plate")
bass = score.part("bass", instrument="808_bass",
volume=0.55, pan=0.0,
sidechain=0.5)
for sym in ["Cm", "Ab", "Bb", "Cm"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("C5",.25),("Eb5",.25),("G5",.25),("C5",.25),
("Eb5",.25),("G5",.25),("C5",.25),("Eb5",.25),
("G5",.25),("Eb5",.25),("C5",.25),("G4",.25),
("C5",.5),(None,.5),("Eb5",.5),("G5",.5),
("Ab4",.25),("C5",.25),("Eb5",.25),("Ab4",.25),
("C5",.25),("Eb5",.25),("Ab4",.25),("C5",.25),
("Eb5",.25),("C5",.25),("Ab4",.25),("Eb4",.25),
("Ab4",.5),(None,.5),("C5",.5),("Eb5",.5),
("Bb4",.25),("D5",.25),("F5",.25),("Bb4",.25),
("D5",.25),("F5",.25),("Bb4",.25),("D5",.25),
("F5",.5),("D5",.5),("Bb4",.5),("F5",.5),
("C5",.25),("Eb5",.25),("G5",.25),("C6",.25),
("G5",.25),("Eb5",.25),("C5",.25),(None,.25),
("C5",1.5),(None,.5),
("G5",.25),("G5",.25),("Eb5",.25),("C5",.25),
("G5",.25),("G5",.25),("Eb5",.25),("C5",.25),
("Eb5",.5),("C5",.5),("G4",.5),("C5",.5),
("Eb5",1),(None,1),
("Ab4",.5),("C5",.5),("Eb5",.5),("Ab5",.5),
("G5",.5),("Eb5",.5),("C5",1),
("Bb4",.5),("D5",.5),("F5",.5),("Bb5",.5),
("F5",.5),("D5",.5),("Bb4",1),
("C5",.5),("Eb5",.5),("G5",.5),("C6",.5),("C6",2),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["C2","C2","C2","C2","Ab1","Ab1","Ab1","Ab1",
"Bb1","Bb1","Bb1","Bb1","C2","C2","C2","C2"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def dub_kingston():
"""Dub in A minor — deep, sparse, drenched in effects."""
print(" Kingston After Dark")
print(" dub drums | triangle melodica + delay + reverb")
print(" square skank + reverb + LP 1.5kHz | sine bass + LP 400Hz")
print(" PWM siren + reverb + LP 1.2kHz")
score = Score("4/4", bpm=72)
score.drums("dub", repeats=8)
chords = score.part("chords", synth="square", envelope="staccato",
volume=0.2, pan=-0.4,
reverb=0.6, reverb_decay=2.5, reverb_type="cathedral",
lowpass=1500, lowpass_q=0.9, detune=8,
humanize=0.2)
lead = score.part("lead", instrument="flute",
volume=0.4, pan=0.3,
delay=0.45, delay_time=0.625, delay_feedback=0.5,
reverb=0.35, reverb_decay=2.0, reverb_type="cathedral")
bass = score.part("bass", instrument="bass_guitar",
volume=0.6, pan=0.0, lowpass=400, lowpass_q=1.5)
siren = score.part("siren", synth="pwm_slow", envelope="pad",
volume=0.15, pan=0.5,
reverb=0.7, reverb_decay=3.0, reverb_type="cathedral",
lowpass=1200, detune=10)
for sym in ["Am", "Am", "Dm", "Dm", "Am", "Am", "Em", "Am"]:
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("A4", 2), (None, 2), ("C5", 1.5), (None, 2.5),
("D5", 1), ("C5", 1), ("A4", 2), (None, 4),
("E5", 2), (None, 2), ("D5", 1.5), ("C5", 1.5), (None, 3),
("A4", 1), ("G4", 1), ("A4", 3), (None, 3),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["A1","A1","A1","A1","D1","D1","D1","D1",
"A1","A1","A1","A1","E1","E1","A1","A1"]:
bass.add(n, Duration.HALF)
for n, d in [
(None, 8), ("A5", 4), (None, 4),
(None, 4), ("E5", 3), (None, 5),
("D5", 4), (None, 4),
]:
siren.rest(d) if n is None else siren.add(n, d)
play_song(score)
def techno_minimal():
"""Minimal techno in F minor — hypnotic and relentless."""
print(" Minimal Techno in F minor")
print(" techno drums | PWM fast lead + LP 1.5kHz Q=3 + delay")
print(" supersaw pad + reverb | sine sub bass")
score = Score("4/4", bpm=130)
score.drums("techno", repeats=8, fill="house", fill_every=8)
pad = score.part("pad", instrument="synth_pad",
volume=0.2, pan=-0.3,
reverb=0.5, reverb_decay=3.0, reverb_type="cathedral",
lowpass=3000,
sidechain=0.6)
lead = score.part("lead", synth="pwm_fast", envelope="staccato",
volume=0.35, pan=0.3,
lowpass=1500, lowpass_q=3.0,
delay=0.3, delay_time=0.231, delay_feedback=0.4,
reverb=0.1, reverb_type="plate",
humanize=0.2)
bass = score.part("bass", instrument="808_bass",
volume=0.55, pan=0.0,
sidechain=0.5)
for sym in ["Fm", "Db", "Eb", "Fm"] * 2:
pad.add(Chord.from_symbol(sym), Duration.WHOLE)
# Minimal arpeggiated sequence — hypnotic repetition
seq = [("F4",.25),("Ab4",.25),("C5",.25),("F4",.25),
("Ab4",.25),("C5",.25),("Eb5",.25),("C5",.25)]
for n, d in seq * 8:
lead.add(n, d)
for n in ["F1","F1","F1","F1","Db1","Db1","Db1","Db1",
"Eb1","Eb1","Eb1","Eb1","F1","F1","F1","F1"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def gospel_shuffle():
"""Gospel in C major — joyful shuffle with FM organ."""
print(" Gospel Shuffle in C major")
print(" gospel drums + fill | FM organ + reverb | triangle lead + delay")
score = Score("4/4", bpm=108)
score.drums("gospel", repeats=8, fill="buildup", fill_every=8)
organ = score.part("organ", instrument="organ",
volume=0.3, pan=-0.3,
reverb=0.45, reverb_decay=2.0, reverb_type="cathedral")
lead = score.part("lead", instrument="flute",
volume=0.4, pan=0.3,
delay=0.2, delay_time=0.278, delay_feedback=0.3,
reverb=0.2, reverb_type="plate")
bass = score.part("bass", instrument="upright_bass",
volume=0.45, pan=0.0, lowpass=500)
for sym in ["C", "Am", "F", "G"] * 2:
organ.add(Chord.from_symbol(sym), Duration.WHOLE)
for n, d in [
("E5",.67),("G5",.33),("C6",1),("B5",.67),("A5",.33),
("G5",1),(None,1),
("A5",.67),("C6",.33),("E5",1),("D5",.67),("C5",.33),
("A4",1),(None,1),
("F5",.67),("A5",.33),("C6",1),("B5",.67),("A5",.33),
("G5",.67),("E5",.33),("C5",1),(None,1),
("D5",.67),("E5",.33),("G5",.67),("B5",.33),
("C6",2),(None,2),
# Second half: more intense
("C6",.67),("B5",.33),("A5",.67),("G5",.33),
("E5",1),("C5",.67),("E5",.33),
("A5",1),("G5",.67),("E5",.33),("C5",1),(None,1),
("F5",1),("A5",.67),("C6",.33),("E6",2),
("D6",.67),("C6",.33),("B5",.67),("G5",.33),
("C6",3),(None,1),
]:
lead.rest(d) if n is None else lead.add(n, d)
for n in ["C2","E2","G2","C3","A1","C2","E2","A2",
"F2","A2","C3","F2","G2","B2","D3","G2"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
def dub_delay_madness():
"""Dub with separate delay snare track — King Tubby style."""
print(" Dub Delay Madness in E minor")
print(" dub drums + separate snare w/ massive delay + reverb")
print(" square skank + reverb | sine sub bass | PWM siren")
score = Score("4/4", bpm=68)
score.drums("dub", repeats=8)
# Separate snare hits — fed through massive delay and reverb
# This is how Tubby did it: mute the snare from the main mix,
# then send it to a separate channel drowning in effects
from pytheory.rhythm import _Hit, DrumSound
for bar in range(8):
offset = bar * 4.0
# Snare on beat 3 of every bar
score._drum_hits.append(_Hit(DrumSound.SNARE, offset + 2.0, 110))
# Occasional rimshot ghost that the delay catches
if bar % 2 == 1:
score._drum_hits.append(_Hit(DrumSound.RIMSHOT, offset + 3.5, 60))
chords = score.part("skank", synth="square", envelope="staccato",
volume=0.15, pan=-0.4,
reverb=0.7, reverb_decay=3.0, reverb_type="cathedral",
lowpass=1200, detune=8, humanize=0.2)
bass = score.part("bass", instrument="bass_guitar",
volume=0.6, pan=0.0, lowpass=350, lowpass_q=1.5)
siren = score.part("siren", synth="pwm_slow", envelope="pad",
volume=0.12, pan=0.5,
reverb=0.8, reverb_decay=4.0, reverb_type="cathedral",
delay=0.4, delay_time=0.88, delay_feedback=0.6,
lowpass=900, detune=10)
# Melodica stabs — sparse, lots of delay
melodica = score.part("melodica", instrument="flute",
volume=0.35, pan=0.3,
delay=0.6, delay_time=0.66, delay_feedback=0.55,
reverb=0.5, reverb_decay=2.5, reverb_type="cathedral")
for sym in ["Em", "Em", "Am", "Am", "Em", "Em", "Bm", "Em"]:
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
for n in ["E1","E1","E1","E1","A1","A1","A1","A1",
"E1","E1","E1","E1","B1","B1","E1","E1"]:
bass.add(n, Duration.HALF)
# Melodica: very sparse — let the delay do the work
for n, d in [
("E5", 1.5), (None, 6.5),
("G5", 1), ("A5", 1), (None, 6),
(None, 4), ("B5", 2), (None, 6),
("E5", 1), (None, 3), ("D5", 1.5), (None, 2.5),
]:
melodica.rest(d) if n is None else melodica.add(n, d)
# Siren: long notes that disappear into the void
for n, d in [
(None, 12), ("B5", 6), (None, 6),
("E5", 4), (None, 4),
]:
siren.rest(d) if n is None else siren.add(n, d)
play_song(score)
def drum_and_bass():
"""Drum and bass in A minor — 174 bpm liquid rollers."""
print(" Liquid DnB in A minor")
print(" drum and bass drums + fill | supersaw pads + reverb")
print(" triangle lead + delay | sine sub bass + LP 300Hz")
score = Score("4/4", bpm=174)
score.drums("drum and bass", repeats=8, fill="buildup", fill_every=8)
pads = score.part("pads", instrument="synth_pad",
volume=0.25, pan=-0.3,
reverb=0.5, reverb_decay=2.5, reverb_type="plate",
lowpass=4000)
lead = score.part("lead", instrument="flute",
volume=0.4, pan=0.3,
delay=0.3, delay_time=0.172, delay_feedback=0.4,
reverb=0.25, reverb_type="plate")
bass = score.part("bass", instrument="808_bass",
volume=0.55, pan=0.0)
for sym in ["Am", "F", "C", "G"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
# Liquid melody — flowing, emotional
for n, d in [
("A5", 1), ("G5", .5), ("E5", .5), ("C5", 1), (None, 1),
("D5", .5), ("E5", .5), ("G5", 1), ("A5", 1.5), (None, .5),
("C6", 1), ("B5", .5), ("A5", .5), ("G5", 1), ("E5", 1),
("F5", .5), ("G5", .5), ("A5", 1.5), (None, .5), ("G5", 1),
("A5", 1), ("G5", .5), ("E5", .5), ("C5", 1), (None, 1),
("E5", .5), ("G5", .5), ("B5", 1), ("A5", 2),
("G5", 1), ("E5", .5), ("D5", .5), ("C5", 1.5), (None, .5),
("E5", .5), ("G5", .5), ("A5", 2), (None, 1),
]:
lead.rest(d) if n is None else lead.add(n, d)
# Sub bass — half note roots, deep
for n in ["A1","A1","F1","F1","C1","C1","G1","G1"] * 2:
bass.add(n, Duration.HALF)
play_song(score)
def drake_vibes():
"""Drake-style moody hip hop — 808s, pads, and melancholy."""
print(" Late Night Texts (Drake-style)")
print(" trap drums | FM bells + reverb + delay | supersaw pads + LP")
print(" sine 808 bass + distortion | PWM slow lead")
score = Score("4/4", bpm=68)
score.drums("trap", repeats=8, fill="trap", fill_every=8)
pads = score.part("pads", instrument="synth_pad",
volume=0.2, pan=-0.25,
reverb=0.5, reverb_decay=3.0, reverb_type="cathedral",
lowpass=2500,
sidechain=0.4)
bells = score.part("bells", instrument="vibraphone",
volume=0.3, pan=0.4,
reverb=0.4, reverb_decay=2.0, reverb_type="plate",
delay=0.25, delay_time=0.44, delay_feedback=0.35)
lead = score.part("lead", synth="pwm_slow", envelope="strings",
volume=0.35, pan=-0.2,
reverb=0.3, reverb_type="cathedral", lowpass=2000,
delay=0.2, delay_time=0.88, delay_feedback=0.3,
humanize=0.2)
bass = score.part("bass", instrument="808_bass",
volume=0.6, pan=0.0,
distortion=0.4, distortion_drive=2.0,
sidechain=0.3)
for sym in ["Ebm", "B", "Gb", "Db"] * 2:
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
# FM bells — sparse, melancholy arpeggios
for n, d in [
("Eb5", .5), ("Gb5", .5), ("Bb5", 1), (None, 2),
("Db5", .5), ("F5", .5), ("Ab5", 1), (None, 2),
("Gb5", .5), ("Bb5", .5), ("Db6", 1), (None, 2),
("F5", .5), ("Ab5", .5), ("Db6", 1.5), (None, 1.5),
("Eb5", .5), ("Gb5", .5), ("Bb5", 1), (None, 2),
("B4", .5), ("Eb5", .5), ("Gb5", 1), (None, 2),
("Gb5", 1), ("F5", .5), ("Eb5", .5), ("Db5", 2),
(None, 4),
]:
bells.rest(d) if n is None else bells.add(n, d)
# PWM lead — long held notes, moody
for n, d in [
(None, 4), ("Bb5", 3), (None, 1),
(None, 2), ("Ab5", 2), ("Gb5", 2), (None, 2),
("Db6", 4), (None, 4),
("Bb5", 2), ("Ab5", 2), (None, 4),
]:
lead.rest(d) if n is None else lead.add(n, d)
# 808 bass — sustained with distortion warmth
for n in ["Eb1","Eb1","Eb1","Eb1","B0","B0","B0","B0",
"Gb1","Gb1","Gb1","Gb1","Db1","Db1","Db1","Db1"] * 2:
bass.add(n, Duration.QUARTER)
play_song(score)
# ── Main ───────────────────────────────────────────────────────────────────
def neon_grid():
"""Cyberpunk electronic — stereo acid, wide pads, ping-pong bells."""
print(" Neon Grid in F minor")
print(" techno drums | dual acid L/R + LFO | supersaw pad spread=1.0")
print(" FM stabs | ping-pong bells | sine sub + sidechain")
score = Score("4/4", bpm=132)
score.drums("techno", repeats=8, fill="house", fill_every=8)
from pytheory.rhythm import _Hit, DrumSound
for bar in range(8):
for beat in range(4):
score._drum_hits.append(_Hit(DrumSound.KICK, bar * 4.0 + beat, 120))
score._drum_pattern_beats = max(score._drum_pattern_beats, 32.0)
sky = score.part(
"sky", instrument="synth_pad",
volume=0.18, pan=0.0,
detune=30, spread=1.0,
reverb=0.6, reverb_decay=3.5,
chorus=0.3, sidechain=0.5,
)
acid_l = score.part(
"acid_l", instrument="acid_bass",
volume=0.35, pan=-0.7,
legato=True, glide=0.025,
distortion=0.9, distortion_drive=12.0,
lowpass=800, lowpass_q=6.0,
delay=0.2, delay_time=0.227, delay_feedback=0.35,
)
acid_l.lfo("lowpass", rate=0.5, min=400, max=3000, bars=8, shape="sine")
acid_r = score.part(
"acid_r", instrument="acid_bass",
volume=0.3, pan=0.7,
legato=True, glide=0.02,
distortion=0.85, distortion_drive=10.0,
lowpass=1000, lowpass_q=5.0,
delay=0.25, delay_time=0.341, delay_feedback=0.4,
)
acid_r.lfo("lowpass", rate=0.33, min=500, max=2500, bars=8, shape="triangle")
sub = score.part(
"sub", instrument="808_bass",
volume=0.55, pan=0.0,
lowpass=160, sidechain=0.85, sidechain_release=0.08,
)
stab = score.part(
"stab", synth="fm", envelope="staccato",
volume=0.2, pan=-0.4,
reverb=0.4, reverb_decay=1.5,
detune=15, spread=0.7,
)
bell_l = score.part(
"bell_l", instrument="vibraphone",
volume=0.1, pan=-1.0,
reverb=0.7, reverb_decay=3.0,
)
bell_r = score.part(
"bell_r", instrument="vibraphone",
volume=0.1, pan=1.0,
reverb=0.7, reverb_decay=3.0,
delay=0.2, delay_time=0.8, delay_feedback=0.4,
)
chords = ["Fm", "Dbm", "Abm", "Ebm"]
for sym in chords * 2:
sky.add(Chord.from_symbol(sym), Duration.WHOLE)
for sym in chords:
acid_l.arpeggio(Chord.from_symbol(sym, octave=2), bars=2,
pattern="up", octaves=2, division=Duration.SIXTEENTH)
for sym in chords:
acid_r.arpeggio(Chord.from_symbol(sym, octave=2), bars=2,
pattern="down", octaves=2, division=Duration.SIXTEENTH)
for n in ["F1"] * 8 + ["Db1"] * 8 + ["Ab1"] * 8 + ["Eb1"] * 8:
sub.add(n, Duration.QUARTER)
for sym in chords * 2:
stab.rest(1)
stab.add(Chord.from_symbol(sym), 0.5)
stab.rest(0.5)
stab.add(Chord.from_symbol(sym), 0.5)
stab.rest(1.5)
for n, v, d in [
("F6", 50, 2), (None, 0, 6), ("Ab6", 45, 2), (None, 0, 6),
("Eb7", 55, 3), (None, 0, 13),
]:
bell_l.rest(d) if n is None else bell_l.add(n, d, velocity=v)
for n, v, d in [
(None, 0, 4), ("Db7", 45, 2), (None, 0, 6),
("F7", 50, 2), (None, 0, 6),
(None, 0, 4), ("Ab6", 40, 4), (None, 0, 8),
]:
bell_r.rest(d) if n is None else bell_r.add(n, d, velocity=v)
play_song(score)
def glass_and_silk():
"""Pure sine and triangle — smooth shapes in a stereo cathedral."""
print(" Glass and Silk in Ab major")
print(" sine + triangle only | waltz 72bpm | cathedral + Taj Mahal reverb")
score = Score("3/4", bpm=72, swing=0.2)
score.drums("waltz", repeats=16)
sub = score.part("sub", synth="sine", envelope="pad",
volume=0.3, pan=0.0, lowpass=120)
voice = score.part("voice", synth="triangle", envelope="strings",
volume=0.45, pan=0.2, legato=True, glide=0.07,
reverb=0.5, reverb_type="cathedral",
delay=0.2, delay_time=0.56, delay_feedback=0.4,
humanize=0.3)
pad = score.part("pad", synth="sine", envelope="pad",
volume=0.2, pan=0.0, detune=10, spread=0.6,
reverb=0.6, reverb_type="taj_mahal",
chorus=0.2, chorus_rate=0.3)
counter = score.part("counter", synth="triangle", envelope="strings",
volume=0.2, pan=-0.5,
reverb=0.4, reverb_type="plate",
delay=0.15, delay_time=0.83, delay_feedback=0.35,
humanize=0.25)
chords = [Chord.from_symbol(s) for s in ["Ab", "Fm", "Db", "Eb"]]
for c in chords * 2:
for _ in range(3):
pad.add(c, Duration.DOTTED_HALF)
for n in (["Ab2"] * 9 + ["F2"] * 9 + ["Db2"] * 9 + ["Eb2"] * 9) * 2:
sub.add(n, Duration.QUARTER)
for n, v, d in [
("Ab4", 60, 3), ("C5", 70, 1.5), ("Eb5", 75, 1.5),
("Ab5", 85, 4.5), (None, 0, 1.5),
("F5", 75, 1.5), ("Ab5", 80, 1.5), ("C6", 90, 3),
("Bb5", 80, 1.5), ("Ab5", 70, 1.5), (None, 0, 3),
("Db5", 70, 1.5), ("Eb5", 80, 1.5), ("Ab5", 95, 3),
("Bb5", 100, 3), ("C6", 105, 4.5), (None, 0, 1.5),
("Bb5", 85, 1.5), ("Ab5", 75, 1.5), ("Eb5", 70, 3),
("C5", 60, 3), ("Ab4", 55, 6), (None, 0, 3),
("Eb5", 65, 3), ("Ab5", 80, 3), ("C6", 90, 4.5), (None, 0, 1.5),
("Bb5", 85, 1.5), ("Ab5", 75, 1.5), ("F5", 70, 3),
("Eb5", 65, 1.5), ("Db5", 60, 1.5), (None, 0, 3),
("Eb5", 70, 1.5), ("F5", 80, 1.5), ("Ab5", 90, 3),
("Bb5", 95, 3), ("Ab5", 85, 3),
("Eb5", 70, 3), ("Ab4", 55, 9),
]:
voice.rest(d) if n is None else voice.add(n, d, velocity=v)
for _ in range(24):
counter.rest(Duration.QUARTER)
for n, v, d in [
(None, 0, 3), ("C6", 55, 3), ("Eb6", 60, 4.5), (None, 0, 1.5),
("Db6", 50, 3), ("C6", 45, 3), (None, 0, 6),
("Eb6", 55, 4.5), ("Db6", 50, 1.5), ("C6", 45, 3),
("Ab5", 40, 6), (None, 0, 3),
("Bb5", 50, 3), ("C6", 55, 4.5), (None, 0, 1.5),
("Ab5", 45, 9),
]:
counter.rest(d) if n is None else counter.add(n, d, velocity=v)
play_song(score)
def dance_party():
"""Dance party — bouncy, joyful, impossible not to move."""
print(" Dance Party at the Reitz House")
print(" disco 128bpm | FM sparkle | square chiptune arps | supersaw pump")
from pytheory.rhythm import _Hit, DrumSound
score = Score("4/4", bpm=128)
score.drums("disco", repeats=8, fill="buildup", fill_every=8)
for bar in range(8):
for beat in range(4):
score._drum_hits.append(_Hit(DrumSound.KICK, bar * 4.0 + beat, 120))
score._drum_pattern_beats = max(score._drum_pattern_beats, 32.0)
bass = score.part("bass", instrument="synth_bass",
volume=0.45, lowpass=500, lowpass_q=1.3,
sidechain=0.75, sidechain_release=0.12)
sparkle = score.part("sparkle", instrument="vibraphone",
volume=0.3, pan=0.4, reverb=0.3, reverb_decay=1.5,
delay=0.2, delay_time=0.234, delay_feedback=0.3)
chords_part = score.part("chords", instrument="synth_pad",
volume=0.2,
reverb=0.4, reverb_type="plate", sidechain=0.7)
fun = score.part("fun", synth="square", envelope="staccato",
volume=0.2, pan=-0.5, delay=0.15, delay_time=0.117,
delay_feedback=0.25, reverb=0.2)
for sym in ["C", "Am", "F", "G"] * 2:
chords_part.add(Chord.from_symbol(sym), Duration.WHOLE)
for n in ["C2", "C2", "C3", "C2", "A1", "A1", "A2", "A1",
"F1", "F1", "F2", "F1", "G1", "G1", "G2", "G1"] * 2:
bass.add(n, Duration.QUARTER)
for n, v, d in [
("E5", 100, 0.5), ("G5", 110, 0.5), ("C6", 120, 1), (None, 0, 0.5),
("B5", 100, 0.5), ("G5", 90, 0.5), ("E5", 100, 0.5),
("C5", 90, 0.5), ("E5", 100, 0.5), ("G5", 110, 1), (None, 0, 0.5),
("A5", 100, 0.5),
("C6", 120, 0.5), ("A5", 100, 0.5), ("F5", 90, 0.5), ("A5", 100, 0.5),
("C6", 110, 1), (None, 0, 1),
("B5", 100, 0.5), ("D6", 120, 0.5), ("B5", 100, 0.5), ("G5", 90, 0.5),
("D5", 80, 0.5), ("G5", 100, 1), (None, 0, 0.5),
("E5", 100, 0.5), ("G5", 110, 0.5), ("C6", 120, 1),
("E6", 125, 1), (None, 0, 0.5),
("D6", 110, 0.5), ("C6", 100, 0.5), ("B5", 90, 0.5),
("A5", 100, 0.5), ("G5", 110, 0.5), ("E5", 90, 1), (None, 0, 0.5),
("F5", 100, 0.5), ("A5", 110, 0.5), ("C6", 120, 1), (None, 0, 0.5),
("B5", 100, 0.5), ("G5", 110, 0.5), ("D6", 120, 0.5),
("C6", 110, 1), ("G5", 90, 0.5), ("C6", 120, 1), (None, 0, 0.5),
]:
sparkle.rest(d) if n is None else sparkle.add(n, d, velocity=v)
for sym in ["C", "Am", "F", "G", "C", "Am", "F", "G"]:
pat = "up" if sym in ("C", "F") else "updown"
fun.arpeggio(sym, bars=1, pattern=pat, octaves=2, division=Duration.EIGHTH)
play_song(score)
def temple_bell():
"""Japanese-inspired — sparse koto, Taj Mahal reverb, silence as instrument."""
print(" Temple Bell")
print(" E hirajoshi | 65 bpm | triangle koto + Taj Mahal reverb")
score = Score("4/4", bpm=65)
score.drums("bolero", repeats=8)
koto = score.part("koto", instrument="koto",
volume=0.45, pan=0.2,
reverb=0.5, reverb_type="taj_mahal")
drone = score.part("drone", synth="sine", envelope="pad",
volume=0.15, reverb=0.6, reverb_type="taj_mahal",
chorus=0.15, chorus_rate=0.2)
bell = score.part("bell", instrument="vibraphone",
volume=0.1, pan=-0.6,
reverb=0.8, reverb_type="taj_mahal")
for _ in range(8):
drone.add("E2", Duration.WHOLE)
for n, v, d in [
("E4", 70, 2), (None, 0, 2), ("A4", 60, 1.5), (None, 0, 2.5),
("B4", 75, 2), ("A4", 60, 1), ("E4", 55, 1), (None, 0, 4),
("C5", 80, 3), (None, 0, 1), ("B4", 65, 1.5), ("A4", 55, 1.5),
("E4", 50, 3), (None, 0, 5),
("F4", 60, 1), ("A4", 70, 1.5), ("B4", 80, 2.5), (None, 0, 3),
("E5", 85, 4), (None, 0, 4),
("C5", 65, 1.5), ("B4", 55, 1.5), ("A4", 50, 2),
("E4", 45, 5), (None, 0, 3),
]:
koto.rest(d) if n is None else koto.add(n, d, velocity=v)
for n, v, d in [
(None, 0, 8), ("E6", 30, 4), (None, 0, 8),
("B6", 25, 3), (None, 0, 9),
("A6", 30, 4), (None, 0, 12),
]:
bell.rest(d) if n is None else bell.add(n, d, velocity=v)
play_song(score)
def cinematic_showcase():
"""Cinematic orchestral showcase — tubular bells, strings, organ, harp, acid bass."""
score = Score("4/4", bpm=100)
# Tubular bells — dramatic intro
bells = score.part("bells", instrument="tubular_bells",
reverb=0.5, reverb_type="cathedral")
bells.add("A3", Duration.WHOLE)
for _ in range(7):
bells.rest(Duration.WHOLE)
# String ensemble — lush wide pad
strings = score.part("strings", instrument="string_ensemble",
reverb=0.4, reverb_type="hall")
strings.rest(Duration.WHOLE)
for sym in ["Am", "F", "C", "G", "Dm", "Am", "E"]:
strings.add(Chord.from_symbol(sym), Duration.WHOLE)
# Cello — deep foundation
cello = score.part("cello", instrument="cello",
reverb=0.3, reverb_type="hall")
cello.rest(Duration.WHOLE)
for n in ["A2", "F2", "C3", "G2", "D3", "A2", "E2"]:
cello.add(n, Duration.WHOLE)
# Violin — legato melody enters bar 3
violin = score.part("violin", instrument="violin",
reverb=0.25, reverb_type="hall", legato=True)
violin.rest(Duration.WHOLE)
violin.rest(Duration.WHOLE)
for note, dur in [
("E5", Duration.HALF), ("C5", Duration.HALF),
("D5", Duration.QUARTER), ("E5", Duration.QUARTER), ("G5", Duration.HALF),
("A5", Duration.HALF), ("G5", Duration.QUARTER), ("E5", Duration.QUARTER),
("F5", Duration.WHOLE),
("E5", Duration.HALF), ("D5", Duration.HALF),
("C5", Duration.HALF), ("B4", Duration.HALF),
("A4", Duration.WHOLE),
]:
violin.add(note, dur)
# Organ — enters halfway, cathedral weight
organ = score.part("organ", instrument="organ",
reverb=0.3, reverb_type="cathedral")
for _ in range(4):
organ.rest(Duration.WHOLE)
for sym in ["Dm", "Am", "E", "Am"]:
organ.add(Chord.from_symbol(sym), Duration.WHOLE)
# Harp — arpeggiated flourishes bars 3-4
harp = score.part("harp", instrument="harp")
harp.rest(Duration.WHOLE)
harp.rest(Duration.WHOLE)
for n in ["A3", "C4", "E4", "A4", "C5", "E5", "A5", "E5",
"G3", "B3", "D4", "G4", "B4", "D5", "G5", "D5"]:
harp.add(n, Duration.EIGHTH)
for _ in range(4):
harp.rest(Duration.WHOLE)
# Vibraphone — shimmer in last bars with delay
vib = score.part("vib", instrument="vibraphone",
delay=0.25, delay_time=0.375, delay_feedback=0.35)
for _ in range(5):
vib.rest(Duration.WHOLE)
for note, dur in [
("E5", Duration.QUARTER), ("D5", Duration.QUARTER),
("C5", Duration.QUARTER), ("A4", Duration.QUARTER),
("B4", Duration.HALF), ("E5", Duration.HALF),
("A5", Duration.WHOLE),
]:
vib.add(note, dur)
# Acid bass — gritty texture bars 4-5
acid = score.part("acid", instrument="acid_bass")
for _ in range(3):
acid.rest(Duration.WHOLE)
for n in ["C2", "C2", "E2", "G2", "G2", "G2", "A2", "E2",
"D2", "D2", "F2", "A2", "A2", "A2", "E2", "E2"]:
acid.add(n, Duration.EIGHTH)
for _ in range(2):
acid.rest(Duration.WHOLE)
# Half time drums
score.drums("half time", repeats=8)
play_song(score, "Cinematic Showcase — A minor")
def greensleeves():
"""Greensleeves — Renaissance lute, meantone tuning, A=415 Hz."""
score = Score("3/4", bpm=120, temperament="meantone", reference_pitch=415.0)
lute = score.part("lute", instrument="acoustic_guitar",
reverb=0.3, reverb_type="taj_mahal")
melody = [
("A4", 1.0, 80),
("C5", 2.0, 85), ("D5", 1.0, 80),
("E5", 3.0, 90),
("F5", 1.0, 75), ("E5", 2.0, 85),
("D5", 1.0, 80),
("B4", 3.0, 85),
("G4", 1.0, 70), ("B4", 2.0, 80),
("C5", 1.0, 75),
("A4", 3.0, 85),
("A4", 1.0, 70), ("A4", 2.0, 75),
("G#4", 1.0, 70),
("A4", 2.0, 80), ("B4", 1.0, 75),
("G4", 3.0, 85),
("E4", 1.0, 70),
("A4", 3.0, 90),
]
for note, dur, vel in melody:
lute.add(note, dur, velocity=vel)
play_song(score, "Greensleeves — Renaissance Lute (Meantone, A=415)")
def tabla_solo_yaman():
"""Tabla solo with tanpura drone, sitar, and Raga Yaman — 22-shruti tuning."""
shruti = SYSTEMS["shruti"]
score = Score("4/4", bpm=160, system=shruti)
h = _Hit
NA = DrumSound.TABLA_NA
TI = DrumSound.TABLA_TIN
GE = DrumSound.TABLA_GE
DH = DrumSound.TABLA_DHA
TT = DrumSound.TABLA_TIT
KE = DrumSound.TABLA_KE
GB = DrumSound.TABLA_GE_BEND
# Tanpura drone — Sa + Pa
tanpura_sa = score.part("tanpura_sa", synth="strings_synth", envelope="pad",
detune=3, lowpass=1000, volume=0.18,
reverb=0.5, reverb_type="taj_mahal")
tanpura_pa = score.part("tanpura_pa", synth="strings_synth", envelope="pad",
detune=3, lowpass=1400, volume=0.14,
reverb=0.5, reverb_type="taj_mahal")
sa3 = Tone("Sa", octave=3, system=shruti)
pa3 = Tone("Pa", octave=3, system=shruti)
for _ in range(16):
tanpura_sa.add(sa3, Duration.WHOLE)
tanpura_pa.add(pa3, Duration.WHOLE)
# Quiet sitar — Raga Yaman (Kalyan thaat)
sitar = score.part("sitar", instrument="sitar", volume=0.12,
reverb=0.4, reverb_type="taj_mahal")
ts = TonedScale(system=shruti, tonic=Tone("Sa", octave=4, system=shruti))
y = list(ts["kalyan"].tones)
S, R, G, M, P, D, N, S2 = y
sitar.rest(Duration.WHOLE)
sitar.rest(Duration.WHOLE)
for tone, dur, vel in [
(S, 3.0, 55), (R, 1.0, 50), (G, 3.0, 58), (R, 1.0, 48),
(S, 4.0, 55), (G, 1.0, 50), (M, 1.0, 52), (P, 3.0, 58),
(M, 1.0, 48), (G, 1.0, 50), (R, 1.0, 48), (S, 4.0, 55),
(P, 2.0, 52), (D, 1.0, 55), (N, 2.0, 58), (S2, 3.0, 60),
(N, 1.0, 52), (D, 1.0, 50), (P, 1.0, 52), (G, 1.0, 48),
(R, 1.0, 48), (S, 4.0, 55),
]:
sitar.add(tone, dur, velocity=vel)
# 4 bars drone intro (silence for drums)
silence = Pattern(name="silence", time_signature="4/4", beats=16.0, hits=[])
score.add_pattern(silence, repeats=1)
# Gentle opening
p1 = Pattern(name="gentle", time_signature="4/4", beats=8.0, hits=[
h(DH, 0.0, 80), h(NA, 2.0, 60),
h(DH, 4.0, 85), h(NA, 5.0, 55), h(NA, 6.0, 60), h(DH, 7.0, 80),
])
# Building with ghost notes
p2 = Pattern(name="build", time_signature="4/4", beats=16.0, hits=[
h(DH, 0.0, 95), h(TT, 0.5, 35), h(NA, 1.0, 70), h(TT, 1.5, 30),
h(NA, 2.0, 65), h(DH, 3.0, 90),
h(DH, 4.0, 100), h(TT, 4.25, 35), h(TT, 4.5, 40), h(NA, 5.0, 75),
h(TT, 5.5, 35), h(NA, 6.0, 70), h(TT, 6.5, 30), h(DH, 7.0, 95),
h(DH, 8.0, 95), h(TI, 9.0, 70), h(TI, 10.0, 72), h(NA, 11.0, 80),
h(TT, 11.25, 40), h(TT, 11.5, 42), h(KE, 11.75, 45),
h(TT, 12.0, 50), h(TT, 12.25, 55), h(KE, 12.5, 58), h(NA, 12.75, 70),
h(DH, 13.0, 100), h(TT, 13.25, 40), h(TT, 13.5, 45), h(KE, 13.75, 50),
h(NA, 14.0, 75), h(KE, 14.25, 50), h(DH, 14.5, 85), h(NA, 14.75, 70),
h(DH, 15.0, 110), h(GB, 15.5, 100),
])
# Full intensity
p3 = Pattern(name="fire", time_signature="4/4", beats=16.0, hits=[
h(TT, 0.0, 50), h(TT, 0.125, 35), h(TT, 0.25, 45), h(KE, 0.5, 55),
h(NA, 0.75, 85),
h(DH, 1.0, 115), h(TT, 1.25, 38), h(DH, 1.5, 70), h(NA, 1.75, 60),
h(TT, 2.0, 50), h(TT, 2.125, 35), h(TT, 2.25, 48), h(KE, 2.5, 55),
h(NA, 2.75, 88),
h(DH, 3.0, 115), h(GB, 3.5, 105), h(NA, 3.75, 72),
h(NA, 4.0, 115), h(NA, 4.25, 60), h(TT, 4.5, 40), h(NA, 4.75, 105),
h(GE, 5.0, 105), h(GE, 5.25, 55), h(GB, 5.5, 95), h(GE, 5.75, 50),
h(NA, 6.0, 115), h(TT, 6.125, 30), h(TT, 6.25, 38), h(NA, 6.5, 100),
h(TT, 6.625, 32), h(TT, 6.75, 42),
h(GB, 7.0, 115), h(KE, 7.25, 52), h(GE, 7.5, 72), h(KE, 7.75, 48),
# Tihai
h(DH, 8.0, 115), h(NA, 8.25, 78), h(TT, 8.5, 52), h(KE, 8.75, 58),
h(DH, 9.0, 105),
h(DH, 9.5, 110), h(NA, 9.75, 78), h(TT, 10.0, 52), h(KE, 10.25, 58),
h(DH, 10.5, 105),
h(DH, 11.0, 120), h(NA, 11.25, 82), h(TT, 11.5, 58), h(KE, 11.75, 62),
h(DH, 12.0, 120),
# Silence... then finish
h(GB, 14.5, 120),
h(DH, 15.5, 127), h(DH, 15.75, 127),
])
score.add_pattern(p1, repeats=1)
score.add_pattern(p2, repeats=1)
score.add_pattern(p3, repeats=1)
score.set_drum_effects(reverb=0.4, reverb_type="taj_mahal")
play_song(score, "Tabla Solo — Raga Yaman (22-Shruti, Taj Mahal)")
SONGS = {
"1": ("Bossa Nova in A minor", bossa_nova_girl),
"2": ("Bebop in Bb major", bebop_in_bb),
"3": ("Salsa Descarga in D minor", salsa_descarga),
"4": ("Afrobeat in E minor", afrobeat_groove),
"5": ("Reggae One-Drop in G major", reggae_one_drop),
"6": ("Funk Workout in E minor", funk_workout),
"7": ("12/8 Blues Shuffle in A", blues_shuffle),
"8": ("Samba in G major", samba_de_janeiro),
"9": ("Jazz Waltz in F major", jazz_waltz),
"10": ("House Anthem in C minor", house_anthem),
"11": ("Kingston After Dark (Dub)", dub_kingston),
"12": ("Minimal Techno in F minor", techno_minimal),
"13": ("Gospel Shuffle in C major", gospel_shuffle),
"14": ("Dub Delay Madness in E minor", dub_delay_madness),
"15": ("Liquid DnB in A minor", drum_and_bass),
"16": ("Late Night Texts (Drake-style)", drake_vibes),
"17": ("Neon Grid (Stereo Acid)", neon_grid),
"18": ("Glass and Silk (Sine+Triangle)", glass_and_silk),
"19": ("Dance Party at the Reitz House", dance_party),
"20": ("Temple Bell (Japanese)", temple_bell),
"21": ("Cinematic Showcase (Orchestral)", cinematic_showcase),
"22": ("Greensleeves (Renaissance Lute)", greensleeves),
"23": ("Tabla Solo (Raga Yaman)", tabla_solo_yaman),
}
if __name__ == "__main__":
try:
print()
print(" PyTheory Song Player")
print(" " + "=" * 40)
print()
for key, (name, _) in SONGS.items():
print(f" {key:>2}. {name}")
print()
choice = input(" Pick a song (1-23, or 'all'): ").strip()
print()
if choice == "all":
for _, (_, fn) in SONGS.items():
fn()
print()
elif choice in SONGS:
SONGS[choice][1]()
else:
print(" Playing all songs...")
for _, (_, fn) in SONGS.items():
fn()
print()
except KeyboardInterrupt:
sd.stop()
print("\n\n Bye!")