class Midi(object): def __init__(self, number_tracks=1, tempo=60, instrument=0): """ instrument: can be an integer or a list """ self.number_tracks = number_tracks self.midi_data = MIDIFile(number_tracks) for track in range(number_tracks): self.midi_data.addTrackName(track, 0, "Track {0}".format(track)) self.midi_data.addTempo(track, 0, tempo) instr = instrument[track] if isinstance(instrument, list) else instrument self.midi_data.addProgramChange(track, 0, 0, instr) def seq_chords(self, seqlist, track=0, time=0): if track + 1 > self.number_tracks: raise MidiError("You are trying to use more tracks than we have.") for item in seqlist: if isinstance(item, NoteSeq): volume = item[0].volume dur = item[0].midi_dur for note in item: self.midi_data.addNote(track, 0, note.midi_number, time, dur, volume) time += dur elif isinstance(item, Rest): time += item.midi_dur else: raise MidiError( "The input should be a list of NoteSeq but yours is a {0}: {1}" .format(type(seqlist), seqlist)) return time def seq_notes(self, noteseq, track=0, time=0): if track + 1 > self.number_tracks: raise MidiError("You are trying to use more tracks than we have.") for note in noteseq: if isinstance(note, Note): self.midi_data.addNote(track, 0, note.midi_number, time, note.midi_dur, note.volume) else: # we ignore the rests pass time += note.midi_dur return time def write(self, filename): if isinstance(filename, str): with open(filename, 'wb') as midifile: self.midi_data.writeFile(midifile) else: self.midi_data.writeFile(filename)
class Midi(object): def __init__(self, number_tracks=1, tempo=60, instrument=0): """ instrument: can be an integer or a list """ self.number_tracks = number_tracks self.midi_data = MIDIFile(number_tracks) for track in range(number_tracks): self.midi_data.addTrackName(track, 0, "Track {0}".format(track)) self.midi_data.addTempo(track, 0, tempo) instr = instrument[track] if isinstance(instrument, list) else instrument self.midi_data.addProgramChange(track, 0, 0, instr) def seq_chords(self, seqlist, track=0, time=0): if track + 1 > self.number_tracks: raise MidiError("You are trying to use more tracks than we have.") for item in seqlist: if isinstance(item, NoteSeq): volume = item[0].volume dur = item[0].midi_dur for note in item: self.midi_data.addNote(track, 0, note.midi_number, time, dur, volume) time += dur elif isinstance(item, Rest): time += item.midi_dur else: raise MidiError( "The input should be a list of NoteSeq but yours is a {0}: {1}".format(type(seqlist), seqlist) ) return time def seq_notes(self, noteseq, track=0, time=0): if track + 1 > self.number_tracks: raise MidiError("You are trying to use more tracks than we have.") for note in noteseq: if isinstance(note, Note): self.midi_data.addNote(track, 0, note.midi_number, time, note.midi_dur, note.volume) else: # we ignore the rests pass time += note.midi_dur return time def write(self, filename): if isinstance(filename, str): with open(filename, "wb") as midifile: self.midi_data.writeFile(midifile) else: self.midi_data.writeFile(filename)
def popcnt(x): return bin(x).count('1') def toscale(scale, note): # todo: totally broken poct = popcnt(scale) n = note % (poct + 1) c = 0 o = 0 for i in format(scale, '012b'): if i == '1': c += 1 if c - 1 == n: break o += 1 return o + note // 12 * 12 scale = int('101001010100', 2) m.addProgramChange(0, 0, 0, 65) m.addProgramChange(1, 1, 0, 63) for t in range(2048): if t % 64 == 0: scale = (scale >> 9) | ((scale & ((1 << 11) - 1)) << 3) writeNote(0, 0, toscale(scale, (t // 2 & t // 5 | t // 8 & t // 16) % 36 + 60), t / 8, 1 / 8, 127) writeNote(1, 1, toscale(scale, (t // 5 | t // 8 | t // 16) % 12 + 36), t / 8, 1 / 8, 127) m.writeFile(open('out.mid', 'wb'))
n = note % (poct + 1) c = 0 o = 0 for i in format(scale, '012b'): if i == '1': c += 1 if c - 1 == n: break o += 1 return o + note // 12 * 12 scale = int('101001010100', 2) # set instruments m.addProgramChange(0, 0, 0, 5) m.addProgramChange(1, 1, 0, 63) m.addProgramChange(2, 2, 0, 5) m.addProgramChange(3, 3, 0, 5) m.addProgramChange(4, 4, 0, 5) m.addProgramChange(5, 5, 0, 116) m.addProgramChange(6, 6, 0, 117) m.addProgramChange(7, 7, 0, 118) t = 0 dt = 0 for _ in range(65536): if dt % 64 == 0: shift = 1 scale = (scale >> (12 - shift)) | ((scale & ((1 << 11) - 1)) << shift) sh = 4