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
def load_from_song(self, song): ''' Fills a mingus-composition object with the data of a Song object ''' if 'bar_length' in song.info: try: self.bar_length = song.info['bar_length'] except: print ("You need to specify length of a Bar first before you can do this") for line in song.lines: track = Track() bar = Bar() for segment in line.segments: if segment.type == 'pause': int_val = None elif segment.type == 'note': int_val = segment.pitch n = Note().from_int(int_val + 48) note_length = float(self.bar_length) / segment.duration if not bar.place_notes(n, note_length): track.add_bar(bar) bar = Bar() bar.place_notes(n, note_length) track.add_bar(bar) self.composition.add_track(track) self.path = song.path self.song_name = song.reader.file_name[:-4]
def figGround(): # Purpose: Do a dictation of one instrument while other instruments are distracting in background. numnotes = setDuration() loopDictation = True while (loopDictation): randInstrument(1, set([ 0, 1, 2, 4, 6, 24, 25, 26, 27, 28, 29, 40, 41, 42, 56, 57, 60, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 78, 79, 80, 81, 82, 83, 85, 102, 103, 104, 105, 108, 109 ])) # Set lead/figure instr randInstrument(2, set([ 44, 45, 48, 49, 50, 51, 52, 53, 54, 55, 61, 62, 63, 86, 87, 88, 89, 90, 91, 92, 93 ])) # Set pad/ground instr randLeadNotes = [] for i in range(0, numnotes): randPitch = Note(12 * randint(3, 6) + randint(0, 12)) # randChord = randLeadNotes.append(randPitch) randBar = Bar() for n in randLeadNotes: randBar.place_notes(n, 4) playBeforeAnswer(randBar) print(randNotes) loopDictation = playAfterAnswer(randBar) print("\n")
def grid_to_bar(self): bar = Bar() bar.length = self.size for col in xrange(self.size): notes = self.column_to_notes(col) bar.place_notes(notes, 4) return bar
def solo_bar(chord_name): scale = generate_scale(chord_name) # note = random.choice(chords.from_shorthand(chord_name)) # note_index = scale.index(note) note_index = random.randrange(len(scale)) note = scale[note_index] beat = 0 duration = 1 bar = Bar() while beat < 1: if beat % .25 == 0: duration = random.choice([4, 8, 16]) stepwise = random.randrange(5) != 0 rest = random.randrange(10) < 3 if rest: bar.place_notes(None, duration) else: if stepwise: interval = random.choice([-1, 1]) else: interval = random.randrange(len(scale)) note_index = ((note_index+interval)+len(scale))%len(scale) note = scale[note_index] bar.place_notes(note, duration) print(note) beat = bar.current_beat print("---") return bar
def init_random_track(key, is_subject=True): notes = keys.get_notes(key) bar = Bar(key=key) while bar.current_beat < 1: # Randomize pitch and duration of each note. duration = 2**random.randint(1, 3) pitch = notes[random.randint(0, 6)] # If it is intened to be a subject, set the first note to the root. if bar.current_beat == 0 and is_subject == True: pitch = notes[0] # If the randomized duration doesn't fit in the bar, make it fit if 1 / duration > 1 - bar.current_beat: duration = 1 / (1 - bar.current_beat) # Place the new note in the bar bar.place_notes(pitch, duration) # Create a track to contain the randomized bar track = Track() track + bar # Return the track return track
def gen_with_rhythm(self,proggresion,rhythm,diatonic): self.get_meter_from_rhythm(rhythm) bar = Bar(key = diatonic[0],meter = self.get_meter_from_rhythm(rhythm)) for i in range(len(proggresion)): bar.place_notes(proggresion[i],rhythm[i]) return bar
def gen_simple(self,diatonic,note_length,proggresion): """generation of a simple song ,each note has the same length""" bar = Bar(diatonic[0],(len(proggresion),note_length)) for i in proggresion: bar.place_notes(i,note_length) return bar
def set_as_beat_strum(self): self.bars = [] for ch in self.chords: b = Bar(key=self.key) i = 0 while i<4: b.place_notes(ch, 4) i += 1 self.add_bar(b)
def set_as_beat_strum(self): self.bars = [] for ch in self.chords: b = Bar(key=self.key) i = 0 while i < 4: b.place_notes(ch, 4) i += 1 self.add_bar(b)
def random_bar(chord_name): scale = generate_scale(chord_name) bar = Bar() beat = 0 while beat < 1: duration = random.choice([4, 8, 16]) note = random.choice(scale) bar.place_notes(note, duration) beat = bar.current_beat return bar
def fill_bars(self, arpeggio, note_duration = 16, bars = 1): generator = arpeggio.get_generator() while bars > 0: b = Bar() b.key = 'C' while not b.is_full(): b.place_notes(generator.next(), note_duration) self.track.add_bar(b) bars -= 1 return self.track
async def on_start(self): self.agent.set("current_bar_no", 0) # inicializa "current_bar_no" en 0 # self.agent.set("tempo", 120) # self.agent.set("key", "C") self.agent.set("melody_track", Track()) self.agent.set("accompaniment_track", Track()) self.agent.set("current_melody_bar", Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE)) self.agent.set("current_accompaniment_bar", Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE))
def fix_track_bar(bar): if type(bar) == list: # i.e. not Bar if bar == []: return [] if len(bar[0]) > 1: # len=3 if list [[a, b, NoteContainer]] b = Bar() b.place_notes(bar[0][2], bar[0][1]) bar = b else: # if list like [Bar] or [Bar, Bar] (hopefully no [Bar]x3's) return bar return [bar]
async def run(self): cbn = self.agent.get("current_bar_no") if cbn < CFG.SONG_LENGTH: # falta sacar con modulo, de momento es un acorde por barra msg = await self.receive() if msg: if self.agent.get("chords_template").match(msg): if chords.determine_triad( getattr(chords, CFG.PROGRESSIONS[cbn])( CFG.SONG_KEY_SIGNATURE), True) == chords.determine_triad( msg.body.split(','), True): cab = self.agent.get("current_accompaniment_bar") cab.place_notes(msg.body.split(','), 1) # de momento es un acorde por barra at = self.agent.get("accompaniment_track") at.add_bar(cab) self.agent.set( "current_accompaniment_bar", Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE)) self.agent.set("accompaniment_track", at) self.set_next_state(S_RECEIVE_NOTE) else: self.set_next_state( S_RECEIVE_CHORD) # Continúa en el mismo estado else: self.set_next_state( S_RECEIVE_CHORD) # Continúa en el mismo estado else: self.set_next_state( S_RECEIVE_CHORD) # Continúa en el mismo estado else: self.set_next_state(S_PUBLISH_SONG)
def __init__(self, starting_note='C-3'): fluidsynth.init(path_to_instrument, audio_driver) self.starting_note = Note(starting_note) self.relative_major_scale = np.array([0, 2, 4, 5, 7, 9, 11]) self.scale = self.relative_major_scale + int(self.starting_note) self.note = Note(self.starting_note) self.bar = Bar() fluidsynth.play_Note(self.note)
def load_from_song(self, song): ''' Fills a mingus-composition object with the data of a Song object ''' if 'bar_length' in song.info: try: self.bar_length = song.info['bar_length'] except: print "You need to specify length of a Bar first before you can do this" for line in song.lines: track = Track() bar = Bar() for segment in line.segments: if segment.type == 'pause': int_val = None elif segment.type == 'note': int_val = segment.pitch n = Note().from_int(int_val + 48) note_length = float(self.bar_length) / segment.duration if not bar.place_notes(n, note_length): track.add_bar(bar) bar = Bar() bar.place_notes(n, note_length) track.add_bar(bar) self.composition.add_track(track) self.path = song.path self.song_name = song.reader.file_name[:-4]
def Bars_from_list(listb=[[0.0, 8.0, None],[0.125, 8.0, ['C-5']]]): ''' Helps TinyDB de-serialisation (load) Input list of (representations of) bars of the form [[position,duration,[note(s)]] , ...] Places these note events into Bar objects and returns as a list of Bars ''' #listb = [notev[0] if len(notev) == 1 else notev for notev in listb] # commented out as was repeating whole bars (notev = [whole bar note container nc]) listb = [nc if type(notev[0])!=float else notev for notev in listb for nc in notev] b = Bar() # we're instantiating Bars so I'm not sure why the outputs are sometimes type [list]..., cf fix_track_bar() bars = [b] for notev in listb: if notev != []: if bars[-1].place_notes(notev[2], notev[1]): pass else: bars.append(Bar()) bars[-1].place_notes(notev[2], notev[1]) return bars
def notes_durations_to_track(_notes, durations=None): ''' params: - _notes: list of list of Notes [['G','B','D','F'], ['C','E','G','B']] - durations: Durations should be a list of integers e.g. [2,2,1] will give | chord 1 chord 2 | chord 3 | TO-DO: - mingus durations are limited to =< 1 bar; we want to be able to parse a duration of '0.5' (because in mingus '4'=crotchet i.e. num subdivs) to refer to 2 bars (just use 1/d) ''' if durations is None: durations = [1] * len(_notes) t = Track() for i, _note in enumerate(_notes): b = Bar() b.place_notes(_note, durations[i]) t.add_bar(b) return t
def sheets_from_peaks(peaks): """Generate and open the sheet music pdf that represents the notes contained in peaks.""" bass_range = Instrument() bass_range.set_range(['A-0', 'C-4']) bass_track = Track(bass_range) treble_range = Instrument() treble_range.set_range(['C-4', 'C-8']) treble_track = Track(treble_range) treble_track.add_bar(Bar()) bass_track.add_bar(Bar()) for time_slice in peaks: bass_chord, treble_chord = [], [] for note_index, note_value in enumerate(time_slice): if note_value: # add 9 to note_index to start at A-0 note = Note().from_int(note_index + 9) if bass_range.note_in_range(note): bass_chord.append(note) elif treble_range.note_in_range(note): treble_chord.append(note) if bass_chord == treble_chord == []: continue for chord, track in ((bass_chord, bass_track), (treble_chord, treble_track)): if track.bars[-1].is_full(): track.add_bar(Bar()) if chord: print chord track.bars[-1] + chord print track else: track.bars[-1].place_rest(4) print bass_track print treble_track merge_rests(treble_track, bass_track) save_and_print(treble_track, bass_track)
def play(self, melody, chords, bpm, scores, bars, key, mode, modeToPass, tra, file, out_dir): t2 = Track() sh = progressions.to_chords(chords, key) for i in range(0, len(sh)): b = Bar(None, (4, 4)) if len(chords[i][0]) > 5: b.place_notes(None, 1) else: b.place_notes(NoteContainer(sh[i]), 1) t2 + b fluidsynth.pan(1, 25) fluidsynth.pan(2, 120) fluidsynth.main_volume(2, 50) fluidsynth.play_Tracks([melody, t2], [1, 2], bpm) # sleep(500000) button = Button(text='Clique para rearmonizar!', command=lambda: self.checkReharmonize( chords, scores, bars, key, mode, modeToPass, tra, bpm, file, out_dir), bg='brown', fg='white', font=('helvetica', 9, 'bold')) self.canvas1.create_window(200, 250, window=button)
def NewTrack(beats, count, withChromatics, with16): """ NewTrack(liczba_uderzeń_w_takcie, liczba_taktów, czy_z_chromatyką, czy_z_16) zwraca krotkę z trackiem i liczbą nut """ track = Track(Instrument()) rhythms = [] noOfNotes = 0 melodyCount = 0 for ii in range(count): rhythms.append(newBarRhythm(beats, with16)) noOfNotes += len(rhythms[ii]) if withChromatics: melody = newMelody(noOfNotes) else: melody = newMelodyWithoutChromatics(noOfNotes) for rhythm in rhythms: b = Bar("C", (beats, 4)) for note in rhythm: k = random.random() if k > pOfRests: b.place_notes(melody[melodyCount], 4 / note) else: b.place_notes(None, 4 / note) melodyCount += 1 track + b return (track, melodyCount)
def easy_bar(notes, durations=None): _default_note_duration = 4 if not durations and notes is not None: durations = [_default_note_duration] * len(notes) # setup Bar object bar = Bar() if (isinstance(notes, NoteContainer) or isinstance(notes, Note) or notes is None): bar.place_notes(notes, _default_note_duration) elif notes is None: bar.place_notes(notes, _default_note_duration) else: for x, d in zip(notes, durations): bar.place_notes(x, d) return bar
def get_bar_from_chord(chord): chord = make_ascending(chord) # print chord b = Bar(meter=(len(chord) + 1, 4)) for n in chord: b.place_notes(n, 4) ## add quarter note b.place_notes(chord, 4) return b
def melDict(): # TO DO: Be able to set options here (how long is dictation, range, etc.) # setPitchSet() numnotes = setDuration() loopDictation = True while (loopDictation): randInstrument(1) randNotes = [] randBar = Bar() for i in range(0, numnotes): randPitch = Note(12 * randint(3, 6) + randint(0, 12)) randNotes.append(randPitch) randBar.place_notes(randPitch, 4) #for n in randNotes: # randBar.place_notes(n, 4) playBeforeAnswer(randBar) print(randNotes) loopDictation = playAfterAnswer(randBar) print("\n")
def get_bar_from_triad(triad): assert len(triad) == 3 triad = make_ascending(triad) # print triad b = Bar() for n in triad: b.place_notes(n, 4) ## add quarter note b.place_notes(triad, 4) return b
def get_bar_from_interval(interval): assert len(interval) == 2 interval = make_ascending(interval) # print interval b = Bar() for n in interval: b.place_notes(n, 4) b.place_notes(interval, 2) return b
def fill_bars(self, arpeggio, note_duration=16, bars=1): generator = arpeggio.get_generator() while bars > 0: b = Bar() b.key = 'C' while not b.is_full(): b.place_notes(generator.next(), note_duration) self.track.add_bar(b) bars -= 1 return self.track
def write_mingus(self, outfile): notes = list(self.timeseries['Notes']) t = Track() for n in range(len(notes)): if n % 4 == 0: b = Bar(self.key, (4, 4)) if notes[n] != 'Z': b + notes[n] else: b + None if (n + 1) % 4 == 0: t + b self.composition + t self.track = t lily_composition = LilyPond.from_Composition(self.composition) print lily_composition LilyPond.to_pdf(lily_composition, outfile)
def createMingusComposition(intermed, timesig, bIsTreble, bSharps): comp = Composition() comp.set_title('Trilled Results') comp.set_author('Author') if bIsTreble: ins = TrebleInstrument('') else: ins = BassInstrument('') track = Track(ins) track.name = 'Part 1' comp.add_track(track) assert len(timesig) == 2 and isinstance(timesig[0], int) and isinstance( timesig[1], int) firstbar = Bar(meter=timesig) track.add_bar(firstbar) mapDurs = { int(intermed.baseDivisions * 4): 1.0, #whole note, int(intermed.baseDivisions * 2): 2.0, #half note int(intermed.baseDivisions * 1): 4.0, #qtr note, and so on int(intermed.baseDivisions * 0.5): 8.0, int(intermed.baseDivisions * 0.25): 16.0, int(intermed.baseDivisions * 0.125): 32.0, int(intermed.baseDivisions * 0.0625): 64.0, } for note in intermed.noteList: if note.pitch == 0 or note.pitch == (0, ): # a rest thepitches = tuple() else: # a note thepitches = [] for pitch in note.pitch: pname, poctave = music_util.noteToName(pitch, bSharps) thepitches.append(pname + '-' + str(poctave)) dur = note.end - note.start if dur not in mapDurs: raise NotesinterpretException('Unknown duration:' + str(dur)) notecontainer = NoteContainer(thepitches) notecontainer.tied = note.isTied bFit = track.add_notes(notecontainer, mapDurs[dur]) assert bFit #note that, naturally, will enforce having correct measure lines, since going across barline throughs exception return comp
def reverse(track, key='C'): # Copy value of reference to aviod problems with overwriting input_track = copy.deepcopy(track) #empty track to write to later reversed_track = Track() b = Bar(key) reversed_track.add_bar(b) #create a reversed list of notes from input track input_notes = input_track.get_notes() reversed_notes = reversed(list(input_notes)) #Add notes to reversed_track for note in reversed_notes: reversed_track.add_notes(note[-1], duration=note[1]) # Return reversed track return reversed_track
def generate_bar(difficulty: float): some_bar = Bar('C', (4, 4)) values = [ value.whole, value.half, value.quarter, value.dots(value.half), value.eighth, value.dots(value.quarter), value.sixteenth, value.dots(value.eighth), value.quarter, value.dots(value.quarter) ] actual_values = [] pitches = [ Note("A", 3), Note("B", 3), Note("C", 4), Note("D", 4), Note("E", 4), Note("F", 4), Note("G", 4), Note("A", 4), Note("B", 4), Note("C", 5), Note("D", 5), Note("E", 5), Note("F", 5), Note("G", 5), Note("A", 5), Note("B", 5), Note("C", 6) ] if difficulty >= 10: actual_values = values else: index = math.ceil(difficulty) actual_values = values[0:index] while some_bar.place_notes(choice(pitches), choice(actual_values)): pass if not some_bar.is_full(): some_bar.place_notes(choice(pitches), some_bar.value_left()) return some_bar
async def run(self): cbn = self.agent.get("current_bar_no") msg = await self.receive() if msg: if self.agent.get("notes_template").match(msg): if Note(msg.body.split(",")[0]).name in getattr( chords, CFG.PROGRESSIONS[cbn])(CFG.SONG_KEY_SIGNATURE): cmb = self.agent.get("current_melody_bar") if cmb.current_beat + 1 / float( msg.body.split(",")[1]) <= cmb.length: cmb.place_notes( msg.body.split(",")[0], int(msg.body.split(",") [1])) # de momento 4 notas por barra if cmb.current_beat == cmb.length: # chechar si llena, entonces agregar a melody_track mt = self.agent.get("melody_track") mt.add_bar(cmb) self.agent.set("melody_track", mt) self.agent.set( "current_melody_bar", Bar(CFG.SONG_KEY_SIGNATURE, CFG.SONG_TIME_SIGNATURE)) self.agent.set("current_bar_no", cbn + 1) print( "{}: {}/{}".format(self.agent.name, cbn + 1, CFG.SONG_LENGTH) ) # falta sacar con modulo, de momento es un acorde por barra self.set_next_state(S_RECEIVE_CHORD) else: self.agent.set("current_melody_bar", cmb) self.set_next_state(S_RECEIVE_NOTE) else: self.set_next_state( S_RECEIVE_NOTE) # Continúa en el mismo estado else: self.set_next_state( S_RECEIVE_NOTE) # Continúa en el mismo estado else: self.set_next_state( S_RECEIVE_NOTE) # Continúa en el mismo estado else: self.set_next_state(S_RECEIVE_NOTE) # Continúa en el mismo estado
def change_speed(track, factor, key, up=True): changed_track = Track() #if factor is 0 we return an empty track if (factor != 0.0): input_track = copy.deepcopy(track) input_notes = input_track.get_notes() b = Bar(key=key) changed_track.add_bar(b) #if we want to speed up (notespeed *= factor) if up: for note in input_notes: changed_track.add_notes(note[-1], int(note[1] * factor)) #if we want to slow down (notespeed *= (1/factor)) else: for note in input_notes: changed_track.add_notes(note[-1], int(note[1] / factor)) return changed_track
def split_bar(bar, split_point): current_pos = 0 bar_l = Bar() if 1/bar[0][1] > split_point: # if the first event crosses the split point (e.g. a conjoined rest) bar_l.place_notes(bar[0][2], 1/split_point) current_pos += split_point bar = [[bar[0][0], 1/(1/bar[0][1]-split_point), bar[0][2]]] + bar[1:] while current_pos < split_point: bar_l.place_notes(bar[0][2], bar[0][1]) current_pos += 1/bar[0][1] bar = bar[1:] bar_r = bar bar_r = [fix_track_bar([b])[0] for b in bar_r] return bar_l, bar_r
def setup_tracks(midi_file_out=None): from tracks import melodies, cantus_firmus, key, meter, species, author # Create a composition, and add the vocal tracks to it. composition = Composition() composition.set_title('Counterpoint Exercise', '') composition.set_author(author, '') # Set up our vocal 'tracks' with the notes, key, meter defined in tracks.py tracks = {} for voice in [Soprano, Alto, Tenor, Bass]: if len(melodies[voice.name]): tracks[voice.name] = Track(instrument=voice()) tracks[voice.name].add_bar(Bar(key=key, meter=meter)) tracks[voice.name].name = voice.name for note in melodies[voice.name]: tracks[voice.name].add_notes(*note) composition.add_track(tracks[voice.name]) if midi_file_out is not None: # Save the midi file! write_Composition(midi_file_out, composition, verbose=True) return composition, [], species
def setup_plotting(): global fig global ax1 global ax2 global ax3 global line1 global line2 global sheet fig = plt.figure(figsize=(12, 8)) ax1 = fig.add_subplot(2, 2, 1) # Volume ax2 = fig.add_subplot(2, 2, 2) # Fourier ax3 = fig.add_subplot(2, 1, 2) # Notes ax3.set_axis_off() line1, = ax1.plot(np.random.randn(CHUNK_SIZE)) line2, = ax2.plot(np.random.randn(CHUNK_SIZE)) b = Bar() bar = LilyPond.from_Bar(b) LilyPond.to_png(bar, "track") img = mpimg.imread("track.png") cropped_image = img[0:300, :, :] sheet = ax3.imshow(cropped_image, cmap='gray', interpolation='antialiased')
def getChordOrArpeggio(self, input_bar): notes = input_bar.get_note_names() random.seed() chord = chords.major_triad(notes[random.randint(0,len(notes) - 1)]) new_bar = Bar() #nc = NoteContainer(chord) #new_bar.place_notes(nc, 1) #return new_bar if(len(notes) % 2 != 0): #this will be a chord nc = NoteContainer(chord) new_bar.place_notes(nc, 1) return new_bar else: #this will be an arpeggio duration = 0 print(str(len(chord))) for note in chord: if(duration == 0): duration = 2 else: duration = 4 new_bar.place_notes(note, duration) return new_bar
def export(melody_track, chords, key, time_sig, bpm, file): i = Instrument() i.instrument_nr = 1 t2 = Track() for i in range(0, len(chords)): b = Bar(key, time_sig) if len(chords[i][0]) > 5: b.place_notes(None, 1) else: b.place_notes(NoteContainer(chords[i]), 1) t2 + b c = Composition() c.add_track(melody_track) c.add_track(t2) out_dir = 'out' if not os.path.exists(out_dir): os.makedirs(out_dir) mid = file.split('/')[-1] if os.path.exists(out_dir + '/' + mid): os.remove(out_dir + '/' + mid) MidiFileOut.write_Composition(out_dir + '/' + mid, c, bpm) file = out_dir + '/' + mid sys.argv.append('') sys.argv.append('') sys.argv[1] = "--midi-file=" + file sys.argv[2] = "--out-dir=" + out_dir midi.main() if os.path.exists(file): os.remove(file)
def generate_solo(chord_list): notes = [] bars = [] note = random.choice(chords.from_shorthand(chord_list[0])) note = Note(note) syncopate = random.randrange(1) == 0 bar = Bar() duration = random.choice([4, 8, 16]) if syncopate: bar.place_notes(None, duration) bar.place_notes(note, duration) notes.append(note) first = True for chord_name in chord_list: if first: beat = bar.current_beat first = False else: bar = Bar() beat = 0 scale = generate_scale(chord_name) while beat < 1: if beat % .25 == 0: duration = random.choice([4, 8, 16]) elif beat % .125 == 0: duration = random.choice([8, 16]) rest = random.randrange(10) == 0 # 1/10 if rest: bar.place_notes(None, duration) else: beginning = beat == 0 stepwise = random.randrange(5) != 0 # 4/5 leap = random.randrange(2) == 0 # 1/2 if len(notes) >= 2: prev_motion = measure_motion(notes[-2], notes[-1], scale) else: prev_motion = random.choice([-1, 1]) direction = int(math.copysign(1, prev_motion)) resolve = False if abs(prev_motion) == 2: if len(notes) >= 3: prev2_motion = measure_motion(notes[-3], notes[-2], scale) else: prev2_motion = 0 if prev2_motion == 2: if random.randrange(2) == 0: stepwise, leap = False, False else: stepwise, leap = False, False elif abs(prev_motion) > 2: stepwise, resolve = True, True if beginning: chord_tones = chords.from_shorthand(chord_name) note = closest_note(notes[-1], chord_tones) elif stepwise: if resolve: interval = -direction else: interval = random.choice([direction, direction, -direction]) # 2/3 probability to continue in same direction if notes[-1].octave <= 3: interval = 1 elif notes[-1].octave >= 5: interval = -1 note = note_at_interval(notes[-1], interval, scale) elif leap: # (1 - 4/5) * 1/2 = 1/10 interval = random.choice([-1, 1]) \ * random.choice(range(3, len(scale))) note = note_at_interval(notes[-1], interval, scale) else: # outlining a chord interval = 2 * direction note = note_at_interval(notes[-1], interval, scale) bar.place_notes(note, duration) notes.append(note) beat = bar.current_beat bars.append(bar) print(notes) return bars
def gen_midi(self, tracks_data): c = Composition() all_tracks = tracks_data["tracks_data"] curr_track = 0; for track_data in all_tracks: #TODO: set author, title, more specific instrument (that has a #range set data_max = max(track_data["note_data"]) data_min = min(track_data["note_data"]) data_dur_max = max(track_data["dur_data"]) data_dur_min = min(track_data["dur_data"]) data_range = data_max - data_min ####DURATIONS#### midi_durs = [self.map_range(0, len(self.mapping_dur_vals) - 1, data_dur_min, data_dur_max, x, "dur") for x in track_data["dur_data"]] midi_durs = [self.mapping_dur_vals[int(x)] for x in midi_durs] print "midi_durs: " print midi_durs ####PITCHES#### midi_vals = [self.map_range(0, len(self.overall_mapping_vals) - 1, data_min, data_max, x, "notes") for x in track_data["note_data"]] midi_vals = [self.overall_mapping_vals[int(x)] for x in midi_vals] print "midi_pitches: " print midi_vals for instr in self.instrs: t = Track() b = Bar() for index, midi_val in enumerate(midi_vals): print "-----------------" print "space left in bar" print b.space_left() if midi_val in instr["mapping_vals"]: print "inserting NON-REST NOTE" print "inserting NON-REST NOTE" val_to_insert = Note().from_int(int(midi_val)) print "DONE INSERTING NON-REST NOTE" else: print "INSERTING REST" val_to_insert = None #insert rest instead print "ABOUT TO INSERT" dur_to_insert_1 = 1.0/((1.0/float(midi_durs[index])) * 0.99) dur_to_insert_2 = 1.0/((1.0/float(midi_durs[index])) * 0.01) b, insert_result_1 = self.insert_into_bar(curr_track, b, val_to_insert, dur_to_insert_1) print "trying to insert note..." print insert_result_1 print "midi note DURATION is: " print midi_durs[index] if insert_result_1: b, insert_result_2 = self.insert_into_bar(curr_track, b, None, dur_to_insert_2) print "trying to insert note..." print insert_result_2 print "midi note DURATION is: " print midi_durs[index] if not insert_result_1: if b.space_left() == 0.0: print "hit edge case!!!!" t.add_bar(b) b = Bar() b, insert_result = self.insert_into_bar(curr_track, b, val_to_insert, dur_to_insert_1) b, insert_result = self.insert_into_bar(curr_track, b, None, dur_to_insert_2) print "bar is now (after edge case): " print b continue space_p = b.space_left() space = 1.0/space_p print "space percentage left: " print space_p print "note space left: " print space note_remainder = value.subtract(midi_durs[index], space) print "note duration: " print midi_durs[index] print "note remainder: " print note_remainder print "bar before INSERTING PART 1 OF TIE: " print b dur_to_insert_1_space = 1.0/((1.0/float(space)) * 0.99) dur_to_insert_2_space = 1.0/((1.0/float(space)) * 0.01) if space <= 16.0: print "NOTE IS LARGER THAN 16 NOTE" b, insert_result = self.insert_into_bar(curr_track, b, val_to_insert, dur_to_insert_1_space) b, insert_result = self.insert_into_bar(curr_track, b, None, 1.0/b.space_left()) else: print "NOTE IS *NOT* LARGER THAN 16 NOTE" b, insert_result = self.insert_into_bar(curr_track, b, None, space) print "bar AFTER: " print b print "inserting part one of tie result: " print insert_result print "is bar full??? (IT SHOULD BE)" print b.is_full() t.add_bar(b) b = Bar() b, insert_result = self.insert_into_bar(curr_track, b, None, note_remainder) print "inserting part TWO of tie result: " print insert_result print "bar after inserting remaining piece: " print b print "BAR IS NOW" print b #end for #add last bar if b.space_left() == 0.0: t.add_bar(b) else: #need to fill remaining space with rest space_p = b.space_left() space = 1.0/space_p #b, insert_result = self.insert_into_bar(curr_track, b, # Note(None), space) print "result for filling rest of last bar with rest: " print insert_result print "is bar full after adding rest to end of last bar??? (IT SHOULD BE)" print b.is_full() print "bar WITH REST is now: " print b t.add_bar(b) logger.debug("Track: ") logger.debug(t) #at very end of loop add track to composition c.add_track(t) curr_track += 1 #write_Composition("midi_success.mid", c); return self.gen_midi_data(c)
from mingus.core import chords, intervals, notes, scales from mingus.containers import Note, NoteContainer, Bar, Track, Composition from mingus.containers.Instrument import MidiInstrument from mingus.midi import MidiFileOut from improv import generate_solo from subprocess import call num_progressions = 4 chords_list = ['CM', 'G7', 'CM7', 'FM7', 'G7', 'Am7', 'G7', 'C#+'] chords_bars = [] for chord in chords_list: chord_nc = NoteContainer(chords.from_shorthand(chord)) bar = Bar() bar.place_notes(chord_nc, 1) chords_bars.append(bar) solo_track = Track() chords_track = Track() for _ in range(num_progressions): for bar in generate_solo(chords_list): solo_track.add_bar(bar) for bar in chords_bars: chords_track.add_bar(bar) guitar = MidiInstrument() guitar.instrument_nr = 26 solo_track.instrument = guitar piano = MidiInstrument() piano.instrument_nr = 0 chords_track.instrument = piano
def set_as_split_chords(self): self.bars = [] noted_chords = map(lambda x: assign_octaves(x, self.octave), self.chords) for ch in noted_chords: b = Bar(key=self.key) if len(ch) == 3: b.place_notes(ch[0], 4) b.place_notes(ch[2], 4) b.place_notes(ch[1], 4) b.place_notes(ch[2], 4) elif len(ch) == 4: b.place_notes(ch[0], 4) b.place_notes(ch[2], 4) b.place_notes(ch[1], 4) b.place_notes(ch[3], 4) else: b.place_notes(ch, 1) self.add_bar(b)
def MIDI_to_Composition(self, file): header, track_data = self.parse_midi_file(file) c = Composition() if header[2]["fps"]: print "Don't know how to parse this yet" return c ticks_per_beat = header[2]["ticks_per_beat"] for track in track_data: t = Track() b = Bar() metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note meter = (4,4) key = 'C' for e in track: deltatime, event = e duration = float(deltatime) / (ticks_per_beat * 4.0) if duration != 0.0: duration = 1.0 / duration if deltatime != 0: if not b.place_notes(NoteContainer(), duration): t + b b = Bar(key, meter) b.place_notes(NoteContainer(), duration) # note off if event["event"] == 8: if deltatime == 0: pass # note on elif event["event"] == 9: n = Note(notes.int_to_note(event["param1"] % 12), event["param1"] / 12 - 1) n.channel = event["channel"] n.velocity = event["param2"] if len(b.bar) > 0: b.bar[-1][2] + n else: b + n # note aftertouch elif event["event"] == 10: pass # controller select elif event["event"] == 11: pass # program change elif event["event"] == 12: i = MidiInstrument() i.instrument_nr = event["param1"] t.instrument = i # meta event elif event["event"] == 15: # Track name if event["meta_event"] == 3: t.name = event["data"] # Marker elif event["meta_event"] == 6: pass # Cue Point elif event["meta_event"] == 7: pass # End of Track elif event["meta_event"] == 47: pass # Set tempo #warning Only the last change in bpm will get saved currently elif event["meta_event"] == 81: mpqn = self.bytes_to_int(event["data"]) bpm = 60000000 / mpqn # Time Signature elif event["meta_event"] == 88: d = event["data"] thirtyseconds = self.bytes_to_int(d[3]) metronome = self.bytes_to_int(d[2]) / 24.0 denom = 2 ** self.bytes_to_int(d[1]) numer = self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) # Key Signature elif event["meta_event"] == 89: pass else: print "Unsupported META event", event["meta_event"] else: print "Unsupported MIDI event", event t + b c.tracks.append(t) return c, bpm
from mingus.containers import Bar, Track from mingus.containers.Instrument import MidiInstrument fluidsynth.init("ChoriumRevA/ChoriumRevA.SF2", "alsa") tr = lambda note: chords.triad(note, "C") # that's stupid # http://www.youtube.com/watch?v=5pidokakU4I prg = [tr("C"), tr("G"), tr("A"), tr("F")] bars = [] for chord in prg: b = Bar() b.place_notes(chord, 4) bars.append(b) t = Track() for b in bars: t.add_bar(b) instrs = list(enumerate(MidiInstrument.names)) shuffle(instrs) for i, name in instrs:
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) c = Composition() if header[2]['fps']: print("Don't know how to parse this yet") return c ticks_per_beat = header[2]['ticks_per_beat'] for track in track_data: t = Track() b = Bar() metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note meter = (4, 4) key = 'C' for e in track: (deltatime, event) = e duration = float(deltatime) / (ticks_per_beat * 4.0) if duration != 0.0: duration = 1.0 / duration if deltatime != 0: if not b.place_notes(NoteContainer(), duration): t + b b = Bar(key, meter) b.place_notes(NoteContainer(), duration) if event['event'] == 8: if deltatime == 0: pass elif event['event'] == 9: # note on n = Note(notes.int_to_note(event['param1'] % 12), event['param1'] / 12 - 1) n.channel = event['channel'] n.velocity = event['param2'] if len(b.bar) > 0: b.bar[-1][2] + n else: b + n elif event['event'] == 10: # note aftertouch pass elif event['event'] == 11: # controller select pass elif event['event'] == 12: # program change i = MidiInstrument() i.instrument_nr = event['param1'] t.instrument = i elif event['event'] == 0x0f: # meta event Text if event['meta_event'] == 1: pass elif event['meta_event'] == 3: # Track name t.name = event['data'] elif event['meta_event'] == 6: # Marker pass elif event['meta_event'] == 7: # Cue Point pass elif event['meta_event'] == 47: # End of Track pass elif event['meta_event'] == 81: # Set tempo warning Only the last change in bpm will get # saved currently mpqn = self.bytes_to_int(event['data']) bpm = 60000000 / mpqn elif event['meta_event'] == 88: # Time Signature d = event['data'] thirtyseconds = self.bytes_to_int(d[3]) metronome = self.bytes_to_int(d[2]) / 24.0 denom = 2 ** self.bytes_to_int(d[1]) numer = self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = self.bytes_to_int(d[0]) minor = self.bytes_to_int(d[0]) if minor: key = 'A' else: key = 'C' for i in range(abs(sharps)): if sharps < 0: key = intervals.major_fourth(key) else: key = intervals.major_fifth(key) b.key = Note(key) else: print('Unsupported META event', event['meta_event']) else: print('Unsupported MIDI event', event) t + b c.tracks.append(t) return (c, bpm)
ini[random.randint(0, 8)] = True chorus = Track(ini).generate(8, BAR_NUMBER, 4, scale=scale1, rand_length=True, time_signature=time_sig, 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
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) c = Composition() if header[2]['fps']: print "Don't know how to parse this yet" return c ticks_per_beat = header[2]['ticks_per_beat'] for track in track_data: # this loop will gather data for all notes, # set up keys and time signatures for all bars # and set the tempo and instrument for the track. metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note step = 256.0 # WARNING: Assumes our smallest desired quantization step is a 256th note. meter = (4, 4) key = 'C' bar = 0 beat = 0 now = (bar, beat) b = None started_notes = {} finished_notes = {} b = Bar(key=key, meter=meter) bars = [b] bpm = None instrument = None track_name = None for deltatime, event in track: if deltatime != 0: duration = (ticks_per_beat * 4.0) / float(deltatime) dur_q = int(round(step/duration)) length_q = int(b.length * step) o_bar = bar c_beat = beat + dur_q bar += int(c_beat / length_q) beat = c_beat % length_q while o_bar < bar: o_bar += 1 o_key = b.key b = Bar(key=key, meter=meter) b.key = o_key bars.append(b) now = (bar, beat) if event['event'] == 8: # note off channel = event['channel'] note_int = event['param1'] velocity = event['param2'] note_name = notes.int_to_note(note_int % 12) octave = note_int / 12 - 1 note = Note(note_name, octave) note.channel = channel note.velocity = velocity x = (channel, note_int) start_time = started_notes[x] del started_notes[x] end_time = now y = (start_time, end_time) if y not in finished_notes: finished_notes[y] = [] finished_notes[y].append(note) elif event['event'] == 9: # note on channel = event['channel'] note_int = event['param1'] velocity = event['param2'] x = (channel, note_int) # add the note to the current NoteContainer started_notes[x] = now elif event['event'] == 10: # note aftertouch pass elif event['event'] == 11: # controller select pass elif event['event'] == 12: # program change # WARNING: only the last change in instrument will get saved. i = MidiInstrument() i.instrument_nr = event['param1'] instrument = i elif event['event'] == 0x0f: # meta event Text if event['meta_event'] == 1: pass elif event['meta_event'] == 3: # Track name track_name = event['data'] elif event['meta_event'] == 6: # Marker pass elif event['meta_event'] == 7: # Cue Point pass elif event['meta_event'] == 47: # End of Track pass elif event['meta_event'] == 81: # Set tempo # WARNING: Only the last change in bpm will get saved mpqn = self.bytes_to_int(event['data']) bpm_o = bpm bpm = 60000000 / mpqn elif event['meta_event'] == 88: # Time Signature d = event['data'] thirtyseconds = self.bytes_to_int(d[3]) metronome = self.bytes_to_int(d[2]) / 24.0 denom = 2 ** self.bytes_to_int(d[1]) numer = self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = self.bytes_to_int(d[0]) minor = self.bytes_to_int(d[0]) if minor: key = 'A' else: key = 'C' for i in xrange(abs(sharps)): if sharps < 0: key = intervals.major_fourth(key) else: key = intervals.major_fifth(key) b.key = Note(key) else: print 'Unsupported META event', event['meta_event'] else: print 'Unsupported MIDI event', event t = Track(instrument) t.name = track_name sorted_notes = {} # sort the notes (so they are added to the bars in order) # this loop will also split up notes that span more than one bar. for x in finished_notes: (start_bar, start_beat), (end_bar, end_beat) = x if end_beat == 0: end_bar -= 1 end_beat = int(bars[end_bar].length * step) while start_bar <= end_bar: nc = NoteContainer(finished_notes[x]) b = bars[start_bar] if start_bar < end_bar: # only executes when note spans more than one bar. length_q = int(b.length * step) dur = int(step/(length_q - start_beat)) else: # always executes - add the final section of this note. dur = int(step/(end_beat-start_beat)) if start_beat != 0: at = float(start_beat)/step else: at = 0.0 if start_bar not in sorted_notes: sorted_notes[start_bar] = {} if at not in sorted_notes[start_bar]: sorted_notes[start_bar][at] = (dur, nc) # set our offsets for the next loop start_beat = 0 start_bar += 1 # add all notes to all bars in order. for start_bar in sorted(sorted_notes.keys()): for at in sorted(sorted_notes[start_bar].keys()): dur, nc = sorted_notes[start_bar][at] bars[start_bar].place_notes_at(nc, dur, at) # add the bars to the track, in order for b in bars: b.fill_with_rests() t + b # add the track to the composition c.tracks.append(t) return (c, bpm)