Commit Graph

30 Commits

Author SHA1 Message Date
kennethreitz 044e9a7eac Fix CI: lazy-import sounddevice so MIDI/render work without PortAudio
sounddevice is now only imported when actually playing audio through
speakers. All other functions (save_midi, render_score, save) work
without PortAudio installed. Fixes 9 test failures in CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 19:43:39 -04:00
kennethreitz 094887c849 v0.25.1: pytheory demo command, README rewrite
- `pytheory demo` plays a randomly generated track (6 moods, different every time)
- README rewritten to showcase full feature set: composition, effects, drums,
  sidechain, automation, MIDI export, AI collaboration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:28:42 -04:00
kennethreitz ac0cc0b6ce v0.25.0: Sidechain compression, song sections, punchier kick
- Sidechain: kick ducks pad/bass for EDM pump (sidechain=0.85)
- Song structure: score.section("verse"), score.repeat("chorus")
- Kick: 808-style 200→45Hz sweep, sub thump, soft saturation
- Section repeat copies notes, drums, automation with offset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:21:33 -04:00
kennethreitz 0c4ba83b0c v0.24.1: Humanize — random micro-timing and velocity variation
Makes programmed parts feel like a real player. Random timing jitter
and velocity wobble applied at render time, score data stays clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:04:07 -04:00
kennethreitz ebf26cfbfa v0.24.0: Velocity, swing, tempo changes, fade in/out
- Per-note velocity for dynamics and accents
- Swing/groove parameter on Score and per-Part override
- score.set_tempo() for mid-song tempo changes with tempo map engine
- Part.fade_in() and Part.fade_out() volume envelopes
- Arpeggiator velocity support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 14:44:50 -04:00
kennethreitz a41f20e805 v0.22.0: LFO automation for parameter modulation
- Part.lfo() generates automation points from oscillator shapes
- 4 shapes: sine, triangle, saw, square
- Rate, range, duration, and resolution all configurable
- Stack LFOs on different params for complex modulation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:52:40 -04:00
kennethreitz 2de263c814 v0.21.0: Effect automation via Part.set(), chorus effect
- Part.set() inserts automation markers for mid-song parameter changes
- Chorus effect (LFO-modulated delay, Juno-style thickening)
- Renderer segments at automation points for per-section processing
- Chain: distortion → chorus → lowpass → delay → reverb
- Docs: automation, chorus, updated signal chain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:49:12 -04:00
kennethreitz a7ad8a374b v0.20.0: Arpeggiator, flat numeral parser, generative showoff
- Part.arpeggio() with 5 patterns, octave spanning, division control
- Roman numeral parser handles bVI, bVII, bIII, #IV prefixes
- song_showoff.py: generative composition using every feature,
  different every time (4 moods, matched keys/drums/effects)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:41:03 -04:00
kennethreitz e75c35a099 v0.19.1: Arpeggiator, legato/glide docs, sequencing page rename
- Part.arpeggio() with up/down/updown/downup/random patterns
- Octave spanning and division control for arps
- Document legato, glide, and arpeggiator in rhythm guide
- Rename docs page to "Sequencing: Rhythm and Scores"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:33:19 -04:00
kennethreitz b9f0a3870a v0.19.0: Legato mode with pitch glide/portamento
- Part(legato=True) renders continuous waveform without per-note retriggering
- Part(glide=0.04) adds 303-style pitch slides between notes
- Phase-accumulating oscillator for smooth frequency changes
- Exponential pitch interpolation for perceptually linear slides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:28:50 -04:00
kennethreitz 8c61cb146b Bump version to 0.18.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:06:29 -04:00
kennethreitz 5d746ed0b1 v0.18.0: Per-part audio effects — reverb, delay, lowpass filter
- Schroeder reverb (4 comb + 2 allpass filters) with mix/decay
- Tempo-synced delay with feedback
- 12 dB/oct biquad lowpass with resonance (Q) control
- Effects set at part creation, applied per-part before mixing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:56:48 -04:00
kennethreitz 89323c0eb3 v0.17.0: 10 new grooves + 10 new fills (58 grooves, 21 fills total)
Grooves: country, ska, dub, jungle, techno, gospel, swing, bolero, tango, flamenco
Fills: reggae, afrobeat, bossa nova, house, trap, hip hop, disco, cumbia, highlife, second line

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:49:14 -04:00
kennethreitz 5a44d619d0 v0.16.0: Drum fills — 11 genre presets with auto-fill support
- Pattern.fill() with 11 presets: rock, jazz, salsa, samba, funk, metal, blast, buildup, breakdown
- Score.fill() inserts a fill at the current position
- Score.drums() auto-fill support: fill_every=4 replaces every 4th bar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:43:46 -04:00
kennethreitz f5bf7ce505 v0.15.1: PWM synths, score.drums() shorthand, docs update
- Synth.PWM_SLOW: pulse width modulation with 0.3 Hz LFO (Juno pads)
- Synth.PWM_FAST: pulse width modulation with 3 Hz LFO (chorus/vibrato)
- Score.drums("preset", repeats=N) shorthand
- All docs updated with score.drums() syntax and 10-synth reference table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:37:36 -04:00
kennethreitz 4f3b706336 v0.15.0: Add square, pulse, FM, noise, and supersaw synth waveforms
- Square wave: chiptune / 8-bit (odd harmonics at 1/n)
- Pulse wave: variable duty cycle NES-style timbres
- FM synthesis: DX7-style carrier/modulator for bells, e-piano, brass
- Noise: white noise for percussion and texture
- Supersaw: 7 detuned saws for trance/EDM pads
- Refactor Synth enum to string-valued with callable dispatch
- All 8 waveforms available via API, Part strings, and CLI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:37:21 -04:00
kennethreitz d0e8e43b56 v0.14.0: Multi-part Score API with Part class
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:24:27 -04:00
kennethreitz adfbc3079a v0.13.1: Fix drum pattern repeat sync
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:10:35 -04:00
kennethreitz f00cf10c41 v0.13.0: Drum synthesizer with play_pattern() and play_score()
- 27 synthesized drum voices (kick, snare, hat, conga, timbale, etc.)
- play_pattern() renders and plays drum patterns through speakers
- play_score() mixes drum patterns + chord progressions together
- Comprehensive drum synthesis docs with sound descriptions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:01:02 -04:00
kennethreitz 4f03bb6616 v0.12.0: Rhythm module with Duration, TimeSignature, Score, MIDI export
- Duration enum (whole through sixteenth, dotted, triplet)
- TimeSignature with string parsing (4/4, 3/4, 6/8, 12/8)
- Score class with fluent .add()/.rest() chaining
- Measure-aware MIDI export with time signature meta events
- Rhythm guide documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:56:46 -04:00
kennethreitz 4aafd8d0b0 v0.11.0: Drop voicings, modulation, degree names, extensions, solfege, CLI identify/midi, docs
- Chord.close_voicing(), open_voicing(), drop2(), drop3()
- Key.modulation_path() for pivot-chord modulation paths
- Scale.degree_name() for traditional function names
- Chord.extensions() for available 9th/11th/13th suggestions
- Tone.solfege for fixed-Do solfege syllables
- CLI identify and midi commands
- Comprehensive docs update covering all v0.9.0–v0.11.0 features

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:49:17 -04:00
kennethreitz c74600d42f v0.10.0: Scale fitness, chord suggestions, Helmholtz, slash chords, MIDI export
- Scale.fitness() scores note-to-scale fit
- Key.suggest_next() for functional harmony chord suggestions
- Tone.helmholtz/scientific notation properties
- Chord.slash() and slash_name for slash chord notation
- save_midi() for Standard MIDI File export
- Fretboard.scale_diagram() highlights chord tones vs passing tones
- Chord.analyze() recognizes borrowed chords (bVI, bVII, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:39:27 -04:00
kennethreitz f4d2cca663 v0.9.0: ADSR envelopes, chord symbol parser, modulation, parallel modes, cents
- Add Envelope enum with 8 ADSR presets (piano, organ, pluck, pad, strings, bell, staccato, none)
- Add Chord.from_symbol() to parse any standard chord symbol without lookup tables
- Add Key.pivot_chords() for finding modulation pivot chords between keys
- Add Scale.parallel_modes() to show all modes sharing the same notes
- Add Tone.cents_difference() for fine pitch comparison in cents
- Add --envelope flag to CLI play command
- Extract C_INDEX constant, removing hardcoded magic number

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:30:46 -04:00
kennethreitz aa454ea7e9 v0.8.3: Chord symbols, common progressions, CLI modes/circle/progressions
- Add Chord.symbol property for standard shorthand notation (Cmaj7, Dm, G7)
- Add Key.common_progressions() to realize all named progressions in a key
- Add CLI commands: modes, circle, progressions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:19:29 -04:00
kennethreitz c307c1e41f v0.4.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 13:34:04 -04:00
kennethreitz da40189845 v0.4.0: key signatures, scale diagrams, chord building, progression analysis
New features:
- Key.signature — sharps/flats count and accidental names
- Key.borrowed_chords — modal interchange from parallel key
- Key.random_progression(n) — weighted random diatonic progressions
- Chord.from_intervals("C", 4, 7) — build from root + semitones
- Chord.from_midi_message(60, 64, 67) — build from MIDI note numbers
- Chord.add_tone(tone) / remove_tone("B") — modify chords immutably
- Tone.letter — "C" from "C#" (letter without accidental)
- Fretboard.scale_diagram(scale) — ASCII neck diagram
- analyze_progression([chords], key="C") → ["I", "vi", "IV", "V"]

443 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 12:48:04 -04:00
kennethreitz 54b82440c4 v0.3.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:56:15 -04:00
kennethreitz 890c3cfbe2 v0.3.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:47:08 -04:00
kennethreitz 59f69079bf Fix pyproject.toml: move dependencies under [project], add build-system
Dependencies were at the root level instead of under [project] — uv
ignored them entirely. This caused uv.lock to omit pytuning, scipy,
numpy, and sounddevice. API reference pages were blank because
autodoc couldn't import the modules.

Also adds [build-system] so uv treats the project as editable
instead of virtual.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:26:28 -04:00
kennethreitz fde1011194 Expand test suite to 178 tests and fix additional bugs
- Add pytest as dev dependency in pyproject.toml
- Fix sawtooth_wave: numpy.linspace requires int for num parameter
- Fix Scale.degree() lookup by name ("tonic", "dominant") was broken
- Add tests for: Tone.from_tuple, from_index, _index, error paths,
  multi-octave arithmetic, descending chromatic walk, all pitch frequencies,
  Pythagorean temperament, all scale degrees by Roman numeral and name,
  Scale repr/slice/degrees mismatch, TonedScale repr/get/with-Tone-object,
  D/F/A/E/B major/minor scales, D Dorian, G Mixolydian, octave boundary
  crossing, all mode intervals including Phrygian/Aeolian/Locrian/Ionian,
  chord intervals/beat_pulse/empty chord, Chord/Fretboard fingering errors,
  all NamedChord qualities (m6/m9/maj9/9), fix_fingering, flat-to-sharp
  conversion, charts total count, charts_for_fretboard, all wave generators,
  wave output types, Synth with real pitches, circle of fifths/fourths,
  relative minor equivalence, enharmonic equivalence in scales, I-IV-V
  progression integration test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:39:12 -04:00