Exemple #1
0
    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])))
Exemple #2
0
	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])))
Exemple #3
0
 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
Exemple #4
0
	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
Exemple #5
0
    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)
Exemple #6
0
	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)
Exemple #7
0
 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)
Exemple #8
0
	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)
Exemple #9
0
	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)
Exemple #10
0
    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)
Exemple #11
0
    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()
Exemple #12
0
	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))
Exemple #13
0
    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)
Exemple #14
0
    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))
Exemple #15
0
	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()
Exemple #16
0
	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)
Exemple #17
0
	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])))
Exemple #18
0
	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
Exemple #19
0
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 > "))
Exemple #20
0
	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
Exemple #21
0
    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
Exemple #22
0
    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
Exemple #23
0
    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])))
Exemple #24
0
        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
Exemple #25
0
		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
Exemple #26
0
	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
Exemple #27
0
 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
Exemple #28
0
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 > "))
Exemple #29
0
	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
Exemple #30
0
	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
Exemple #31
0
    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
Exemple #32
0
    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