495 Commits

Author SHA1 Message Date
kennethreitz 57079a43ac Merge feature/non-12-tet: microtonal systems, historical tuning
11 microtonal systems, Bohlen-Pierce tritave, just intonation,
reference pitch, Score(system=, temperament=, reference_pitch=).
TET(n) factory for any equal temperament. 819 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:34:12 -04:00
kennethreitz 1d07b06968 Add Greensleeves (Renaissance lute, meantone A=415) to songs.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:33:50 -04:00
kennethreitz 9887b59cfb Add reference_pitch to Score and playback pipeline
Score(reference_pitch=415.0, temperament="meantone") renders an
entire piece at Baroque pitch with historical tuning. Flows through
to all .pitch() calls in both normal and legato renderers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:32:11 -04:00
kennethreitz 9850a8016e Bohlen-Pierce, just intonation, temperament in Score/playback
- Bohlen-Pierce (13-TET tritave): period=3.0 support in pitch(),
  System, and TET factory. 13 equal divisions of the 3:1 ratio.
- Just intonation temperament: 5-limit JI ratios (pure 3/2 fifths,
  5/4 thirds). Use temperament="just" anywhere.
- Score(temperament="just") flows through to playback — all .pitch()
  calls in the render pipeline use the Score's temperament.
- Carnatic 72-TET system with 10 melakartas.
- Fix c_index for Indian, Arabic, and Gamelan 12-TET systems.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:24:03 -04:00
kennethreitz 35f5f35dc5 Carnatic 72-TET, Score system param, 22 microtonal tests
- Carnatic (72-TET): 10 melakartas including shankarabharanam,
  kalyani, mayamalavagowla, kharaharapriya, etc.
- Score(system=) param passes tuning system to all parts, so
  Part.add("Sa") resolves through the correct system
- 22 new tests covering all microtonal systems: TET factory,
  19/31-TET, shruti, maqam, slendro, pelog, thai, makam,
  carnatic, circle of fifths, from_frequency, Score integration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:18:09 -04:00
kennethreitz 47ca94111f Add gamelan slendro/pelog, Thai 7-TET, Turkish 53-TET makam
- Slendro (5-TET): true equal 5-tone gamelan tuning, 240 cents/step
- Pelog (9-TET): 7-of-9 gamelan tuning with pathet nem/lima/barang
- Thai classical (7-TET): 7 equal divisions (~171 cents each)
- Turkish makam (53-TET): Arel-Ezgi-Uzdilek system with 9 makams
  (rast, hicaz, ussak, nihavend, huseyni, kurdi, segah, saba, huzzam)
- Fix octave parser to only match trailing digits (not "Mib+3")
- Fix _index to use _name_to_index (avoid creating Tone objects)
- Fix _math to use per-system c_index

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:11:19 -04:00
kennethreitz 62cfbb2591 Add 22-shruti Indian and 24-TET Arabic maqam systems
- "shruti" system: 22 named shrutis with proper microtonal intervals
  for all 10 thaats (bilawal, bhairav, todi, etc.) and pentatonic
  scales (bhupali, malkauns, durga). Captures the 2-shruti vs 3-shruti
  distinctions that 12-TET approximations lose.

- "maqam" system: 24-TET with quarter-tone positions (↑/↓ notation).
  True maqam Rast with quarter-flat E and B. Bayati, Saba, Sikah,
  Hijaz, and 6 more maqamat with exact quarter-tone intervals.

- 12-TET "indian" and "arabic" systems preserved for backwards compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:04:27 -04:00
kennethreitz de855a3fe6 Add non-12-TET support: TET() factory, 19-TET, 31-TET
- TET(n) factory creates N-tone equal temperament systems
- Built-in named systems: "19-tet" and "31-tet" with proper note
  names and scale definitions (major, minor, harmonic minor, pentatonic)
- Per-system c_index replaces global C_INDEX constant
- Fix 6 hardcoded '12's in tones.py: from_frequency, from_midi,
  interval_to, midi property, circle_of_fifths/fourths
- Numbered pitch classes for custom EDOs: TET(17) uses "0"-"16"
- Octave parser skips numeric-only names (fixes "0" being eaten)

Refs #38

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:58:33 -04:00
kennethreitz dc9f7b3342 Update changelog for 0.32.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:50:52 -04:00
kennethreitz 60fdff6d36 Merge pull request #43 from kennethreitz/fix/enharmonics-and-double-accidentals
Support enharmonic spellings and double accidentals
2026-03-26 23:50:33 -04:00
kennethreitz f42d38d1fd Support Cb, Fb, E#, B#, double sharps/flats, unicode symbols
- Cb, Fb, E#, B# resolve to their enharmonic equivalents (fixes #40)
- C##, Dbb, etc. resolve via semitone arithmetic (fixes #41)
- Unicode symbols accepted: ♯ ♭ 𝄪 𝄫
- 'x'/'X' accepted as double sharp (Bach notation): Fx = F##
- resolve_name handles all accidentals dynamically

Closes #40, closes #41

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:48:42 -04:00
kennethreitz 5a4122d61f Merge pull request #42 from kennethreitz/fix/tone-validate-early
Validate tone name at construction time
2026-03-26 23:43:41 -04:00
kennethreitz 3e4ba54a32 Validate tone name at construction time (fixes #39)
Tone("X") now raises ValueError immediately instead of silently
storing an invalid name and only failing on .frequency access.

Closes #39

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:43:00 -04:00
kennethreitz 5dd1c5e15d v0.32.0: 8 new synth features, highpass filter, preset overhaul
Filter envelope, velocity→brightness, sub-oscillator, tremolo,
saturation, noise layer, phaser, configurable FM. Highpass filter.
Bowed and mallet envelopes. Improved strings_synth with additive
synthesis. All 38 instrument presets sanity-checked and enhanced.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.32.0
2026-03-26 22:00:49 -04:00
kennethreitz e46732fb5a Improved strings_synth, highpass filter, bowed envelope
- Rewrite strings_wave with additive synthesis: natural 1/n harmonic
  rolloff shaped by body resonance curve, per-harmonic phase
  randomization, delayed vibrato onset, bow pressure variation
- Add highpass filter (12dB/oct biquad) to signal chain and Part API
- Add BOWED envelope (40ms attack with bite) for string instruments
- Update string presets to use strings_synth + bowed envelope

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:38:15 -04:00
kennethreitz 833ab56857 Fix solo string instruments: clean triangle, no detune
Solo violin/viola/cello/contrabass now use triangle + strings envelope
(clean, clear). String ensemble keeps strings_synth + detune for
thick ensemble textures. Solo instruments need clarity, not width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:26:35 -04:00
kennethreitz 6b2b1e201e Update index.rst with 13 synths, 38 instrument presets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:20:46 -04:00
kennethreitz f9c81fe05f v0.31.0: 3 new synths, 38 instrument presets
- Karplus-Strong pluck (physical modeling for guitar/harp/koto)
- Hammond organ (additive drawbar synthesis)
- String ensemble (filtered saw with body resonance formants)
- 38 instrument presets: score.part("lead", instrument="violin")
- Demo updated with pluck_synth, organ_synth, strings_synth

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.31.0
2026-03-26 21:18:27 -04:00
kennethreitz 931ec905c3 Add 3 new synths + 38 instrument presets
New synths:
- pluck_synth: Karplus-Strong physical modeling (guitar, harp, koto)
- organ_synth: Hammond-style additive drawbar synthesis
- strings_synth: Filtered saw with body resonance formants

38 instrument presets across 7 categories: keys, strings, woodwinds,
brass, plucked, synth, percussion/mallet. Each preset combines synth,
envelope, and effects to approximate real instruments.

score.part("lead", instrument="violin")
Score.list_instruments()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:15:56 -04:00
kennethreitz 799ffbdac9 Add MIT LICENSE file
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:02:44 -04:00
kennethreitz b29b33524f v0.30.0: Drums as Parts, split drums, kick-only sidechain, MIDI import
- Drums are real Parts with full effects pipeline
- split=True creates kick/snare/hats/toms/cymbals/percussion Parts
- Sidechain triggers on kick only
- Score.from_midi() imports Standard MIDI Files
- Document split drums workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.30.0
2026-03-26 20:27:10 -04:00
kennethreitz 25f25c1f23 Split drums into separate Parts: kick, snare, hats, toms, cymbals, percussion
score.drums("rock", split=True) creates independent Parts per group.
Each gets its own effects chain. set_drum_effects() applies to all.
Sidechain triggers on kick only. Render loop handles multiple drum Parts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:26:08 -04:00
kennethreitz 3f1d632285 Sidechain triggers on kick only, not all drum hits
Hi-hats and snares no longer duck the pad — only the kick does.
This is how sidechain compression works in real mixes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:22:20 -04:00
kennethreitz 1938037458 Update changelog: drums as Part
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:20:05 -04:00
kennethreitz f7c05e1b31 Drums are now a real Part — same effects pipeline, zero duplication
_drum_hits and _drum_pattern_beats proxy through score.parts['drums'].
Drum Part goes through _apply_part_effects like any other Part.
set_drum_effects() is now sugar over the Part's attributes.
All 789 tests pass with no API changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:17:05 -04:00
kennethreitz c375785bb9 Update changelog for drum bus effects
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:12:06 -04:00
kennethreitz 9ebd54b7fc Add drum bus effects — same engine as parts, zero duplication
score.set_drum_effects(reverb=0.2, reverb_type="plate", lowpass=8000)
Uses _apply_effects_with_params on each stereo channel.
Supports all effects: reverb, delay, lowpass, distortion, chorus.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:11:40 -04:00
kennethreitz ce68ad8f19 Update changelog for v0.29.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:09:00 -04:00
kennethreitz f402e76480 Rename song.py → songs.py, polish all 20 songs with effects
Every song now has: stereo panning, convolution reverb (plate/cathedral),
humanize (0.2), detune (8-12) on pads, sidechain on electronic tracks,
lowpass on bass, delay on leads. No melodies changed — just better sound.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:03:15 -04:00
kennethreitz 4d3c7e0d6c v0.29.0: MIDI import — Score.from_midi()
Load any Standard MIDI File into a Score. Zero-dependency parser
handles Type 0 and Type 1 files. Each channel becomes a Part,
channel 10 becomes drum hits. Roundtrip with save_midi works.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.29.0
2026-03-26 14:25:19 -04:00
kennethreitz 5a74a6f715 v0.28.3: Better demo songs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.28.3
2026-03-26 11:39:14 -04:00
kennethreitz 5416674858 Rewrite demo songs: stereo, effects, humanize, 8 moods
Each demo now uses pan, detune, spread, convolution reverb,
sidechain, humanize, velocity accents, genre-matched fills.
Added Dub and Temple moods.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:38:19 -04:00
kennethreitz 9a5f305ac6 Add CLAUDE.md with release process and music preferences
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:05:24 -04:00
kennethreitz bc38ce73f0 Update changelog for v0.28.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v0.27.0 v0.19.0 v0.9.0 v0.11.0 v0.12.0 v0.13.0 v0.28.2 v0.28.0 v0.10.0 v0.26.0 v0.25.0 v0.24.0 v0.22.0 v0.21.0 v0.20.0 v0.14.0 v0.18.0 v0.17.0 v0.16.0 v0.15.0
2026-03-26 11:00:17 -04:00
kennethreitz 081b924d29 v0.28.2: Tighter drum humanize default (0.15)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:59:41 -04:00
kennethreitz 427ff44ce9 Lower drum_humanize default to 0.15 — tighter feel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:54:13 -04:00
kennethreitz 360a908464 v0.28.1: Humanized drum hits
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:53:45 -04:00
kennethreitz a8dd4d6542 Humanize drum hits — random timing jitter and velocity variation
Drums now have micro-timing and velocity imperfections like a real
drummer. Default 0.3 (subtle). Control via Score(drum_humanize=0.5).
Kick stays tightest, hats and ghost notes drift naturally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:51:18 -04:00
kennethreitz 866b110afa Sync all summary pages with current feature set
index.rst: add figured bass, pitch class sets, scale recommendation,
stereo, detune, pan/spread, master compressor, REPL
quickstart.rst: same updates to "What's in the Box"
README.md: add stereo, sidechain, compressor, repl, forte numbers
drums.rst: document stereo drum panning
playback.rst: document stereo output and master compressor
cli.rst: add REPL section with cross-reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:29:12 -04:00
kennethreitz 0fc0b87017 Move closing line below toctree
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:22:53 -04:00
kennethreitz 1a724a94b0 Add closing line to homepage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:18:42 -04:00
kennethreitz b239e9a997 Add warm closing paragraphs to all 11 guide pages
Every page now ends on prose instead of a code block.
Chords, tones, scales, effects, drums, CLI, cookbook,
fretboard, playback, systems, theory — each with a
sentence that ties the page together.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:17:36 -04:00
kennethreitz a766737707 v0.28.0: Figured bass, pitch class sets, scale recommendation
- Chord.figured_bass: classical inversion notation (6, 6/4, 7, 6/5, 4/3, 2)
- Chord.analyze_figured(): Roman numerals with figured bass (V6/5, ii6)
- Chord.pitch_classes, normal_form, prime_form, forte_number: set theory
- Scale.recommend(): ranked scale suggestions from note sets
- Forte catalog: all trichords and tetrachords
- Documented in chords and scales guides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:13:26 -04:00
kennethreitz 0843c21884 v0.27.2: Temple Bell song
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:59:03 -04:00
kennethreitz eb7a2bf27d Add Temple Bell (Japanese) to song player — #20
Sparse triangle koto over E hirajoshi scale, Taj Mahal reverb,
sine drone, FM bells. Silence as instrument.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:58:07 -04:00
kennethreitz c78530611d v0.27.1: Tab completion in REPL
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:52:50 -04:00
kennethreitz 7267d25fb5 Add tab completion to REPL
Context-aware: commands on first word, drum presets after 'drums',
synth names after 'part', chord symbols after 'arp'/'chord',
note names after 'add', systems after 'system', LFO params after
'set'/'lfo', envelope names as third arg for 'part'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:52:08 -04:00
kennethreitz 53db299b5f v0.27.0: High-quality drum sounds, Dance Party song
All 15 drum sounds rewritten with inharmonic partials, proper
transients, multi-mode resonance, and saturation. Song #19:
Dance Party at the Reitz House — for Sarah and Malachi.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:41:57 -04:00
kennethreitz a4fa233edf Rewrite all drum sounds for higher quality
Every percussion voice improved with proper transients, inharmonic
partials, multi-mode resonance, and saturation:
- Clap: 808-style layered bursts
- Rimshot: dual resonance (rim+head)
- Toms: pitch sweep + shell resonance + stick attack
- Crash: 5 inharmonic metallic partials
- Ride: 4 partials + stick click
- Cowbell: 808 square-ish tones
- Clave: dual wood resonance
- Conga: pitch drop + shell mode + slap
- Shaker: shaped envelope + sparkle
- Tambourine: 4 jingle frequencies
- Timbale: metal shell overtones
- Agogo: 3 bell modes
- Guiro: rhythmic ridge scrapes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:39:27 -04:00
kennethreitz e7e90382c5 v0.26.3: Stereo drums, stereo convolution reverb, 2 new songs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:37:10 -04:00