Two variants modeling Himalayan singing bowl acoustics:
- Strike: mallet hit with chirp from inharmonic partials, long ring
- Ring: rim-rubbed sustained tone with slow build and beating modes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_Channel now stores and applies: chorus, detune, distortion,
saturation, tremolo, analog, delay, phaser, sub_osc, noise_mix.
TUI fx command: fx <ch> <param> <val> to tweak any effect live.
fx alone lists all available params. fx <ch> shows current values.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes CI failure — rtmidi needs ALSA headers on Linux which
aren't available in the test runner. Now optional: import is
lazy with clear error message if missing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LiveEngine listens for MIDI input and synthesizes audio in real-time.
Each MIDI channel maps to a pytheory instrument with its own synth,
envelope, and effects. Supports polyphony, voice stealing, and
GM drum channel (10).
Adds python-rtmidi as a dependency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the numeral package with ~30 lines of int2roman()/roman2int()
in _statics.py. Reduces supply chain surface. Fixes#47.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Smoothly sweep any parameter (lowpass, reverb, distortion, etc.)
from current value to target with linear, ease_in, ease_out, or
ease_in_out interpolation curves.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Part.crescendo(), Part.decrescendo(), Part.swell(), and Part.dynamics()
for velocity ramps and custom curves across note sequences.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 6 new drum fills: cajon flam, cajon rumble, cajon breakdown,
metal triplet, metal blast, metal cascade. 27 fills total.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Duration enum now supports multiplication, division, and addition
so expressions like `Duration.WHOLE * 2` work instead of raising TypeError.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace pytuning with 30-line native implementations of EDO,
Pythagorean, and quarter-comma meantone scale generators
- Lazy-load scipy.signal (337ms) — only imported when audio rendering
is actually used, not on theory-only imports
- Removes pytuning and sympy from dependencies entirely
Import time: 0.479s → 0.056s (8.5x faster)
Closes#44
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16 dedicated instrument synths, speaker cab sim, analog drift,
strumming with fretboard lookup, dhol/dholak/mridangam/djembe/
metal kit with 22 patterns, 5 new demo moods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
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>
- 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>
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>
Different comb filter delay times per channel create natural stereo
width in the reverb tail. Effects chain skips mono reverb in favor
of stereo reverb applied in the mixer after panning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Feed-forward compression (threshold=0.5, ratio=4:1) with envelope
following, makeup gain, and brick-wall limiter at 0.95. Replaces
simple normalization. Everything sounds louder and punchier.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
- `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>