"""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!")