diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/MEMORY.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/MEMORY.md deleted file mode 100644 index 6427641..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/MEMORY.md +++ /dev/null @@ -1,5 +0,0 @@ -- [Kenneth's music preferences](user_kenneth_music.md) — mixing, composition, workflow for Interpretations album -- [Interpretations Album](project_interpretations_album.md) — album project, tracks are real music not demos -- [Commit every change](feedback_commit_every_change.md) — don't batch commits, commit after every edit -- [Volume and compressor](feedback_volume_compressor.md) — volume=0.0 breaks parts, use velocity for fading -- [Taj mahal on drums](feedback_taj_mahal_drums.md) — creates choir artifacts, use algorithmic reverb instead diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_commit_every_change.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_commit_every_change.md deleted file mode 100644 index c8a52ce..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_commit_every_change.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Commit every change -description: Kenneth wants every code change committed immediately, not batched -type: feedback ---- - -Commit every change as it's made — don't batch up multiple changes before committing. - -**Why:** Kenneth works iteratively and wants a clean git history of each tweak. He often asks to hear the result immediately after changes, and having uncommitted work makes rollbacks harder. -**How to apply:** After every edit (volume change, instrument swap, part addition), commit immediately before playing or moving on. diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_taj_mahal_drums.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_taj_mahal_drums.md deleted file mode 100644 index ce01a36..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_taj_mahal_drums.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Taj mahal reverb creates choir sound on drums -description: Convolution reverb (taj_mahal) on percussive hits creates unwanted harmonic/choral artifacts -type: feedback ---- - -Don't use reverb_type="taj_mahal" on drum/percussion parts — the long IR creates harmonic resonances that sound like a choir. Use algorithmic reverb (reverb=0.35, reverb_decay=1.5) for drums instead. - -**Why:** Discovered during Raga Midnight — tabla with taj_mahal reverb sounded like a choir was singing. Cathedral reverb is OK for cajon. Taj mahal works great on sustained instruments (tambura, sitar, Rhodes, pad, singing bowl). -**How to apply:** Reserve taj_mahal for melodic/sustained instruments. Use algorithmic or cathedral reverb for percussion. diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_volume_compressor.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_volume_compressor.md deleted file mode 100644 index 7f6625f..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/feedback_volume_compressor.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Volume and compressor behavior -description: part.volume doesn't always work as expected due to master compressor — use velocity for fading, rests for silence -type: feedback ---- - -Don't use volume=0.0 on parts and then .set(volume=X) to fade in — the renderer may not handle this correctly. Instead: -- Start parts at their real volume -- Use .rest() for silent sections -- Fade dynamics via velocity, not volume -- The master compressor normalizes sparse arrangements to full volume — more parts playing simultaneously keeps relative levels sane - -**Why:** We discovered volume=0.0 parts produced silence even after .set() changes, and the compressor over-amplified solo instruments. -**How to apply:** Always set non-zero starting volume. Use velocity for dynamics. For drum parts, volume param requires the pytheory fix (drum_part.volume multiplication in play.py). diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/project_interpretations_album.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/project_interpretations_album.md deleted file mode 100644 index ab018a3..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/project_interpretations_album.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Interpretations Album -description: Kenneth is making an album called "Interpretations" — raga.py is intended as a real track -type: project ---- - -Kenneth is producing an album called "Interpretations". The raga.py example ("Raga Midnight") is intended as an actual track on this album, not just a demo. Quality bar is album-ready. - -**Why:** This is real music production, not just testing pytheory features. -**How to apply:** Treat composition decisions seriously — musical quality matters more than demonstrating API features. Push for authenticity and expressiveness. diff --git a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/user_kenneth_music.md b/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/user_kenneth_music.md deleted file mode 100644 index 26e50af..0000000 --- a/.claude/projects/-Users-kennethreitz-repos-interpretations/memory/user_kenneth_music.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Kenneth's music production preferences -description: Preferences for mixing, sound design, and composition learned during Interpretations album -type: user ---- - -Kenneth is producing an album called "Interpretations" using pytheory. He has a good ear and knows what he wants. - -Mixing preferences: -- Loves taj mahal reverb on melodic instruments -- Wants loud kick and sub bass — always asks to make them louder -- Prefers cathedral reverb on cajon over taj mahal -- Dislikes didgeridoo being too loud — it eats the mix -- Sitar needs to cut through — less reverb, more volume -- Drums generally need to be louder than initial settings - -Composition preferences: -- Likes Indian classical instruments (tabla, sitar, tambura, dhol) -- Appreciates proper musical structure (tabla tihai cadence, raga form) -- Enjoys genre mashups (Mario + Drake, acid + cajon) -- Wants humanize on most parts -- Sarah is involved — she requested the Sufjan/RKS track -- Prefers 432 Hz reference pitch for meditative tracks -- Likes shruti tuning system on Score (not Key) - -Workflow: -- Iterates fast — makes a change, listens, adjusts -- Commits frequently -- Uses pytheory's play_score() for rendering, not the live engine (for now) diff --git a/.gitignore b/.gitignore index c513d9c..5a5fc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ *.egg-info/ wavs/ mp3s/ +.claude/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 205dd7e..b55ab62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## 2026-04-01 +- **Track 10: The Dialogue** — E Phrygian, 75 BPM, shruti just intonation, A=432 Hz. Sitar (human) and theremin (machine) find each other through call-and-response. House kick + hats + clap enter at bar 41. 32nd note sitar shredding at the peak with dry reverb. - **Track 9: The Temple** — A Phrygian, 65 BPM, shruti just intonation, A=432 Hz. Singing bowls, tambura, harmonium, bansuri, tabla solo, triple sitar solo with 32nd note shredding, theremin at the peak, electronic kick. +- Raga Midnight: sitar reverb reduced for clarity - **play.py** — interactive curses track picker, progress bar playback, `--from-time`/`--to-time` seeking, `--pitch` override, `--solo`/`--mute` parts, WAV/MIDI export. - Acid Reign: cajon louder (0.5), less reverb (0.2) - ASCII art header added to README diff --git a/tracks/the_dialogue.py b/tracks/the_dialogue.py index 86266af..b1b3366 100644 --- a/tracks/the_dialogue.py +++ b/tracks/the_dialogue.py @@ -220,7 +220,8 @@ for _ in range(2): (Ma,112),(Pa.add(-12),80),(Pa,115),(Pa.add(-12),82), (Dha,118),(Pa.add(-12),80),(Ni,120),(Pa.add(-12),82)]: sitar.add(note, Duration.SIXTEENTH, velocity=vel) -# 32nd note shred +# 32nd note shred — pull reverb back so the notes cut through +sitar.set(reverb=0.1, delay=0.08) for note in [Sa, Re, Ga, Ma, Pa, Dha, Ni, Sa.add(12), Sa.add(12), Ni, Dha, Pa, Ma, Ga, Re, Sa]: sitar.add(note, 0.125, velocity=125) @@ -228,7 +229,8 @@ for note in [Sa, Re, Ga, Ma, Pa, Dha, Ni, Sa.add(12), for note in [Ni, Dha, Pa, Ma, Ga, Re, Sa, Pa.add(-12), Sa, Re, Ga, Ma, Pa, Dha, Ni, Sa.add(12)]: sitar.add(note, 0.125, velocity=120) -# Held peak note +# Held peak note — reverb back for the sustain +sitar.set(reverb=0.35, delay=0.25) sitar.add(Sa.add(12), Duration.HALF, velocity=127, bend=-0.2) sitar.add(Pa, Duration.HALF, velocity=110) sitar.add(Sa, Duration.WHOLE, velocity=100, bend=-0.15)