Document missing API features across guides

- chords: open_voicing() alongside other voicings, normal_form() in
  pitch class sets section
- tones: is_natural, is_sharp, is_flat accidental properties
- scales: Key.seventh() for individual degrees, expanded
  Scale.recommend() explanation of how ranking works

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 17:33:47 -04:00
parent c1925af69d
commit b3f3e985b4
3 changed files with 77 additions and 1 deletions
+24
View File
@@ -503,9 +503,16 @@ are standard arranging techniques for spreading chord tones across registers:
>>> cmaj7 = Chord.from_symbol("Cmaj7")
>>> cmaj7.close_voicing()
<Chord C major 7th>
>>> cmaj7.open_voicing()
<Chord C major 7th>
>>> cmaj7.drop2()
<Chord C major 7th>
``open_voicing()`` takes the close voicing and raises every other
non-root tone by an octave, spreading the chord across two octaves.
The result is a wider, more spacious sound — common in orchestral
writing and piano ballads where you want the harmony to breathe.
Chord Extensions
----------------
@@ -596,6 +603,23 @@ music that doesn't follow traditional harmony, this is the tool.
Major and minor triads share the same prime form — they're inversions
of each other in pitch class space.
The **normal form** is the intermediate step — the most compact ascending
arrangement of pitch classes before transposition. It preserves the
actual pitch classes (not transposed to 0), so it tells you which
specific notes are in the set:
.. code-block:: pycon
>>> Chord.from_tones("C", "E", "G").normal_form
(0, 4, 7)
>>> Chord.from_tones("A", "C", "E").normal_form
(9, 0, 4)
Normal form keeps the original pitch classes; prime form transposes to 0
for comparison. Use ``normal_form`` when you care about which notes,
``prime_form`` when you care about the abstract shape.
.. code-block:: pycon
>>> Chord.from_tones("C", "E", "G").forte_number
+27 -1
View File
@@ -269,6 +269,23 @@ easy:
['G major', 'A minor', 'B minor', 'C major', 'D major', 'E minor', 'F# diminished']
>>> key.seventh_chords
['G major 7th', 'A minor 7th', 'B minor 7th', 'C major 7th', 'D dominant 7th', 'E minor 7th', 'F# half-diminished 7th']
Build a seventh chord on any individual degree with ``seventh()``:
.. code-block:: pycon
>>> key.seventh(0) # I7
G major 7th
>>> key.seventh(4) # V7
D dominant 7th
>>> key.seventh(6) # vii7
F# half-diminished 7th
This is the single-degree version of ``seventh_chords`` — useful when
you need one specific chord rather than the full list.
.. code-block:: pycon
>>> Key.detect("C", "E", "G", "A", "D")
C major
@@ -440,7 +457,16 @@ alternative scales to improvise over:
>>> Scale.recommend("C", "Eb", "F", "Gb", "G", "Bb", top=3)
[('C', 'blues', 1.0), ...]
Chromatic scales are deprioritized since they match everything.
How it works: ``recommend()`` tests your notes against every scale in
every key (all 12 tonics times all scale types in the Western system).
Each candidate is scored using ``fitness()`` — the fraction of your notes
that belong to that scale (1.0 = perfect match). Results are ranked by
fitness, with chromatic scales deprioritized since they match everything.
Scales whose length is closer to the number of input notes are preferred
when fitness scores tie.
Returns a list of ``(tonic, scale_name, fitness)`` tuples. Pass ``top=``
to control how many results you get back (default 5).
Parallel Modes
~~~~~~~~~~~~~~
+26
View File
@@ -357,6 +357,32 @@ every tone knows its enharmonic spelling:
>>> Tone.from_string("C4", system="western").enharmonic is None
True
Accidental Properties
~~~~~~~~~~~~~~~~~~~~~
Check whether a tone is natural, sharp, or flat:
.. code-block:: pycon
>>> c = Tone.from_string("C4", system="western")
>>> c.is_natural
True
>>> c.is_sharp
False
>>> cs = Tone.from_string("C#4", system="western")
>>> cs.is_sharp
True
>>> cs.is_natural
False
>>> bb = Tone.from_string("Bb4", system="western")
>>> bb.is_flat
True
Useful for filtering — for example, finding all natural notes in a
scale, or counting accidentals in a melody.
Extended Enharmonics
~~~~~~~~~~~~~~~~~~~~