mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-06-05 06:46:14 +00:00
a5c9a46eb2
String ensembles: 6-10 players. Cellos: 3 players. Choir: 6 voices. Cathedral siren pad: 4 voices. Makes everything sound fuller and more alive. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3066 lines
126 KiB
Python
3066 lines
126 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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="upright_bass",
|
|
volume=0.45, pan=0.0, lowpass=600,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["Am", "Am", "Dm", "Dm", "E7", "E7", "Am", "Am"]:
|
|
rhodes.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("E5",.67,85),("D5",.33,75),("C5",.67,80),("B4",.33,70),("A4",1,85),("C5",.67,78),("E5",.33,82),
|
|
("D5",.67,78),("C5",.33,72),("A4",1,80),(None,1,0),
|
|
("F5",.67,88),("E5",.33,78),("D5",.67,82),("C5",.33,72),("D5",1,80),("F5",.67,85),("A5",.33,90),
|
|
("G5",.67,82),("F5",.33,75),("D5",1,78),(None,1,0),
|
|
("G#5",.67,92),("F5",.33,78),("E5",.67,85),("D5",.33,75),("E5",1,82),(None,.5,0),("B4",.5,72),
|
|
("D5",.67,78),("E5",.33,82),("G#4",1,75),(None,1,0),
|
|
("A4",1,80),("C5",.67,78),("E5",.33,85),("A5",1.5,95),(None,.5,0),
|
|
("G5",.67,82),("E5",.33,78),("C5",.67,75),("A4",.33,70),("A4",2,85),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="upright_bass",
|
|
volume=0.4, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["Bb", "Gm", "Cm", "F7"] * 2:
|
|
rhodes.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("Bb4",.67,82),("D5",.33,75),("F5",.67,88),("D5",.33,78),
|
|
("Bb4",.67,80),("C5",.33,72),("D5",.67,82),("F5",.33,85),
|
|
("G5",.67,90),("F5",.33,78),("D5",.67,82),("Bb4",.33,72),
|
|
("A4",.67,78),("Bb4",.33,72),("D5",.67,85),("G4",.33,70),
|
|
("C5",.67,82),("Eb5",.33,78),("G5",.67,92),("Eb5",.33,80),
|
|
("C5",.67,78),("D5",.33,75),("Eb5",.67,82),("F5",.33,85),
|
|
("A5",.67,95),("G5",.33,82),("F5",.67,85),("Eb5",.33,78),
|
|
("D5",.67,80),("C5",.33,72),("A4",.5,75),(None,.5,0),
|
|
("Bb4",1,85),("D5",.67,80),("F5",.33,88),
|
|
("G5",.67,90),("F5",.33,82),("D5",.67,78),("Bb4",.33,72),
|
|
("Bb5",.67,95),("A5",.33,85),("G5",.67,88),("F5",.33,80),
|
|
("Eb5",.67,82),("D5",.33,75),("Bb4",.67,78),("G4",.33,70),
|
|
("C5",.5,78),(None,.5,0),("Eb5",.67,82),("G5",.33,88),
|
|
("F5",.67,85),("Eb5",.33,78),("D5",.67,82),("C5",.33,75),
|
|
("A4",.67,78),("C5",.33,80),("Eb5",.67,85),("F5",.33,88),
|
|
("G5",.67,92),("A5",.33,88),("Bb5",1,95),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="synth_bass",
|
|
volume=0.45, pan=0.0, lowpass=500, lowpass_q=1.3,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["Em7b5", "A7", "Dm7", "Bbmaj7"] * 2:
|
|
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("E5",.67,85),("G5",.33,78),("Bb5",.67,92),("A5",.33,82),
|
|
("G5",.67,85),("F5",.33,78),("E5",.67,82),("D5",.33,75),
|
|
("C#5",.67,80),("D5",.33,75),("E5",.67,85),("G5",.33,80),
|
|
("F5",.67,82),("E5",.33,78),("C#5",.5,75),(None,.5,0),
|
|
("D5",.5,78),(None,.17,0),("F5",.67,85),("A5",.33,90),
|
|
("G5",.67,88),("F5",.33,80),("E5",.67,82),("D5",.33,75),
|
|
("Bb4",1,78),("D5",.67,82),("F5",.33,88),("A5",1,95),(None,1,0),
|
|
("E5",.5,80),("F5",.5,82),("G5",.67,88),("A5",.33,85),
|
|
("Bb5",.67,95),("A5",.33,85),("G5",.67,88),("E5",.33,78),
|
|
("C#5",.67,80),("E5",.33,82),("A5",.67,92),("G5",.33,85),
|
|
("F5",.67,82),("E5",.33,78),("C#5",.67,75),("A4",.33,70),
|
|
("D5",1,82),("F5",.67,85),("A5",.33,92),("G5",.67,88),("F5",.33,80),("D5",1,78),(None,1,0),
|
|
("Bb4",.67,75),("D5",.33,80),("F5",.67,88),("Bb5",.33,95),("A5",1.5,90),(None,.5,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="bass_guitar",
|
|
volume=0.5, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["Em", "Am", "D", "C"] * 2:
|
|
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
riff = [("E5",.5,82),("G5",.5,78),("A5",.5,88),("G5",.5,80),
|
|
("E5",.5,78),("D5",.5,72),("E5",1,85),
|
|
("E5",.5,80),("G5",.5,78),("A5",.5,88),("B5",.5,92),
|
|
("A5",.5,85),("G5",.5,78),("E5",1,82),
|
|
(None,.5,0),("A5",.5,85),("G5",.5,80),("E5",.5,75),
|
|
("D5",1,78),("E5",.5,80),("G5",.5,82),
|
|
("A5",.5,88),("B5",.5,92),("A5",.5,85),("G5",.5,80),
|
|
("E5",1.5,82),(None,.5,0)]
|
|
for n, d, v in riff * 2:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="bass_guitar",
|
|
volume=0.55, pan=0.0, lowpass=400, lowpass_q=1.3,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["G", "C", "D", "C"] * 2:
|
|
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("G5",1.5,85),(None,.5,0),("B5",1,90),("A5",1,82),
|
|
("G5",2,80),("E5",1,75),("D5",1,72),
|
|
("C5",1.5,78),(None,.5,0),("E5",1,80),("G5",1,85),
|
|
("A5",1.5,88),(None,.5,0),("G5",2,82),
|
|
("D5",1.5,78),(None,.5,0),("E5",1,80),("G5",1,85),
|
|
("A5",2,90),("B5",1,92),("A5",1,85),
|
|
("G5",1.5,82),(None,.5,0),("E5",1,78),("D5",1,72),
|
|
("G4",3,75),(None,1,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="synth_bass",
|
|
volume=0.5, pan=0.0, lowpass=600, lowpass_q=1.2,
|
|
humanize=0.2, reverb=0.15)
|
|
|
|
for sym in ["Em", "Am", "D", "B7"] * 2:
|
|
chords.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("E5",.25,90),("E5",.25,78),(None,.25,0),("G5",.25,85),
|
|
(None,.25,0),("A5",.25,88),("G5",.25,82),("E5",.25,78),
|
|
("D5",.5,80),("E5",.5,85),(None,.5,0),("B4",.5,72),
|
|
("E5",.25,88),("E5",.25,78),(None,.25,0),("G5",.25,85),
|
|
(None,.25,0),("A5",.25,90),("B5",.25,92),("A5",.25,85),
|
|
("G5",.5,82),("E5",.5,78),(None,1,0),
|
|
("A4",.25,80),("C5",.25,82),("E5",.25,88),("A5",.25,92),
|
|
("G5",.5,85),("E5",.5,78),(None,.5,0),("C5",.5,75),
|
|
("A4",.5,78),("C5",.5,80),("D5",.5,82),("E5",.5,85),
|
|
("E5",1,82),(None,1,0),
|
|
("D5",.25,82),("F#5",.25,85),("A5",.25,90),("D5",.25,78),
|
|
("F#5",.5,85),("D5",.5,78),("A4",.5,75),("D5",.5,80),
|
|
("D#5",.5,82),("F#5",.5,88),("B4",.5,78),("D#5",.5,82),
|
|
("F#5",1,85),(None,1,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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 | saxophone lead + reverb + delay | upright 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="saxophone",
|
|
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,
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="upright_bass",
|
|
volume=0.5, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
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, v in [
|
|
("A4",1,80),("C5",.67,85),("A4",.33,75),("E4",1,78),
|
|
(None,.5,0),("A4",.5,80),("C5",.67,85),("D5",.33,82),
|
|
("E5",1.5,92),("D5",.5,80),("C5",.5,78),("A4",.5,75),
|
|
("E4",1.5,72),(None,.5,0),("A4",1,80),
|
|
("D5",1,85),("F5",.67,90),("D5",.33,78),("A4",1,80),
|
|
(None,1,0),("D5",.67,82),("F5",.33,88),("A5",1,95),
|
|
("G5",.67,88),("F5",.33,80),("D5",1,78),(None,1,0),
|
|
("E5",.67,85),("G#4",.33,72),("B4",.67,80),("E5",.33,85),
|
|
("D5",1,82),("A4",1,78),(None,1,0),
|
|
("A4",.67,78),("C5",.33,82),("E5",.67,90),("A5",.33,95),
|
|
("A5",2,92),(None,1,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="bass_guitar",
|
|
volume=0.45, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["G", "Em", "Am", "D7"] * 2:
|
|
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("B5",.33,88),("A5",.33,82),("G5",.34,78),("F#5",.5,82),("E5",.5,75),
|
|
("D5",.5,72),("G5",.5,80),("B5",.5,88),("A5",.5,82),
|
|
("G5",.67,85),("E5",.33,78),("D5",.67,75),("B4",.33,70),("G4",1,72),(None,1,0),
|
|
("E5",.5,80),("G5",.5,85),("B5",.5,90),("A5",.5,82),
|
|
("G5",.67,85),("F#5",.33,80),("E5",.67,78),("D5",.33,72),("E5",1,80),(None,1,0),
|
|
("A5",.5,85),("C6",.5,92),("B5",.5,88),("A5",.5,82),
|
|
("G5",.67,85),("E5",.33,78),("C5",.67,75),("A4",.33,70),("A4",1,72),(None,1,0),
|
|
("D5",.5,78),("F#5",.5,85),("A5",.5,90),("C5",.5,75),
|
|
("B4",.67,78),("A4",.33,72),("G4",.67,70),("F#4",.33,68),("G4",2,75),(None,2,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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,
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="upright_bass",
|
|
volume=0.4, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
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, v in [
|
|
("A5",1.5,85),("G5",.5,78),("F5",1,80),("E5",1,75),("C5",1,72),("F5",1,80),
|
|
("A5",2,88),(None,1,0),("G5",2,82),(None,1,0),
|
|
("Bb5",1,90),("A5",.5,82),("G5",.5,78),("F5",1,80),("D5",1,75),("G5",1,82),
|
|
("Bb5",2,90),(None,1,0),("A5",1.5,85),("G5",.5,78),("F5",1,80),
|
|
("E5",1,78),("G5",1,82),("Bb5",1,88),("A5",1.5,85),("G5",.5,78),("E5",1,75),
|
|
("C5",2,72),(None,1,0),("E5",1,78),("G5",1,82),("C5",1,72),
|
|
("F5",2,82),("A5",1,88),("C6",2,92),(None,1,0),
|
|
("A5",1,85),("F5",1,80),("C5",1,72),("F5",3,82),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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,
|
|
reverb=0.1)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="bass_guitar",
|
|
volume=0.6, pan=0.0, lowpass=400, lowpass_q=1.5,
|
|
humanize=0.2)
|
|
siren = score.part("siren", synth="pwm_slow", envelope="pad",
|
|
volume=0.15, pan=0.5, ensemble=4,
|
|
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, v in [
|
|
("A4", 2, 78), (None, 2, 0), ("C5", 1.5, 82), (None, 2.5, 0),
|
|
("D5", 1, 85), ("C5", 1, 78), ("A4", 2, 75), (None, 4, 0),
|
|
("E5", 2, 88), (None, 2, 0), ("D5", 1.5, 82), ("C5", 1.5, 78), (None, 3, 0),
|
|
("A4", 1, 75), ("G4", 1, 70), ("A4", 3, 78), (None, 3, 0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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,
|
|
reverb=0.1)
|
|
|
|
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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="upright_bass",
|
|
volume=0.45, pan=0.0, lowpass=500,
|
|
humanize=0.2, reverb=0.2)
|
|
|
|
for sym in ["C", "Am", "F", "G"] * 2:
|
|
organ.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
for n, d, v in [
|
|
("E5",.67,82),("G5",.33,78),("C6",1,92),("B5",.67,85),("A5",.33,80),
|
|
("G5",1,82),(None,1,0),
|
|
("A5",.67,85),("C6",.33,88),("E5",1,80),("D5",.67,78),("C5",.33,72),
|
|
("A4",1,75),(None,1,0),
|
|
("F5",.67,82),("A5",.33,85),("C6",1,92),("B5",.67,88),("A5",.33,82),
|
|
("G5",.67,80),("E5",.33,75),("C5",1,72),(None,1,0),
|
|
("D5",.67,78),("E5",.33,80),("G5",.67,85),("B5",.33,88),
|
|
("C6",2,92),(None,2,0),
|
|
# Second half: more intense
|
|
("C6",.67,95),("B5",.33,88),("A5",.67,90),("G5",.33,82),
|
|
("E5",1,85),("C5",.67,78),("E5",.33,82),
|
|
("A5",1,90),("G5",.67,85),("E5",.33,78),("C5",1,75),(None,1,0),
|
|
("F5",1,85),("A5",.67,90),("C6",.33,95),("E6",2,100),
|
|
("D6",.67,92),("C6",.33,88),("B5",.67,90),("G5",.33,82),
|
|
("C6",3,95),(None,1,0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
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,
|
|
humanize=0.2)
|
|
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",
|
|
humanize=0.2)
|
|
|
|
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, v in [
|
|
("E5", 1.5, 78), (None, 6.5, 0),
|
|
("G5", 1, 82), ("A5", 1, 85), (None, 6, 0),
|
|
(None, 4, 0), ("B5", 2, 88), (None, 6, 0),
|
|
("E5", 1, 75), (None, 3, 0), ("D5", 1.5, 72), (None, 2.5, 0),
|
|
]:
|
|
melodica.rest(d) if n is None else melodica.add(n, d, velocity=v)
|
|
|
|
# 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",
|
|
humanize=0.2)
|
|
bass = score.part("bass", instrument="808_bass",
|
|
volume=0.55, pan=0.0,
|
|
reverb=0.1)
|
|
|
|
for sym in ["Am", "F", "C", "G"] * 2:
|
|
pads.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
# Liquid melody — flowing, emotional
|
|
for n, d, v in [
|
|
("A5", 1, 85), ("G5", .5, 78), ("E5", .5, 72), ("C5", 1, 75), (None, 1, 0),
|
|
("D5", .5, 72), ("E5", .5, 78), ("G5", 1, 82), ("A5", 1.5, 88), (None, .5, 0),
|
|
("C6", 1, 92), ("B5", .5, 85), ("A5", .5, 80), ("G5", 1, 82), ("E5", 1, 75),
|
|
("F5", .5, 78), ("G5", .5, 82), ("A5", 1.5, 88), (None, .5, 0), ("G5", 1, 80),
|
|
("A5", 1, 85), ("G5", .5, 78), ("E5", .5, 72), ("C5", 1, 75), (None, 1, 0),
|
|
("E5", .5, 78), ("G5", .5, 82), ("B5", 1, 90), ("A5", 2, 85),
|
|
("G5", 1, 80), ("E5", .5, 75), ("D5", .5, 70), ("C5", 1.5, 72), (None, .5, 0),
|
|
("E5", .5, 78), ("G5", .5, 82), ("A5", 2, 88), (None, 1, 0),
|
|
]:
|
|
lead.rest(d) if n is None else lead.add(n, d, velocity=v)
|
|
|
|
# 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,
|
|
humanize=0.2)
|
|
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,
|
|
reverb=0.15)
|
|
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,
|
|
humanize=0.2)
|
|
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", ensemble=8,
|
|
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", ensemble=3,
|
|
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)")
|
|
|
|
|
|
def journey():
|
|
"""Journey — piano → orchestra → world → sitar EDM.
|
|
|
|
One reverb space (Taj Mahal), tanpura drone throughout. Piano opens
|
|
alone, cello joins, harp/oboe/flute take over with djembe, sitar
|
|
arrives over tabla, builds to an EDM section with house drums.
|
|
"""
|
|
REV = "taj_mahal"
|
|
score = Score("4/4", bpm=72)
|
|
|
|
# ── Drone — runs the entire piece ──
|
|
tanpura = score.part("tanpura", synth="strings_synth", envelope="pad",
|
|
detune=3, lowpass=1000, volume=0.12,
|
|
reverb=0.6, reverb_type=REV)
|
|
for _ in range(40):
|
|
tanpura.add("A2", Duration.WHOLE)
|
|
|
|
# ── Bars 1-8: Piano alone, then cello ──
|
|
piano = score.part("piano", instrument="piano", volume=0.35,
|
|
reverb=0.6, reverb_type=REV)
|
|
for notes in [
|
|
["A2","E3","A3","C4","E4","C4","A3","E3"],
|
|
["F2","C3","F3","A3","C4","A3","F3","C3"],
|
|
["G2","D3","G3","B3","D4","B3","G3","D3"],
|
|
["E2","B2","E3","G#3","B3","G#3","E3","B2"],
|
|
["A2","E3","A3","C4","E4","C4","A3","E3"],
|
|
["D2","A2","D3","F3","A3","F3","D3","A2"],
|
|
["E2","B2","E3","G#3","B3","G#3","E3","B2"],
|
|
["A2","E3","A3","C4","E4","A4","E4","C4"],
|
|
]:
|
|
for n in notes:
|
|
piano.add(n, Duration.EIGHTH, velocity=68)
|
|
|
|
cello = score.part("cello", instrument="cello", volume=0.2,
|
|
reverb=0.55, reverb_type=REV)
|
|
cello.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("A3", 4.0, 55), ("C4", 4.0, 58),
|
|
("B3", 2.0, 52), ("A3", 2.0, 50), ("G3", 4.0, 55),
|
|
("F3", 4.0, 52), ("E3", 4.0, 55), ("A3", 4.0, 58),
|
|
]:
|
|
cello.add(note, dur, velocity=vel)
|
|
|
|
# ── Bars 9-16: Harp + oboe + flute + djembe ──
|
|
harp = score.part("harp", instrument="harp", volume=0.28,
|
|
reverb=0.6, reverb_type=REV)
|
|
oboe = score.part("oboe", instrument="oboe", volume=0.22,
|
|
reverb=0.55, reverb_type=REV)
|
|
flute = score.part("flute", instrument="flute", volume=0.18,
|
|
reverb=0.55, reverb_type=REV)
|
|
for _ in range(8):
|
|
harp.rest(Duration.WHOLE)
|
|
for notes in [
|
|
["A3","C4","E4","A4","C5","E5","A5","E5"],
|
|
["D3","F3","A3","D4","F4","A4","D5","A4"],
|
|
["E3","G3","B3","E4","G4","B4","E5","B4"],
|
|
["A3","C4","E4","A4","E5","C5","A4","E4"],
|
|
["F3","A3","C4","F4","A4","C5","F5","C5"],
|
|
["E3","G#3","B3","E4","G#4","B4","E5","B4"],
|
|
]:
|
|
for n in notes:
|
|
harp.add(n, Duration.EIGHTH, velocity=58)
|
|
for _ in range(9):
|
|
oboe.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("E5", 1.5, 62), ("D5", 0.5, 55), ("C5", 1.0, 58),
|
|
("A4", 1.0, 62), ("G4", 1.0, 55), ("A4", 1.5, 58),
|
|
("B4", 0.5, 52), ("C5", 2.0, 62), ("A4", 4.0, 58),
|
|
]:
|
|
oboe.add(note, dur, velocity=vel)
|
|
for _ in range(10):
|
|
flute.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("A5", 2.0, 50), ("G5", 1.0, 45), ("E5", 1.0, 48),
|
|
("D5", 2.0, 50), ("C5", 1.0, 45), ("A4", 1.0, 48),
|
|
("G4", 2.0, 50), ("A4", 2.0, 52),
|
|
]:
|
|
flute.add(note, dur, velocity=vel)
|
|
|
|
# ── Bars 15-20: Sitar + tabla ──
|
|
sitar = score.part("sitar", instrument="sitar", volume=0.2,
|
|
reverb=0.6, reverb_type=REV)
|
|
for _ in range(14):
|
|
sitar.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("A4", 1.0, 70), ("Bb4", 0.5, 60), ("A4", 0.5, 65),
|
|
("C5", 1.5, 75), ("Bb4", 0.5, 60),
|
|
("D5", 1.0, 70), ("E5", 1.5, 78),
|
|
("F5", 0.5, 62), ("E5", 1.0, 70),
|
|
("D5", 0.5, 62), ("C5", 0.5, 65), ("Bb4", 0.5, 58),
|
|
("A4", 2.0, 75),
|
|
("Bb4", 0.25, 55), ("C5", 0.25, 58), ("D5", 0.25, 62),
|
|
("E5", 0.25, 68),
|
|
("F5", 0.25, 65), ("G5", 0.25, 70), ("A5", 0.5, 80),
|
|
("G5", 0.25, 62), ("F5", 0.25, 58), ("E5", 0.5, 62),
|
|
("C5", 0.5, 58), ("Bb4", 0.5, 55), ("A4", 2.0, 75),
|
|
]:
|
|
sitar.add(note, dur, velocity=vel)
|
|
|
|
# ── EDM section — sitar over house beat ──
|
|
# Solo sections: 8+8+8+12 = 36 beats = 9 bars
|
|
# Total bars before EDM: 8 piano + 6 harp + 6 djembe + 4 tabla + 9 solo = 33
|
|
edm_start = 33
|
|
pad = score.part("pad", instrument="synth_pad", volume=0.18,
|
|
reverb=0.6, reverb_type=REV,
|
|
sidechain=0.6, sidechain_release=0.15)
|
|
for _ in range(edm_start):
|
|
pad.rest(Duration.WHOLE)
|
|
for sym in ["Am", "F", "G", "Em"] * 2:
|
|
pad.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
sub = score.part("sub", instrument="808_bass", volume=0.4)
|
|
for _ in range(edm_start):
|
|
sub.rest(Duration.WHOLE)
|
|
for n in ["A1","A1","F1","F1","G1","G1","E1","E1"] * 2:
|
|
sub.add(n, Duration.HALF)
|
|
|
|
sitar2 = score.part("sitar2", instrument="sitar", volume=0.4,
|
|
reverb=0.3, reverb_type=REV)
|
|
for _ in range(edm_start + 2):
|
|
sitar2.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("A4", 0.25, 75), ("C5", 0.25, 78), ("E5", 0.5, 85),
|
|
("D5", 0.25, 72), ("C5", 0.25, 70), ("A4", 0.5, 75),
|
|
("G4", 0.25, 68), ("A4", 0.25, 72), ("C5", 0.5, 78),
|
|
("A4", 0.5, 72),
|
|
("E5", 0.5, 82), ("D5", 0.25, 72), ("C5", 0.25, 70),
|
|
("A4", 0.5, 75), ("G4", 0.5, 68), ("A4", 1.0, 78),
|
|
] * 2:
|
|
sitar2.add(note, dur, velocity=vel)
|
|
|
|
# Drums: djembe bars 9-14, tabla bars 15-20, house bars 21-28
|
|
DJB = DrumSound.DJEMBE_BASS
|
|
DJT = DrumSound.DJEMBE_TONE
|
|
DJS = DrumSound.DJEMBE_SLAP
|
|
NA = DrumSound.TABLA_NA
|
|
DH = DrumSound.TABLA_DHA
|
|
TT = DrumSound.TABLA_TIT
|
|
GB = DrumSound.TABLA_GE_BEND
|
|
|
|
silence = Pattern(name="s", time_signature="4/4", beats=32.0, hits=[])
|
|
score.add_pattern(silence, repeats=1)
|
|
p_dj = Pattern(name="dj", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DJB, 0.0, 48), _Hit(DJT, 1.0, 40), _Hit(DJT, 1.5, 35),
|
|
_Hit(DJS, 2.0, 45), _Hit(DJT, 3.0, 40),
|
|
_Hit(DJB, 4.0, 52), _Hit(DJT, 5.0, 42), _Hit(DJT, 5.5, 38),
|
|
_Hit(DJS, 6.0, 48), _Hit(DJT, 6.5, 35), _Hit(DJS, 7.0, 45),
|
|
])
|
|
score.add_pattern(p_dj, repeats=3)
|
|
p_tab = Pattern(name="tab", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 80), _Hit(TT, 0.5, 30), _Hit(NA, 1.0, 65),
|
|
_Hit(NA, 2.0, 60), _Hit(DH, 3.0, 80),
|
|
_Hit(DH, 4.0, 85), _Hit(TT, 4.25, 32), _Hit(TT, 4.5, 35),
|
|
_Hit(NA, 5.0, 68), _Hit(TT, 5.5, 30), _Hit(NA, 6.0, 65),
|
|
_Hit(DH, 7.0, 85),
|
|
])
|
|
score.add_pattern(p_tab, repeats=2)
|
|
|
|
# Tabla solo — everything drops out, just tabla and drone
|
|
KE = DrumSound.TABLA_KE
|
|
TI = DrumSound.TABLA_TIN
|
|
GE = DrumSound.TABLA_GE
|
|
T3 = 1.0 / 12.0 # 32nd triplet
|
|
T9 = 1.0 / 9.0 # ninth note
|
|
|
|
# Part 1: whisper — space, breath, single hits
|
|
p_solo1 = Pattern(name="solo1", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 78),
|
|
_Hit(NA, 2.0, 55),
|
|
_Hit(DH, 4.0, 82),
|
|
_Hit(TT, 5.0, 30), _Hit(NA, 5.5, 52), _Hit(TT, 6.0, 28),
|
|
_Hit(DH, 7.0, 78),
|
|
])
|
|
score.add_pattern(p_solo1, repeats=1)
|
|
|
|
# Part 2: ghosts emerge — 16th note ghost fills between accents
|
|
p_solo2 = Pattern(name="solo2", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 92), _Hit(TT, 0.25, 32), _Hit(TT, 0.5, 35),
|
|
_Hit(NA, 1.0, 68), _Hit(TT, 1.25, 30), _Hit(TT, 1.5, 28),
|
|
_Hit(NA, 2.0, 62), _Hit(TT, 2.5, 32), _Hit(DH, 3.0, 88),
|
|
_Hit(TT, 3.25, 35), _Hit(TT, 3.5, 38),
|
|
_Hit(DH, 4.0, 95), _Hit(TT, 4.25, 38), _Hit(TT, 4.5, 42),
|
|
_Hit(NA, 5.0, 72), _Hit(TT, 5.25, 32), _Hit(TT, 5.5, 35),
|
|
_Hit(KE, 5.75, 40),
|
|
_Hit(NA, 6.0, 68), _Hit(TT, 6.25, 35), _Hit(KE, 6.5, 38),
|
|
_Hit(DH, 7.0, 95), _Hit(GB, 7.5, 88),
|
|
])
|
|
score.add_pattern(p_solo2, repeats=1)
|
|
|
|
# Part 3: call and response — dayan vs bayan, dynamics wide open
|
|
p_solo3 = Pattern(name="solo3", time_signature="4/4", beats=8.0, hits=[
|
|
# Dayan speaks
|
|
_Hit(NA, 0.0, 110), _Hit(NA, 0.25, 55), _Hit(TT, 0.5, 38),
|
|
_Hit(NA, 0.75, 100),
|
|
# Bayan answers
|
|
_Hit(GE, 1.0, 100), _Hit(GE, 1.25, 50), _Hit(GB, 1.5, 90),
|
|
_Hit(GE, 1.75, 45),
|
|
# Dayan louder
|
|
_Hit(NA, 2.0, 115), _Hit(TT, 2.125, 30), _Hit(TT, 2.25, 35),
|
|
_Hit(NA, 2.5, 105), _Hit(TT, 2.625, 32), _Hit(TT, 2.75, 38),
|
|
# Bayan louder
|
|
_Hit(GB, 3.0, 112), _Hit(KE, 3.25, 50), _Hit(GE, 3.5, 68),
|
|
_Hit(KE, 3.75, 45),
|
|
# Together — explosion
|
|
_Hit(DH, 4.0, 120), _Hit(TT, 4.25, 45), _Hit(TT, 4.5, 48),
|
|
_Hit(DH, 5.0, 115), _Hit(TT, 5.25, 42), _Hit(NA, 5.5, 72),
|
|
# 9-tuplet — the weird one, breaks the grid
|
|
*[_Hit(TT if i % 2 == 0 else KE, 6.0 + i * T9, 38 + i * 5)
|
|
for i in range(9)],
|
|
_Hit(DH, 7.0, 118),
|
|
])
|
|
score.add_pattern(p_solo3, repeats=1)
|
|
|
|
# Part 4: blazing — 32nd triplets, cascades, tihai finale
|
|
p_solo4 = Pattern(name="solo4", time_signature="4/4", beats=12.0, hits=[
|
|
# 32nd triplet opening flourish
|
|
*[_Hit(TT, 0.0 + i * T3, 40 + i * 2) for i in range(12)],
|
|
_Hit(DH, 1.0, 120), _Hit(GB, 1.5, 108),
|
|
# Rapid alternating hands
|
|
_Hit(NA, 2.0, 110), _Hit(KE, 2.125, 45), _Hit(NA, 2.25, 105),
|
|
_Hit(KE, 2.375, 48), _Hit(NA, 2.5, 108), _Hit(KE, 2.625, 50),
|
|
_Hit(NA, 2.75, 112),
|
|
_Hit(DH, 3.0, 118),
|
|
# Another 32nd triplet burst — longer, crescendo
|
|
*[_Hit(TT, 3.5 + i * T3, 32 + i * 4) for i in range(18)],
|
|
_Hit(DH, 5.0, 122), _Hit(DH, 5.25, 118), _Hit(GB, 5.5, 115),
|
|
# 9 against 4 polyrhythm moment
|
|
_Hit(GE, 6.0, 88), _Hit(GE, 7.0, 85),
|
|
*[_Hit(NA if i % 3 == 0 else TT, 6.0 + i * (2.0 / 9.0), 42 + (i % 3) * 15)
|
|
for i in range(9)],
|
|
# Grand tihai — 3x pattern, each louder
|
|
_Hit(DH, 8.0, 108), _Hit(NA, 8.25, 72), _Hit(TT, 8.5, 48),
|
|
_Hit(KE, 8.75, 52), _Hit(DH, 9.0, 100),
|
|
_Hit(DH, 9.25, 112), _Hit(NA, 9.5, 78), _Hit(TT, 9.75, 52),
|
|
_Hit(KE, 10.0, 58), _Hit(DH, 10.25, 108),
|
|
_Hit(DH, 10.5, 120), _Hit(NA, 10.75, 85), _Hit(TT, 11.0, 58),
|
|
_Hit(KE, 11.25, 62), _Hit(DH, 11.5, 127),
|
|
# Silence.....
|
|
# SLAM
|
|
_Hit(GB, 11.875, 127),
|
|
])
|
|
score.add_pattern(p_solo4, repeats=1)
|
|
|
|
score.drums("house", repeats=8)
|
|
score.set_drum_effects(reverb=0.3, reverb_type=REV)
|
|
|
|
play_song(score, "Journey — Piano → World → Sitar EDM (Taj Mahal)")
|
|
|
|
|
|
def epic_bhairav():
|
|
"""Epic Bhairav — orchestral + choir + tabla with extended solo finale."""
|
|
shruti = SYSTEMS["shruti"]
|
|
score = Score("4/4", bpm=90, system=shruti)
|
|
REV = "taj_mahal"
|
|
T3 = 1.0 / 12.0
|
|
T9 = 1.0 / 9.0
|
|
|
|
ts = TonedScale(system=shruti, tonic=Tone("Sa", octave=4, system=shruti))
|
|
bh = list(ts["bhairav"].tones)
|
|
S, kR, G, M, P, kD, N, S2 = bh
|
|
|
|
NA = DrumSound.TABLA_NA
|
|
DH = DrumSound.TABLA_DHA
|
|
TT = DrumSound.TABLA_TIT
|
|
KE = DrumSound.TABLA_KE
|
|
GB = DrumSound.TABLA_GE_BEND
|
|
GE = DrumSound.TABLA_GE
|
|
DJB = DrumSound.DJEMBE_BASS
|
|
DJT = DrumSound.DJEMBE_TONE
|
|
DJS = DrumSound.DJEMBE_SLAP
|
|
|
|
# Tanpura
|
|
tanpura = score.part("tanpura", synth="strings_synth", envelope="pad",
|
|
detune=3, lowpass=900, volume=0.14, reverb=0.4, reverb_type=REV)
|
|
tanpura_pa = score.part("tanpura_pa", synth="strings_synth", envelope="pad",
|
|
detune=3, lowpass=1200, volume=0.1, reverb=0.4, reverb_type=REV)
|
|
sa = Tone("Sa", octave=3, system=shruti)
|
|
pa = Tone("Pa", octave=3, system=shruti)
|
|
for _ in range(34):
|
|
tanpura.add(sa, Duration.WHOLE)
|
|
tanpura_pa.add(pa, Duration.WHOLE)
|
|
|
|
# Timpani
|
|
timp = score.part("timp", instrument="timpani")
|
|
timp.roll(Tone("Sa", octave=2, system=shruti), Duration.WHOLE,
|
|
velocity_start=20, velocity_end=90, speed=0.125)
|
|
timp.add(Tone("Sa", octave=2, system=shruti), Duration.HALF, velocity=105)
|
|
timp.rest(Duration.HALF)
|
|
for _ in range(8):
|
|
timp.rest(Duration.WHOLE)
|
|
timp.roll(Tone("Sa", octave=2, system=shruti), Duration.WHOLE,
|
|
velocity_start=25, velocity_end=115, speed=0.125)
|
|
timp.add(Tone("Sa", octave=2, system=shruti), Duration.HALF, velocity=120)
|
|
timp.add(Tone("Pa", octave=2, system=shruti), Duration.HALF, velocity=115)
|
|
|
|
# Choir — bar 3
|
|
choir = score.part("choir", synth="vocal_synth", envelope="pad", ensemble=6,
|
|
detune=8, spread=0.4, reverb=0.4, reverb_type=REV, volume=0.2)
|
|
for _ in range(2):
|
|
choir.rest(Duration.WHOLE)
|
|
for tone, dur, lyric, vel in [
|
|
(S, 4.0, "ah", 60), (M, 4.0, "oh", 62), (P, 4.0, "ah", 68),
|
|
(S, 4.0, "ee", 65), (kD, 4.0, "oh", 70), (P, 4.0, "ah", 72),
|
|
]:
|
|
choir.add(tone, dur, velocity=vel, lyric=lyric)
|
|
|
|
# Bansuri — bar 5
|
|
bansuri = score.part("bansuri", instrument="flute", volume=0.22,
|
|
reverb=0.4, reverb_type=REV)
|
|
for _ in range(4):
|
|
bansuri.rest(Duration.WHOLE)
|
|
for tone, dur, vel in [
|
|
(P, 2.0, 58), (kD, 1.0, 50), (P, 1.0, 55),
|
|
(M, 2.0, 55), (G, 1.0, 50), (kR, 1.0, 48), (S, 4.0, 58),
|
|
]:
|
|
bansuri.add(tone, dur, velocity=vel)
|
|
|
|
# Cello — bar 3
|
|
cello = score.part("cello", instrument="cello", volume=0.22, reverb=0.4, reverb_type=REV, ensemble=3)
|
|
for _ in range(2):
|
|
cello.rest(Duration.WHOLE)
|
|
for name, dur, vel in [
|
|
("Sa", 4.0, 55), ("Ma", 4.0, 52), ("Pa", 4.0, 58),
|
|
("Sa", 4.0, 55), ("komal Dha", 4.0, 58), ("Pa", 4.0, 55),
|
|
]:
|
|
cello.add(Tone(name, octave=2, system=shruti), dur, velocity=vel)
|
|
|
|
# Sitar — bar 9
|
|
sitar = score.part("sitar", instrument="sitar", volume=0.25, reverb=0.4, reverb_type=REV)
|
|
for _ in range(8):
|
|
sitar.rest(Duration.WHOLE)
|
|
for tone, dur, vel in [
|
|
(S, 1.0, 72), (kR, 0.5, 62), (S, 0.5, 68), (G, 2.0, 78),
|
|
(M, 1.0, 72), (P, 2.0, 82), (kD, 0.5, 65), (P, 1.0, 75),
|
|
(M, 0.5, 65), (G, 0.5, 68), (kR, 0.5, 60), (S, 2.0, 78),
|
|
(kR, 0.25, 62), (G, 0.25, 65), (M, 0.25, 70), (P, 0.25, 75),
|
|
(kD, 0.25, 70), (N, 0.25, 78), (S2, 0.5, 88),
|
|
(N, 0.25, 68), (kD, 0.25, 62), (P, 0.5, 68),
|
|
(M, 0.5, 62), (G, 0.5, 65), (kR, 0.5, 58), (S, 2.0, 80),
|
|
]:
|
|
sitar.add(tone, dur, velocity=vel)
|
|
|
|
# Strings — bar 13
|
|
strings = score.part("strings", instrument="string_ensemble", volume=0.18,
|
|
reverb=0.4, reverb_type=REV, ensemble=10)
|
|
for _ in range(12):
|
|
strings.rest(Duration.WHOLE)
|
|
for name, dur, vel in [("Sa", 4.0, 58), ("Ma", 4.0, 62), ("Pa", 4.0, 68), ("Sa", 4.0, 72)]:
|
|
strings.add(Tone(name, octave=3, system=shruti), dur, velocity=vel)
|
|
|
|
# Harp — bar 14
|
|
harp = score.part("harp", instrument="harp", volume=0.15, reverb=0.4, reverb_type=REV)
|
|
for _ in range(13):
|
|
harp.rest(Duration.WHOLE)
|
|
for name in ["Sa", "komal Ga", "Pa", "Sa", "Pa", "komal Ga", "Sa", "Sa"]:
|
|
oct = 4 if name == "Sa" and harp.total_beats > 55 else 3
|
|
harp.add(Tone(name, octave=oct, system=shruti), Duration.EIGHTH, velocity=50)
|
|
|
|
# Drums
|
|
silence = Pattern(name="s", time_signature="4/4", beats=16.0, hits=[])
|
|
score.add_pattern(silence, repeats=1)
|
|
p_dj = Pattern(name="dj", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DJB, 0.0, 45), _Hit(DJT, 1.0, 38), _Hit(DJT, 1.5, 32),
|
|
_Hit(DJS, 2.0, 42), _Hit(DJT, 3.0, 38),
|
|
_Hit(DJB, 4.0, 50), _Hit(DJT, 5.0, 42), _Hit(DJT, 5.5, 35),
|
|
_Hit(DJS, 6.0, 48), _Hit(DJT, 6.5, 32), _Hit(DJS, 7.0, 45),
|
|
])
|
|
score.add_pattern(p_dj, repeats=2)
|
|
p_tab = Pattern(name="tab", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 82), _Hit(TT, 0.5, 30), _Hit(NA, 1.0, 65),
|
|
_Hit(NA, 2.0, 60), _Hit(DH, 3.0, 82),
|
|
_Hit(DH, 4.0, 88), _Hit(TT, 4.25, 32), _Hit(TT, 4.5, 35),
|
|
_Hit(NA, 5.0, 68), _Hit(TT, 5.5, 30), _Hit(NA, 6.0, 65),
|
|
_Hit(DH, 7.0, 88),
|
|
])
|
|
score.add_pattern(p_tab, repeats=3)
|
|
|
|
# Extended tabla finale — whisper → ghosts → call/response → blazing
|
|
p_f1 = Pattern(name="f1", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 78), _Hit(NA, 2.0, 55),
|
|
_Hit(DH, 4.0, 82), _Hit(TT, 5.0, 30), _Hit(NA, 5.5, 52),
|
|
_Hit(DH, 7.0, 78),
|
|
])
|
|
score.add_pattern(p_f1, repeats=1)
|
|
p_f2 = Pattern(name="f2", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH, 0.0, 95), _Hit(TT, 0.25, 35), _Hit(TT, 0.5, 38),
|
|
_Hit(NA, 1.0, 70), _Hit(TT, 1.25, 30), _Hit(NA, 2.0, 65),
|
|
_Hit(TT, 2.5, 35), _Hit(DH, 3.0, 90),
|
|
_Hit(DH, 4.0, 98), _Hit(TT, 4.25, 38), _Hit(TT, 4.5, 42),
|
|
_Hit(NA, 5.0, 75), _Hit(KE, 5.5, 40), _Hit(NA, 6.0, 70),
|
|
_Hit(KE, 6.5, 42), _Hit(DH, 7.0, 100), _Hit(GB, 7.5, 92),
|
|
])
|
|
score.add_pattern(p_f2, repeats=1)
|
|
p_f3 = Pattern(name="f3", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(NA, 0.0, 112), _Hit(NA, 0.25, 58), _Hit(TT, 0.5, 40), _Hit(NA, 0.75, 105),
|
|
_Hit(GE, 1.0, 105), _Hit(GE, 1.25, 52), _Hit(GB, 1.5, 95), _Hit(GE, 1.75, 48),
|
|
_Hit(NA, 2.0, 115), _Hit(TT, 2.125, 32), _Hit(TT, 2.25, 38),
|
|
_Hit(NA, 2.5, 108), _Hit(TT, 2.625, 35), _Hit(TT, 2.75, 42),
|
|
_Hit(GB, 3.0, 115), _Hit(KE, 3.25, 52), _Hit(GE, 3.5, 70),
|
|
_Hit(DH, 4.0, 118),
|
|
*[_Hit(TT if i % 2 == 0 else KE, 5.0 + i * T9, 40 + i * 5) for i in range(9)],
|
|
_Hit(DH, 7.0, 120),
|
|
])
|
|
score.add_pattern(p_f3, repeats=1)
|
|
|
|
# Part 3.5: polyrhythm — space and conversation, not density
|
|
T5 = 4.0 / 5.0
|
|
p_poly = Pattern(name="poly", time_signature="4/4", beats=16.0, hits=[
|
|
# Bar 1: single Dha, let reverb ring. Bayan answers.
|
|
_Hit(DH, 0.0, 95),
|
|
_Hit(GB, 3.0, 88),
|
|
# Bar 2: one 5-group phrase, then breathe
|
|
_Hit(NA, 4.0, 75), _Hit(TT, 4.0 + T5, 42),
|
|
_Hit(NA, 4.0 + 2*T5, 70), _Hit(TT, 4.0 + 3*T5, 40),
|
|
_Hit(DH, 4.0 + 4*T5, 88),
|
|
# Bar 3: bayan, pause, one floating 9-group
|
|
_Hit(GB, 8.0, 100),
|
|
_Hit(NA, 9.0, 62),
|
|
*[_Hit(TT if i % 2 == 0 else KE, 10.0 + i * T9, 35 + i * 4)
|
|
for i in range(9)],
|
|
_Hit(DH, 11.0, 105),
|
|
# Bar 4: simple question-answer into sam
|
|
_Hit(DH, 12.0, 100), _Hit(NA, 12.5, 62),
|
|
_Hit(GE, 13.0, 88),
|
|
_Hit(NA, 14.0, 72), _Hit(TT, 14.25, 40), _Hit(NA, 14.5, 70),
|
|
_Hit(DH, 15.0, 112), _Hit(GB, 15.5, 105),
|
|
])
|
|
score.add_pattern(p_poly, repeats=1)
|
|
|
|
p_f4 = Pattern(name="f4", time_signature="4/4", beats=12.0, hits=[
|
|
*[_Hit(TT, 0.0 + i * T3, 38 + i * 2) for i in range(12)],
|
|
_Hit(DH, 1.0, 118), _Hit(GB, 1.5, 110),
|
|
_Hit(NA, 2.0, 112), _Hit(KE, 2.125, 48), _Hit(NA, 2.25, 108),
|
|
_Hit(KE, 2.375, 50), _Hit(NA, 2.5, 110), _Hit(KE, 2.625, 52), _Hit(NA, 2.75, 115),
|
|
_Hit(DH, 3.0, 120),
|
|
*[_Hit(TT, 3.5 + i * T3, 30 + i * 4) for i in range(18)],
|
|
_Hit(DH, 5.0, 122), _Hit(DH, 5.25, 118), _Hit(GB, 5.5, 115),
|
|
_Hit(GE, 6.0, 90), _Hit(GE, 7.0, 88),
|
|
*[_Hit(NA if i % 3 == 0 else TT, 6.0 + i * (2.0/9.0), 42 + (i%3)*15) for i in range(9)],
|
|
_Hit(DH, 8.0, 110), _Hit(NA, 8.25, 75), _Hit(TT, 8.5, 50),
|
|
_Hit(KE, 8.75, 55), _Hit(DH, 9.0, 105),
|
|
_Hit(DH, 9.25, 115), _Hit(NA, 9.5, 80), _Hit(TT, 9.75, 55),
|
|
_Hit(KE, 10.0, 60), _Hit(DH, 10.25, 110),
|
|
_Hit(DH, 10.5, 122), _Hit(NA, 10.75, 85), _Hit(TT, 11.0, 60),
|
|
_Hit(KE, 11.25, 65), _Hit(DH, 11.5, 127),
|
|
_Hit(GB, 11.875, 127),
|
|
])
|
|
score.add_pattern(p_f4, repeats=1)
|
|
score.set_drum_effects(reverb=0.4, reverb_type=REV)
|
|
|
|
play_song(score, "Epic Bhairav — Orchestra + Choir + Tabla (22-Shruti JI)")
|
|
|
|
|
|
def acoustic_ensemble():
|
|
"""Acoustic Ensemble — guitar, ukulele, mandolin, cajón."""
|
|
import random
|
|
from pytheory import Fretboard
|
|
random.seed(7)
|
|
score = Score("4/4", bpm=115)
|
|
|
|
fb_g = Fretboard.guitar()
|
|
guitar = score.part("guitar", instrument="acoustic_guitar", fretboard=fb_g,
|
|
reverb=0.3, reverb_type="plate", humanize=0.2, pan=-0.3)
|
|
|
|
fb_u = Fretboard.ukulele()
|
|
uke = score.part("uke", instrument="ukulele", fretboard=fb_u,
|
|
reverb=0.25, reverb_type="plate", humanize=0.25, pan=0.3)
|
|
|
|
fb_m = Fretboard.mandolin()
|
|
mando = score.part("mando", instrument="mandolin", fretboard=fb_m,
|
|
reverb=0.25, reverb_type="plate", humanize=0.2, pan=0.15)
|
|
|
|
for sym in ["C", "G", "Am", "F"] * 3:
|
|
vd = random.randint(75, 95)
|
|
vu = random.randint(58, 78)
|
|
guitar.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
guitar.strum(sym, Duration.EIGHTH, direction="up", velocity=vu)
|
|
guitar.strum(sym, Duration.EIGHTH, direction="down", velocity=vd - 8)
|
|
guitar.strum(sym, Duration.QUARTER, direction="up", velocity=vu)
|
|
guitar.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
|
|
vd2 = random.randint(65, 88)
|
|
vu2 = random.randint(50, 72)
|
|
uke.rest(Duration.EIGHTH)
|
|
uke.strum(sym, Duration.EIGHTH, direction="up", velocity=vu2)
|
|
uke.strum(sym, Duration.QUARTER, direction="down", velocity=vd2)
|
|
uke.strum(sym, Duration.EIGHTH, direction="up", velocity=vu2)
|
|
uke.strum(sym, Duration.EIGHTH, direction="down", velocity=vd2 - 5)
|
|
uke.strum(sym, Duration.QUARTER, direction="up", velocity=vu2)
|
|
|
|
mando.strum(sym, Duration.EIGHTH, direction="down",
|
|
velocity=random.randint(65, 82))
|
|
mando.strum(sym, Duration.EIGHTH, direction="up",
|
|
velocity=random.randint(55, 72))
|
|
mando.strum(sym, Duration.EIGHTH, direction="down",
|
|
velocity=random.randint(65, 82))
|
|
mando.rest(Duration.EIGHTH)
|
|
mando.strum(sym, Duration.EIGHTH, direction="up",
|
|
velocity=random.randint(55, 72))
|
|
mando.strum(sym, Duration.EIGHTH, direction="down",
|
|
velocity=random.randint(68, 85))
|
|
mando.strum(sym, Duration.QUARTER, direction="down",
|
|
velocity=random.randint(70, 85))
|
|
|
|
score.drums("cajon", repeats=6)
|
|
score.set_drum_effects(reverb=0.15)
|
|
|
|
play_song(score, "Acoustic Ensemble — Guitar, Uke, Mandolin, Cajón")
|
|
|
|
|
|
def ascent():
|
|
"""Ascent — from the deep to the sky, theremin solo, tabla solo."""
|
|
import random
|
|
from pytheory import Fretboard
|
|
random.seed(13)
|
|
score = Score("4/4", bpm=80)
|
|
REV = "cathedral"
|
|
T3 = 1.0 / 12.0
|
|
T9 = 1.0 / 9.0
|
|
|
|
NA = DrumSound.TABLA_NA; DH_ = DrumSound.TABLA_DHA
|
|
TT_ = DrumSound.TABLA_TIT; KE_ = DrumSound.TABLA_KE
|
|
GB_ = DrumSound.TABLA_GE_BEND; GE_ = DrumSound.TABLA_GE
|
|
DJB_ = DrumSound.DJEMBE_BASS; DJT_ = DrumSound.DJEMBE_TONE
|
|
DJS_ = DrumSound.DJEMBE_SLAP
|
|
CB_ = DrumSound.CAJON_BASS; CSL_ = DrumSound.CAJON_SLAP
|
|
CT_ = DrumSound.CAJON_TAP
|
|
|
|
# Didgeridoo drone
|
|
didg = score.part("didg", instrument="didgeridoo", volume=0.15)
|
|
for _ in range(32):
|
|
didg.add("E1", 4.0, velocity=52)
|
|
|
|
# 1: THE DEEP (1-4)
|
|
grain = score.part("grain", synth="granular_synth", envelope="pad",
|
|
lowpass=800, reverb=0.55, reverb_type="cave", volume=0.12)
|
|
for note in ["E2", "B2", "E2", "G2"]:
|
|
grain.add(note, 4.0, velocity=40)
|
|
|
|
# 2: LIGHT (3-6)
|
|
kal = score.part("kalimba", instrument="kalimba", volume=0.2,
|
|
delay=0.2, delay_time=0.375, delay_feedback=0.4,
|
|
reverb=0.45, reverb_type=REV)
|
|
kal.rest(8.0)
|
|
for note, vel in [("B4",58),("E5",62),("G5",65),("B5",68),
|
|
("G5",62),("E5",58),("B4",55),("E4",52)]:
|
|
kal.add(note, Duration.QUARTER, velocity=vel)
|
|
kal.rest(4.0)
|
|
for note, vel in [("E5",60),("G5",65),("B5",70),("E6",72),
|
|
("B5",65),("G5",60),("E5",58),("B4",55)]:
|
|
kal.add(note, Duration.QUARTER, velocity=vel)
|
|
|
|
# 3: SURFACING (5-8)
|
|
cello = score.part("cello", instrument="cello", volume=0.22,
|
|
reverb=0.4, reverb_type=REV, ensemble=3)
|
|
cello.rest(16.0)
|
|
for note, dur, vel in [("E2",4.0,52),("G2",4.0,55),("B2",4.0,58),("E3",4.0,62)]:
|
|
cello.add(note, dur, velocity=vel)
|
|
|
|
# 4: AIR (7-10) — piano + quiet uke
|
|
piano = score.part("piano", instrument="piano", volume=0.28,
|
|
reverb=0.35, reverb_type=REV)
|
|
piano.rest(24.0)
|
|
for notes in [
|
|
["E3","B3","E4","G4","B4","G4","E4","B3"],
|
|
["C3","G3","C4","E4","G4","E4","C4","G3"],
|
|
["A2","E3","A3","C4","E4","C4","A3","E3"],
|
|
["B2","F#3","B3","D4","F#4","D4","B3","F#3"],
|
|
]:
|
|
for n in notes:
|
|
piano.add(n, Duration.EIGHTH, velocity=random.randint(58, 70))
|
|
|
|
fb = Fretboard.ukulele()
|
|
uke = score.part("uke", instrument="ukulele", fretboard=fb,
|
|
reverb=0.4, reverb_type=REV, humanize=0.2,
|
|
pan=-0.2, volume=0.15)
|
|
uke.rest(28.0)
|
|
for sym in ["Em", "C", "Am", "B"]:
|
|
vd = random.randint(60, 75)
|
|
vu = random.randint(45, 62)
|
|
uke.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
uke.strum(sym, Duration.EIGHTH, direction="up", velocity=vu)
|
|
uke.strum(sym, Duration.EIGHTH, direction="down", velocity=vd - 8)
|
|
uke.strum(sym, Duration.QUARTER, direction="up", velocity=vu)
|
|
uke.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
|
|
# 5: THEREMIN SOLO (11-16)
|
|
steel = score.part("steel", instrument="pedal_steel", volume=0.16,
|
|
reverb=0.4, reverb_type=REV, pan=0.2)
|
|
steel.rest(36.0)
|
|
for note, dur, vel in [("B4",3.0,58),("A4",1.0,50),("G4",2.0,55),("E4",2.0,52)]:
|
|
steel.add(note, dur, velocity=vel)
|
|
|
|
theremin = score.part("theremin", instrument="theremin", volume=0.3,
|
|
reverb=0.45, reverb_type=REV,
|
|
delay=0.15, delay_time=0.375, delay_feedback=0.3)
|
|
theremin.rest(40.0)
|
|
for note, dur, vel in [
|
|
("E4",2.0,62),("G4",1.0,58),("B4",1.0,62),
|
|
("A4",2.0,65),("G4",1.0,58),("E4",1.0,55),("D4",3.0,60),("E4",1.0,58),
|
|
("G4",1.0,62),("B4",1.5,68),("D5",0.5,65),
|
|
("E5",2.0,72),("D5",1.0,65),("B4",1.0,62),
|
|
("G4",1.0,60),("A4",1.0,62),("B4",2.0,68),
|
|
("E5",1.5,75),("G5",1.5,80),("B5",2.0,85),
|
|
("A5",1.0,78),("G5",1.0,72),("E5",2.0,75),
|
|
("D5",1.0,68),("B4",1.0,62),("E4",4.0,70),
|
|
]:
|
|
theremin.add(note, dur, velocity=vel)
|
|
|
|
strings = score.part("strings", instrument="string_ensemble", volume=0.15,
|
|
reverb=0.45, reverb_type=REV, ensemble=8)
|
|
strings.rest(40.0)
|
|
for sym, vel in [("Em",52),("C",55),("Am",58),("B",55),("Em",60),("C",62)]:
|
|
strings.add(Chord.from_symbol(sym), 4.0, velocity=vel)
|
|
|
|
# 6: THE PEAK (17-18)
|
|
flute = score.part("flute", instrument="flute", volume=0.2, reverb=0.4, reverb_type=REV)
|
|
flute.rest(64.0)
|
|
for note, dur, vel in [
|
|
("B5",2.0,55),("A5",1.0,50),("G5",1.0,52),
|
|
("E5",2.0,55),("D5",1.0,50),("E5",1.0,52),
|
|
]:
|
|
flute.add(note, dur, velocity=vel)
|
|
|
|
harp = score.part("harp", instrument="harp", volume=0.16, reverb=0.4, reverb_type=REV)
|
|
harp.rest(68.0)
|
|
for n in ["B5","G5","E5","B4","G4","E4","B3","E3"]:
|
|
harp.add(n, Duration.QUARTER, velocity=random.randint(48, 58))
|
|
|
|
timp = score.part("timp", instrument="timpani")
|
|
timp.rest(64.0)
|
|
timp.roll("E2", 4.0, velocity_start=20, velocity_end=95, speed=0.125)
|
|
timp.add("E2", 4.0, velocity=105)
|
|
|
|
# Drums: silence → cajón → djembe → tabla solo
|
|
score.add_pattern(Pattern(name="s", time_signature="4/4", beats=16.0, hits=[]),
|
|
repeats=1)
|
|
p_caj = Pattern(name="caj", time_signature="4/4", beats=4.0, hits=[
|
|
_Hit(CB_, 0.0, 58), _Hit(CT_, 0.5, 22), _Hit(CSL_, 1.0, 50),
|
|
_Hit(CT_, 1.5, 20), _Hit(CB_, 2.0, 55), _Hit(CT_, 2.5, 22),
|
|
_Hit(CSL_, 3.0, 52),
|
|
])
|
|
score.add_pattern(p_caj, repeats=4)
|
|
p_dj = Pattern(name="dj", time_signature="4/4", beats=4.0, hits=[
|
|
_Hit(DJB_, 0.0, 42), _Hit(DJT_, 1.0, 35), _Hit(DJT_, 1.5, 30),
|
|
_Hit(DJS_, 2.0, 38), _Hit(DJT_, 3.0, 35),
|
|
])
|
|
score.add_pattern(p_dj, repeats=10)
|
|
|
|
# 7: TABLA SOLO (bars 19-26)
|
|
score.add_pattern(Pattern(name="ts1", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH_, 0.0, 72), _Hit(NA, 2.5, 48),
|
|
_Hit(DH_, 4.0, 75), _Hit(TT_, 5.5, 25), _Hit(NA, 6.0, 45),
|
|
_Hit(DH_, 7.5, 72),
|
|
]), repeats=1)
|
|
score.add_pattern(Pattern(name="ts2", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH_, 0.0, 85), _Hit(TT_, 0.25, 30), _Hit(TT_, 0.5, 32),
|
|
_Hit(NA, 1.0, 62), _Hit(TT_, 1.25, 25), _Hit(NA, 2.0, 58),
|
|
_Hit(TT_, 2.5, 28), _Hit(DH_, 3.0, 82),
|
|
_Hit(DH_, 4.0, 90), _Hit(TT_, 4.25, 32), _Hit(TT_, 4.5, 35),
|
|
_Hit(NA, 5.0, 68), _Hit(KE_, 5.5, 35), _Hit(NA, 6.0, 62),
|
|
_Hit(KE_, 6.5, 38), _Hit(DH_, 7.0, 92), _Hit(GB_, 7.5, 85),
|
|
]), repeats=1)
|
|
score.add_pattern(Pattern(name="ts3", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(NA, 0.0, 108), _Hit(NA, 0.25, 52), _Hit(TT_, 0.5, 35),
|
|
_Hit(NA, 0.75, 100),
|
|
_Hit(GE_, 1.0, 98), _Hit(GE_, 1.25, 48), _Hit(GB_, 1.5, 90),
|
|
_Hit(GE_, 1.75, 42),
|
|
_Hit(NA, 2.0, 110), _Hit(TT_, 2.125, 28), _Hit(TT_, 2.25, 32),
|
|
_Hit(NA, 2.5, 102), _Hit(TT_, 2.625, 30), _Hit(TT_, 2.75, 35),
|
|
_Hit(GB_, 3.0, 110), _Hit(KE_, 3.25, 45), _Hit(GE_, 3.5, 65),
|
|
_Hit(DH_, 4.0, 112),
|
|
*[_Hit(TT_ if i % 2 == 0 else KE_, 5.0 + i * T9, 35 + i * 5)
|
|
for i in range(9)],
|
|
_Hit(DH_, 7.0, 115),
|
|
]), repeats=1)
|
|
score.add_pattern(Pattern(name="ts4", time_signature="4/4", beats=8.0, hits=[
|
|
*[_Hit(TT_, i * T3, 32 + i * 2) for i in range(12)],
|
|
_Hit(DH_, 1.0, 115), _Hit(GB_, 1.5, 105),
|
|
_Hit(NA, 2.0, 108), _Hit(KE_, 2.125, 42), _Hit(NA, 2.25, 102),
|
|
_Hit(KE_, 2.375, 45), _Hit(NA, 2.5, 105), _Hit(KE_, 2.625, 48),
|
|
_Hit(NA, 2.75, 110), _Hit(DH_, 3.0, 118),
|
|
*[_Hit(TT_, 3.5 + i * T3, 30 + i * 4) for i in range(12)],
|
|
_Hit(DH_, 4.5, 120), _Hit(DH_, 4.75, 115), _Hit(GB_, 5.0, 112),
|
|
_Hit(GE_, 5.5, 85), _Hit(GE_, 6.5, 82),
|
|
*[_Hit(NA if i % 3 == 0 else TT_, 5.5 + i * (2.0 / 9.0),
|
|
40 + (i % 3) * 12) for i in range(9)],
|
|
_Hit(DH_, 7.5, 127), _Hit(GB_, 7.875, 127),
|
|
]), repeats=1)
|
|
score.set_drum_effects(reverb=0.3, reverb_type=REV)
|
|
|
|
play_song(score, "Ascent — Deep → Sky → Theremin Solo → Tabla Solo")
|
|
|
|
|
|
def descent():
|
|
"""Descent — generative, different every time. From sky to deep."""
|
|
import random
|
|
import time
|
|
from pytheory import Fretboard, TonedScale
|
|
|
|
# No seed — truly random every play
|
|
random.seed(int(time.time() * 1000) % 2**31)
|
|
|
|
# Random key — always minor, always dark
|
|
roots = ["A", "B", "C", "D", "E", "F", "G"]
|
|
root = random.choice(roots)
|
|
mode = random.choice(["minor", "harmonic minor"])
|
|
key = Key(root, mode)
|
|
scale_tones = [t.name for t in key.scale.tones[:-1]]
|
|
|
|
bpm = random.randint(65, 85)
|
|
score = Score("4/4", bpm=bpm)
|
|
REV = random.choice(["cathedral", "taj_mahal", "cave"])
|
|
|
|
T3 = 1.0 / 12.0
|
|
NA = DrumSound.TABLA_NA; DH_ = DrumSound.TABLA_DHA
|
|
TT_ = DrumSound.TABLA_TIT; KE_ = DrumSound.TABLA_KE
|
|
GB_ = DrumSound.TABLA_GE_BEND; GE_ = DrumSound.TABLA_GE
|
|
|
|
print(f" {root} {mode} | {bpm} bpm | {REV}")
|
|
|
|
# ── Pad drone — random synth, the whole piece ──
|
|
pad_synth = random.choice(["strings_synth", "granular_synth", "vocal_synth"])
|
|
pad = score.part("pad", synth=pad_synth, envelope="pad",
|
|
detune=random.randint(6, 14), spread=0.4,
|
|
reverb=0.5, reverb_type=REV, volume=0.15,
|
|
analog=random.uniform(0.1, 0.4))
|
|
prog = key.progression("i", "iv", "V", "i")
|
|
for _ in range(6):
|
|
for chord in prog:
|
|
pad.add(chord, Duration.WHOLE, velocity=random.randint(48, 62))
|
|
|
|
# ── 1: HIGH — theremin or flute, random melody from scale ──
|
|
lead_synth = random.choice(["theremin", "flute", "pedal_steel"])
|
|
lead = score.part("lead", instrument=lead_synth, volume=0.25,
|
|
reverb=0.4, reverb_type=REV,
|
|
delay=0.2, delay_time=random.uniform(0.2, 0.5),
|
|
delay_feedback=random.uniform(0.2, 0.4))
|
|
lead.rest(4.0)
|
|
# Generate melody by WALKING the scale — stepwise with occasional leaps
|
|
# Real melodies move to neighboring notes, not random jumps
|
|
scale_idx = len(scale_tones) - 1 # start high
|
|
octave = 5
|
|
for _ in range(random.randint(10, 16)):
|
|
note = scale_tones[scale_idx]
|
|
dur = random.choice([1.5, 2.0, 3.0, 4.0])
|
|
vel = random.randint(58, 70)
|
|
lead.add(f"{note}{octave}", dur, velocity=vel)
|
|
# Mostly step down (descent!), sometimes hold, rare leap
|
|
r = random.random()
|
|
if r < 0.5: # step down
|
|
scale_idx -= 1
|
|
elif r < 0.65: # step up (tension)
|
|
scale_idx += 1
|
|
elif r < 0.8: # leap down
|
|
scale_idx -= random.randint(2, 3)
|
|
# else hold same note
|
|
# Wrap octaves
|
|
if scale_idx < 0:
|
|
scale_idx += len(scale_tones)
|
|
octave -= 1
|
|
elif scale_idx >= len(scale_tones):
|
|
scale_idx -= len(scale_tones)
|
|
octave += 1
|
|
octave = max(3, min(5, octave))
|
|
|
|
# ── 2: Kalimba or steel drum — random arpeggios ──
|
|
sparkle_inst = random.choice(["kalimba", "steel_drum", "vibraphone", "harp"])
|
|
sparkle = score.part("sparkle", instrument=sparkle_inst, volume=0.18,
|
|
delay=0.2, delay_time=random.uniform(0.15, 0.4),
|
|
delay_feedback=random.uniform(0.3, 0.5),
|
|
reverb=0.4, reverb_type=REV)
|
|
sparkle.rest(8.0)
|
|
# Arpeggios — walk chord tones in patterns, not random
|
|
for chord in prog * 3:
|
|
chord_tones = [t.name for t in chord.tones]
|
|
pattern_type = random.choice(["up", "down", "updown"])
|
|
oct = random.choice([4, 5])
|
|
if pattern_type == "up":
|
|
seq = chord_tones + [chord_tones[0]]
|
|
elif pattern_type == "down":
|
|
seq = list(reversed(chord_tones)) + [chord_tones[-1]]
|
|
else:
|
|
seq = chord_tones + list(reversed(chord_tones[1:-1]))
|
|
# Pad to 8 notes
|
|
while len(seq) < 8:
|
|
seq = seq + seq
|
|
seq = seq[:8]
|
|
for i, n in enumerate(seq):
|
|
o = oct + (1 if i >= 4 and pattern_type == "up" else 0)
|
|
sparkle.add(f"{n}{o}", Duration.EIGHTH,
|
|
velocity=random.randint(48, 58))
|
|
|
|
# ── 3: Piano — random broken chords ──
|
|
piano = score.part("piano", instrument="piano", volume=0.22,
|
|
reverb=0.35, reverb_type=REV)
|
|
piano.rest(random.uniform(8.0, 16.0))
|
|
for chord in prog * 2:
|
|
chord_tones = [t.name for t in chord.tones]
|
|
oct = random.choice([3, 4])
|
|
# Walk up the chord then back down
|
|
up = [f"{n}{oct}" for n in chord_tones]
|
|
up.append(f"{chord_tones[0]}{oct+1}")
|
|
down = [f"{n}{oct}" for n in reversed(chord_tones[:-1])]
|
|
arp = (up + down)[:8]
|
|
for n in arp:
|
|
piano.add(n, Duration.EIGHTH,
|
|
velocity=random.randint(58, 65))
|
|
|
|
# ── 4: Cello — descending long notes ──
|
|
cello = score.part("cello", instrument="cello", volume=0.2,
|
|
reverb=0.4, reverb_type=REV)
|
|
cello.rest(16.0)
|
|
oct = 3
|
|
for _ in range(8):
|
|
note = random.choice(scale_tones)
|
|
cello.add(f"{note}{oct}", 4.0, velocity=random.randint(48, 62))
|
|
if random.random() < 0.4 and oct > 2:
|
|
oct -= 1
|
|
|
|
# ── 5: Bass — deep, sparse ──
|
|
bass_inst = random.choice(["upright_bass", "didgeridoo"])
|
|
bass = score.part("bass", instrument=bass_inst, volume=0.18)
|
|
bass.rest(random.uniform(4.0, 12.0))
|
|
for chord in prog * 4:
|
|
r = chord.root
|
|
if r:
|
|
oct = 2 if bass_inst == "upright_bass" else 1
|
|
bass.add(f"{r.name}{oct}", 4.0,
|
|
velocity=random.randint(50, 65))
|
|
|
|
# ── Drums: random combination ──
|
|
drum_start = random.randint(2, 5) * 4 # 8-20 beats silence
|
|
score.add_pattern(Pattern(name="s", time_signature="4/4",
|
|
beats=float(drum_start), hits=[]),
|
|
repeats=1)
|
|
|
|
# Pick random world drum combo
|
|
drum_choice = random.choice(["cajon folk", "djembe", "keherwa", "dadra"])
|
|
score.drums(drum_choice, repeats=random.randint(6, 12))
|
|
|
|
# Tabla solo at the end — always
|
|
score.add_pattern(Pattern(name="ts1", time_signature="4/4", beats=8.0, hits=[
|
|
_Hit(DH_, 0.0, 72), _Hit(NA, 2.5, 48),
|
|
_Hit(DH_, 4.0, 75), _Hit(TT_, 5.5, 25), _Hit(NA, 6.0, 45),
|
|
_Hit(DH_, 7.5, 72),
|
|
]), repeats=1)
|
|
|
|
# Generate random tabla solo — different every time
|
|
solo_hits = []
|
|
beat = 0.0
|
|
while beat < 16.0:
|
|
stroke = random.choice([DH_, NA, TT_, KE_, GB_, GE_])
|
|
vel = random.randint(35, 120)
|
|
# Ghost notes are quiet, accents are loud
|
|
if stroke == TT_:
|
|
vel = random.randint(25, 50)
|
|
elif stroke in (DH_, GB_):
|
|
vel = random.randint(70, 120)
|
|
solo_hits.append(_Hit(stroke, beat, vel))
|
|
# Random spacing — mix of tight and open
|
|
beat += random.choice([0.125, 0.25, 0.25, 0.5, 0.5, 1.0])
|
|
|
|
score.add_pattern(Pattern(name="ts_rand", time_signature="4/4",
|
|
beats=16.0, hits=solo_hits), repeats=1)
|
|
score.set_drum_effects(reverb=0.3, reverb_type=REV)
|
|
|
|
play_song(score, f"Descent — {root} {mode} (generative, {REV})")
|
|
|
|
|
|
def pop_rock():
|
|
"""Pop Rock — the I-V-vi-IV progression that launched a thousand hits."""
|
|
import random
|
|
from pytheory import Fretboard
|
|
random.seed(42)
|
|
score = Score("4/4", bpm=120)
|
|
fb = Fretboard.guitar()
|
|
|
|
guitar = score.part("guitar", instrument="acoustic_guitar", fretboard=fb,
|
|
reverb=0.2, reverb_type="plate", humanize=0.15, pan=-0.2)
|
|
bass = score.part("bass", instrument="bass_guitar", volume=0.35, humanize=0.1)
|
|
lead = score.part("lead", instrument="electric_guitar",
|
|
cabinet=1.0, cabinet_brightness=0.6,
|
|
reverb=0.2, reverb_type="plate", pan=0.2)
|
|
strings = score.part("strings", instrument="string_ensemble", volume=0.12,
|
|
reverb=0.35, reverb_type="hall", ensemble=6)
|
|
|
|
prog = ["G", "D", "Em", "C"]
|
|
|
|
# Intro — picked
|
|
for sym in prog:
|
|
chord_obj = Chord.from_symbol(sym)
|
|
tones = [t.name for t in chord_obj.tones]
|
|
for t in tones:
|
|
guitar.add(f"{t}3", Duration.QUARTER,
|
|
velocity=random.randint(62, 72))
|
|
|
|
# Verse — strum
|
|
for _ in range(2):
|
|
for sym in prog:
|
|
vd = random.randint(72, 88)
|
|
vu = random.randint(55, 70)
|
|
guitar.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
guitar.strum(sym, Duration.EIGHTH, direction="up", velocity=vu)
|
|
guitar.strum(sym, Duration.EIGHTH, direction="down", velocity=vd - 8)
|
|
guitar.strum(sym, Duration.QUARTER, direction="up", velocity=vu)
|
|
guitar.strum(sym, Duration.QUARTER, direction="down", velocity=vd)
|
|
|
|
bass_notes = ["G2", "G2", "D2", "D2", "E2", "E2", "C2", "C2"]
|
|
for _ in range(3):
|
|
for n in bass_notes:
|
|
bass.add(n, Duration.HALF, velocity=random.randint(68, 78))
|
|
|
|
# Melody
|
|
for _ in range(4):
|
|
lead.rest(Duration.WHOLE)
|
|
for note, dur, vel in [
|
|
("B4",0.5,78),("B4",0.5,75),("B4",0.5,78),("B4",0.5,72),
|
|
("A4",0.5,75),("A4",0.5,72),("B4",1.0,80),
|
|
("B4",0.5,78),("B4",0.5,75),("B4",0.5,78),("D5",0.5,82),
|
|
("G4",0.75,72),("G4",0.25,68),("A4",1.0,78),
|
|
("B4",0.5,78),("B4",0.5,75),("B4",0.5,78),("B4",0.5,72),
|
|
("A4",0.5,75),("A4",0.5,72),("B4",0.5,78),("A4",0.5,72),
|
|
("G4",2.0,80),
|
|
]:
|
|
lead.add(note, dur, velocity=vel)
|
|
|
|
for _ in range(4):
|
|
strings.rest(Duration.WHOLE)
|
|
for sym in prog * 2:
|
|
strings.add(Chord.from_symbol(sym), Duration.WHOLE,
|
|
velocity=random.randint(55, 68))
|
|
|
|
score.drums("rock", repeats=6)
|
|
|
|
play_song(score, "Pop Rock — G D Em C (I-V-vi-IV)")
|
|
|
|
|
|
def sitar_drone():
|
|
"""Sitar Drone — Raga Bhairav with hold() polyphony, 22-shruti JI."""
|
|
shruti = SYSTEMS["shruti"]
|
|
score = Score("4/4", bpm=72, system=shruti)
|
|
|
|
ts = TonedScale(system=shruti, tonic=Tone("Sa", octave=4, system=shruti))
|
|
bh = list(ts["bhairav"].tones)
|
|
S, kR, G, M, P, kD, N, S2 = bh
|
|
|
|
sitar = score.part("sitar", instrument="sitar", volume=0.3,
|
|
reverb=0.4, reverb_type="taj_mahal")
|
|
# Sa drone held — rings under the whole melody
|
|
sitar.hold(Tone("Sa", octave=3, system=shruti), 32.0, velocity=60)
|
|
sitar.rest(Duration.WHOLE)
|
|
for tone, dur, vel in [
|
|
(S, 2.0, 72), (kR, 0.5, 62), (S, 0.5, 68),
|
|
(G, 2.0, 78), (kR, 0.5, 60), (G, 0.5, 70),
|
|
(M, 1.5, 75), (P, 2.5, 82),
|
|
(kD, 0.5, 65), (P, 1.0, 75), (M, 0.5, 65),
|
|
(G, 0.5, 68), (kR, 0.5, 60), (S, 2.0, 78),
|
|
(kR, 0.25, 62), (G, 0.25, 65), (M, 0.25, 70), (P, 0.25, 75),
|
|
(kD, 0.25, 70), (N, 0.25, 78), (S2, 0.5, 85),
|
|
(N, 0.25, 68), (kD, 0.25, 62), (P, 0.5, 68),
|
|
(M, 0.5, 62), (G, 0.5, 65), (kR, 0.5, 58),
|
|
(S, 4.0, 80),
|
|
]:
|
|
sitar.add(tone, dur, velocity=vel)
|
|
|
|
tanpura = score.part("tanpura", synth="strings_synth", envelope="pad",
|
|
detune=3, lowpass=900, volume=0.12,
|
|
reverb=0.5, reverb_type="taj_mahal")
|
|
tanpura_pa = score.part("tanpura_pa", synth="strings_synth", envelope="pad",
|
|
detune=3, lowpass=1200, volume=0.1,
|
|
reverb=0.5, reverb_type="taj_mahal")
|
|
for _ in range(8):
|
|
tanpura.add(Tone("Sa", octave=3, system=shruti), Duration.WHOLE)
|
|
tanpura_pa.add(Tone("Pa", octave=3, system=shruti), Duration.WHOLE)
|
|
|
|
NA = DrumSound.TABLA_NA
|
|
DH_ = DrumSound.TABLA_DHA
|
|
TT_ = DrumSound.TABLA_TIT
|
|
silence = Pattern(name="s", time_signature="4/4", beats=8.0, hits=[])
|
|
score.add_pattern(silence, repeats=1)
|
|
p = Pattern(name="t", time_signature="4/4", beats=4.0, hits=[
|
|
_Hit(DH_, 0.0, 68), _Hit(TT_, 0.5, 25), _Hit(NA, 1.0, 55),
|
|
_Hit(NA, 2.0, 52), _Hit(DH_, 3.0, 68),
|
|
])
|
|
score.add_pattern(p, repeats=6)
|
|
score.set_drum_effects(reverb=0.25, reverb_type="taj_mahal")
|
|
|
|
play_song(score, "Sitar Drone — Raga Bhairav (22-Shruti JI, hold() polyphony)")
|
|
|
|
|
|
def acid_tabla():
|
|
"""Acid Tabla — 303 filter automation meets Indian percussion."""
|
|
score = Score("4/4", bpm=132)
|
|
|
|
# ── House drums ──
|
|
score.drums("house", repeats=20, fill="house", fill_every=8)
|
|
score.set_drum_effects(volume=0.45)
|
|
|
|
# ── 303 acid bass ──
|
|
acid = score.part("acid", synth="saw", volume=0.75,
|
|
legato=True, glide=0.035,
|
|
distortion=0.35, distortion_drive=4.5,
|
|
saturation=0.15, humanize=0.05)
|
|
|
|
# Intro (4 bars): filter closed, high resonance
|
|
acid.set(lowpass=600, lowpass_q=12.0)
|
|
for _ in range(4):
|
|
for n in ["C3","C3","C2","C3","Eb3","C2","G2","C3"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
|
|
# Build (4 bars): filter opens
|
|
acid.ramp(over=Duration.WHOLE * 4, curve="ease_in", lowpass=4500)
|
|
for _ in range(4):
|
|
for n in ["C2","G2","C3","Eb3","C2","Bb2","G2","C3"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
|
|
# Peak (4 bars): wide open, wilder pattern
|
|
acid.set(lowpass=7000, lowpass_q=7.0)
|
|
for _ in range(2):
|
|
for n in ["C2","C3","Eb3","G3","C2","Bb2","G2","Eb3"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
for _ in range(2):
|
|
for n in ["C2","Eb3","C3","G3","Bb2","C3","G2","C2"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
|
|
# Tabla section (4 bars): filter pulls back
|
|
acid.set(lowpass=3000, lowpass_q=5.0)
|
|
for _ in range(4):
|
|
for n in ["C2","G2","C3","C2","Eb2","G2","Bb2","C2"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
|
|
# Outro (4 bars): filter closes
|
|
acid.ramp(over=Duration.WHOLE * 4, curve="ease_out", lowpass=400, lowpass_q=15.0)
|
|
for _ in range(4):
|
|
for n in ["C3","G2","C2","C3","C2","G2","Eb2","C2"]:
|
|
acid.add(n, Duration.EIGHTH)
|
|
|
|
# ── Tabla: enters bar 9, rides through to the end ──
|
|
tabla = score.part("tabla", synth="sine", volume=0.55, reverb=0.15)
|
|
|
|
# 8 bars rest
|
|
for _ in range(64):
|
|
tabla.rest(Duration.EIGHTH)
|
|
|
|
# Bars 9-12: keherwa groove
|
|
for _ in range(4):
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=100, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=55)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=50)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=88)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=82)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=52)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=95, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_GE, Duration.EIGHTH, velocity=78)
|
|
|
|
# Bars 13-14: busier with 16ths
|
|
for _ in range(2):
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=105, articulation="marcato")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=52)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=90)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=85)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=58)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=100, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_GE_BEND, Duration.EIGHTH, velocity=88)
|
|
|
|
# Bars 15-16: tihai crescendo ending
|
|
for vel in [85, 90, 95]:
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=vel, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=int(vel * 0.6))
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=int(vel * 0.75))
|
|
for vel in [100, 105, 110]:
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=vel, articulation="marcato")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=int(vel * 0.55))
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=int(vel * 0.7))
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.QUARTER, velocity=127, articulation="fermata")
|
|
tabla.hit(DrumSound.TABLA_GE_BEND, Duration.QUARTER, velocity=110)
|
|
tabla.rest(Duration.HALF)
|
|
|
|
# Bars 17-20: tabla continues through outro, lighter
|
|
for _ in range(4):
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=85, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=45)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=42)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=75)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=70)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=42)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=80)
|
|
tabla.hit(DrumSound.TABLA_GE, Duration.EIGHTH, velocity=65)
|
|
|
|
# ── Pad: enters at peak, fades during outro ──
|
|
pad = score.part("pad", synth="supersaw", envelope="pad", volume=0.0,
|
|
reverb=0.4, chorus=0.2, detune=10, lowpass=2500)
|
|
for _ in range(32):
|
|
pad.rest(Duration.QUARTER)
|
|
pad.ramp(over=Duration.WHOLE * 2, volume=0.18)
|
|
for sym in ["Cm", "Ab", "Eb", "Bb"] * 3:
|
|
pad.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
pad.ramp(over=Duration.WHOLE * 2, curve="ease_out", volume=0.0)
|
|
for sym in ["Cm", "Cm"]:
|
|
pad.add(Chord.from_symbol(sym), Duration.WHOLE)
|
|
|
|
play_song(score, "Acid Tabla — 303 filter automation + tabla (ramp, articulations, Part.hit)")
|
|
|
|
|
|
def snare_cadence():
|
|
"""Snare Cadence — full drumline with ensemble, flams, diddles, cheese."""
|
|
score = Score("4/4", bpm=120)
|
|
|
|
S = DrumSound.MARCH_SNARE
|
|
R = DrumSound.MARCH_RIMSHOT
|
|
C = DrumSound.MARCH_CLICK
|
|
Q1 = DrumSound.QUAD_1
|
|
Q2 = DrumSound.QUAD_2
|
|
Q3 = DrumSound.QUAD_3
|
|
Q4 = DrumSound.QUAD_4
|
|
QS = DrumSound.QUAD_SPOCK
|
|
B1 = DrumSound.BASS_1
|
|
B2 = DrumSound.BASS_2
|
|
B3 = DrumSound.BASS_3
|
|
B4 = DrumSound.BASS_4
|
|
B5 = DrumSound.BASS_5
|
|
|
|
# Snare line — 8 players
|
|
p = score.part("snares", synth="sine", volume=0.9, reverb=0.2, ensemble=8)
|
|
# Quad line — 4 players
|
|
q = score.part("quads", synth="sine", volume=0.5, reverb=0.2, ensemble=4)
|
|
# Bass line — 5 players
|
|
b = score.part("basses", synth="sine", volume=0.55, reverb=0.2, ensemble=5)
|
|
|
|
_trip = 1.0 / 3
|
|
|
|
# Helper: bass split run (down or up)
|
|
def bass_down(dur=Duration.SIXTEENTH):
|
|
b.hit(B1, dur, velocity=95)
|
|
b.hit(B2, dur, velocity=90)
|
|
b.hit(B3, dur, velocity=85)
|
|
b.hit(B4, dur, velocity=90)
|
|
|
|
def bass_up(dur=Duration.SIXTEENTH):
|
|
b.hit(B4, dur, velocity=90)
|
|
b.hit(B3, dur, velocity=85)
|
|
b.hit(B2, dur, velocity=90)
|
|
b.hit(B1, dur, velocity=95)
|
|
|
|
def bass_hit(dur=Duration.QUARTER):
|
|
b.hit(B3, dur, velocity=100)
|
|
|
|
def quad_sweep_down():
|
|
q.hit(Q1, Duration.SIXTEENTH, velocity=95)
|
|
q.hit(Q2, Duration.SIXTEENTH, velocity=88)
|
|
q.hit(Q3, Duration.SIXTEENTH, velocity=82)
|
|
q.hit(Q4, Duration.SIXTEENTH, velocity=78)
|
|
|
|
def quad_sweep_up():
|
|
q.hit(Q4, Duration.SIXTEENTH, velocity=78)
|
|
q.hit(Q3, Duration.SIXTEENTH, velocity=82)
|
|
q.hit(Q2, Duration.SIXTEENTH, velocity=88)
|
|
q.hit(Q1, Duration.SIXTEENTH, velocity=95)
|
|
|
|
# ── Click count-off ──
|
|
for _ in range(4):
|
|
p.hit(C, Duration.QUARTER, velocity=95)
|
|
q.rest(Duration.QUARTER)
|
|
b.rest(Duration.QUARTER)
|
|
|
|
# ── Section 1: 16th groove — snares only (4 bars) ──
|
|
for _ in range(16):
|
|
q.rest(Duration.QUARTER)
|
|
b.rest(Duration.QUARTER)
|
|
|
|
for _ in range(2):
|
|
p.hit(R, Duration.SIXTEENTH, velocity=118)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=35)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(R, Duration.SIXTEENTH, velocity=115)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.hit(R, Duration.SIXTEENTH, velocity=118)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=35)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.hit(R, Duration.SIXTEENTH, velocity=120)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
|
|
# Triplets mixed in
|
|
for _ in range(2):
|
|
p.hit(R, _trip, velocity=118)
|
|
p.hit(S, _trip, velocity=32)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.hit(R, _trip, velocity=115)
|
|
p.hit(S, _trip, velocity=28)
|
|
p.hit(S, _trip, velocity=32)
|
|
p.hit(R, Duration.SIXTEENTH, velocity=118)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
p.hit(R, _trip, velocity=118)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.hit(S, _trip, velocity=35)
|
|
|
|
# ── Section 2: Quads + bass enter (4 bars) ──
|
|
for _ in range(2):
|
|
p.flam(S, Duration.QUARTER, velocity=118)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.hit(R, _trip, velocity=118)
|
|
p.hit(S, _trip, velocity=28)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.flam(S, Duration.QUARTER, velocity=118)
|
|
|
|
quad_sweep_down()
|
|
q.hit(QS, Duration.QUARTER, velocity=100)
|
|
quad_sweep_up()
|
|
q.hit(QS, Duration.QUARTER, velocity=100)
|
|
|
|
bass_hit()
|
|
b.hit(B5, Duration.QUARTER, velocity=95)
|
|
bass_hit()
|
|
b.hit(B1, Duration.QUARTER, velocity=95)
|
|
|
|
for _ in range(2):
|
|
p.hit(S, _trip, velocity=35)
|
|
p.flam(S, _trip * 2, velocity=118)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
p.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
p.flam(S, Duration.QUARTER, velocity=118)
|
|
p.hit(S, _trip, velocity=28)
|
|
p.hit(R, _trip, velocity=122)
|
|
p.hit(S, _trip, velocity=35)
|
|
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
q.hit(Q1, Duration.EIGHTH, velocity=95)
|
|
q.hit(Q4, Duration.EIGHTH, velocity=85)
|
|
q.hit(QS, Duration.QUARTER, velocity=100)
|
|
|
|
bass_down()
|
|
bass_up()
|
|
b.hit(B3, Duration.HALF, velocity=100)
|
|
|
|
# ── Section 3: Flams + diddles + full line (4 bars) ──
|
|
for _ in range(2):
|
|
p.flam(S, Duration.QUARTER, velocity=120)
|
|
p.diddle(S, Duration.EIGHTH, velocity=45)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.hit(S, _trip, velocity=32)
|
|
p.hit(S, _trip, velocity=28)
|
|
p.hit(R, Duration.EIGHTH, velocity=122)
|
|
p.diddle(S, Duration.EIGHTH, velocity=42)
|
|
|
|
q.hit(Q1, Duration.QUARTER, velocity=95)
|
|
q.hit(Q3, Duration.EIGHTH, velocity=55)
|
|
q.hit(Q2, _trip, velocity=55)
|
|
q.hit(Q3, _trip, velocity=55)
|
|
q.hit(Q4, _trip, velocity=55)
|
|
q.hit(QS, Duration.EIGHTH, velocity=100)
|
|
q.hit(Q1, Duration.EIGHTH, velocity=55)
|
|
|
|
bass_hit()
|
|
b.hit(B1, Duration.EIGHTH, velocity=90)
|
|
b.hit(B5, Duration.EIGHTH, velocity=95)
|
|
bass_hit()
|
|
b.hit(B5, Duration.EIGHTH, velocity=90)
|
|
b.hit(B1, Duration.EIGHTH, velocity=95)
|
|
|
|
for _ in range(2):
|
|
p.diddle(S, Duration.EIGHTH, velocity=45)
|
|
p.hit(R, _trip, velocity=120)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.hit(S, _trip, velocity=32)
|
|
p.diddle(S, Duration.EIGHTH, velocity=48)
|
|
p.hit(R, _trip, velocity=118)
|
|
p.hit(S, _trip, velocity=28)
|
|
p.hit(S, _trip, velocity=30)
|
|
p.flam(S, Duration.EIGHTH, velocity=122)
|
|
p.hit(S, Duration.EIGHTH, velocity=35)
|
|
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
|
|
bass_down()
|
|
bass_up()
|
|
bass_down()
|
|
bass_up()
|
|
|
|
# ── Section 4: Cheese + 32nds (4 bars) ──
|
|
for _ in range(2):
|
|
p.cheese(S, Duration.QUARTER, velocity=120)
|
|
p.hit(S, 0.0625, velocity=30)
|
|
p.hit(S, 0.0625, velocity=32)
|
|
p.hit(S, 0.0625, velocity=35)
|
|
p.hit(S, 0.0625, velocity=30)
|
|
p.cheese(S, Duration.QUARTER, velocity=118)
|
|
p.diddle(S, Duration.EIGHTH, velocity=48)
|
|
p.hit(R, Duration.EIGHTH, velocity=125)
|
|
|
|
q.hit(QS, Duration.QUARTER, velocity=105)
|
|
q.hit(Q1, Duration.SIXTEENTH, velocity=55)
|
|
q.hit(Q2, Duration.SIXTEENTH, velocity=55)
|
|
q.hit(Q3, Duration.SIXTEENTH, velocity=55)
|
|
q.hit(Q4, Duration.SIXTEENTH, velocity=55)
|
|
q.hit(QS, Duration.QUARTER, velocity=105)
|
|
q.hit(Q4, Duration.EIGHTH, velocity=55)
|
|
q.hit(Q1, Duration.EIGHTH, velocity=90)
|
|
|
|
bass_hit()
|
|
b.hit(B1, Duration.EIGHTH, velocity=90)
|
|
b.hit(B3, Duration.EIGHTH, velocity=85)
|
|
b.hit(B5, Duration.EIGHTH, velocity=95)
|
|
b.hit(B3, Duration.EIGHTH, velocity=85)
|
|
bass_hit()
|
|
b.rest(Duration.QUARTER)
|
|
|
|
# All cheese
|
|
p.cheese(S, Duration.QUARTER, velocity=122)
|
|
p.cheese(S, Duration.QUARTER, velocity=120)
|
|
p.cheese(S, Duration.QUARTER, velocity=125)
|
|
p.cheese(S, Duration.QUARTER, velocity=122)
|
|
|
|
q.hit(QS, Duration.QUARTER, velocity=105)
|
|
q.hit(QS, Duration.QUARTER, velocity=105)
|
|
q.hit(QS, Duration.QUARTER, velocity=108)
|
|
q.hit(QS, Duration.QUARTER, velocity=105)
|
|
|
|
b.hit(B5, Duration.QUARTER, velocity=100)
|
|
b.hit(B3, Duration.QUARTER, velocity=100)
|
|
b.hit(B1, Duration.QUARTER, velocity=100)
|
|
b.hit(B3, Duration.QUARTER, velocity=100)
|
|
|
|
p.flam(S, Duration.EIGHTH, velocity=120)
|
|
p.diddle(S, Duration.EIGHTH, velocity=50)
|
|
p.flam(S, Duration.EIGHTH, velocity=122)
|
|
p.diddle(S, Duration.EIGHTH, velocity=52)
|
|
p.flam(S, Duration.EIGHTH, velocity=125)
|
|
p.diddle(S, Duration.EIGHTH, velocity=55)
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
p.hit(S, Duration.EIGHTH, velocity=38)
|
|
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
|
|
bass_down()
|
|
bass_up()
|
|
bass_down()
|
|
bass_up()
|
|
|
|
# ── Section 5: 16ths + triplet 16ths + 32nds (4 bars) ──
|
|
_trip16 = 1.0 / 6
|
|
|
|
for _ in range(2):
|
|
for beat in range(4):
|
|
p.hit(R, _trip, velocity=118)
|
|
p.hit(S, _trip, velocity=35)
|
|
p.hit(S, _trip, velocity=32)
|
|
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
quad_sweep_down()
|
|
quad_sweep_up()
|
|
|
|
bass_hit()
|
|
b.hit(B5, Duration.QUARTER, velocity=95)
|
|
bass_hit()
|
|
b.hit(B1, Duration.QUARTER, velocity=95)
|
|
|
|
# 32nd run crescendo
|
|
for i in range(32):
|
|
p.hit(S, 0.0625, velocity=min(22 + i * 3, 92))
|
|
p.hit(R, Duration.EIGHTH, velocity=125)
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
|
|
for _ in range(4):
|
|
q.hit(Q1, 0.0625, velocity=55)
|
|
q.hit(Q2, 0.0625, velocity=55)
|
|
q.hit(Q3, 0.0625, velocity=55)
|
|
q.hit(Q4, 0.0625, velocity=55)
|
|
q.hit(QS, Duration.QUARTER, velocity=108)
|
|
|
|
bass_down()
|
|
bass_up()
|
|
bass_down()
|
|
b.hit(B5, Duration.QUARTER, velocity=100)
|
|
b.hit(B1, Duration.QUARTER, velocity=100)
|
|
|
|
# Triplet 16ths — all sections
|
|
for _ in range(2):
|
|
for beat in range(4):
|
|
p.hit(R, _trip16, velocity=115)
|
|
p.hit(S, _trip16, velocity=30)
|
|
p.hit(S, _trip16, velocity=32)
|
|
p.hit(R, _trip16, velocity=112)
|
|
p.hit(S, _trip16, velocity=28)
|
|
p.hit(S, _trip16, velocity=30)
|
|
|
|
for beat in range(4):
|
|
q.hit(Q1, _trip16, velocity=90)
|
|
q.hit(Q2, _trip16, velocity=55)
|
|
q.hit(Q3, _trip16, velocity=55)
|
|
q.hit(Q4, _trip16, velocity=55)
|
|
q.hit(Q3, _trip16, velocity=55)
|
|
q.hit(Q2, _trip16, velocity=55)
|
|
|
|
bass_down()
|
|
bass_up()
|
|
bass_down()
|
|
bass_up()
|
|
|
|
# ── Section 6: Buzz roll climax (2 bars) ──
|
|
for i in range(64):
|
|
p.hit(S, 0.0625, velocity=min(20 + i * 1.5, 100))
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
|
|
for i in range(32):
|
|
q.hit([Q1, Q2, Q3, Q4][i % 4], 0.0625, velocity=min(40 + i * 2, 95))
|
|
q.hit(QS, Duration.QUARTER, velocity=110)
|
|
|
|
for i in range(16):
|
|
b.hit([B1, B2, B3, B4, B5, B4, B3, B2,
|
|
B1, B2, B3, B4, B5, B4, B3, B2][i], Duration.SIXTEENTH, velocity=90)
|
|
b.hit(B3, Duration.HALF, velocity=100)
|
|
b.hit(B3, Duration.HALF, velocity=100)
|
|
|
|
# ── Ending: big unison hits ──
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
q.hit(QS, Duration.EIGHTH, velocity=110)
|
|
b.hit(B3, Duration.EIGHTH, velocity=100)
|
|
|
|
p.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
q.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
b.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
|
|
p.hit(R, Duration.EIGHTH, velocity=127)
|
|
q.hit(QS, Duration.EIGHTH, velocity=110)
|
|
b.hit(B3, Duration.EIGHTH, velocity=100)
|
|
|
|
p.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
q.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
b.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
|
|
# Flam into final CRACK — all sections
|
|
p.flam(S, Duration.EIGHTH, velocity=127)
|
|
q.hit(QS, Duration.EIGHTH, velocity=110)
|
|
b.hit(B3, Duration.EIGHTH, velocity=100)
|
|
|
|
p.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
q.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
b.rest(Duration.QUARTER + Duration.EIGHTH)
|
|
|
|
p.hit(R, Duration.QUARTER, velocity=127)
|
|
q.hit(QS, Duration.QUARTER, velocity=110)
|
|
b.hit(B3, Duration.QUARTER, velocity=100)
|
|
|
|
p.rest(Duration.HALF)
|
|
q.rest(Duration.HALF)
|
|
b.rest(Duration.HALF)
|
|
|
|
play_song(score, "Snare Cadence — full drumline (8 snares, 4 quads, 5 basses)")
|
|
|
|
|
|
def ensemble_showcase():
|
|
"""Ensemble Showcase — acid bass, tabla solo, strings, snare line."""
|
|
score = Score("4/4", bpm=128)
|
|
|
|
# ── Drums: house kit ──
|
|
score.drums("house", repeats=24, fill="house", fill_every=8)
|
|
score.set_drum_effects(volume=0.4, reverb=0.1)
|
|
|
|
# ── 303 Acid Bass: detuned, spread, LFO filter, ensemble=3 ──
|
|
acid = score.part("acid", synth="saw", volume=0.55, ensemble=3,
|
|
lowpass=400, lowpass_q=10.0, distortion=0.35,
|
|
distortion_drive=4.0, legato=True, glide=0.03,
|
|
detune=12, spread=0.4, sub_osc=0.15,
|
|
sidechain=0.5, sidechain_release=0.08)
|
|
|
|
acid.lfo("lowpass", rate=0.5, min=400, max=5000, bars=16, shape="sine")
|
|
for _ in range(8):
|
|
for n in ["C2", "C3", "C2", "Eb2", "C2", "G2", "Bb2", "C2"]:
|
|
acid.add(n, Duration.EIGHTH, velocity=90)
|
|
|
|
acid.ramp(over=Duration.WHOLE * 8, curve="ease_in", lowpass=6000)
|
|
for _ in range(8):
|
|
for n in ["C2", "Eb3", "C3", "G2", "Bb2", "C3", "G2", "C2"]:
|
|
acid.add(n, Duration.EIGHTH, velocity=95)
|
|
|
|
acid.ramp(over=Duration.WHOLE * 8, curve="ease_out", lowpass=500)
|
|
for _ in range(8):
|
|
for n in ["C2", "C3", "C2", "Eb2", "C2", "G2", "Bb2", "C2"]:
|
|
acid.add(n, Duration.EIGHTH, velocity=88)
|
|
|
|
# ── Strings: 16-player ensemble pad ──
|
|
strings = score.part("strings", instrument="string_ensemble", volume=0.0,
|
|
reverb=0.4, ensemble=16, detune=8, spread=0.5)
|
|
|
|
for _ in range(32):
|
|
strings.rest(Duration.QUARTER)
|
|
strings.ramp(over=Duration.WHOLE * 4, curve="ease_in", volume=0.18)
|
|
for ch in ["Cm", "Ab", "Eb", "Bb"] * 4:
|
|
strings.add(Chord.from_symbol(ch), Duration.WHOLE, velocity=55)
|
|
strings.ramp(over=Duration.WHOLE * 4, curve="ease_out", volume=0.0)
|
|
for ch in ["Cm", "Ab", "Eb", "Bb"]:
|
|
strings.add(Chord.from_symbol(ch), Duration.WHOLE, velocity=45)
|
|
for _ in range(16):
|
|
strings.rest(Duration.QUARTER)
|
|
|
|
# ── Tabla: ensemble=3, enters bar 9 ──
|
|
tabla = score.part("tabla", synth="sine", volume=0.0, reverb=0.15, ensemble=3)
|
|
|
|
for _ in range(32):
|
|
tabla.rest(Duration.QUARTER)
|
|
tabla.ramp(over=Duration.WHOLE * 2, volume=0.45)
|
|
|
|
# Keherwa groove — 8 bars
|
|
for _ in range(8):
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=95, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=50)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=82)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=78)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=88, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_GE, Duration.EIGHTH, velocity=72)
|
|
|
|
# Tabla solo — getting busier
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=100, articulation="marcato")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=45)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=85)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=80)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=45)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=55)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=95, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_GE_BEND, Duration.EIGHTH, velocity=82)
|
|
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=105, articulation="marcato")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=55)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=45)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=48)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=88)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.SIXTEENTH, velocity=100)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=50)
|
|
tabla.hit(DrumSound.TABLA_GE_BEND, Duration.EIGHTH, velocity=85)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=108, articulation="accent")
|
|
|
|
# Tihai crescendo
|
|
for vel in [85, 90, 95, 100, 105, 110]:
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=vel, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.SIXTEENTH, velocity=int(vel * 0.55))
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.SIXTEENTH, velocity=int(vel * 0.7))
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.QUARTER, velocity=125, articulation="fermata")
|
|
tabla.hit(DrumSound.TABLA_GE_BEND, Duration.QUARTER, velocity=110)
|
|
|
|
# Groove out
|
|
for _ in range(4):
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=88, articulation="accent")
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=45)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=42)
|
|
tabla.hit(DrumSound.TABLA_NA, Duration.EIGHTH, velocity=75)
|
|
tabla.hit(DrumSound.TABLA_TIN, Duration.EIGHTH, velocity=70)
|
|
tabla.hit(DrumSound.TABLA_TIT, Duration.EIGHTH, velocity=42)
|
|
tabla.hit(DrumSound.TABLA_DHA, Duration.EIGHTH, velocity=80)
|
|
tabla.hit(DrumSound.TABLA_GE, Duration.EIGHTH, velocity=65)
|
|
|
|
# ── Snare line: 8-player ensemble, enters bar 17 ──
|
|
S = DrumSound.MARCH_SNARE
|
|
R = DrumSound.MARCH_RIMSHOT
|
|
|
|
snares = score.part("snares", synth="sine", volume=0.0, reverb=0.15, ensemble=8)
|
|
|
|
for _ in range(64):
|
|
snares.rest(Duration.QUARTER)
|
|
snares.ramp(over=Duration.WHOLE * 2, volume=0.7)
|
|
|
|
for _ in range(4):
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=118)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=115)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=118)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=35)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=120)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
|
|
# Buzz roll finale
|
|
for i in range(64):
|
|
snares.hit(S, 0.0625, velocity=min(20 + i * 1.5, 100))
|
|
snares.hit(R, Duration.EIGHTH, velocity=127)
|
|
snares.hit(R, Duration.EIGHTH, velocity=127)
|
|
|
|
snares.ramp(over=Duration.WHOLE * 2, curve="ease_out", volume=0.0)
|
|
for _ in range(2):
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=110)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=108)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=105)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
snares.hit(R, Duration.SIXTEENTH, velocity=100)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=30)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=28)
|
|
snares.hit(S, Duration.SIXTEENTH, velocity=32)
|
|
|
|
# ── Lead synth: 6-player ensemble, enters bar 5 ──
|
|
lead = score.part("lead", synth="saw", envelope="pluck", volume=0.0,
|
|
lowpass=3500, detune=6, chorus=0.1, reverb=0.2,
|
|
delay=0.15, delay_time=0.33, delay_feedback=0.25,
|
|
ensemble=6)
|
|
|
|
for _ in range(16):
|
|
lead.rest(Duration.QUARTER)
|
|
lead.ramp(over=Duration.WHOLE * 2, volume=0.3)
|
|
|
|
for _ in range(2):
|
|
lead.add("Eb5", Duration.QUARTER, velocity=88)
|
|
lead.add("G5", Duration.QUARTER, velocity=92)
|
|
lead.add("Bb5", Duration.HALF, velocity=95, articulation="accent")
|
|
lead.add("Ab5", Duration.QUARTER, velocity=88)
|
|
lead.add("G5", Duration.QUARTER, velocity=85)
|
|
lead.add("Eb5", Duration.QUARTER, velocity=82)
|
|
lead.add("D5", Duration.QUARTER, velocity=80)
|
|
|
|
lead.swell(["Eb5", "G5", "Bb5", "C6", "Bb5", "G5", "Eb5", "D5"],
|
|
Duration.QUARTER, low_vel=75, peak_vel=105)
|
|
lead.decrescendo(["Eb5", "D5", "C5", "Bb4"], Duration.HALF,
|
|
start_vel=90, end_vel=60)
|
|
|
|
for _ in range(16):
|
|
lead.rest(Duration.QUARTER)
|
|
|
|
lead.ramp(over=Duration.WHOLE * 2, volume=0.35)
|
|
lead.crescendo(["C5", "Eb5", "G5", "Bb5", "C6", "Eb6", "C6", "Bb5"],
|
|
Duration.QUARTER, start_vel=80, end_vel=110)
|
|
lead.add("G5", Duration.HALF, velocity=105, bend=1, bend_type="smooth")
|
|
lead.add("Eb5", Duration.HALF, velocity=95)
|
|
lead.decrescendo(["C5", "Bb4", "G4", "Eb4"], Duration.WHOLE,
|
|
start_vel=85, end_vel=40)
|
|
|
|
play_song(score, "Ensemble Showcase — acid bass, tabla solo, 16-player strings, 8-player snare line")
|
|
|
|
|
|
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),
|
|
"24": ("Journey (Western → World → Indian)", journey),
|
|
"25": ("Epic Bhairav (Orchestral + Tabla)", epic_bhairav),
|
|
"26": ("Acoustic Ensemble (Guitar+Uke+Mando+Cajón)", acoustic_ensemble),
|
|
"27": ("Ascent (Deep → Sky → Tabla Solo)", ascent),
|
|
"28": ("Descent (Generative — different every time)", descent),
|
|
"29": ("Pop Rock (I-V-vi-IV)", pop_rock),
|
|
"30": ("Sitar Drone (Bhairav, hold() polyphony)", sitar_drone),
|
|
"31": ("Acid Tabla (303 + tabla, ramp, articulations)", acid_tabla),
|
|
"32": ("Snare Cadence (marching snare, flams, diddles)", snare_cadence),
|
|
"33": ("Ensemble Showcase (acid+tabla+strings+snare line)", ensemble_showcase),
|
|
}
|
|
|
|
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-33, 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!")
|