Skip to content

Commit 8f63f5a

Browse files
authored
Merge pull request #2054 from float3/realize-cache-altered-degrees
Key the realization cache on the altered degrees
2 parents 2c806e5 + d042989 commit 8f63f5a

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎music21/scale/intervalNetwork.py‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ def __str__(self) -> str:
8080

8181

8282
type CacheKey = tuple[
83-
int|Terminus, str, str|None, str|None, bool, bool|None]
83+
int|Terminus, str, str|None, str|None, bool, bool|None,
84+
tuple[tuple[int, Direction, int, int|float], ...]]
8485

8586
class AlteredDegree(t.TypedDict):
8687
'''
@@ -1421,6 +1422,7 @@ def _getCacheKey(
14211422
*,
14221423
includeFirst: bool,
14231424
reverse: bool|None = None, # only meaningful for descending
1425+
alteredDegrees: AlteredDegrees|None = None,
14241426
) -> CacheKey:
14251427
'''
14261428
Return key for caching based on critical components.
@@ -1434,12 +1436,23 @@ def _getCacheKey(
14341436
maxKey = maxPitch.nameWithOctave
14351437
else:
14361438
maxKey = None
1439+
1440+
# an interval's generic number and semitones say what it is, and are
1441+
# cheaper to read than its name
1442+
alteredKey: tuple[tuple[int, Direction, int, int|float], ...] = ()
1443+
if alteredDegrees:
1444+
alteredKey = tuple([(degree,
1445+
spec['direction'],
1446+
spec['interval'].generic.directed,
1447+
spec['interval'].semitones)
1448+
for degree, spec in alteredDegrees.items()])
14371449
return (nodeObj.id,
14381450
pitchReference.nameWithOctave,
14391451
minKey,
14401452
maxKey,
14411453
includeFirst,
14421454
reverse,
1455+
alteredKey,
14431456
)
14441457

14451458
def realizeAscending(
@@ -1513,7 +1526,8 @@ def realizeAscending(
15131526
pitchReference,
15141527
minPitch,
15151528
maxPitch,
1516-
includeFirst=False)
1529+
includeFirst=False,
1530+
alteredDegrees=alteredDegrees)
15171531
if ck in self._ascendingCache:
15181532
return self._ascendingCache[ck]
15191533
else:
@@ -1720,6 +1734,7 @@ def realizeDescending(
17201734
maxPitch=maxPitchObj,
17211735
includeFirst=includeFirst,
17221736
reverse=reverse,
1737+
alteredDegrees=alteredDegrees,
17231738
)
17241739
if ck in self._descendingCache:
17251740
return self._descendingCache[ck]

‎music21/scale/test_scale_main.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ def testDeriveHarmonicMinor(self):
320320
sc = scale.HarmonicMinorScale()
321321
self.assertEqual(sc.derive(['C', 'D', 'E-', 'B']).name, 'C harmonic minor')
322322

323+
def testHarmonicMinorKeepsItsSeventhAfterNextPitch(self):
324+
sc = scale.HarmonicMinorScale('g4')
325+
sc.nextPitch('a4')
326+
self.assertEqual(self.pitchOut(sc.pitches), '[G4, A4, B-4, C5, D5, E-5, F#5, G5]')
327+
323328
def testDeriveByDegree(self):
324329
sc1 = scale.MajorScale()
325330
self.assertEqual(str(sc1.deriveByDegree(7, 'G#')),

0 commit comments

Comments
 (0)