def _partMelodyAnalysis(self, m21part): """ Analyses one stream of notes. """ n = 5 # What is this good for? Sometimes the id was an integer, then it is useless and will likely cause trouble. # If this causes/caused trouble tell me (johannes). if isinstance(m21part.id, int): return # train on midiPrograms or partIDs if self._midiUse: partInstr = m21part.getInstrument() partName = str(partInstr.midiProgram) else: partName = str(m21part.id) partNotes = m21part.flat.notes if len(partNotes) < n: return for i in range(0, len(partNotes) - n): # THIS IS NECESSARY MAGIC! sNT = partNotes[i:i + n] [note for note in sNT] # EOM noteNGram = ngram.NoteNGram(sNT) self._melody[partName].seenOnCondition(noteNGram.condition, noteNGram.sample) logger.status( "Conditional frequency distribution for %s has %i conditions." % (partName, len(self._melody[partName])))
def _partMelodyAnalysis(self, m21part): """ Analyses one stream of notes. """ n = 5 # What is this good for? Sometimes the id was an integer, then it is useless and will likely cause trouble. # If this causes/caused trouble tell me (johannes). if isinstance(m21part.id, int): return # train on midiPrograms or partIDs if self._midiUse: partInstr = m21part.getInstrument() partName = str(partInstr.midiProgram) else: partName = str(m21part.id) partNotes = m21part.flat.notes if len(partNotes) < n: return for i in range(0, len(partNotes) - n): # THIS IS NECESSARY MAGIC! sNT = partNotes[i:i+n] [note for note in sNT] # EOM noteNGram = ngram.NoteNGram(sNT) self._melody[partName].seenOnCondition(noteNGram.condition, noteNGram.sample) logger.status("Conditional frequency distribution for %s has %i conditions." % (partName, len(self._melody[partName])))
def _writeDumps(self): todo = copy.deepcopy(self._analysums) for analysum in self._analysums: logger.status("Dumping results of %s analysis." % analysum) self._dumpToCorpus(analysum, getattr(self, '_' + analysum)) todo.remove(analysum) self._analysums = todo
def _fixNote(self, note, offset): """ Fixes a note. """ if not self._activeStructure: return music42.makeCmaj(note) while not self._activeStructure.chordAt(offset).isCompatible(note): logger.status("Transposing %s." % str(note)) return note.transpose(-1)
def _instrumentsAnalysis(self, m21score): """ Adds a scores instruments to the list of instruments. """ for part in m21score: # check if its a part if isinstance(part, music21.stream.Part): if not isinstance(part.id, int): partName = str(part.id) logger.status("Instrument %s occurs in score." % partName) self._instruments.seen(partName)
def _structureAnalysis(self, m21score): """ Analyses the chord structure of a score. """ logger.status("Creating structure ngrams for a score.") if not m21score[0]: return for part in m21score: if isinstance(part, music21.stream.Part): self._partStructureAnalysis(part)
def _processScore(self, xmlScore): """ From an XML file process a score. """ inMemory = self._parse(xmlScore) # YOU ARE HERE! for analysum in self._analysums: logger.status("Analysing %s." % analysum) getattr(self, '_%sAnalysis' % analysum)(inMemory) if analysum == 'midiProgs': self._setMidiUseFlag()
def _midiProgsAnalysis(self, m21score): """ Adds a scores midi-programs to the list of midi-programs """ for part in m21score: if isinstance(part, music21.stream.Part): # check if its an instrument partInstr = part.getInstrument() #if isinstance(part[0], music21.instrument.Instrument): midiProg = partInstr.midiProgram logger.status("midi program %s occurs in score." % midiProg) self._midiProgs.seen(str(midiProg))
def _melodyAnalysis(self, m21score): """ Analyses the melody style of a corpus. """ logger.status("Creating melody ngrams for a score.") # What is the next line good for? if not m21score[0]: return for part in m21score: if isinstance(part, music21.stream.Part): self._partMelodyAnalysis(part)
def _partStructureAnalysis(self, m21part): """ Analyses the chord structure for one stream of notes. """ n = 3 if isinstance(m21part.id, int): return if self._midiUse: partInstr = m21part.getInstrument() partName = str(partInstr.midiProgram) else: partName = str(m21part.id) chordProg = chordial.fromNotes(m21part) for i in range(0, len(chordProg) - n): chordNGram = ngram.ChordNGram(chordProg[i:i+n]) self._structure[partName].seenOnCondition(chordNGram.condition, chordNGram.sample) logger.status("Conditional frequency distribution for %s has %i conditions." % (partName, len(self._structure[partName])))
def run(self): """ Starts the training. """ logger.status("Parsing and analysing %i XML files." % len(self._sourceFiles)) self._hitDumps() if len(self._analysums) > 0: for i in range(len(self._sourceFiles)): xmlScore = self._sourceFiles[i] logger.status("Processing %i of %i. (%s)" % (i+1, len(self._sourceFiles), xmlScore)) self._processScore(xmlScore) self._writeDumps() self._setMidiUseFlag() # start instrumentChoice self._instrumentChoice() self._successful = True return True
def generate(collection, corpus, xmls): print "" logger.status("Starting analysis.") trainer = training.Trainer(collection, corpus, xmls) trainer.run() logger.status("Finished analysis.") logger.status("Starting generation.") generator = generation.Generator(trainer.results) again = 'a' while again == 'a': song = generator.generate() # add more choices if you like ;) addendum = ['2010','reloaded','interpretation','(unreleased)', 'ringtone', 'brand new!', 'Masterpiece', 'Magnum Opus', 'demo', 'hidden track', 'new album pre-release'] # insert metadata: song.insert(music21.metadata.Metadata()) song.metadata.title = '%s %s %s' % (collection.upper(), corpus.capitalize(), str(random.choice(addendum))) song.metadata.composer = 'Practical Music Listener Pleasing' # copyright doesn't seem to work this way #song.metadata.Copyright = "test" try: song.write('musicxml', '%s_%s_%s.xml' % (collection, corpus, datetime.datetime.now().isoformat())) except Exception: continue try: song.show() except music21.environment.EnvironmentException: logger.journal("Couldn't use show method to display generated score.") again = str(raw_input(" `a` to create another, anything else to exit to menu > "))
def _generateStructure(self, measureNum, measureLen): """ Generates a chord structure for the score. """ currOffset = 0.0 history = random.choice(self._structure[self._instruments.top].conditions) logger.status("Starting from " + str(history)) chordProg = chordial.ChordProgression() for chord in history: chordProg.addChordAt(chord.name, currOffset) currOffset += chord.quarterLength while currOffset < measureNum * measureLen: nextChord = self._predictChord(history) chordProg.addChordAt(nextChord.name, currOffset) currOffset += nextChord.quarterLength history = history[1:] + (nextChord,) logger.status("Current history is %s" % str(history)) self._activeStructure = chordProg
def _generateStructure(self, measureNum, measureLen): """ Generates a chord structure for the score. """ currOffset = 0.0 history = random.choice( self._structure[self._instruments.top].conditions) logger.status("Starting from " + str(history)) chordProg = chordial.ChordProgression() for chord in history: chordProg.addChordAt(chord.name, currOffset) currOffset += chord.quarterLength while currOffset < measureNum * measureLen: nextChord = self._predictChord(history) chordProg.addChordAt(nextChord.name, currOffset) currOffset += nextChord.quarterLength history = history[1:] + (nextChord, ) logger.status("Current history is %s" % str(history)) self._activeStructure = chordProg
def run(self): """ Starts the training. """ logger.status("Parsing and analysing %i XML files." % len(self._sourceFiles)) self._hitDumps() if len(self._analysums) > 0: for i in range(len(self._sourceFiles)): xmlScore = self._sourceFiles[i] logger.status("Processing %i of %i. (%s)" % (i + 1, len(self._sourceFiles), xmlScore)) self._processScore(xmlScore) self._writeDumps() self._setMidiUseFlag() # start instrumentChoice self._instrumentChoice() self._successful = True return True
def _partStructureAnalysis(self, m21part): """ Analyses the chord structure for one stream of notes. """ n = 3 if isinstance(m21part.id, int): return if self._midiUse: partInstr = m21part.getInstrument() partName = str(partInstr.midiProgram) else: partName = str(m21part.id) chordProg = chordial.fromNotes(m21part) for i in range(0, len(chordProg) - n): chordNGram = ngram.ChordNGram(chordProg[i:i + n]) self._structure[partName].seenOnCondition(chordNGram.condition, chordNGram.sample) logger.status( "Conditional frequency distribution for %s has %i conditions." % (partName, len(self._structure[partName])))
def _createMeasuresWithLength(length, musicSamplesMeasures=[1, 2]): localHistory = history localCurrOffset = currOffset # loop to avoid index errors when generating verse and so on while len(musicSamplesMeasures) < length: # create some music score = [] for note in localHistory: score.append(self._fixNote(note, localCurrOffset)) localCurrOffset += note.quarterLength # the limit is quite high to avoid index out of range errors below while localCurrOffset < measureNum * 4 * measureLen: nextNote = self._predictNote(localHistory, partName) score.append(self._fixNote(nextNote, localCurrOffset)) localCurrOffset += nextNote.quarterLength localHistory = localHistory[1:] + (nextNote, ) logger.status("Current history is " + str(localHistory)) # create a part musicSamples = music21.stream.Part() for note in score: musicSamples.append(note) # reset the values localCurrOffset = 0.0 # new random starting point localHistory = random.choice(self._melody[partName].conditions) # extract measures musicSamplesMeasures = musicSamples.makeMeasures() return musicSamplesMeasures
def _createMeasuresWithLength(length, musicSamplesMeasures = [1,2]): localHistory = history localCurrOffset = currOffset # loop to avoid index errors when generating verse and so on while len(musicSamplesMeasures) < length: # create some music score = [] for note in localHistory: score.append(self._fixNote(note, localCurrOffset)) localCurrOffset += note.quarterLength # the limit is quite high to avoid index out of range errors below while localCurrOffset < measureNum * 4 * measureLen: nextNote = self._predictNote(localHistory, partName) score.append(self._fixNote(nextNote, localCurrOffset)) localCurrOffset += nextNote.quarterLength localHistory = localHistory[1:] + (nextNote,) logger.status("Current history is " + str(localHistory)) # create a part musicSamples = music21.stream.Part() for note in score: musicSamples.append(note) # reset the values localCurrOffset = 0.0 # new random starting point localHistory = random.choice(self._melody[partName].conditions) # extract measures musicSamplesMeasures = musicSamples.makeMeasures() return musicSamplesMeasures
def _hitDumps(self): """ Try to get all analysums from dumps and cross them from the todo list if found. """ todo = copy.deepcopy(self._analysums) for analysum in self._analysums: logger.status("Looking for previously saved %s analysis." % analysum) dump = self._loadFromCorpus(analysum) if dump: setattr(self, '_' + analysum, dump) todo.remove(analysum) logger.status("Using previously analysed data.") else: logger.status("Found no previously analysed data.") self._analysums = todo
def generate(collection, corpus, xmls): print "" logger.status("Starting analysis.") trainer = training.Trainer(collection, corpus, xmls) trainer.run() logger.status("Finished analysis.") logger.status("Starting generation.") generator = generation.Generator(trainer.results) again = 'a' while again == 'a': song = generator.generate() # add more choices if you like ;) addendum = [ '2010', 'reloaded', 'interpretation', '(unreleased)', 'ringtone', 'brand new!', 'Masterpiece', 'Magnum Opus', 'demo', 'hidden track', 'new album pre-release' ] # insert metadata: song.insert(music21.metadata.Metadata()) song.metadata.title = '%s %s %s' % (collection.upper(), corpus.capitalize(), str(random.choice(addendum))) song.metadata.composer = 'Practical Music Listener Pleasing' # copyright doesn't seem to work this way #song.metadata.Copyright = "test" try: song.write( 'musicxml', '%s_%s_%s.xml' % (collection, corpus, datetime.datetime.now().isoformat())) except Exception: continue try: song.show() except music21.environment.EnvironmentException: logger.journal( "Couldn't use show method to display generated score.") again = str( raw_input( " `a` to create another, anything else to exit to menu > "))
def _generatePart(self, partName, measureNum, measureLen): """ Generates a part from its available data on call. """ currOffset = 0.0 # random starting point history = random.choice(self._melody[partName].conditions) logger.status("Starting from " + str(history)) part = music21.stream.Part() partInstr = self._insertInstrument(part, partName) # Insert instrument specific generation procedures here # using instrumentGroups might be helpful restMeasure = music21.stream.Measure() rest = music21.note.Rest() rest.quarterLength = 4 restMeasure.append(rest) #-----------------------------------------------------------------# # Define inner functions for reuse, but which need access to local variables. def _createMeasuresWithLength(length, musicSamplesMeasures = [1,2]): localHistory = history localCurrOffset = currOffset # loop to avoid index errors when generating verse and so on while len(musicSamplesMeasures) < length: # create some music score = [] for note in localHistory: score.append(self._fixNote(note, localCurrOffset)) localCurrOffset += note.quarterLength # the limit is quite high to avoid index out of range errors below while localCurrOffset < measureNum * 4 * measureLen: nextNote = self._predictNote(localHistory, partName) score.append(self._fixNote(nextNote, localCurrOffset)) localCurrOffset += nextNote.quarterLength localHistory = localHistory[1:] + (nextNote,) logger.status("Current history is " + str(localHistory)) # create a part musicSamples = music21.stream.Part() for note in score: musicSamples.append(note) # reset the values localCurrOffset = 0.0 # new random starting point localHistory = random.choice(self._melody[partName].conditions) # extract measures musicSamplesMeasures = musicSamples.makeMeasures() return musicSamplesMeasures #-----------------------------------------------------------------# # Melody if partInstr.midiProgram in mididicts.instrumentGroups["melody"] and self._melodyFree: musicSamplesMeasures = _createMeasuresWithLength(14) # create song components from measures intrOutro = [] intrOutro.append(musicSamplesMeasures[0]) intrOutro.append(musicSamplesMeasures[1]) freemel = True melchoice = 0 print "\nDo you want to create a free or a very structured melody?" while True: melchoice = raw_input("enter 'f' for a free or 's' for a structured melody: ") if melchoice == "f": break elif melchoice == "s": break if str(melchoice) == "f": freemel = True else: freemel = False # create a free melody if freemel: mel = [] mel.append(musicSamplesMeasures[2]) mel.append(musicSamplesMeasures[3]) mel.append(musicSamplesMeasures[4]) mel.append(musicSamplesMeasures[5]) mel.append(musicSamplesMeasures[6]) mel.append(musicSamplesMeasures[7]) mel.append(musicSamplesMeasures[8]) mel.append(musicSamplesMeasures[9]) mel.append(musicSamplesMeasures[10]) mel.append(musicSamplesMeasures[11]) mel.append(musicSamplesMeasures[12]) mel.append(musicSamplesMeasures[13]) mel.append(musicSamplesMeasures[14]) mel.append(musicSamplesMeasures[15]) mel.append(musicSamplesMeasures[16]) mel.append(musicSamplesMeasures[17]) mel.append(musicSamplesMeasures[18]) mel.append(musicSamplesMeasures[19]) mel.append(musicSamplesMeasures[20]) mel.append(musicSamplesMeasures[21]) mel.append(musicSamplesMeasures[2]) mel.append(musicSamplesMeasures[3]) mel.append(musicSamplesMeasures[4]) mel.append(musicSamplesMeasures[5]) mel.append(musicSamplesMeasures[6]) mel.append(musicSamplesMeasures[7]) mel.append(musicSamplesMeasures[8]) mel.append(musicSamplesMeasures[9]) helper.resetContexts([intrOutro, mel]) helper.combineSubparts(part, [mel], intrOutro) if not freemel: verse = [] verse.append(musicSamplesMeasures[2]) verse.append(musicSamplesMeasures[3]) verse.append(musicSamplesMeasures[4]) verse.append(musicSamplesMeasures[5]) chorus = [] chorus.append(musicSamplesMeasures[6]) chorus.append(musicSamplesMeasures[7]) chorus.append(musicSamplesMeasures[8]) chorus.append(musicSamplesMeasures[9]) bridge = [] bridge.append(musicSamplesMeasures[10]) bridge.append(musicSamplesMeasures[11]) bridge.append(musicSamplesMeasures[12]) bridge.append(musicSamplesMeasures[5]) helper.resetContexts([intrOutro, verse, chorus, bridge]) helper.combineSubparts(part, [verse, verse, chorus, verse, chorus, bridge, chorus], intrOutro) self._melodyFree = False #-----------------------------------------------------------------# # Drums elif partInstr.midiProgram in mididicts.instrumentGroups["rhythm"] or not self._melodyFree: musicSamplesMeasures = _createMeasuresWithLength(6) # create song components verse = [] verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[2]) chorus = [] chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) bridge = [] bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[2]) helper.resetContexts([verse, chorus, bridge]) helper.combineSubparts(part, [verse, verse, chorus, verse, chorus, bridge, chorus], restMeasure, numOfRepeats = 2) #-----------------------------------------------------------------# # all the rest else: musicSamplesMeasures = _createMeasuresWithLength(6) # create song components verse = [] verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[2]) chorus = [] chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) bridge = [] bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[6]) bridge.append(musicSamplesMeasures[6]) bridge.append(musicSamplesMeasures[2]) helper.resetContexts([verse, chorus, bridge]) helper.combineSubparts(part, [verse, verse, chorus, verse, chorus, bridge, chorus], restMeasure, numOfRepeats = 2) return part
def generate(self): """ Generate a whole new score. """ measureNum = 32 measureLen = 4 s = music21.stream.Score() logger.status("Generating structure for score.") self._generateStructure(measureNum, measureLen) self._melodyFree = True for instrument in self._activeInstruments: logger.status("Generating part for %s." % instrument) # TODO determine measureNum and measureLen through analysis newPart = self._generatePart(instrument, measureNum, measureLen) # check and change conflicting notes e = 0 while e < len(newPart): if not isinstance(newPart[e], music21.stream.Measure): e = e + 1 continue newM = newPart[e] for oldPart in s: if not e < len(oldPart): continue oldM = oldPart[e] if isinstance(oldM, music21.ElementWrapper) and isinstance(oldM.obj, list): oldMList = oldM.obj else: oldMList = [oldM] for oldM in oldMList: for elem in newM: sameOffset = [] # dont use .isNote (isinstance produces less errors because only few objects have an isNote function) if isinstance(elem, music21.note.Note): for oelem in oldM: if isinstance(oelem, music21.note.Note): # all notes that overlap with the current note are stored in sameOffset if elem.offset in range(oelem.offset, (oelem.offset + oelem.quarterLength)) or oelem.offset in range(elem.offset, (elem.offset + elem.quarterLength)): sameOffset.append(oelem) # if overlapping notes were found: if sameOffset: for i in range(len(sameOffset)): for j in range(len(sameOffset)): k = 0 while self._areConflicting(sameOffset[i], elem) or self._areConflicting(sameOffset[j], elem): logger.status("transposing: %s" % str(elem)) elem = elem.transpose(-1) logger.status("transposed: %s" % str(elem)) # k prevents infinite loops k = k + 1 if k == 40: logger.status("%s is not harmonizable" % str(elem)) break e = e + 1 s.insert(0, newPart) #self._smoothEnd(s) return s
def _generatePart(self, partName, measureNum, measureLen): """ Generates a part from its available data on call. """ currOffset = 0.0 # random starting point history = random.choice(self._melody[partName].conditions) logger.status("Starting from " + str(history)) part = music21.stream.Part() partInstr = self._insertInstrument(part, partName) # Insert instrument specific generation procedures here # using instrumentGroups might be helpful restMeasure = music21.stream.Measure() rest = music21.note.Rest() rest.quarterLength = 4 restMeasure.append(rest) #-----------------------------------------------------------------# # Define inner functions for reuse, but which need access to local variables. def _createMeasuresWithLength(length, musicSamplesMeasures=[1, 2]): localHistory = history localCurrOffset = currOffset # loop to avoid index errors when generating verse and so on while len(musicSamplesMeasures) < length: # create some music score = [] for note in localHistory: score.append(self._fixNote(note, localCurrOffset)) localCurrOffset += note.quarterLength # the limit is quite high to avoid index out of range errors below while localCurrOffset < measureNum * 4 * measureLen: nextNote = self._predictNote(localHistory, partName) score.append(self._fixNote(nextNote, localCurrOffset)) localCurrOffset += nextNote.quarterLength localHistory = localHistory[1:] + (nextNote, ) logger.status("Current history is " + str(localHistory)) # create a part musicSamples = music21.stream.Part() for note in score: musicSamples.append(note) # reset the values localCurrOffset = 0.0 # new random starting point localHistory = random.choice(self._melody[partName].conditions) # extract measures musicSamplesMeasures = musicSamples.makeMeasures() return musicSamplesMeasures #-----------------------------------------------------------------# # Melody if partInstr.midiProgram in mididicts.instrumentGroups[ "melody"] and self._melodyFree: musicSamplesMeasures = _createMeasuresWithLength(14) # create song components from measures intrOutro = [] intrOutro.append(musicSamplesMeasures[0]) intrOutro.append(musicSamplesMeasures[1]) freemel = True melchoice = 0 print "\nDo you want to create a free or a very structured melody?" while True: melchoice = raw_input( "enter 'f' for a free or 's' for a structured melody: ") if melchoice == "f": break elif melchoice == "s": break if str(melchoice) == "f": freemel = True else: freemel = False # create a free melody if freemel: mel = [] mel.append(musicSamplesMeasures[2]) mel.append(musicSamplesMeasures[3]) mel.append(musicSamplesMeasures[4]) mel.append(musicSamplesMeasures[5]) mel.append(musicSamplesMeasures[6]) mel.append(musicSamplesMeasures[7]) mel.append(musicSamplesMeasures[8]) mel.append(musicSamplesMeasures[9]) mel.append(musicSamplesMeasures[10]) mel.append(musicSamplesMeasures[11]) mel.append(musicSamplesMeasures[12]) mel.append(musicSamplesMeasures[13]) mel.append(musicSamplesMeasures[14]) mel.append(musicSamplesMeasures[15]) mel.append(musicSamplesMeasures[16]) mel.append(musicSamplesMeasures[17]) mel.append(musicSamplesMeasures[18]) mel.append(musicSamplesMeasures[19]) mel.append(musicSamplesMeasures[20]) mel.append(musicSamplesMeasures[21]) mel.append(musicSamplesMeasures[2]) mel.append(musicSamplesMeasures[3]) mel.append(musicSamplesMeasures[4]) mel.append(musicSamplesMeasures[5]) mel.append(musicSamplesMeasures[6]) mel.append(musicSamplesMeasures[7]) mel.append(musicSamplesMeasures[8]) mel.append(musicSamplesMeasures[9]) helper.resetContexts([intrOutro, mel]) helper.combineSubparts(part, [mel], intrOutro) if not freemel: verse = [] verse.append(musicSamplesMeasures[2]) verse.append(musicSamplesMeasures[3]) verse.append(musicSamplesMeasures[4]) verse.append(musicSamplesMeasures[5]) chorus = [] chorus.append(musicSamplesMeasures[6]) chorus.append(musicSamplesMeasures[7]) chorus.append(musicSamplesMeasures[8]) chorus.append(musicSamplesMeasures[9]) bridge = [] bridge.append(musicSamplesMeasures[10]) bridge.append(musicSamplesMeasures[11]) bridge.append(musicSamplesMeasures[12]) bridge.append(musicSamplesMeasures[5]) helper.resetContexts([intrOutro, verse, chorus, bridge]) helper.combineSubparts( part, [verse, verse, chorus, verse, chorus, bridge, chorus], intrOutro) self._melodyFree = False #-----------------------------------------------------------------# # Drums elif partInstr.midiProgram in mididicts.instrumentGroups[ "rhythm"] or not self._melodyFree: musicSamplesMeasures = _createMeasuresWithLength(6) # create song components verse = [] verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[2]) chorus = [] chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) bridge = [] bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[2]) helper.resetContexts([verse, chorus, bridge]) helper.combineSubparts( part, [verse, verse, chorus, verse, chorus, bridge, chorus], restMeasure, numOfRepeats=2) #-----------------------------------------------------------------# # all the rest else: musicSamplesMeasures = _createMeasuresWithLength(6) # create song components verse = [] verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[1]) verse.append(musicSamplesMeasures[2]) chorus = [] chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) chorus.append(musicSamplesMeasures[3]) chorus.append(musicSamplesMeasures[4]) bridge = [] bridge.append(musicSamplesMeasures[5]) bridge.append(musicSamplesMeasures[6]) bridge.append(musicSamplesMeasures[6]) bridge.append(musicSamplesMeasures[2]) helper.resetContexts([verse, chorus, bridge]) helper.combineSubparts( part, [verse, verse, chorus, verse, chorus, bridge, chorus], restMeasure, numOfRepeats=2) return part
def generate(self): """ Generate a whole new score. """ measureNum = 32 measureLen = 4 s = music21.stream.Score() logger.status("Generating structure for score.") self._generateStructure(measureNum, measureLen) self._melodyFree = True for instrument in self._activeInstruments: logger.status("Generating part for %s." % instrument) # TODO determine measureNum and measureLen through analysis newPart = self._generatePart(instrument, measureNum, measureLen) # check and change conflicting notes e = 0 while e < len(newPart): if not isinstance(newPart[e], music21.stream.Measure): e = e + 1 continue newM = newPart[e] for oldPart in s: if not e < len(oldPart): continue oldM = oldPart[e] if isinstance(oldM, music21.ElementWrapper) and isinstance( oldM.obj, list): oldMList = oldM.obj else: oldMList = [oldM] for oldM in oldMList: for elem in newM: sameOffset = [] # dont use .isNote (isinstance produces less errors because only few objects have an isNote function) if isinstance(elem, music21.note.Note): for oelem in oldM: if isinstance(oelem, music21.note.Note): # all notes that overlap with the current note are stored in sameOffset if elem.offset in range( oelem.offset, (oelem.offset + oelem.quarterLength )) or oelem.offset in range( elem.offset, (elem.offset + elem.quarterLength)): sameOffset.append(oelem) # if overlapping notes were found: if sameOffset: for i in range(len(sameOffset)): for j in range(len(sameOffset)): k = 0 while self._areConflicting( sameOffset[i], elem) or self._areConflicting( sameOffset[j], elem): logger.status("transposing: %s" % str(elem)) elem = elem.transpose(-1) logger.status("transposed: %s" % str(elem)) # k prevents infinite loops k = k + 1 if k == 40: logger.status( "%s is not harmonizable" % str(elem)) break e = e + 1 s.insert(0, newPart) #self._smoothEnd(s) return s