def generate(self, length, bars, octave, scale=["C", "D", "E", "G", "A"], instrument=1, rand_length=False, time_signature=(4, 4), velocity=[64, 64], channel=1, rests=True, rule_number=30): # create the instrument for the main track instr = MidiInstrument() instr.instrument_nr = instrument # MIDI instrument number: http://www.midi.org/techspecs/gm1sound.php track = containers.Track(instr) self.set_instrument(instrument) if not self.initial: self.initial = [False] * 9 print "Error: initial set empty. Defaulting..." if rand_length: # start with quarter note as base length = 4 automata = Engine(rule_number, init_row=self.initial, edge_type=EdgeType.LOOP) # Index counting for diagnostics self.counts = dict((n, 0) for n in range(0, len(scale) * 2)) index = 5 # starting value for b in range(0, (length * bars) / 4): bar = Bar("C", time_signature) while bar.space_left() != 0: # runs until we're out of space for notes (e.g. complete bar) automata.step() # take a step index = self.get_chosen_note(index, automata.rows[-1]) if rand_length: # if we're randomly generating lengths of notes length = int(math.pow(2, random.randint(1, 4))) left = bar.space_left() space = ( (left - (left % 0.25)) * 16) if left > 0.25 else left * 16 # checks if we have enough space if space < 16 / length: length = int(16.0 / space) if rests and random.randint(0, 20) == 1: # same rest generation bar.place_rest(16) continue # skip the rest name = list(scale)[index if index < 5 else index - 4] # can be used for diagnostics self.counts[index] += 1 # add to count data self.notes.append(index) n = Note(name, octave=octave if index < 5 else octave + 1) n.set_velocity(random.randint(velocity[0], velocity[1])) # random velocity, can feel more "real" n.set_channel(channel) # if we want > 1 instruments we need > 1 channel bar.place_notes(n, length) # print self.format_block(automata.rows[-1]) track.add_bar(bar) # add bar to track self.track = track # set our track object to the newly generated track # for n in self.counts: # print str(n) + ": " + str(self.counts[n]) # diagnostics # print "=======" return self
velocity=vel) song = Composition() trackmain = Track() # here is where you set the actual instrument print "Melody instrument: " + trackmain.set_instrument(instr).names[instr] + " ({})".format(instr) s = SongGen.Song() trackmain = s.generate(chorus, verse, bridge, trackmain.track) # LAST BAR b = Bar() n = Note('C', 4) n.set_channel(1) b.place_notes(n, 4) trackmain.add_bar(b) song.add_track(trackmain) # END MELODY # # BEGIN HARMONY # # setup verse ini = [False] * 5 ini[random.randint(0, 4)] = True # instr = random.randint(1, 104) instr = 33