Esempio n. 1
0
 def generateFirstSpecies(self, stream1, minorScale):
     '''Given a stream (the cantus firmus) and the stream's key in the
     form of a MinorScale object, generates a stream of first species
     counterpoint that follows the rules of 21M.301.'''
     # DOES NOT YET CHECK FOR TOO MANY THIRDS/SIXTHS IN A ROW,
     # DOES NOT YET RAISE LEADING TONES, AND DOES NOT CHECK FOR NOODLING.
     stream2 = Stream([])
     firstNote = stream1.notes[0]
     choices = [interval.transposeNote(firstNote, "P1"),\
                interval.transposeNote(firstNote, "P5"),\
                interval.transposeNote(firstNote, "P8")]
     note1 = random.choice(choices)
     note1.duration = firstNote.duration
     stream2.append(note1)
     afterLeap = False
     for i in range(1, len(stream1.notes)):
         prevFirmus = stream1.notes[i-1]
         currFirmus = stream1.notes[i]
         prevNote = stream2.notes[i-1]
         choices = self.generateValidNotes(prevFirmus, currFirmus, prevNote, afterLeap, minorScale)
         if len(choices) == 0:
             raise ModalCounterpointException("Sorry, please try again")
         newNote = random.choice(choices)
         newNote.duration = currFirmus.duration
         stream2.append(newNote)
         int = interval.notesToInterval(prevNote, newNote)
         if int.generic.undirected > 3: afterLeap = True
         else: afterLeap = False
     return stream2
Esempio n. 2
0
 def raiseLeadingTone(self, stream1, minorScale):
     '''Given a stream of notes and a minor scale object, returns a new
     stream that raises all the leading tones of the original stream. Also
     raises the sixth if applicable to avoid augmented intervals.'''
     notes2 = stream1.notes[:]
     stream2 = Stream(notes2)
     sixth = minorScale.pitchFromScaleDegree(6).name
     seventh = minorScale.pitchFromScaleDegree(7).name
     tonic = minorScale.getTonic().name
     for i in range(len(stream1.notes)-2):
         note1 = stream1.notes[i]
         note2 = stream1.notes[i+1]
         note3 = stream1.notes[i+2]
         if note1 is not None and note2 is not None and note3 is not None:
             if note1.name == sixth and note2.name == seventh and note3.name == tonic:
                 newNote1 = interval.transposeNote(note1, "A1")
                 newNote2 = interval.transposeNote(note2, "A1")
                 stream2.notes[i] = newNote1
                 stream2.notes[i+1] = newNote2
     for i in range(len(stream1.notes)-1):
         note1 = stream1.notes[i]
         note2 = stream1.notes[i+1]
         if note1 is not None and note2 is not None:
             if note1.name == seventh and note2.name == tonic:
                 newNote = interval.transposeNote(note1, "A1")
                 stream2.notes[i] = newNote
     return stream2
Esempio n. 3
0
    def parseData(self, sounding, qL=2, splitNote="C4"):
        theSound = sounding.IntervallStruktur
        bassnotes = list(sounding.Bassnoten)
        bassschritte = sounding.Bassschritte
        followingSoundings = []
        for bs in bassschritte:
            for syz in bassschritte[bs]:
                followingSoundings.append((bs, syz))

        #print(followingSoundings)
        bass = note.Note(bassnotes[0])
        bass.quarterLength = qL

        for each in followingSoundings:
            self._distributeNotes2VocalScore(theSound, bass, splitNote)
            secondBass = interval.transposeNote(bass, each[0])
            self._distributeNotes2VocalScore(each[1], secondBass, splitNote)
Esempio n. 4
0
    def _distributeNotes2VocalScore(self,
                                    listOfIntervals,
                                    bassNote,
                                    splitNote="C4"):
        cpBass = deepcopy(bassNote)
        if bassNote.pitch >= pitch.Pitch(splitNote):
            self.part1.append(cpBass)
        else:
            self.part2.append(cpBass)

        #offset setzen
        offset = cpBass.offset

        #Akkorde hinzusetzen
        for intv in listOfIntervals:
            #print(intv)
            nNew = interval.transposeNote(bassNote, intv)
            if nNew.pitch >= pitch.Pitch(splitNote):
                self.part1.insert(offset, nNew)
            else:
                self.part2.insert(offset, nNew)
Esempio n. 5
0
    def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorScale):
        '''Helper function for generateFirstSpecies; gets a list of possible
        next notes based on valid melodic intervals, then checks each one so
        that parallel/hidden fifths/octaves, voice crossing, and invalid
        harmonies are prevented. Adds extra weight to notes that would create
        contrary motion.'''
        print currFirmus.name
        valid = []
        bottomInt = interval.notesToInterval(prevFirmus, currFirmus)
        if bottomInt.direction < 0: ascending = True
        else: ascending = False

        n1 = interval.transposeNote(prevNote, "m2")
        n2 = interval.transposeNote(prevNote, "M2")
        n3 = interval.transposeNote(prevNote, "m3")
        n4 = interval.transposeNote(prevNote, "M3")
        n5 = interval.transposeNote(prevNote, "P4")
        n6 = interval.transposeNote(prevNote, "P5")
        if afterLeap: possible = [n1, n2, n3, n4]
        else: possible = [n1, n2, n3, n4, n5, n6]
        possible.extend(possible)

        n7 = interval.transposeNote(prevNote, "m-2")
        n8 = interval.transposeNote(prevNote, "M-2")
        n9 = interval.transposeNote(prevNote, "m-3")
        n10 = interval.transposeNote(prevNote, "M-3")
        n11 = interval.transposeNote(prevNote, "P-4")
        n12 = interval.transposeNote(prevNote, "P-5")
        if afterLeap: possible.extend([n7, n8, n9, n10])
        else: possible.extend([n7, n8, n9, n10, n11, n12])
        print "possible: ", [note1.name for note1 in possible]
        
        for note1 in possible:
            try: validHarmony = self.isValidHarmony(note1, currFirmus)
            except: validHarmony = False

#            vlq = VoiceLeadingQuartet(prevNote, prevFirmus, note1, currFirmus)
#            par5 = vlq.parallelFifth()
#            par8 = vlq.parallelOctave()
#            hid5 = vlq.hiddenFifth()
#            hid8 = vlq.hiddenOctave()
#            par1 = vlq.parallelUnison()
            
            try: par5 = self.isParallelFifth(prevNote, note1, prevFirmus, currFirmus)
            except: par5 = True
            try: par8 = self.isParallelOctave(prevNote, note1, prevFirmus, currFirmus)
            except: par8 = True
            try: hid5 = self.isHiddenFifth(prevNote, note1, prevFirmus, currFirmus)
            except: hid5 = True
            try: hid8 = self.isHiddenOctave(prevNote, note1, prevFirmus, currFirmus)
            except: hid8 = True
            try: par1 = self.isParallelUnison(prevNote, note1, prevFirmus, currFirmus)
            except: par1 = True
            try:
                distance = interval.notesToInterval(currFirmus, note1)
                if distance.direction < 0: crossing = True
                else: crossing = False
            except: crossing = True
            goodNotes = minorScale.getConcreteMelodicMinorScale()
            goodNames = [note2.name for note2 in goodNotes]
            if validHarmony and (not par5) and (not par8) and (not hid5) and\
               (not hid8) and (not par1) and (not crossing):
                if note1.name in goodNames:
                    print "adding: ", note1.name, note1.octave
                    valid.append(note1)
        print
        return valid