Commit Graph

112 Commits

Author SHA1 Message Date
kennethreitz 7153dc908f Add Chord.from_name, Interval constants, PROGRESSIONS, enharmonic, fix API docs
New features:
- Chord.from_name("Am7") — build chords from chart names
- Chord.__str__() — prints "C major" instead of raw tones
- Interval constants: Interval.PERFECT_FIFTH, MAJOR_THIRD, OCTAVE, etc.
- PROGRESSIONS dict: 8 common progressions as Roman numeral tuples
  ("I-V-vi-IV", "ii-V-I", "12-bar blues", etc.)
- Tone.enharmonic: C# → "Db", natural notes → None
- Key.__str__(): "C major"

Fix: docs CI now installs all dependencies (uv sync --group docs)
so autodoc can import pytheory modules. API reference pages were
blank on GitHub Pages because pytuning/scipy weren't installed.

New example: examples/explore.py — comprehensive demo of the full API.

393 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:09:16 -04:00
kennethreitz 240d2564a4 Remove logo from README
Removed logo image from README.
2026-03-22 07:03:41 -04:00
kennethreitz fd6ae888cf Add GitHub link and banner to docs sidebar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:02:45 -04:00
kennethreitz c6e3f56136 Add Key class, Note alias, rewrite README
Key class — the friendliest entry point for music theory:
  Key("C", "major").chords → all diatonic triads
  Key("C", "major").seventh_chords → all diatonic 7th chords
  Key("C", "major").progression("I", "V", "vi", "IV")
  Key("C", "major").relative → Key("A", "minor")
  Key("C", "major").parallel → Key("C", "minor")

Note = Tone alias for discoverability.

README rewritten to showcase the full API:
  tones, scales, diatonic harmony, chord analysis,
  6 systems, 25 instruments, audio playback,
  comprehensive feature list.

381 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:00:22 -04:00
kennethreitz 5850ac00d5 Fix docs build warnings: malformed table and short underline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:57:44 -04:00
kennethreitz 74ce7e39f8 Rewrite fretboard docs: all 25 instruments documented
Organized by family:
- Guitars: standard, 12-string, bass, alternate tunings
- Mandolin family: mandolin, mandola, octave mandolin, mandocello
- Bowed strings: violin, viola, cello, double bass, erhu
- Plucked: ukulele, banjo, harp
- World: oud, sitar, shamisen, pipa, bouzouki, lute, balalaika, charango
- Steel: pedal steel
- Keyboards: piano (88), synth (61), mini (25)

Each section includes tuning details, cultural context, and Wikipedia links.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:55:26 -04:00
kennethreitz d5beab46f2 Add Fretboard.keyboard() for piano/synth controllers
Fretboard.keyboard(keys=88, start="A0") — configurable key count:
- 88 keys = full piano (A0-C8)
- 61 keys = standard synth controller
- 49/37/25 keys = compact MIDI controllers

25 instrument presets total. 368 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:53:47 -04:00
kennethreitz 5e09e64c2d Add 9 world instruments: bouzouki, oud, sitar, shamisen, erhu, charango, pipa, balalaika, lute
World instruments:
- bouzouki (Irish GDAD / Greek CFAD)
- oud (Arabic, 6 courses, fretless)
- sitar (Indian, 7 main strings)
- shamisen (Japanese, 3 strings, honchoshi tuning)
- erhu (Chinese, 2 strings, bowed)
- charango (Andean, 5 courses, re-entrant)
- pipa (Chinese lute, 4 strings)
- balalaika (Russian, 3 strings, 2 in unison)
- lute (Renaissance, 6 courses)

24 instrument presets total. 365 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:52:39 -04:00
kennethreitz 8bf716d1db Add full mandolin family, double bass, harp, pedal steel
Complete mandolin family (all tuned in fifths):
- mandolin     E5 A4 D4 G3 (= violin)
- mandola      A4 D4 G3 C3 (= viola, a 5th lower)
- octave_mandolin  E4 A3 D3 G2 (octave below mandolin)
- mandocello   A3 D3 G2 C2 (= cello)

New instruments:
- double_bass   G2 D2 A1 E1 (tuned in 4ths, unlike bowed strings)
- harp          47 strings, C1 to G7 (concert pedal harp)
- pedal_steel   10 strings, E9 Nashville tuning

15 instrument presets total. 355 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:50:02 -04:00
kennethreitz fcfba20ec5 Add mandolin, mandola, violin, viola, cello, banjo, 12-string presets
New Fretboard presets:
- Fretboard.mandolin()  — E5 A4 D4 G3 (tuned in 5ths)
- Fretboard.mandola()   — A4 D4 G3 C3 (octave below mandolin)
- Fretboard.violin()    — E5 A4 D4 G3 (same as mandolin)
- Fretboard.viola()     — A4 D4 G3 C3 (5th below violin)
- Fretboard.cello()     — A3 D3 G2 C2 (octave below viola)
- Fretboard.banjo(tuning) — open G, open D, double C
- Fretboard.twelve_string() — 12-string guitar (6 doubled courses)

Updated fretboard docs with string family section and custom
instrument examples (mandola, baritone ukulele, upright bass).

347 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:48:25 -04:00
kennethreitz 858f0c1c06 Add inversions, from_frequency, from_midi, harmonize, progressions
Tone:
- Tone.from_frequency(440) → <Tone A4> (nearest 12-TET note)
- Tone.from_midi(60) → <Tone C4> (MIDI note number conversion)

Chord:
- chord.inversion(1) → first inversion (root up an octave)
- chord.inversion(2) → second inversion
- Inversions preserve chord identity

Scale:
- scale.seventh(0) → Imaj7 seventh chord from scale degree
- scale.harmonize() → all diatonic triads
  ['C major', 'D minor', 'E minor', 'F major', 'G major', 'A minor', 'B diminished']
- scale.progression("I", "V", "vi", "IV") → chord progression from
  Roman numerals, with "7" suffix for seventh chords

339 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:45:19 -04:00
kennethreitz 4b9534eb9b v0.3.0: interval naming, MIDI, transpose, chord root/quality, clean API
New features:
- Tone.interval_to(other): "perfect 5th", "major 3rd", "octave"
- Tone.midi: MIDI note number (C4=60, A4=69)
- Tone.transpose(n): alias for tone arithmetic
- Chord.transpose(n): shift all tones, preserving quality
- Chord.root: identify the root tone
- Chord.quality: identify the chord quality ("major", "minor 7th")
- Scale.transpose(n): shift to a new key

Cleanup:
- __version__ = "0.3.0"
- __all__ defined — no more ceil/floor leaking
- pyproject.toml: author, license, classifiers, project URLs

319 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:42:31 -04:00
kennethreitz fdb724f788 Fix RST inline markup: remove bold wrapping around links
RST cannot nest inline markup — **`link <url>`_** renders the raw
markup instead of a clickable link. Removed all 37 instances across
5 guide pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:39:58 -04:00
kennethreitz 245a8a1257 Add Wikipedia links throughout docs, showcase dissonance API, update copyright
- Link key music theory terms to Wikipedia across all guide pages
- Physics of Consonance section now demos .harmony, .dissonance,
  .tension, and .beat_frequencies with code examples
- Copyright updated to 2026

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:35:40 -04:00
kennethreitz 4ab8be49a5 Add Music Theory Fundamentals page and deepen theory throughout docs
New: Music Theory Fundamentals guide covering:
- Sound and pitch (frequency ranges, logarithmic perception)
- Why twelve notes (harmonic series, Pythagorean comma)
- Intervals as atoms of music (size, quality, perfect vs major/minor)
- Keys and key signatures (sharp/flat key tables, FCGDAEB mnemonic)
- Functional harmony (tonic/subdominant/dominant, T-S-D-T)
- The dominant seventh (leading tone, tritone resolution)
- Rhythm and meter (4/4, 3/4, 6/8, odd meters)
- Physics of consonance (waveform alignment, cultural context)

Enriched existing pages:
- Tones: overtone series table, enharmonic equivalents and spelling rules
- Scales: 12-bar blues, parallel major/minor, borrowed chords,
  more progression examples with song references
- Chords: inversions (root/1st/2nd/3rd), extended chords (9ths/11ths/13ths)

Also: add Gauges analytics tracking to all pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:29:16 -04:00
kennethreitz 427a3fc3b1 Add Tone.circle_of_fifths() and Tone.circle_of_fourths()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:26:15 -04:00
kennethreitz c3f9e98332 Add chord identification, voice leading, harmonic analysis, tension, overtones
New features:
- Chord.identify(): name any chord (17 patterns — triads, 7ths, 9ths, sus, power)
- Chord.voice_leading(other): find smoothest voice motion between chords
- Chord.analyze(key): Roman numeral analysis (I, ii, V7, etc.)
- Chord.tension: score with tritone count, dominant function detection
- Tone.overtones(n): harmonic series frequencies

Also:
- Rewrite README with all current features and docs link
- Add all new features to chords guide with music theory context
- Remove logo from docs sidebar
- 296 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:25:31 -04:00
kennethreitz e1c2ef03d7 Comprehensive music theory documentation pass
Every guide page rewritten with deep music theory content:

- Tones: scientific pitch notation, frequency/pitch relationship,
  temperament history (equal/Pythagorean/meantone), interval table
  with song examples, circle of fifths
- Scales: interval pattern construction, major/minor/harmonic minor
  theory, all 7 modes with character descriptions and song references,
  scale degree names and functions, diatonic harmony and common
  chord progressions (I-IV-V, I-V-vi-IV, ii-V-I)
- Chords: triad and seventh chord construction tables, all 12 chord
  qualities with interval formulas, consonance/dissonance theory
  (Pythagoras to Plomp-Levelt), beat frequency perceptual ranges
- Fretboard: how frets work, string interval explanation, reading
  fingering notation, 8 alternate tunings with musical context,
  custom instrument examples (banjo, mandolin)
- Playback: waveform physics (harmonics, Fourier), temperament
  listening guide
- Quickstart: updated feature list (6 systems, 40+ scales, 144 chords)
- Fix duplicate logo/title in sidebar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:20:01 -04:00
kennethreitz 21cd99425b Add Blues/Pentatonic and Javanese Gamelan systems
Blues: major/minor pentatonic, blues scale, major blues, dominant,
  minor (Dorian). The foundational scales of blues, rock, and jazz.

Gamelan: slendro (5-tone equidistant), pelog (7-tone with 3 pathet
  subsets: nem, barang, lima). 12-TET approximations of Javanese
  gamelan tuning with traditional tone names (ji, ro, lu, pat, mo,
  nem, pi/barang).

Total systems: 6 (western, indian, arabic, japanese, blues, gamelan)
277 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:15:11 -04:00
kennethreitz 69ddb1eb64 Rewrite chord analysis with musically accurate models
intervals: now returns semitone counts (integers) instead of Hz
  differences — octave-invariant and musically meaningful

harmony: frequency ratio simplicity model — reduces each pairwise
  frequency ratio to simplest form and scores by 1/(num+denom).
  Simple ratios (octave 2:1, fifth 3:2) score highest.

dissonance: Plomp-Levelt roughness with Bark-scale critical bandwidth
  (Zwicker & Terhardt 1980). Models sensory roughness from interfering
  fundamentals — peaks when freq difference ≈ critical bandwidth.

beat_frequencies: new property returning all pairwise beat frequencies
  as sorted (tone, tone, hz) tuples

beat_pulse: returns smallest non-zero beat frequency (most perceptible)

All properties have detailed docstrings with psychoacoustic references,
perceptual ranges, and usage examples.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:13:05 -04:00
kennethreitz 23c17589eb Simplify installation instructions in docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:07:57 -04:00
kennethreitz e09dfe70b8 Remove redundant title below logo in docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:07:31 -04:00
kennethreitz cceac40a88 Add Arabic and Japanese systems, guitar tuning presets, logo, systems docs
New systems:
- Arabic (Maqam): 10 maqamat (ajam, hijaz, nahawand, nikriz, saba, etc.)
  with Arabic solfège tone names (Do, Re, Mi, Fa, Sol, La, Si)
- Japanese: 6 pentatonic scales (hirajoshi, in, yo, iwato, kumoi, insen)
  and 2 heptatonic scales (ritsu, ryo)

Fretboard improvements:
- Fretboard.guitar() now accepts tuning parameter
- Built-in tunings: standard, drop d, open g, open d, open e, open a,
  dadgad, half step down
- Custom tuning via tuple: Fretboard.guitar(("E4", "B3", ...))
- Fretboard.bass(five_string=True) for 5-string bass

Docs:
- Add Musical Systems guide page with all 4 systems
- Add logo to docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:06:17 -04:00
kennethreitz da08d30e8d Add Indian classical (Hindustani) music system with 10 thaats
- 12 swaras: Sa, komal Re, Re, komal Ga, Ga, Ma, tivra Ma, Pa, komal Dha, Dha, komal Ni, Ni
- 10 thaats (parent scales): Bilawal, Khamaj, Kafi, Asavari, Bhairavi,
  Kalyan, Bhairav, Poorvi, Marwa, Todi
- Extends generate_scale to accept direct interval patterns
- Sa maps to C's pitch position (Sa4 = 261.63 Hz)
- 17 new tests for Indian system

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:00:00 -04:00
kennethreitz e79b3ac15e Add CNAME for pytheory.kennethreitz.org
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:53:59 -04:00
kennethreitz cb3fd4526a Fix docs build: mock sounddevice for environments without PortAudio
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:52:50 -04:00
kennethreitz 7229399135 Add GitHub Pages deployment for Sphinx docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:51:55 -04:00
kennethreitz 0d740cd6fe Merge pull request #35 from kennethreitz/improvements
Fix music theory accuracy and core bugs
2026-03-22 05:49:33 -04:00
kennethreitz 3142872533 Add root Makefile with docs and test targets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:48:54 -04:00
kennethreitz 4a77f9163e Add Sphinx documentation with alabaster theme
- User guide: quickstart, tones, scales, chords, fretboard, playback
- API reference: autodoc for all modules
- alabaster theme with Napoleon for Google/NumPy docstrings
- Update project description in pyproject.toml
- Add sphinx to docs dependency group

Build with: uv run --group docs sphinx-build -b html docs docs/_build/html

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:47:20 -04:00
kennethreitz 3d58f837a2 Fix CI: gracefully handle missing PortAudio, skip play tests
- Make play module import optional in __init__.py (PortAudio may not
  be installed in CI environments)
- Skip wave generation and synth tests when PortAudio unavailable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:43:29 -04:00
kennethreitz cd8ace3020 Add Pythonic API improvements across the library
Tone:
- Add + operator for semitone addition (C4 + 7 → G4)
- Add - operator for subtraction and interval measurement (G4 - C4 → 7)
- Add <, <=, >, >= comparison by pitch frequency
- Add str() support (str(tone) → "C4")
- Add .frequency property as shorthand for .pitch()
- Tones are now sortable: sorted([G4, C4, E4]) works

Scale:
- Add iteration: for tone in scale
- Add len(): len(scale) → 8
- Add "in" operator: "C" in scale, tone in scale
- Add .note_names property
- Add .chord(*degrees) to build chords from scale degrees
- Add .triad(root) to build triads with octave wrapping

Chord:
- Add iteration: for tone in chord
- Add len(): len(chord) → 3
- Add "in" operator: "C" in chord

Fretboard:
- Add .guitar() classmethod for standard tuning
- Add .bass() classmethod for standard bass tuning
- Add .ukulele() classmethod for standard ukulele tuning
- Add iteration and len()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:42:29 -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
kennethreitz bc8dede856 Add CI workflow with pytest across Python 3.10-3.13
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:35:12 -04:00
kennethreitz dff12678ba Fix music theory accuracy and core bugs across the library
- Fix Tone.__init__ overwriting explicit octave kwarg when parsing name
- Fix Tone.__eq__ calling names as attribute instead of method, add __hash__
- Fix octave arithmetic to use C-based boundaries (scientific pitch notation)
- Fix pitch() to account for octave (was ignoring it entirely)
- Fix modal scale generation: modes were overwritten due to DEGREES loop bug
- Fix modal offset rotation off-by-one in generate_scale
- Fix scales._scales property being called as function
- Fix chord intervals: major/minor thirds were swapped, added missing chord tones
- Remove broken duplicate NamedChord class in chords.py
- Expand test suite from 11 to 83 tests covering tones, scales, modes, chords,
  pitches, fingerings, and intervals

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 05:34:11 -04:00
kennethreitz 43f7271394 Create FUNDING.yml 2024-11-17 06:28:04 -05:00
kennethreitz f93a6127ba Delete .github/FUNDING.yml 2024-11-05 11:21:15 -05:00
kennethreitz 98ea64640d Refactor hello.py to rename it to examples/chord_charts.py and improve chord chart display and playback 2024-11-05 11:20:43 -05:00
kennethreitz 1e31196e19 Bump version to 0.2.0 in pyproject.toml 2024-11-05 10:54:11 -05:00
kennethreitz 399c517226 Refactor hello.py to display standard guitar chord charts and add C minor chord playback 2024-11-05 10:52:48 -05:00
kennethreitz 08d14b0802 Refactor hello.py to display standard guitar chord charts 2024-11-05 10:38:41 -05:00
kennethreitz 3ca8f541c8 Refactor imports to optimize module usage 2024-11-05 10:29:33 -05:00
kennethreitz 44c1ea8ec6 Refactor hello.py to add C minor chord playback 2024-11-05 10:29:28 -05:00
kennethreitz 658659ca7b Refactor play.py to add play function for playing tones or chords 2024-11-05 10:22:51 -05:00
kennethreitz ad390467b9 Refactor play.py to add triangle_wave function for triangle wave synthesis 2024-11-05 10:22:34 -05:00
kennethreitz e902228912 Refactor Chord class to add fingering method for custom chord positions 2024-11-05 10:16:31 -05:00
kennethreitz 71e78934ee Refactor Chord class to calculate beat pulse between tones 2024-11-05 10:02:54 -05:00
kennethreitz 76f16938d6 Refactor chord and tone classes for improved readability and maintainability 2024-11-05 09:59:00 -05:00
kennethreitz 91b25e22d1 Update project dependencies: Replace pygame with sounddevice 2024-11-05 09:50:23 -05:00
kennethreitz b1edecc291 refactor: Update .gitignore to ignore pytheory.egg-info 2024-11-05 09:48:49 -05:00