def testEx01(self): # Basic operations for creating and manipulating scales. sc1 = scale.MajorScale('a-') # get pitches from any range of this scale #print(sc1.getPitches('g2', 'c4')) self.assertEqual(', '.join([p.nameWithOctave for p in sc1.getPitches('g2', 'c4')]), 'G2, A-2, B-2, C3, D-3, E-3, F3, G3, A-3, B-3, C4') # get a scale degree from a pitch #print(sc1.getScaleDegreeFromPitch('b-')) self.assertEqual(sc1.getScaleDegreeFromPitch('b-'), 2) # what is the scale degree of the pitch in relative minor #print(str(sc1.getRelativeMinor().getScaleDegreeFromPitch('b-'))) self.assertEqual(sc1.getRelativeMinor().getScaleDegreeFromPitch('b-'), 4) # given a pitch in this scale, what is the next pitch #print(sc1.next('g2', 'ascending')) self.assertEqual(str(sc1.next('g2', 'ascending')), 'A-2') # descending three scale steps #print(sc1.next('g2', 'descending', 3)) self.assertEqual(str(sc1.next('g2', 'descending', 3)), 'D-2') # derive a new major scale based on a pitch for a scale degree #print(sc1.deriveByDegree(7, 'f#4').pitches) self.assertEqual(common.pitchList(sc1.deriveByDegree(7, 'f#4').pitches), '[G3, A3, B3, C4, D4, E4, F#4, G4]') # a whole tone scale sc2 = scale.WholeToneScale('f#') # get pitches from any range of this scale #print str(sc2.getPitches('g2', 'c4')) self.assertEqual(common.pitchList(sc2.getPitches('g2', 'c4')), '[A-2, B-2, C3, D3, F-3, G-3, A-3, B-3, C4]') # get a scale degree from a pitch #print(str(sc2.getScaleDegreeFromPitch('e'))) self.assertEqual(sc2.getScaleDegreeFromPitch('e'), 6) # given a pitch in this scale, what is the next pitch #print(sc2.next('d4', 'ascending')) self.assertEqual(str(sc2.next('d4', 'ascending')), 'E4') # transpose the scale #print(sc2.transpose('m2').pitches) self.assertEqual(common.pitchList(sc2.transpose('m2').pitches), '[G4, A4, B4, C#5, D#5, E#5, G5]') # get as a chord and get its forte class self.assertEqual(sc2.transpose('m2').chord.forteClass, '6-35')
def testScales01(self): from music21 import pitch #==== "fig-py01" # Providing a tonic makes this concrete sc1 = scale.MajorScale('g4') sc2 = scale.MajorScale('e-3') # Comparing Concrete and Abstract Scales assert (sc1 == sc2) == False assert (sc1.abstract == sc2.abstract) == True # Without arguments, getPitches() returns a single span assert common.pitchList(sc1.getPitches()) == '[G4, A4, B4, C5, D5, E5, F#5, G5]' assert common.pitchList(sc2.getPitches('c2', 'c3')) == '[C2, D2, E-2, F2, G2, A-2, B-2, C3]' # As a Chord, Scale pitches gain additional functionality assert sc1.getChord().forteClass == '7-35' # Given a degree, get the pitch assert str(sc1.pitchFromDegree(5)) == 'D5' assert common.pitchList(sc2.pitchesFromScaleDegrees([7,2], 'e-6', 'e-9')) == '[F6, D7, F7, D8, F8, D9]' # Get a scale degree from a pitch assert sc1.getScaleDegreeFromPitch('d') == 5 assert sc2.getScaleDegreeFromPitch('d') == 7 # Get the next pitch given step directions match = [pitch.Pitch('g2')] for direction in [1, 1, 1, -2, 4, -1, 1, 1, 1]: # Append the next pitch based on the last-added pitch match.append(sc1.next(match[-1], direction)) assert common.pitchList(match), '[G2, A2, B2, C3, A2, E3, D3, E3, F#3, G3]' # Derive new scales based on a provided collection or degree assert str(sc1.derive(['c4', 'g4', 'b8', 'f2'])) == '<music21.scale.MajorScale C major>' assert str(sc1.deriveByDegree(7, 'C#')) == '<music21.scale.MajorScale D major>' # Methods unique to DiatonicScale subclasses assert str(sc2.getRelativeMinor()) == '<music21.scale.MinorScale C minor>' #==== "fig-py01" end #==== "fig-py02" sc1 = scale.PhrygianScale('g4') assert common.pitchList(sc1.getPitches()) == '[G4, A-4, B-4, C5, D5, E-5, F5, G5]' assert str(sc1.getRelativeMajor()) == '<music21.scale.MajorScale E- major>' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('G4', 'D5') sc2 = scale.HypodorianScale('a6') assert common.pitchList(sc2.getPitches('e2', 'e3')) == '[E2, F#2, G2, A2, B2, C3, D3, E3]' assert str(sc2.getRelativeMajor()) == '<music21.scale.MajorScale G major>' assert str(sc2.getTonic()), str(sc2.getDominant()) == ('A6', 'C7') #==== "fig-py02" end #==== "fig-py06" # see below #==== "fig-py06" end #==== "fig-py03" #print('\n\nfig-py03') sc1 = scale.HarmonicMinorScale('a3') assert common.pitchList(sc1.getPitches()) == '[A3, B3, C4, D4, E4, F4, G#4, A4]' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('A3', 'E4') s = stream.Stream() for d in [1, 3, 2, 1, 6, 5, 8, 7, 8]: s.append(note.Note( sc1.pitchFromDegree(d, equateTermini=False), type='eighth')) #s.show() #==== "fig-py03" end #==== "fig-py04" import random sc1 = scale.MelodicMinorScale('c4') assert common.pitchList(sc1.getPitches(direction='ascending')) == '[C4, D4, E-4, F4, G4, A4, B4, C5]' assert common.pitchList(sc1.getPitches('c3', 'c5', direction='descending')) == '[C5, B-4, A-4, G4, F4, E-4, D4, C4, B-3, A-3, G3, F3, E-3, D3, C3]' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('C4', 'G4') s = stream.Stream() p = None for i in range(16): direction = random.choice([-1, 1]) for j in range(2): p = sc1.next(p, direction) s.append(note.Note(p, quarterLength=.25)) #s.show() #==== "fig-py04" end #==== "fig-py05" sc1 = scale.OctatonicScale('e3', 'm2') assert common.pitchList(sc1.getPitches()) == '[E3, F3, G3, A-3, B-3, C-4, D-4, D4, E4]' sc2 = scale.OctatonicScale('e3', 'M2') assert common.pitchList(sc2.getPitches()) == '[E3, F#3, G3, A3, B-3, C4, D-4, E-4, F-4]' part1 = stream.Part() part2 = stream.Part() durPart1 = [1,1,.5,.5,1] durPart2 = [3,1] degrees = list(range(1,9)) for unused in range(4): random.shuffle(degrees) random.shuffle(durPart1) random.shuffle(durPart2) i = 0 for dur in durPart1: part1.append(note.Note(sc2.pitchFromDegree(degrees[i]), quarterLength = dur)) i += 1 for dur in durPart2: part2.append(note.Note( sc2.pitchFromDegree(degrees[i], minPitch='c2', maxPitch='c3'), quarterLength=dur)) i += 1 s = stream.Score() s.insert(0, part1) s.insert(0, part2) #s.show() # add notation example; perhaps create tri-chords from scale-completing selections #==== "fig-py05" end #sc = scale.SieveScale('c2', '(-3@2 & 4) | (-3@1 & 4@1) | (3@2 & 4@2) | (-3 & 4@3)') #==== "fig-py07" # add examples sc1 = scale.SieveScale('c4', '3@0|4@0') assert common.pitchList(sc1.getPitches()) == '[C4, E-4, F-4, G-4, A-4, A4, C5]' sc2 = scale.SieveScale('c4', '5@0|7@0') assert common.pitchList(sc2.getPitches()) == '[C4, F4, G4, B-4, D5, E-5, A-5, A5, C#6, E6, F#6, B6]' s = stream.Stream() pColection = sc2.getPitches('c3', 'c7') random.shuffle(pColection) for p in pColection: s.append(note.Note(p, type='16th')) #s.show() #==== "fig-py07" end #==== "fig-py08" sc1 = scale.RagAsawari('g3') assert common.pitchList(sc1.getPitches(direction='ascending')) == '[G3, A3, C4, D4, E-4, G4]' assert common.pitchList(sc1.getPitches(direction='descending')) == '[G4, F4, E-4, D4, C4, B-3, A3, G3]' sc2 = scale.RagMarwa('g3') assert common.pitchList(sc2.getPitches(direction='ascending')) == '[G3, A-3, B3, C#4, E4, F#4, E4, G4, A-4]' assert common.pitchList(sc2.getPitches(direction='descending')) == '[A-4, G4, A-4, F#4, E4, C#4, B3, A-3, G3]' p1 = None s = stream.Stream() for direction in ([1]*10) + ([-1]*8) + ([1]*4) + ([-1]*3) + ([1]*4): p1 = sc1.next(p1, direction) s.append(note.Note(p1, quarterLength=.25)) #s.show() p1 = None s = stream.Stream() for direction in ([1]*10) + ([-1]*8) + ([1]*4) + ([-1]*3) + ([1]*4): p1 = sc2.next(p1, direction) s.append(note.Note(p1, quarterLength=.25)) #s.show() #==== "fig-py08" end #==== "fig-py09" #import random sc1 = scale.WeightedHexatonicBlues('c3') p = 'c3' s = stream.Stream() for n in range(32): p = sc1.next(p, random.choice([-1, 1])) n = note.Note(p, quarterLength=random.choice([.5,.25,.25])) s.append(n)
def testScales01(self): from music21 import pitch #==== "fig-py01" # Providing a tonic makes this concrete sc1 = scale.MajorScale('g4') sc2 = scale.MajorScale('e-3') # Comparing Concrete and Abstract Scales assert (sc1 == sc2) == False assert (sc1.abstract == sc2.abstract) == True # Without arguments, getPitches() returns a single span assert common.pitchList( sc1.getPitches()) == '[G4, A4, B4, C5, D5, E5, F#5, G5]' assert common.pitchList(sc2.getPitches( 'c2', 'c3')) == '[C2, D2, E-2, F2, G2, A-2, B-2, C3]' # As a Chord, Scale pitches gain additional functionality assert sc1.getChord().forteClass == '7-35' # Given a degree, get the pitch assert str(sc1.pitchFromDegree(5)) == 'D5' assert common.pitchList( sc2.pitchesFromScaleDegrees([7, 2], 'e-6', 'e-9')) == '[F6, D7, F7, D8, F8, D9]' # Get a scale degree from a pitch assert sc1.getScaleDegreeFromPitch('d') == 5 assert sc2.getScaleDegreeFromPitch('d') == 7 # Get the next pitch given step directions match = [pitch.Pitch('g2')] for direction in [1, 1, 1, -2, 4, -1, 1, 1, 1]: # Append the next pitch based on the last-added pitch match.append(sc1.next(match[-1], direction)) assert common.pitchList( match), '[G2, A2, B2, C3, A2, E3, D3, E3, F#3, G3]' # Derive new scales based on a provided collection or degree assert str(sc1.derive(['c4', 'g4', 'b8', 'f2'])) == '<music21.scale.MajorScale C major>' assert str(sc1.deriveByDegree( 7, 'C#')) == '<music21.scale.MajorScale D major>' # Methods unique to DiatonicScale subclasses assert str( sc2.getRelativeMinor()) == '<music21.scale.MinorScale C minor>' #==== "fig-py01" end #==== "fig-py02" sc1 = scale.PhrygianScale('g4') assert common.pitchList( sc1.getPitches()) == '[G4, A-4, B-4, C5, D5, E-5, F5, G5]' assert str( sc1.getRelativeMajor()) == '<music21.scale.MajorScale E- major>' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('G4', 'D5') sc2 = scale.HypodorianScale('a6') assert common.pitchList(sc2.getPitches( 'e2', 'e3')) == '[E2, F#2, G2, A2, B2, C3, D3, E3]' assert str( sc2.getRelativeMajor()) == '<music21.scale.MajorScale G major>' assert str(sc2.getTonic()), str(sc2.getDominant()) == ('A6', 'C7') #==== "fig-py02" end #==== "fig-py06" # see below #==== "fig-py06" end #==== "fig-py03" #print('\n\nfig-py03') sc1 = scale.HarmonicMinorScale('a3') assert common.pitchList( sc1.getPitches()) == '[A3, B3, C4, D4, E4, F4, G#4, A4]' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('A3', 'E4') s = stream.Stream() for d in [1, 3, 2, 1, 6, 5, 8, 7, 8]: s.append( note.Note(sc1.pitchFromDegree(d, equateTermini=False), type='eighth')) #s.show() #==== "fig-py03" end #==== "fig-py04" import random sc1 = scale.MelodicMinorScale('c4') assert common.pitchList(sc1.getPitches( direction='ascending')) == '[C4, D4, E-4, F4, G4, A4, B4, C5]' assert common.pitchList( sc1.getPitches('c3', 'c5', direction='descending') ) == '[C5, B-4, A-4, G4, F4, E-4, D4, C4, B-3, A-3, G3, F3, E-3, D3, C3]' assert str(sc1.getTonic()), str(sc1.getDominant()) == ('C4', 'G4') s = stream.Stream() p = None for i in range(16): direction = random.choice([-1, 1]) for j in range(2): p = sc1.next(p, direction) s.append(note.Note(p, quarterLength=.25)) #s.show() #==== "fig-py04" end #==== "fig-py05" sc1 = scale.OctatonicScale('e3', 'm2') assert common.pitchList( sc1.getPitches()) == '[E3, F3, G3, A-3, B-3, C-4, D-4, D4, E4]' sc2 = scale.OctatonicScale('e3', 'M2') assert common.pitchList( sc2.getPitches()) == '[E3, F#3, G3, A3, B-3, C4, D-4, E-4, F-4]' part1 = stream.Part() part2 = stream.Part() durPart1 = [1, 1, .5, .5, 1] durPart2 = [3, 1] degrees = list(range(1, 9)) for unused in range(4): random.shuffle(degrees) random.shuffle(durPart1) random.shuffle(durPart2) i = 0 for dur in durPart1: part1.append( note.Note(sc2.pitchFromDegree(degrees[i]), quarterLength=dur)) i += 1 for dur in durPart2: part2.append( note.Note(sc2.pitchFromDegree(degrees[i], minPitch='c2', maxPitch='c3'), quarterLength=dur)) i += 1 s = stream.Score() s.insert(0, part1) s.insert(0, part2) #s.show() # add notation example; perhaps create tri-chords from scale-completing selections #==== "fig-py05" end #sc = scale.SieveScale('c2', '(-3@2 & 4) | (-3@1 & 4@1) | (3@2 & 4@2) | (-3 & 4@3)') #==== "fig-py07" # add examples sc1 = scale.SieveScale('c4', '3@0|4@0') assert common.pitchList( sc1.getPitches()) == '[C4, E-4, F-4, G-4, A-4, A4, C5]' sc2 = scale.SieveScale('c4', '5@0|7@0') assert common.pitchList(sc2.getPitches( )) == '[C4, F4, G4, B-4, D5, E-5, A-5, A5, C#6, E6, F#6, B6]' s = stream.Stream() pColection = sc2.getPitches('c3', 'c7') random.shuffle(pColection) for p in pColection: s.append(note.Note(p, type='16th')) #s.show() #==== "fig-py07" end #==== "fig-py08" sc1 = scale.RagAsawari('g3') assert common.pitchList(sc1.getPitches( direction='ascending')) == '[G3, A3, C4, D4, E-4, G4]' assert common.pitchList(sc1.getPitches( direction='descending')) == '[G4, F4, E-4, D4, C4, B-3, A3, G3]' sc2 = scale.RagMarwa('g3') assert common.pitchList(sc2.getPitches(direction='ascending') ) == '[G3, A-3, B3, C#4, E4, F#4, E4, G4, A-4]' assert common.pitchList( sc2.getPitches(direction='descending' )) == '[A-4, G4, A-4, F#4, E4, C#4, B3, A-3, G3]' p1 = None s = stream.Stream() for direction in ([1] * 10) + ([-1] * 8) + ([1] * 4) + ([-1] * 3) + ([1] * 4): p1 = sc1.next(p1, direction) s.append(note.Note(p1, quarterLength=.25)) #s.show() p1 = None s = stream.Stream() for direction in ([1] * 10) + ([-1] * 8) + ([1] * 4) + ([-1] * 3) + ([1] * 4): p1 = sc2.next(p1, direction) s.append(note.Note(p1, quarterLength=.25)) #s.show() #==== "fig-py08" end #==== "fig-py09" #import random sc1 = scale.WeightedHexatonicBlues('c3') p = 'c3' s = stream.Stream() for n in range(32): p = sc1.next(p, random.choice([-1, 1])) n = note.Note(p, quarterLength=random.choice([.5, .25, .25])) s.append(n)