Skip to content

Commit

Permalink
removed tie-breaking in key-to-notes, updated docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
bmcfee committed Jun 8, 2020
1 parent ec7fbda commit ec02cce
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
33 changes: 14 additions & 19 deletions librosa/core/time_frequency.py
Expand Up @@ -569,24 +569,24 @@ def midi_to_note(midi, octave=True, cents=False, key='C:maj', unicode=True):
>>> librosa.midi_to_note(37)
'C♯2'
>>> librosa.midi_to_note(37, unicode=False)
'C#2'
>>> librosa.midi_to_note(-2)
'A♯-2'
>>> librosa.midi_to_note(104.7)
'A7'
>>> librosa.midi_to_note(104.7, cents=True)
'A7-30'
>>> librosa.midi_to_note(list(range(12, 24)))
['C0', 'C♯0', 'D0', 'D♯0', 'E0', 'F0', 'F♯0', 'G0', 'G♯0', 'A0', 'A♯0', 'B0']
Use a key signature to resolve enharmonic equivalences
>>> librosa.midi_to_note(range(12), key='A:min')
>>> librosa.midi_to_note(range(12, 24), key='F:min')
['C0', 'D♭0', 'D0', 'E♭0', 'E0', 'F0', 'G♭0', 'G0', 'A♭0', 'A0', 'B♭0', 'B0']
Parameters
Expand Down Expand Up @@ -623,7 +623,7 @@ def midi_to_note(midi, octave=True, cents=False, key='C:maj', unicode=True):
midi_to_hz
note_to_midi
hz_to_note
key_to_note
key_to_notes
'''

if cents and not octave:
Expand Down Expand Up @@ -1716,8 +1716,9 @@ def samples_like(X, hop_length=512, n_fft=None, axis=-1):


@cache(level=10)
def key_to_notes(key, unicode=True):
'''Construct the names for 12 chromatic notes for a given key.
def key_to_notes(key, unicode=True):
'''Lists all 12 note names in the chromatic scale, as spelled according to
a given key (major or minor).
This function exists to resolve enharmonic equivalences between different
spellings for the same pitch (e.g. C♯ vs D♭), and is primarily useful when producing
Expand All @@ -1731,8 +1732,7 @@ def key_to_notes(key, unicode=True):
2. If the tonic does not have an accidental, accidentals will be inferred to minimize
the total number used for diatonic scale degrees.
3. If there is a tie (e.g., in the case of C:maj vs A:min), sharps will be preferred
for major keys, and flats will be preferred for minor keys.
3. If there is a tie (e.g., in the case of C:maj vs A:min), sharps will be preferred.
Parameters
----------
Expand Down Expand Up @@ -1766,9 +1766,9 @@ def key_to_notes(key, unicode=True):
>>> librosa.key_to_notes('C:maj')
['C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯', 'A', 'A♯', 'B']
`A:min` will use all flats
`A:min` has the same notes
>>> librosa.key_to_notes('A:min')
['C', 'D♭', 'D', 'E♭', 'E', 'F', 'G♭', 'G', 'A♭', 'A', 'B♭', 'B']
['C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯', 'A', 'A♯', 'B']
`A♯:min` will use sharps, but spell note 0 (`C`) as `B♯`
>>> librosa.key_to_notes('A#:min')
Expand Down Expand Up @@ -1824,17 +1824,12 @@ def key_to_notes(key, unicode=True):
# use sharps explicitly
use_sharps = True

elif 0 < tonic_number < 6:
elif 0 <= tonic_number < 6:
use_sharps = True

elif tonic_number > 6:
use_sharps = False

else:
# Equal numbers of sharps and flats for tonics 0 and 6
# break ties for major => sharp, minor => flat
use_sharps = major

# Basic note sequences for simple keys
notes_sharp = ['C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯', 'A', 'A♯', 'B']
notes_flat = ['C', 'D♭', 'D', 'E♭', 'E', 'F', 'G♭', 'G', 'A♭', 'A', 'B♭', 'B']
Expand Down
2 changes: 1 addition & 1 deletion tests/test_time_frequency.py
Expand Up @@ -540,7 +540,7 @@ def test_key_to_notes_badkey():
@pytest.mark.parametrize('key,ref_notes', [
# Test for implicit accidentals, ties
('C:maj', ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']),
('A:min', ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']),
('A:min', ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']),
# Test for implicit accidentals, unambiguous
('D:maj', ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']),
('F:min', ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']),
Expand Down

0 comments on commit ec02cce

Please sign in to comment.