mirror of
https://github.com/kennethreitz/interpretations.git
synced 2026-06-05 06:46:15 +00:00
9d27bb0f91
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
498 lines
20 KiB
Python
498 lines
20 KiB
Python
"""
|
|
THE INTERRUPTION — a string quartet gets ambushed by drum & bass.
|
|
Classical beauty. Then at bar 33 the breakbeat hits and the strings
|
|
just... keep playing. Like a concert in a warehouse.
|
|
"""
|
|
|
|
from pytheory import Key, Duration, Score, Tone, play_score
|
|
from pytheory.rhythm import DrumSound
|
|
|
|
key = Key("D", "minor")
|
|
s = key.scale
|
|
prog = key.progression("i", "VI", "iv", "V")
|
|
prog2 = key.progression("i", "VII", "III", "iv")
|
|
|
|
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=85)
|
|
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
# STRUCTURE (80 bars):
|
|
# Bars 1-32: String quartet — pure classical, no hint of what's coming
|
|
# Bar 33: THE INTERRUPTION — DnB breakbeat slams in at 170 BPM feel
|
|
# Bars 33-64: Strings + DnB coexisting, sub bass, the collision
|
|
# Bars 65-80: Strings win — beat dissolves, quartet plays out
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
|
|
# ── HARPSICHORD — baroque opening, sets the scene ───────────────
|
|
harpsi = score.part("harpsichord", instrument="harpsichord", volume=0.3,
|
|
reverb=0.55, reverb_type="cathedral",
|
|
delay=0.15, delay_time=0.35, delay_feedback=0.2,
|
|
pan=0.1, humanize=0.08)
|
|
|
|
# Bars 1-16: arpeggiated chords — elegant, formal
|
|
for _ in range(4):
|
|
for chord in prog:
|
|
harpsi.add(chord, Duration.QUARTER, velocity=72)
|
|
harpsi.rest(Duration.QUARTER)
|
|
harpsi.add(chord, Duration.QUARTER, velocity=65)
|
|
harpsi.rest(Duration.QUARTER)
|
|
|
|
# Bars 17-32: thinner, violins take over
|
|
for _ in range(2):
|
|
for chord in prog:
|
|
harpsi.add(chord, Duration.HALF, velocity=55)
|
|
harpsi.rest(Duration.HALF)
|
|
for _ in range(8):
|
|
harpsi.rest(Duration.WHOLE)
|
|
|
|
# Bars 33-64: gone — obliterated by the beat
|
|
for _ in range(32):
|
|
harpsi.rest(Duration.WHOLE)
|
|
|
|
# Bars 65-80: returns for the ending — full circle
|
|
for _ in range(2):
|
|
for chord in prog:
|
|
harpsi.add(chord, Duration.QUARTER, velocity=60)
|
|
harpsi.rest(Duration.QUARTER)
|
|
harpsi.add(chord, Duration.QUARTER, velocity=52)
|
|
harpsi.rest(Duration.QUARTER)
|
|
for _ in range(8):
|
|
harpsi.rest(Duration.WHOLE)
|
|
|
|
# ── FLUTE — soaring above the quartet, baroque ornamental ───────
|
|
flute = score.part("flute", instrument="flute", volume=0.22,
|
|
reverb=0.5, reverb_type="cathedral",
|
|
delay=0.12, delay_time=0.35, delay_feedback=0.15,
|
|
pan=0.3, humanize=0.1)
|
|
|
|
# Bars 1-4: silent — let the harpsichord set the scene
|
|
for _ in range(4):
|
|
flute.rest(Duration.WHOLE)
|
|
|
|
# Bars 5-16: ornamental melody — floats above the strings
|
|
flute_a = [
|
|
(D.add(12), Duration.QUARTER, 78), (E.add(12), Duration.EIGHTH, 72),
|
|
(F.add(12), Duration.EIGHTH, 75), (A.add(12), Duration.HALF, 80),
|
|
(G.add(12), Duration.QUARTER, 75), (F.add(12), Duration.EIGHTH, 70),
|
|
(E.add(12), Duration.EIGHTH, 68), (D.add(12), Duration.HALF, 72),
|
|
(F.add(12), Duration.QUARTER, 78), (G.add(12), Duration.QUARTER, 75),
|
|
(A.add(12), Duration.HALF, 82),
|
|
(Bb.add(12), Duration.QUARTER, 78), (A.add(12), Duration.EIGHTH, 72),
|
|
(G.add(12), Duration.EIGHTH, 70), (F.add(12), Duration.HALF, 75),
|
|
]
|
|
flute_b = [
|
|
(A.add(12), Duration.HALF, 80), (Bb.add(12), Duration.QUARTER, 75),
|
|
(A.add(12), Duration.QUARTER, 72),
|
|
(G.add(12), Duration.QUARTER, 70), (F.add(12), Duration.EIGHTH, 65),
|
|
(E.add(12), Duration.EIGHTH, 62), (D.add(12), Duration.HALF, 68),
|
|
(None, Duration.QUARTER, 0), (F.add(12), Duration.EIGHTH, 72),
|
|
(G.add(12), Duration.EIGHTH, 75), (A.add(12), Duration.HALF, 80),
|
|
(D.add(12), Duration.WHOLE, 75),
|
|
]
|
|
for _ in range(2):
|
|
for note, dur, vel in flute_a:
|
|
flute.add(note, dur, velocity=vel)
|
|
for note, dur, vel in flute_b:
|
|
if note is None:
|
|
flute.rest(dur)
|
|
else:
|
|
flute.add(note, dur, velocity=vel)
|
|
|
|
# Bars 17-32: more active — 16th note runs between phrases
|
|
flute_c = [
|
|
(D.add(12), Duration.EIGHTH, 82), (E.add(12), Duration.SIXTEENTH, 75),
|
|
(F.add(12), Duration.SIXTEENTH, 78), (G.add(12), Duration.QUARTER, 80),
|
|
(A.add(12), Duration.HALF, 85),
|
|
(G.add(12), Duration.EIGHTH, 78), (F.add(12), Duration.SIXTEENTH, 72),
|
|
(E.add(12), Duration.SIXTEENTH, 70), (D.add(12), Duration.QUARTER, 75),
|
|
(F.add(12), Duration.HALF, 78),
|
|
(A.add(12), Duration.QUARTER, 85), (Bb.add(12), Duration.EIGHTH, 80),
|
|
(A.add(12), Duration.EIGHTH, 78), (G.add(12), Duration.HALF, 75),
|
|
(D.add(12), Duration.WHOLE, 72),
|
|
]
|
|
for _ in range(4):
|
|
for note, dur, vel in flute_c:
|
|
flute.add(note, dur, velocity=vel)
|
|
|
|
# Bars 33-64: keeps playing through the interruption — unshaken
|
|
flute.set(volume=0.4)
|
|
for _ in range(4):
|
|
for note, dur, vel in flute_a:
|
|
flute.add(note, dur, velocity=min(127, vel + 8))
|
|
for note, dur, vel in flute_b:
|
|
if note is None:
|
|
flute.rest(dur)
|
|
else:
|
|
flute.add(note, dur, velocity=min(127, vel + 8))
|
|
|
|
# Bars 65-80: returns to gentle — the quartet wins
|
|
flute.set(volume=0.3)
|
|
for _ in range(2):
|
|
for note, dur, vel in flute_a:
|
|
flute.add(note, dur, velocity=max(40, vel - 10))
|
|
for note, dur, vel in flute_b:
|
|
if note is None:
|
|
flute.rest(dur)
|
|
else:
|
|
flute.add(note, dur, velocity=max(40, vel - 12))
|
|
|
|
# ── HARP — arpeggiated chords, delicate, angelic ────────────────
|
|
harp = score.part("harp", instrument="harp", volume=0.28,
|
|
reverb=0.25, reverb_decay=1.0,
|
|
delay=0.1, delay_time=0.353, delay_feedback=0.15,
|
|
pan=-0.25, humanize=0.1)
|
|
|
|
# Bars 1-8: silent — let harpsichord establish
|
|
for _ in range(8):
|
|
harp.rest(Duration.WHOLE)
|
|
|
|
# Bars 9-32: arpeggiated chords — cascading 16ths
|
|
harp_arps = {
|
|
"i": [D.add(-12), A.add(-12), D, F, A, F, D, A.add(-12)],
|
|
"VI": [Bb.add(-24), F.add(-12), Bb.add(-12), D, F, D, Bb.add(-12), F.add(-12)],
|
|
"iv": [G.add(-12), Bb.add(-12), D, G, Bb, G, D, Bb.add(-12)],
|
|
"V": [A.add(-24), E.add(-12), A.add(-12), C, E, C, A.add(-12), E.add(-12)],
|
|
}
|
|
chord_order = ["i", "VI", "iv", "V"]
|
|
for _ in range(6):
|
|
for name in chord_order:
|
|
for note in harp_arps[name]:
|
|
harp.add(note, Duration.EIGHTH, velocity=62)
|
|
|
|
# Bars 33-48: keeps going through the interruption, quieter
|
|
harp.set(volume=0.18)
|
|
for _ in range(4):
|
|
for name in chord_order:
|
|
for note in harp_arps[name]:
|
|
harp.add(note, Duration.EIGHTH, velocity=55)
|
|
|
|
# Bars 49-64: silent — overwhelmed
|
|
for _ in range(16):
|
|
harp.rest(Duration.WHOLE)
|
|
|
|
# Bars 65-80: returns for the ending
|
|
harp.set(volume=0.22)
|
|
for _ in range(4):
|
|
for name in chord_order:
|
|
for note in harp_arps[name]:
|
|
harp.add(note, Duration.EIGHTH, velocity=58)
|
|
|
|
# ── VIOLIN 1 — melody, the lead voice ──────────────────────────
|
|
violin1 = score.part("violin_1", instrument="violin", volume=0.4,
|
|
reverb=0.5, reverb_type="cathedral",
|
|
chorus=0.18, chorus_rate=0.3, chorus_depth=0.006,
|
|
delay=0.1, delay_time=0.25, delay_feedback=0.15,
|
|
pan=-0.35, humanize=0.1)
|
|
|
|
# Bars 1-16: opening melody — lyrical, romantic
|
|
melody_a = [
|
|
(A, Duration.HALF, 80), (Bb, Duration.QUARTER, 72),
|
|
(A, Duration.QUARTER, 75),
|
|
(G, Duration.HALF, 78), (F, Duration.QUARTER, 70),
|
|
(E, Duration.QUARTER, 68),
|
|
(F, Duration.DOTTED_HALF, 82), (E, Duration.QUARTER, 72),
|
|
(D, Duration.WHOLE, 78),
|
|
]
|
|
melody_b = [
|
|
(D.add(12), Duration.HALF, 85), (C.add(12), Duration.QUARTER, 78),
|
|
(Bb, Duration.QUARTER, 75),
|
|
(A, Duration.HALF, 80), (G, Duration.QUARTER, 72),
|
|
(F, Duration.QUARTER, 70),
|
|
(G, Duration.HALF, 78), (A, Duration.QUARTER, 75),
|
|
(Bb, Duration.QUARTER, 72),
|
|
(A, Duration.WHOLE, 82),
|
|
]
|
|
for _ in range(2):
|
|
for note, dur, vel in melody_a:
|
|
violin1.add(note, dur, velocity=vel)
|
|
for note, dur, vel in melody_b:
|
|
violin1.add(note, dur, velocity=vel)
|
|
|
|
# Bars 17-32: development — higher, more intense
|
|
melody_c = [
|
|
(D.add(12), Duration.QUARTER, 88), (E.add(12), Duration.QUARTER, 82),
|
|
(F.add(12), Duration.HALF, 90),
|
|
(E.add(12), Duration.QUARTER, 82), (D.add(12), Duration.QUARTER, 78),
|
|
(C.add(12), Duration.QUARTER, 80), (Bb, Duration.QUARTER, 75),
|
|
(A, Duration.HALF, 85), (G, Duration.QUARTER, 78),
|
|
(A, Duration.QUARTER, 80),
|
|
(D.add(12), Duration.WHOLE, 88),
|
|
]
|
|
for _ in range(2):
|
|
for note, dur, vel in melody_c:
|
|
violin1.add(note, dur, velocity=vel)
|
|
for note, dur, vel in melody_a:
|
|
violin1.add(note, dur, velocity=vel)
|
|
|
|
# Bars 33-64: THE INTERRUPTION — strings keep playing, unshaken
|
|
for _ in range(4):
|
|
for note, dur, vel in melody_b:
|
|
violin1.add(note, dur, velocity=min(127, vel + 10))
|
|
for note, dur, vel in melody_c:
|
|
violin1.add(note, dur, velocity=min(127, vel + 10))
|
|
|
|
# Bars 65-80: strings take over again, softer
|
|
for _ in range(2):
|
|
for note, dur, vel in melody_a:
|
|
violin1.add(note, dur, velocity=max(40, vel - 10))
|
|
for note, dur, vel in melody_b:
|
|
violin1.add(note, dur, velocity=max(40, vel - 15))
|
|
|
|
# ── VIOLIN 2 — harmony, follows violin 1 a third below ─────────
|
|
violin2 = score.part("violin_2", instrument="violin", volume=0.32,
|
|
reverb=0.5, reverb_type="cathedral",
|
|
chorus=0.18, chorus_rate=0.25, chorus_depth=0.006,
|
|
delay=0.1, delay_time=0.28, delay_feedback=0.12,
|
|
pan=0.4, humanize=0.1)
|
|
|
|
# Bars 1-16: harmony part
|
|
harm_a = [
|
|
(F, Duration.HALF, 72), (G, Duration.QUARTER, 65),
|
|
(F, Duration.QUARTER, 68),
|
|
(E, Duration.HALF, 70), (D, Duration.QUARTER, 62),
|
|
(C, Duration.QUARTER, 60),
|
|
(D, Duration.DOTTED_HALF, 75), (C, Duration.QUARTER, 65),
|
|
(D, Duration.WHOLE, 70),
|
|
]
|
|
harm_b = [
|
|
(Bb, Duration.HALF, 78), (A, Duration.QUARTER, 70),
|
|
(G, Duration.QUARTER, 68),
|
|
(F, Duration.HALF, 72), (E, Duration.QUARTER, 65),
|
|
(D, Duration.QUARTER, 62),
|
|
(E, Duration.HALF, 70), (F, Duration.QUARTER, 68),
|
|
(G, Duration.QUARTER, 65),
|
|
(F, Duration.WHOLE, 75),
|
|
]
|
|
for _ in range(2):
|
|
for note, dur, vel in harm_a:
|
|
violin2.add(note, dur, velocity=vel)
|
|
for note, dur, vel in harm_b:
|
|
violin2.add(note, dur, velocity=vel)
|
|
|
|
# Bars 17-32
|
|
for _ in range(4):
|
|
for note, dur, vel in harm_b:
|
|
violin2.add(note, dur, velocity=vel)
|
|
|
|
# Bars 33-64
|
|
for _ in range(4):
|
|
for note, dur, vel in harm_a:
|
|
violin2.add(note, dur, velocity=min(127, vel + 8))
|
|
for note, dur, vel in harm_b:
|
|
violin2.add(note, dur, velocity=min(127, vel + 8))
|
|
|
|
# Bars 65-80
|
|
for _ in range(2):
|
|
for note, dur, vel in harm_a:
|
|
violin2.add(note, dur, velocity=max(35, vel - 12))
|
|
for note, dur, vel in harm_b:
|
|
violin2.add(note, dur, velocity=max(35, vel - 15))
|
|
|
|
# ── VIOLA — inner voice, warm ──────────────────────────────────
|
|
viola = score.part("viola", instrument="viola", volume=0.3,
|
|
reverb=0.5, reverb_type="cathedral",
|
|
chorus=0.15, chorus_rate=0.2, chorus_depth=0.006,
|
|
pan=-0.15, humanize=0.1)
|
|
|
|
# Whole note chords throughout — the glue
|
|
for _ in range(10):
|
|
for chord in prog:
|
|
viola.add(chord, Duration.WHOLE, velocity=65)
|
|
for _ in range(10):
|
|
for chord in prog2:
|
|
viola.add(chord, Duration.WHOLE, velocity=60)
|
|
|
|
# ── CELLO — bass voice, foundation ─────────────────────────────
|
|
cello = score.part("cello", instrument="cello", volume=0.35,
|
|
reverb=0.45, reverb_type="cathedral",
|
|
chorus=0.1, chorus_rate=0.15, chorus_depth=0.004,
|
|
pan=0.15, humanize=0.1)
|
|
|
|
# Walking bass in half notes
|
|
cello_line = [
|
|
(D.add(-12), Duration.HALF, 75), (A.add(-24), Duration.HALF, 70),
|
|
(Bb.add(-24), Duration.HALF, 72), (F.add(-12), Duration.HALF, 68),
|
|
(G.add(-12), Duration.HALF, 70), (D.add(-12), Duration.HALF, 72),
|
|
(A.add(-12), Duration.HALF, 75), (E.add(-12), Duration.HALF, 70),
|
|
]
|
|
for _ in range(20):
|
|
for note, dur, vel in cello_line:
|
|
cello.add(note, dur, velocity=vel)
|
|
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
# BAR 33: THE INTERRUPTION
|
|
# DnB breakbeat at double time (feels like 170 even though clock is 85)
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
|
|
K = DrumSound.KICK
|
|
S = DrumSound.SNARE
|
|
CH = DrumSound.CLOSED_HAT
|
|
OH = DrumSound.OPEN_HAT
|
|
|
|
# ── BREAKBEAT — enters bar 33, no warning ──────────────────────
|
|
beat = score.part("breakbeat", volume=0.9, humanize=0.06,
|
|
reverb=0.25, reverb_decay=1.0,
|
|
delay=0.15, delay_time=0.353, delay_feedback=0.2,
|
|
pan=-0.1)
|
|
|
|
# Bars 1-32: silence — the audience suspects nothing
|
|
for _ in range(32):
|
|
beat.rest(Duration.WHOLE)
|
|
|
|
# Bars 33-64: DnB breakbeat — 16th notes at 85 BPM = 8th notes at 170
|
|
# Classic amen-style break
|
|
for bar in range(32):
|
|
if bar % 8 == 7:
|
|
# Fill — snare into 32nd note hat cascade
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=108)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=105)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=110)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=100)
|
|
# 32nd note hat roll
|
|
for i in range(8):
|
|
vel = min(127, 55 + i * 8)
|
|
beat.hit(CH, 0.125, velocity=vel)
|
|
# Back to snare hits
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=112)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=115)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=118)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=120)
|
|
elif bar % 4 == 3:
|
|
# Mini fill — 32nd hat flurry on beat 4
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=110)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=50)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=45)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=48)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=105)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=50)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=42)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=95)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=48)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=100)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=108)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=45)
|
|
# 32nd note hat burst
|
|
for i in range(8):
|
|
beat.hit(CH, 0.125, velocity=min(90, 50 + i * 5))
|
|
else:
|
|
# K---S--K-KS----
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=110)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=50)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=45)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=48)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=105)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=50)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=42)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=95)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=48)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=100)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=108)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=45)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=48)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=42)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=50)
|
|
beat.hit(CH, Duration.SIXTEENTH, velocity=45)
|
|
|
|
# Bars 65-72: beat thins out — strings winning
|
|
for bar in range(8):
|
|
vel = max(25, 100 - bar * 9)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=vel)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=max(20, vel - 5))
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=max(20, vel - 10))
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.hit(K, Duration.SIXTEENTH, velocity=max(20, vel - 8))
|
|
beat.hit(S, Duration.SIXTEENTH, velocity=max(20, vel - 5))
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
beat.rest(Duration.SIXTEENTH)
|
|
|
|
# Bars 73-80: gone
|
|
for _ in range(8):
|
|
beat.rest(Duration.WHOLE)
|
|
|
|
# ── 808 KICK — four on the floor, the slap ─────────────────────
|
|
kick808 = score.part("kick808", volume=1.0, humanize=0.03,
|
|
distortion=0.1, distortion_drive=1.5)
|
|
|
|
for _ in range(32):
|
|
kick808.rest(Duration.WHOLE)
|
|
|
|
# Bars 33-64: FOUR ON THE FLOOR — hits like a truck
|
|
for _ in range(32):
|
|
for beat_num in range(4):
|
|
kick808.hit(K, Duration.QUARTER, velocity=125)
|
|
|
|
# Bars 65-72: fading
|
|
for bar in range(8):
|
|
vel = max(30, 120 - bar * 12)
|
|
for beat_num in range(4):
|
|
kick808.hit(K, Duration.QUARTER, velocity=vel)
|
|
|
|
# Bars 73-80: gone
|
|
for _ in range(8):
|
|
kick808.rest(Duration.WHOLE)
|
|
|
|
# ── SUB BASS — DnB sub, enters with the beat ───────────────────
|
|
sub = score.part("sub", synth="sine", envelope="pad", volume=0.9,
|
|
lowpass=150, distortion=0.25, distortion_drive=3.5,
|
|
sub_osc=0.7, sidechain=0.6)
|
|
|
|
for _ in range(32):
|
|
sub.rest(Duration.WHOLE)
|
|
|
|
# Bars 33-64: following the root
|
|
sub_roots = [D.add(-24), Bb.add(-24), G.add(-24), A.add(-24)]
|
|
for _ in range(8):
|
|
for root in sub_roots:
|
|
sub.add(root, Duration.WHOLE, velocity=95)
|
|
|
|
# Bars 65-80: fading
|
|
for vel in [85, 78, 70, 62, 55, 48, 40, 35, 30, 25, 22, 20, 18, 15, 12, 8]:
|
|
sub.add(D.add(-24), Duration.WHOLE, velocity=vel)
|
|
|
|
# ── REESE BASS — detuned saw, DnB signature ────────────────────
|
|
reese = score.part("reese", synth="drift", envelope="pad", volume=0.2,
|
|
lowpass=400, detune=15, spread=0.3,
|
|
distortion=0.2, sidechain=0.55,
|
|
reverb=0.2, reverb_decay=1.5,
|
|
delay=0.1, delay_time=0.706, delay_feedback=0.2,
|
|
pan=0.15)
|
|
|
|
for _ in range(32):
|
|
reese.rest(Duration.WHOLE)
|
|
|
|
# Bars 33-64: dark, menacing
|
|
for _ in range(8):
|
|
for root in sub_roots:
|
|
reese.add(root.add(12), Duration.WHOLE, velocity=75)
|
|
|
|
# Bars 65-80: fading
|
|
for vel in [65, 58, 52, 46, 40, 35, 30, 26, 22, 18, 16, 14, 12, 10, 8, 5]:
|
|
reese.add(D.add(-12), Duration.WHOLE, velocity=vel)
|
|
|
|
# ═════════════════════════════════════════════════════════════════
|
|
import sys
|
|
|
|
print(f"Key: {key}")
|
|
print(f"BPM: 85 (DnB section feels like 170)")
|
|
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 THE INTERRUPTION (live engine)...")
|
|
from pytheory_live.live import LiveEngine
|
|
engine = LiveEngine(buffer_size=1024)
|
|
engine.play_score(score)
|
|
else:
|
|
print("Playing THE INTERRUPTION...")
|
|
play_score(score)
|