Files
kennethreitz 00fc35de19 Refactor all tracks to be more pythonic — audio verified bit-identical
Every track: tuple-unpacked scale degrees, small local helpers
(rest_bars, chord_bars, play_phrase), data-driven drum patterns and
phrase tuples, sparse-event dicts, explicit velocity lists for fades,
dead code removed. Net -1,415 lines across 25 files.

Adds .fingerprint.py, a verification harness that hashes every audible
parameter of a score (notes, voicings, velocities, bends, drum hits,
LFO automation, part settings). All 25 tracks fingerprint identical to
their pre-refactor baselines, stored in .fingerprints/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 00:32:38 -04:00

363 lines
12 KiB
Python

"""
THE OBSERVATORY — chapel harmonies broadcast through shortwave static.
An organ learns to levitate. By the time the kick arrives,
the room is already in orbit.
G minor, 112 BPM. Radio hiss, bell, organ, choir, arp,
sub bass, and a patient house pulse.
"""
from pytheory import Key, Duration, Score, play_score
from pytheory.rhythm import DrumSound
key = Key("G", "minor")
s = key.scale # G A Bb C D Eb F
G, A, Bb, C, D, Eb, F = s[:7]
score = Score("4/4", bpm=112)
K = DrumSound.KICK
CL = DrumSound.CLAP
CH = DrumSound.CLOSED_HAT
OH = DrumSound.OPEN_HAT
prog = key.progression("i", "VI", "III", "VII") # Gm - Eb - Bb - F
roots = [G.add(-24), Eb.add(-24), Bb.add(-24), F.add(-24)]
def rest_bars(part, n):
for _ in range(n):
part.rest(Duration.WHOLE)
def chord_bars(part, chords, vel, repeats):
for _ in range(repeats):
for chord in chords:
part.add(chord, Duration.WHOLE, velocity=vel)
# ═══════════════════════════════════════════════════════════════════
# STRUCTURE (96 bars, ~5.1 minutes at 112 BPM):
# Bars 1-8: Shortwave hiss + bell. Empty room, open sky.
# Bars 9-16: Organ enters — first human architecture.
# Bars 17-32: Arp appears, still no drums. The orbit begins.
# Bars 33-48: Kick/sub/clap enter — lift.
# Bars 49-64: Choir + signal melody — the windows open.
# Bars 65-80: Peak — full transmission, bright and weightless.
# Bars 81-88: Drums thin out. Organ and choir suspend.
# Bars 89-96: Static, bell, and one last heartbeat.
# ═══════════════════════════════════════════════════════════════════
# ── RADIO HISS — the sky itself ───────────────────────────────────
radio = score.part("radio", synth="noise", envelope="pad", volume=0.04,
reverb=0.85, reverb_type="taj_mahal",
lowpass=900, pan=-0.35)
radio.lfo("lowpass", rate=0.012, min=300, max=1800, bars=96, shape="sine")
radio.lfo("volume", rate=0.02, min=0.02, max=0.06, bars=96, shape="triangle")
for _ in range(96):
radio.add(G, Duration.WHOLE, velocity=25)
# ── BOWL — section markers, like light reflecting off metal ──────
bowl = score.part("bowl", instrument="singing_bowl", volume=0.42,
reverb=1.0, reverb_type="taj_mahal",
delay=0.25, delay_time=0.875, delay_feedback=0.35,
pan=0.2)
marker_bars = {1: 78, 9: 72, 17: 68, 33: 75, 49: 72, 65: 76, 81: 60, 89: 54}
for bar in range(1, 97):
if bar in marker_bars:
note = G.add(-24) if bar < 65 else D.add(-12)
bowl.add(note, Duration.WHOLE, velocity=marker_bars[bar])
else:
bowl.rest(Duration.WHOLE)
# ── ORGAN — square-wave chapel, warm but slightly unreal ──────────
organ = score.part("organ", synth="square", envelope="organ", volume=0.14,
reverb=0.78, reverb_type="taj_mahal",
chorus=0.25, chorus_rate=0.18, chorus_depth=0.01,
lowpass=1800, pan=-0.15)
low_prog = [c.transpose(-12) for c in prog]
mid_prog = prog
high_prog = [c.transpose(12) for c in prog]
# Bars 1-8: silence
rest_bars(organ, 8)
# Bars 9-16: first statement, low and slow
chord_bars(organ, low_prog, vel=52, repeats=2)
# Bars 17-32: stronger, still no pulse beneath it
chord_bars(organ, low_prog, vel=60, repeats=4)
# Bars 33-64: fully present
chord_bars(organ, mid_prog, vel=72, repeats=8)
# Bars 65-80: brighter voicings at the peak
chord_bars(organ, high_prog, vel=66, repeats=4)
# Bars 81-88: suspended, looking down at the earth
chord_bars(organ, [mid_prog[0], mid_prog[1], mid_prog[0], mid_prog[3]],
vel=54, repeats=2)
# Bars 89-96: fading architecture
for chord, vel in zip(low_prog * 2, [50, 44, 40, 36, 30, 24, 16, 8]):
organ.add(chord, Duration.WHOLE, velocity=vel)
# ── CHOIR — the air inside the room starts singing ────────────────
choir = score.part("choir", instrument="choir", volume=0.11,
reverb=0.95, reverb_type="taj_mahal",
chorus=0.35, chorus_rate=0.08, chorus_depth=0.012,
pan=0.25)
# Bars 1-32: silence
rest_bars(choir, 32)
# Bars 33-48: arrives behind the drums, soft
chord_bars(choir, prog, vel=38, repeats=4)
# Bars 49-80: fully open
chord_bars(choir, prog, vel=48, repeats=8)
# Bars 81-88: held breath
chord_bars(choir, [prog[0], prog[1], prog[0], prog[3]], vel=36, repeats=2)
# Bars 89-96: gone
rest_bars(choir, 8)
# ── HALO PAD — the light around the chord, not the chord itself ──
halo = score.part("halo", synth="supersaw", envelope="pad", volume=0.08,
reverb=0.65, reverb_type="taj_mahal",
chorus=0.45, chorus_rate=0.2, chorus_depth=0.008,
lowpass=1200, pan=-0.25)
halo.lfo("lowpass", rate=0.01, min=500, max=2800, bars=96, shape="triangle")
# Bars 1-48: silence
rest_bars(halo, 48)
# Bars 49-80: glow at the peak
chord_bars(halo, prog, vel=42, repeats=8)
# Bars 81-96: silence
rest_bars(halo, 16)
# ── ARP — the signal lock, patient and inevitable ────────────────
arp = score.part("arp", synth="saw", envelope="pluck", volume=0.35,
reverb=0.3, delay=0.35, delay_time=0.234,
delay_feedback=0.42, lowpass=1300, detune=5,
pan=0.15, humanize=0.03)
arp.lfo("lowpass", rate=0.009, min=900, max=5200, bars=96, shape="saw")
P1 = [
G.add(12), None, D.add(12), None,
Bb, None, F.add(12), None,
G.add(12), None, D.add(12), None,
C.add(12), Bb, F, D,
]
P2 = [
G.add(12), D.add(12), F.add(12), D.add(12),
Eb.add(12), D.add(12), Bb, D.add(12),
G.add(12), D.add(12), F.add(12), D.add(12),
C.add(12), Bb, F, D,
]
def arp_bar(notes, vel):
for note in notes:
if note is None:
arp.rest(Duration.SIXTEENTH)
else:
arp.add(note, Duration.SIXTEENTH, velocity=vel)
# Bars 1-16: silence
rest_bars(arp, 16)
# Bars 17-32: emerges quietly
for _ in range(8):
arp_bar(P1, 50)
arp_bar(P2, 54)
# Bars 33-48: steady and confident
for _ in range(8):
arp_bar(P1, 64)
arp_bar(P2, 68)
# Bars 49-64: brighter
for _ in range(8):
arp_bar(P1, 76)
arp_bar(P2, 80)
# Bars 65-80: peak — no more hesitation
for _ in range(8):
arp_bar(P2, 88)
arp_bar(P1, 92)
# Bars 81-88: thinning out
for _ in range(4):
arp_bar(P1, 62)
arp_bar(P2, 58)
# Bars 89-96: silence
rest_bars(arp, 8)
# ── SUB — the floor finally arrives beneath the chapel ───────────
sub = score.part("sub", synth="sine", envelope="pad", volume=0.28,
lowpass=120, distortion=0.12, distortion_drive=2.5,
sub_osc=0.4, sidechain=0.25)
# Bars 1-32: silence
rest_bars(sub, 32)
# Bars 33-80: root motion, simple and physical
for _ in range(12):
for root in roots:
sub.add(root, Duration.HALF, velocity=92)
sub.rest(Duration.HALF)
# Bars 81-88: just the home note, held
for _ in range(8):
sub.add(G.add(-24), Duration.HALF, velocity=72)
sub.rest(Duration.HALF)
# Bars 89-96: fading heartbeat
for vel in [66, 58, 50, 42, 34, 26, 16, 0]:
if vel > 0:
sub.add(G.add(-24), Duration.HALF, velocity=vel)
sub.rest(Duration.HALF)
else:
sub.rest(Duration.WHOLE)
# ── KICK — the patient release ────────────────────────────────────
kick = score.part("kick", volume=0.55, humanize=0.03)
# Bars 1-32: none
rest_bars(kick, 32)
# Bars 33-80: four on the floor
for _ in range(48 * 4):
kick.hit(K, Duration.QUARTER, velocity=114)
# Bars 81-88: still there, but more human now
for _ in range(8):
kick.hit(K, Duration.QUARTER, velocity=95)
kick.rest(Duration.QUARTER)
kick.hit(K, Duration.QUARTER, velocity=88)
kick.rest(Duration.QUARTER)
# Bars 89-96: last pulses
for vel in [88, 82, 76, 68, 58, 46, 32, 18]:
kick.hit(K, Duration.QUARTER, velocity=vel)
kick.rest(Duration.DOTTED_HALF)
# ── CLAP — 2 and 4, but never aggressive ─────────────────────────
clap = score.part("clap", volume=0.28, reverb=0.18,
delay=0.1, delay_time=0.268, delay_feedback=0.15,
pan=-0.1, humanize=0.04)
# Bars 1-32: silence
rest_bars(clap, 32)
# Bars 33-80: standard house backbeat
for _ in range(48):
clap.rest(Duration.QUARTER)
clap.hit(CL, Duration.QUARTER, velocity=96)
clap.rest(Duration.QUARTER)
clap.hit(CL, Duration.QUARTER, velocity=98)
# Bars 81-96: silence
rest_bars(clap, 16)
# ── HATS — offbeat shimmer ────────────────────────────────────────
hats = score.part("hats", volume=0.22, pan=0.1, humanize=0.04)
# Bars 1-32: silence
rest_bars(hats, 32)
# Bars 33-80: offbeat 8ths, occasional open hat on the turn
for bar in range(48):
for beat in range(4):
hats.rest(Duration.EIGHTH)
sound = OH if beat == 3 and bar % 4 == 3 else CH
vel = 74 if sound == CH else 68
hats.hit(sound, Duration.EIGHTH, velocity=vel)
# Bars 81-88: thinner
for _ in range(8 * 4):
hats.rest(Duration.EIGHTH)
hats.hit(CH, Duration.EIGHTH, velocity=52)
# Bars 89-96: silence
rest_bars(hats, 8)
# ── SIGNAL — the melody finally resolves the transmission ────────
signal = score.part("signal", instrument="theremin", volume=0.3,
reverb=0.35, reverb_type="taj_mahal",
delay=0.2, delay_time=0.375, delay_feedback=0.25,
pan=0.35, humanize=0.05)
# Bars 1-48: silence
rest_bars(signal, 48)
phrase_a = [
(D.add(12), Duration.HALF, 70, 0.2),
(F.add(12), Duration.QUARTER, 74, 0.0),
(G.add(12), Duration.QUARTER, 78, 0.35),
(Bb.add(12), Duration.HALF, 80, -0.2),
(A.add(12), Duration.QUARTER, 68, 0.0),
(G.add(12), Duration.QUARTER, 72, 0.0),
(F.add(12), Duration.HALF, 70, 0.15),
(Eb.add(12), Duration.QUARTER, 68, 0.0),
(D.add(12), Duration.QUARTER, 66, -0.1),
(G.add(12), Duration.WHOLE, 78, 0.0),
]
phrase_b = [
(G.add(12), Duration.QUARTER, 78, 0.0),
(Bb.add(12), Duration.QUARTER, 82, 0.15),
(D.add(24), Duration.HALF, 86, -0.2),
(F.add(24), Duration.HALF, 84, 0.0),
(Eb.add(24), Duration.QUARTER, 78, 0.0),
(D.add(24), Duration.QUARTER, 76, 0.0),
(Bb.add(12), Duration.HALF, 72, -0.15),
(A.add(12), Duration.QUARTER, 68, 0.0),
(G.add(12), Duration.QUARTER, 66, 0.0),
(F.add(12), Duration.WHOLE, 74, 0.0),
]
def signal_phrase(phrase, reps):
for _ in range(reps):
for note, dur, vel, bend in phrase:
signal.add(note, dur, velocity=vel, bend=bend)
# Bars 49-64: first message
signal_phrase(phrase_a, reps=4)
# Bars 65-80: stronger reply
signal_phrase(phrase_b, reps=4)
# Bars 81-96: silence
rest_bars(signal, 16)
# ═══════════════════════════════════════════════════════════════════
import sys
print(f"Key: {key}")
print(f"BPM: 112")
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 OBSERVATORY (live engine)...")
from pytheory_live.live import LiveEngine
engine = LiveEngine(buffer_size=1024)
engine.play_score(score)
else:
print("Playing THE OBSERVATORY...")
play_score(score)