- 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>
- 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>
- 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>
- 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>
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>
- 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>