def test_transpose_rest(self): b = Bar() b.place_notes("C-4", 4) b.place_rest(4) c = Bar() c.place_notes("E-4", 4) c.place_rest(4) b.transpose("3", True) self.assertEqual(b, c)
def test_augment_rest(self): b = Bar() b.place_notes("C-4", 4) b.place_rest(4) c = Bar() c.place_notes("C#-4", 4) c.place_rest(4) b.augment() self.assertEqual(b, c)
def test_diminish_rest(self): b = Bar() b.place_notes("C#-4", 4) b.place_rest(4) c = Bar() c.place_notes("C-4", 4) c.place_rest(4) b.diminish() self.assertEqual(b, c)
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) # print('MIDI_to_Composition:', track_data[1]) # print('===') # print(track_data[2]) # for j in track_data[2]: # if j[1]['event'] == 9 or j[1]['event'] == 8: # print('MIDI_to_Composition:', j[0], j[1]['event'], Note(notes.int_to_note(j[1]['param1'] % 12))) 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_idx, track in enumerate(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' NOTE_ON_counter = 0 for event_idx, e in enumerate(track): (deltatime, event) = e duration = float(deltatime) / (ticks_per_beat * 4.0) if NOTE_ON_counter == 0 and duration != 0 and event['event'] == 9: # then we need to add a rest before playing b.place_rest(1.0/duration) NOTE_ON_counter += 1 # this logic is nice and clear... if duration != 0.0: duration = 1.0 / duration if len(b.bar) > 0: current_length = b.bar[-1][1] b.bar[-1][1] = duration if current_length - duration != 0: b.current_beat -= 1.0 / current_length b.current_beat += 1.0 / duration 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), np.floor(event['param1'] / 12)) # this was event['param1']/12 - 1 but that gives skewed, incorrect octaves 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 = d[3] #self.bytes_to_int(d[3]) metronome = d[2]//24.0 #self.bytes_to_int(d[2]) / 24.0 denom = 2**d[1] #2 ** self.bytes_to_int(d[1]) numer = d[0]#self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = d[0] #self.bytes_to_int(d[0]) minor = d[0] #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)