Skip to content

Commit 3fae7a1

Browse files
authored
Merge pull request #1695 from TimFelixBeyer/dissonance-score-fix
Make `_dissonanceScore` independent of octaves
2 parents e532560 + 6371669 commit 3fae7a1

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

music21/pitch.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,10 @@ def _convertHarmonicToCents(value: int|float) -> int:
553553
# -----------------------------------------------------------------------------
554554

555555

556-
def _dissonanceScore(pitches, smallPythagoreanRatio=True, accidentalPenalty=True, triadAward=True):
556+
def _dissonanceScore(pitches: list[Pitch],
557+
smallPythagoreanRatio: bool = True,
558+
accidentalPenalty: bool = True,
559+
triadAward: bool = True):
557560
r'''
558561
Calculates the 'dissonance' of a list of pitches based on three criteria:
559562
it is considered more consonant if 1. the numerator and denominator of the
@@ -577,17 +580,20 @@ def _dissonanceScore(pitches, smallPythagoreanRatio=True, accidentalPenalty=True
577580

578581
if smallPythagoreanRatio or triadAward:
579582
try:
580-
intervals = [interval.Interval(noteStart=p1, noteEnd=p2)
581-
for p1, p2 in itertools.combinations(pitches, 2)]
583+
intervals = []
584+
for p1, p2 in itertools.combinations(pitches, 2):
585+
p2 = copy.deepcopy(p2)
586+
p2.octave = None
587+
this_interval = interval.Interval(noteStart=p1, noteEnd=p2)
588+
intervals.append(this_interval)
582589
except interval.IntervalException:
583590
return math.inf
584591
if smallPythagoreanRatio:
585592
# score_ratio = Pythagorean ratio complexity per pitch
586593
for this_interval in intervals:
587594
# does not accept weird intervals, e.g. with semitones
588595
ratio = interval.intervalToPythagoreanRatio(this_interval)
589-
# d2 is 1.0
590-
penalty = math.log(ratio.numerator * ratio.denominator / ratio) * 0.03792663444
596+
penalty = math.log(ratio.denominator) * 0.07585326888
591597
score_ratio += penalty
592598

593599
score_ratio /= len(pitches)
@@ -607,7 +613,7 @@ def _dissonanceScore(pitches, smallPythagoreanRatio=True, accidentalPenalty=True
607613
+ accidentalPenalty + triadAward)
608614

609615

610-
def _bruteForceEnharmonicsSearch(oldPitches, scoreFunc=_dissonanceScore):
616+
def _bruteForceEnharmonicsSearch(oldPitches: list[Pitch], scoreFunc=_dissonanceScore):
611617
'''
612618
A brute-force way of simplifying -- useful if there are fewer than 5 pitches
613619
'''
@@ -617,7 +623,7 @@ def _bruteForceEnharmonicsSearch(oldPitches, scoreFunc=_dissonanceScore):
617623
return oldPitches[:1] + list(newPitches)
618624

619625

620-
def _greedyEnharmonicsSearch(oldPitches, scoreFunc=_dissonanceScore):
626+
def _greedyEnharmonicsSearch(oldPitches: list[Pitch], scoreFunc=_dissonanceScore):
621627
newPitches = oldPitches[:1]
622628
for oldPitch in oldPitches[1:]:
623629
candidates = [oldPitch] + oldPitch.getAllCommonEnharmonics()

0 commit comments

Comments
 (0)