def generateScaleList(self): n1 = self.tonic n2 = interval.transposePitch(n1, "M2") n3 = interval.transposePitch(n1, "m3") n4 = interval.transposePitch(n1, "P4") n5 = interval.transposePitch(n1, "P5") n6 = interval.transposePitch(n1, "m6") n7 = interval.transposePitch(n1, "m7") return [n1, n2, n3, n4, n5, n6, n7]
def getLeadingTone(self): return interval.transposePitch(self.pitchFromScaleDegree(7), "A1")
def getConcreteMelodicMinorScale(self): scale = self.getConcreteHarmonicMinorScale() scale[5] = interval.transposePitch(self.pitchFromScaleDegree(6), "A1") for n in range(0, 7): scale.append(self.pitchFromScaleDegree(7-n)) return scale
def getConcreteHarmonicMinorScale(self): scale = self.scaleList[:] scale[6] = self.getLeadingTone() scale.append(interval.transposePitch(self.tonic, "P8")) return scale
def getConcreteMajorScale(self): scale = self.scaleList[:] scale.append(interval.transposePitch(self.tonic, "P8")) return scale
def unparse_grammar(m1_grammar, m1_chords): m1_elements = stream.Voice() currOffset = 0.0 # for recalculate last chord. prevElement = None for ix, grammarElement in enumerate(m1_grammar.split(" ")): terms = grammarElement.split(",") currOffset += float(terms[1]) # works just fine # Case 1: it's a rest. Just append if terms[0] == "R": rNote = note.Rest(quarterLength=float(terms[1])) m1_elements.insert(currOffset, rNote) continue # Get the last chord first so you can find chord note, scale note, etc. try: lastChord = [n for n in m1_chords if n.offset <= currOffset][-1] except IndexError: m1_chords[0].offset = 0.0 lastChord = [n for n in m1_chords if n.offset <= currOffset][-1] # Case: no < > (should just be the first note) so generate from range # of lowest chord note to highest chord note (if not a chord note, else # just generate one of the actual chord notes). # Case #1: if no < > to indicate next note range. Usually this lack of < > # is for the first note (no precedent), or for rests. if len(terms) == 2: # Case 1: if no < >. insertNote = note.Note() # default is C # Case C: chord note. if terms[0] == "C": insertNote = __generate_chord_tone(lastChord) # Case S: scale note. elif terms[0] == "S": insertNote = __generate_scale_tone(lastChord) # Case A: approach note. # Handle both A and X notes here for now. else: insertNote = __generate_approach_tone(lastChord) # Update the stream of generated notes insertNote.quarterLength = float(terms[1]) if insertNote.octave < 4: insertNote.octave = 4 m1_elements.insert(currOffset, insertNote) prevElement = insertNote # Case #2: if < > for the increment. Usually for notes after the first one. else: # Get lower, upper intervals and notes. interval1 = interval.Interval(terms[2].replace("<", "")) interval2 = interval.Interval(terms[3].replace(">", "")) if interval1.cents > interval2.cents: upperInterval, lowerInterval = interval1, interval2 else: upperInterval, lowerInterval = interval2, interval1 lowPitch = interval.transposePitch(prevElement.pitch, lowerInterval) highPitch = interval.transposePitch(prevElement.pitch, upperInterval) numNotes = int(highPitch.ps - lowPitch.ps + 1) # for range(s, e) # Case C: chord note, must be within increment (terms[2]). # First, transpose note with lowerInterval to get note that is # the lower bound. Then iterate over, and find valid notes. Then # choose randomly from those. if terms[0] == "C": relevantChordTones = [] for i in range(0, numNotes): currNote = note.Note( lowPitch.transpose(i).simplifyEnharmonic()) if __is_chord_tone(lastChord, currNote): relevantChordTones.append(currNote) if len(relevantChordTones) > 1: insertNote = random.choice([ i for i in relevantChordTones if i.nameWithOctave != prevElement.nameWithOctave ]) elif len(relevantChordTones) == 1: insertNote = relevantChordTones[0] else: # if no choices, set to prev element +-1 whole step insertNote = prevElement.transpose(random.choice([-2, 2])) if insertNote.octave < 3: insertNote.octave = 3 insertNote.quarterLength = float(terms[1]) m1_elements.insert(currOffset, insertNote) # Case S: scale note, must be within increment. elif terms[0] == "S": relevantScaleTones = [] for i in range(0, numNotes): currNote = note.Note( lowPitch.transpose(i).simplifyEnharmonic()) if __is_scale_tone(lastChord, currNote): relevantScaleTones.append(currNote) if len(relevantScaleTones) > 1: insertNote = random.choice([ i for i in relevantScaleTones if i.nameWithOctave != prevElement.nameWithOctave ]) elif len(relevantScaleTones) == 1: insertNote = relevantScaleTones[0] else: # if no choices, set to prev element +-1 whole step insertNote = prevElement.transpose(random.choice([-2, 2])) if insertNote.octave < 3: insertNote.octave = 3 insertNote.quarterLength = float(terms[1]) m1_elements.insert(currOffset, insertNote) # Case A: approach tone, must be within increment. # For now: handle both A and X cases. else: relevantApproachTones = [] for i in range(0, numNotes): currNote = note.Note( lowPitch.transpose(i).simplifyEnharmonic()) if __is_approach_tone(lastChord, currNote): relevantApproachTones.append(currNote) if len(relevantApproachTones) > 1: insertNote = random.choice([ i for i in relevantApproachTones if i.nameWithOctave != prevElement.nameWithOctave ]) elif len(relevantApproachTones) == 1: insertNote = relevantApproachTones[0] else: # if no choices, set to prev element +-1 whole step insertNote = prevElement.transpose(random.choice([-2, 2])) if insertNote.octave < 3: insertNote.octave = 3 insertNote.quarterLength = float(terms[1]) m1_elements.insert(currOffset, insertNote) # update the previous element. prevElement = insertNote return m1_elements