Exemple #1
0
 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]
Exemple #2
0
 def getLeadingTone(self):
     return interval.transposePitch(self.pitchFromScaleDegree(7), "A1")
Exemple #3
0
 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
Exemple #4
0
 def getConcreteHarmonicMinorScale(self):
     scale = self.scaleList[:]
     scale[6] = self.getLeadingTone()
     scale.append(interval.transposePitch(self.tonic, "P8"))
     return scale
Exemple #5
0
 def getConcreteMajorScale(self):
     scale = self.scaleList[:]
     scale.append(interval.transposePitch(self.tonic, "P8"))        
     return scale
Exemple #6
0
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