Add Sleight of Hand (track 13) — nine genre shifts, one track

D minor, 100 BPM. Music box → didgeridoo → jazz piano → 808 drop →
solo theremin → choir → acid 303 through the choir → music box over
boom bap → everything at once. Singing bowl marks every transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 01:44:43 -04:00
parent 95350a43e3
commit 12f4a8e26d
4 changed files with 415 additions and 1 deletions
+1
View File
@@ -2,6 +2,7 @@
## 2026-04-02
- **Track 13: Sleight of Hand** — D minor, 100 BPM. Nine genre shifts in 72 bars. The 303 through the choir is the moment.
- **Track 12: Gravity** — C minor, 88 BPM. Hip hop with sparse piano, 808, boom bap + trap hats. Eastern touches: buried tambura, singing bowl bookends, sitar bend in breakdown.
- The Interruption: breakbeat delay (jungle echo), reese wide with reverb+delay, kick808 distortion, velocity list fades, harp shimmer delay
- The Observatory: stereo spread — radio left, signal right, broadcast crosses the field, clap delay
+2 -1
View File
@@ -28,7 +28,8 @@ Each track is a `.py` file. Run it to hear it.
9. **The Dialogue** — E Phrygian (Bhairavi), 75 BPM, shruti just intonation, A=432 Hz. Sitar (human) and theremin (machine) start alone, find each other through call-and-response, and become something neither could be on their own. House beat enters when they find the groove.
10. **Voltage** — F minor, 138 BPM. Raw oscillators, nothing else. Sine sub, saw lead, pulse counter-rhythm. Rhythm is pitch. Saw arp solo, pulse arp solo, 32nd note chaos at the peak. Aggressive, monophonic, electric.
11. **The Observatory** — G minor, 112 BPM. Chapel harmonies broadcast through shortwave static. Radio hiss, singing bowl, square-wave organ, choir, saw arp, supersaw halo pad, theremin signal melody. Patient house pulse arrives at bar 33.
12. **Gravity** — C minor, 88 BPM. Serious hip hop. Sparse piano stabs, 808 sub, boom bap drums with trap hat evolution. Rhodes melody, string swell. Tambura buried underneath, singing bowl bookends, one sitar bend in the breakdown. The weight of it all.
12. **Gravity** — C minor, 88 BPM. Sparse piano stabs, 808 sub, boom bap drums with trap hat evolution. Rhodes melody, string swell. Tambura buried underneath, singing bowl bookends, one sitar bend in the breakdown. The weight of it all.
13. **Sleight of Hand** — D minor, 100 BPM. Music box → didgeridoo → jazz piano → 808 drop → solo theremin → choir → acid 303 rips through the choir → music box returns over boom bap. You never see the next move coming.
## Usage
+1
View File
@@ -51,6 +51,7 @@ ALBUM_ORDER = [
"voltage.py",
"the_observatory.py",
"gravity.py",
"sleight_of_hand.py",
]
+411
View File
@@ -0,0 +1,411 @@
"""
SLEIGHT OF HAND — you never see the next move coming.
Every section is a surprise. Each one beautiful.
Together, they shouldn't work. They do.
D minor, 100 BPM.
"""
from pytheory import Key, Duration, Score, Tone, play_score
from pytheory.rhythm import DrumSound
key = Key("D", "minor")
s = key.scale # D E F G A Bb C
D = s[0]; E = s[1]; F = s[2]; G = s[3]
A = s[4]; Bb = s[5]; C = s[6]
score = Score("4/4", bpm=100)
K = DrumSound.KICK
S = DrumSound.SNARE
CH = DrumSound.CLOSED_HAT
OH = DrumSound.OPEN_HAT
prog = key.progression("i", "VII", "VI", "v")
# ═══════════════════════════════════════════════════════════════════
# STRUCTURE (72 bars, ~4:19):
# Bars 1-8: Music box — innocent, delicate, a lullaby
# Bars 9-16: Didgeridoo drone — the room changes completely
# Bars 17-24: Piano jazz chords — wait, where are we?
# Bars 25-32: 808 + trap hats slam in — now it's hip hop
# Bars 33-40: Everything drops to solo theremin — aching, alone
# Bars 41-48: Choir swells from nowhere — cathedral out of thin air
# Bars 49-56: Acid 303 rips through the choir — what??
# Bars 57-64: Music box returns — but now the 808 is underneath
# Bars 65-72: Everything at once — the trick revealed
# ═══════════════════════════════════════════════════════════════════
# ── MUSIC BOX — innocent opening, you think you know this track ──
box = score.part("music_box", instrument="music_box", volume=0.35,
reverb=0.5, reverb_type="taj_mahal",
delay=0.2, delay_time=0.3, delay_feedback=0.3,
pan=-0.2, humanize=0.08)
# Bars 1-8: simple melody — like a child's toy
box_melody = [
(D.add(12), Duration.QUARTER, 72), (F.add(12), Duration.QUARTER, 68),
(A.add(12), Duration.HALF, 75),
(G.add(12), Duration.QUARTER, 70), (F.add(12), Duration.EIGHTH, 65),
(E.add(12), Duration.EIGHTH, 62), (D.add(12), Duration.HALF, 68),
(A, Duration.QUARTER, 65), (D.add(12), Duration.QUARTER, 70),
(F.add(12), Duration.HALF, 72),
(E.add(12), Duration.QUARTER, 68), (D.add(12), Duration.QUARTER, 65),
(C.add(12), Duration.QUARTER, 62), (D.add(12), Duration.QUARTER, 70),
(None, Duration.QUARTER, 0), (A.add(12), Duration.QUARTER, 72),
(G.add(12), Duration.QUARTER, 68), (F.add(12), Duration.QUARTER, 65),
(D.add(12), Duration.WHOLE, 72),
(None, Duration.WHOLE, 0),
]
for note, dur, vel in box_melody:
if note is None:
box.rest(dur)
else:
box.add(note, dur, velocity=vel)
# Bars 9-56: silent
for _ in range(48):
box.rest(Duration.WHOLE)
# Bars 57-64: RETURNS — same melody, but everything's different now
box.set(volume=0.3)
for note, dur, vel in box_melody:
if note is None:
box.rest(dur)
else:
box.add(note, dur, velocity=max(30, vel - 8))
# Bars 65-72: continues into the finale, fading
for note, dur, vel in box_melody[:10]:
if note is None:
box.rest(dur)
else:
box.add(note, dur, velocity=max(25, vel - 20))
for _ in range(4):
box.rest(Duration.WHOLE)
# ── DIDGERIDOO — the room changes, bar 9 ─────────────────────
didge = score.part("didge", instrument="didgeridoo", volume=0.12,
reverb=0.35, reverb_type="cathedral",
chorus=0.2, chorus_rate=0.05, chorus_depth=0.01,
lowpass=350, pan=0.1)
for _ in range(8):
didge.rest(Duration.WHOLE)
# Bars 9-16: primal drone — where did the music box go?
for _ in range(8):
didge.add(D.add(-24), Duration.WHOLE, velocity=62)
# Bars 17-24: fades under the piano
for vel in [52, 42, 32, 22, 15, 10, 5, 0]:
if vel > 0:
didge.add(D.add(-24), Duration.WHOLE, velocity=vel)
else:
didge.rest(Duration.WHOLE)
# Silent rest of track
for _ in range(48):
didge.rest(Duration.WHOLE)
# ── SINGING BOWL — transitions, the thread ───────────────────
bowl = score.part("bowl", instrument="singing_bowl", volume=0.3,
reverb=0.8, reverb_type="taj_mahal",
delay=0.15, delay_time=0.6, delay_feedback=0.2,
pan=0.25)
# Strike at every section change
section_bars = {1: 60, 9: 65, 17: 58, 25: 70, 33: 62, 41: 68,
49: 55, 57: 65, 65: 72}
for bar in range(1, 73):
if bar in section_bars:
bowl.add(D.add(-24), Duration.WHOLE, velocity=section_bars[bar])
else:
bowl.rest(Duration.WHOLE)
# ── PIANO — jazz chords out of nowhere, bar 17 ───────────────
piano = score.part("piano", instrument="piano", volume=0.4,
reverb=0.45, reverb_type="taj_mahal",
delay=0.1, delay_time=0.3, delay_feedback=0.15,
pan=-0.15, humanize=0.1)
for _ in range(16):
piano.rest(Duration.WHOLE)
# Bars 17-24: jazzy — extended chords, unexpected voicings
jazz_prog = key.progression("i", "iv", "VII", "III")
for _ in range(2):
for chord in jazz_prog:
piano.add(chord, Duration.EIGHTH, velocity=72)
piano.rest(Duration.QUARTER)
piano.rest(Duration.EIGHTH)
piano.add(chord, Duration.EIGHTH, velocity=58)
piano.rest(Duration.QUARTER)
piano.rest(Duration.EIGHTH)
# Bars 25-32: stays through the beat drop — anchoring the chaos
for _ in range(2):
for chord in jazz_prog:
piano.add(chord, Duration.EIGHTH, velocity=68)
piano.rest(Duration.DOTTED_QUARTER)
piano.rest(Duration.HALF)
# Bars 33-40: silent — theremin owns this
for _ in range(8):
piano.rest(Duration.WHOLE)
# Bars 41-48: returns under choir — gentle arps
for _ in range(2):
for chord in prog:
piano.add(chord, Duration.QUARTER, velocity=52)
piano.rest(Duration.DOTTED_HALF)
# Bars 49-56: silent — 303 owns this
for _ in range(8):
piano.rest(Duration.WHOLE)
# Bars 57-72: underneath the music box return
for _ in range(4):
for chord in prog:
piano.add(chord, Duration.EIGHTH, velocity=55)
piano.rest(Duration.DOTTED_QUARTER)
piano.rest(Duration.HALF)
# ── 808 — slams in at bar 25 ─────────────────────────────────
sub = score.part("808", synth="sine", envelope="pad", volume=0.6,
lowpass=200, distortion=0.2, distortion_drive=3.0,
sub_osc=0.5, saturation=0.4, sidechain=0.3)
roots = [D.add(-24), C.add(-24), Bb.add(-24), A.add(-24)]
for _ in range(24):
sub.rest(Duration.WHOLE)
# Bars 25-32: drops in — the shock
for _ in range(2):
for root in roots:
sub.add(root, Duration.WHOLE, velocity=40)
# Bars 33-40: stays through theremin — the weight underneath
for _ in range(8):
sub.add(D.add(-24), Duration.WHOLE, velocity=30)
# Bars 41-48: fades under choir
for vel in [28, 25, 22, 18, 15, 12, 8, 0]:
if vel > 0:
sub.add(D.add(-24), Duration.WHOLE, velocity=vel)
else:
sub.rest(Duration.WHOLE)
# Bars 49-56: back with the 303
for _ in range(2):
for root in roots:
sub.add(root, Duration.WHOLE, velocity=38)
# Bars 57-72: underneath the music box — the big reveal
for _ in range(4):
for root in roots:
sub.add(root, Duration.WHOLE, velocity=35)
# ── TRAP HATS — with the 808, bar 25 ─────────────────────────
hats = score.part("hats", volume=0.25, pan=0.2, humanize=0.05)
for _ in range(24):
hats.rest(Duration.WHOLE)
# Bars 25-32: trap hats — 16ths with rolls
for bar in range(8):
if bar % 4 == 3:
for i in range(32):
hats.hit(CH, 0.125, velocity=min(85, 40 + i * 2))
else:
for beat in range(4):
hats.hit(CH, Duration.SIXTEENTH, velocity=70)
hats.hit(CH, Duration.SIXTEENTH, velocity=42)
hats.hit(CH, Duration.SIXTEENTH, velocity=55)
hats.hit(CH, Duration.SIXTEENTH, velocity=38)
# Bars 33-56: silent
for _ in range(24):
hats.rest(Duration.WHOLE)
# Bars 57-64: back with the music box — gentler
for _ in range(8):
for beat in range(4):
hats.hit(CH, Duration.EIGHTH, velocity=58)
hats.hit(CH, Duration.EIGHTH, velocity=35)
# Bars 65-72: full trap hats for the finale
for bar in range(8):
if bar % 4 == 3:
for i in range(32):
hats.hit(CH, 0.125, velocity=min(90, 42 + i * 2))
else:
for beat in range(4):
hats.hit(CH, Duration.SIXTEENTH, velocity=72)
hats.hit(CH, Duration.SIXTEENTH, velocity=45)
hats.hit(CH, Duration.SIXTEENTH, velocity=58)
hats.hit(CH, Duration.SIXTEENTH, velocity=40)
# ── KICK + SNARE — boom bap, bars 25-32 and 57-72 ────────────
kick = score.part("kick", volume=0.7, humanize=0.04,
distortion=0.08, distortion_drive=1.5)
snare = score.part("snare", volume=0.5, humanize=0.04,
reverb=0.2, reverb_decay=0.8,
delay=0.06, delay_time=0.3, delay_feedback=0.1,
pan=0.05)
for _ in range(24):
kick.rest(Duration.WHOLE)
snare.rest(Duration.WHOLE)
# Bars 25-32: the drop
for _ in range(8):
kick.hit(K, Duration.QUARTER, velocity=110)
kick.rest(Duration.EIGHTH)
kick.hit(K, Duration.EIGHTH, velocity=92)
kick.hit(K, Duration.QUARTER, velocity=105)
kick.rest(Duration.QUARTER)
snare.rest(Duration.QUARTER)
snare.hit(S, Duration.QUARTER, velocity=102)
snare.rest(Duration.QUARTER)
snare.hit(S, Duration.QUARTER, velocity=105)
# Bars 33-56: silent
for _ in range(24):
kick.rest(Duration.WHOLE)
snare.rest(Duration.WHOLE)
# Bars 57-72: back for the reveal + finale
for _ in range(16):
kick.hit(K, Duration.QUARTER, velocity=108)
kick.rest(Duration.EIGHTH)
kick.hit(K, Duration.EIGHTH, velocity=90)
kick.hit(K, Duration.QUARTER, velocity=102)
kick.rest(Duration.QUARTER)
snare.rest(Duration.QUARTER)
snare.hit(S, Duration.QUARTER, velocity=100)
snare.rest(Duration.QUARTER)
snare.hit(S, Duration.QUARTER, velocity=102)
# ── THEREMIN — solo, bar 33, the emotional gut punch ──────────
theremin = score.part("theremin", instrument="theremin", volume=0.35,
reverb=0.4, reverb_type="taj_mahal",
delay=0.12, delay_time=0.3, delay_feedback=0.15,
pan=-0.1, humanize=0.06)
for _ in range(32):
theremin.rest(Duration.WHOLE)
# Bars 33-40: alone with just the 808 — aching
theremin.add(A, Duration.WHOLE, velocity=72, bend=0.5)
theremin.add(F, Duration.WHOLE, velocity=68, bend=-0.25)
theremin.rest(Duration.WHOLE)
theremin.add(D.add(12), Duration.HALF, velocity=78, bend=1.0)
theremin.add(C.add(12), Duration.HALF, velocity=72, bend=-0.5)
theremin.add(Bb, Duration.WHOLE, velocity=70, bend=0.25)
theremin.rest(Duration.WHOLE)
theremin.add(A, Duration.HALF, velocity=65, bend=-0.15)
theremin.add(D, Duration.HALF, velocity=60)
theremin.rest(Duration.WHOLE)
# Bars 41-72: silent
for _ in range(32):
theremin.rest(Duration.WHOLE)
# ── CHOIR — swells from nowhere, bar 41 ──────────────────────
choir = score.part("choir", instrument="choir", volume=0.15,
reverb=0.8, reverb_type="cathedral",
chorus=0.3, chorus_rate=0.08, chorus_depth=0.012,
pan=0.2)
for _ in range(40):
choir.rest(Duration.WHOLE)
# Bars 41-48: cathedral appears — where did this come from?
for vel in [25, 32, 38, 42, 45, 48, 50, 52]:
choir.add(prog[vel % 4], Duration.WHOLE, velocity=vel)
# Bars 49-56: continues under the 303
for _ in range(2):
for chord in prog:
choir.add(chord, Duration.WHOLE, velocity=45)
# Bars 57-64: fading
for vel in [42, 38, 32, 28, 22, 18, 12, 0]:
if vel > 0:
choir.add(prog[0], Duration.WHOLE, velocity=vel)
else:
choir.rest(Duration.WHOLE)
# Bars 65-72: silent
for _ in range(8):
choir.rest(Duration.WHOLE)
# ── ACID 303 — rips through the choir, bar 49 ────────────────
acid = score.part("303", synth="saw", volume=0.4,
lowpass=2000, lowpass_q=10.0,
distortion=0.3, distortion_drive=3.5,
saturation=0.7, legato=True, glide=0.05,
reverb=0.2, reverb_type="spring",
delay=0.2, delay_time=0.3, delay_feedback=0.3,
pan=-0.25)
acid.lfo("lowpass", rate=0.02, min=600, max=8000, bars=8, shape="saw")
for _ in range(48):
acid.rest(Duration.WHOLE)
# Bars 49-56: acid line — screaming through the choir
acid_pattern = [
(D, Duration.SIXTEENTH, 105), (None, Duration.SIXTEENTH, 0),
(D, Duration.SIXTEENTH, 98), (F, Duration.SIXTEENTH, 92),
(D, Duration.SIXTEENTH, 108), (None, Duration.SIXTEENTH, 0),
(C, Duration.EIGHTH, 88),
(D, Duration.SIXTEENTH, 110), (A.add(-12), Duration.SIXTEENTH, 95),
(D, Duration.SIXTEENTH, 102), (None, Duration.SIXTEENTH, 0),
(Bb.add(-12), Duration.EIGHTH, 92),
(D, Duration.EIGHTH, 108),
]
for _ in range(8):
for note, dur, vel in acid_pattern:
if note is None:
acid.rest(dur)
else:
acid.add(note, dur, velocity=vel)
# Bars 57-72: silent — it was just a visit
for _ in range(16):
acid.rest(Duration.WHOLE)
# ── STRINGS — only in the finale, the grand reveal ───────────
strings = score.part("strings", instrument="string_ensemble", volume=0.12,
reverb=0.55, reverb_type="cathedral",
chorus=0.2, chorus_rate=0.15, chorus_depth=0.006,
pan=-0.2)
for _ in range(64):
strings.rest(Duration.WHOLE)
# Bars 65-72: everything together — strings tie the bow
for vel in [30, 38, 45, 50, 52, 48, 40, 28]:
strings.add(prog[vel % 4], Duration.WHOLE, velocity=vel)
# ═════════════════════════════════════════════════════════════════
import sys
print(f"Key: {key}")
print(f"BPM: 100")
print(f"Parts: {list(score.parts.keys())}")
print(f"Duration: {score.duration_ms / 1000:.1f}s | {score.measures} measures")
if "--live" in sys.argv:
print("Playing SLEIGHT OF HAND (live engine)...")
from pytheory_live.live import LiveEngine
engine = LiveEngine(buffer_size=1024)
engine.play_score(score)
else:
print("Playing SLEIGHT OF HAND...")
play_score(score)