def get_out_port(port_name: str) -> MidiOut: midi_out = MidiOut() midi_out_ports = midi_out.get_ports() try: midi_out.open_port(midi_out_ports.index(port_name)) except ValueError: raise ValueError(port_name) from None return midi_out
def get_ports(port_name: str, *, clock_source: bool = False) -> Tuple[MidiIn, MidiOut]: midi_in = MidiIn() midi_out = MidiOut() midi_in_ports = midi_in.get_ports() midi_out_ports = midi_out.get_ports() try: midi_in.open_port(midi_in_ports.index(port_name)) except ValueError: raise ValueError(port_name) from None if clock_source: midi_in.ignore_types(timing=False) try: midi_out.open_port(midi_out_ports.index(port_name)) except ValueError: raise ValueError(port_name) from None return midi_in, midi_out
from rtmidi import MidiOut from heapq import heappop, heappush from time import sleep from pymusic.midi.parser import MidiParser from pymusic.score import Rest p = MidiParser('res/palestrina_missa_papae_marcelli_kyrie.mid') score = p.parse() output = MidiOut() output.open_port(5) cursor_heap = [] tracks = {} cur_time = 0 _track_id = 0 for track in score.tracks: notes_sets_of_sylls = [s.notes for s in track.syllables] notes = [] for nset in notes_sets_of_sylls: notes += nset if len(notes) == 0: continue tracks[_track_id] = notes output.send_message([0xC0 + _track_id, 0]) #track.instrument]) heappush(cursor_heap, (tracks[_track_id][0].time_in_score, (0, _track_id))) if type(tracks[_track_id][0]) != Rest: output.send_message( [0x90 + _track_id, tracks[_track_id][0].midi_note, 0x40])
class Player: def __init__(self, queue=Queue(), running=Value('i', False), tempo=Value('i', default_tempo), deadline=Value('f', 0)): self.midiout = MidiOut() self.midi_for_file = MidiFile() self.last_chord = empty_chord self.queue_out = queue self.running = running self.tempo = tempo self.deadline = deadline self.start_peak = Value('f', 0) self.start_chord = 0 def play_peak(self, number=default_peak_number, velocity=default_peak_velocity): note_on = Message('note_on', note=number, velocity=velocity, channel=default_ultrasound_channel).bytes() self.midiout.send_message(note_on) sleep(default_peak_time) note_off = Message('note_off', note=number, velocity=min_velocity, channel=default_ultrasound_channel).bytes() self.midiout.send_message(note_off) def play_chord_same_time(self): chord = self.queue_out.get() # print("player get", chord, "vel", chord.velocity, "queue", self.queue_out.qsize(), "time", time.monotonic()) if chord.velocity > 127: chord.velocity = 127 if chord.duration == 0: return for note in chord.notes: if note.number > 127: print("an incorrect note in player") return if self.last_chord != empty_chord: for note in self.last_chord.notes: note_off = Message('note_off', note=note.number, velocity=min_velocity, channel=default_channel).bytes() self.midiout.send_message(note_off) for note in chord.notes: note_on = Message('note_on', note=note.number, velocity=chord.velocity, channel=default_channel).bytes() self.midiout.send_message(note_on) self.last_chord = chord sleep(len_in_s(chord.duration, self.tempo.value)) if self.last_chord == chord: for note in chord.notes: note_off = Message('note_off', note=note.number, velocity=min_velocity, channel=default_channel).bytes() self.midiout.send_message(note_off) def play_chord_arpeggio(self, track=np.array([])): chord = self.queue_out.get() print("player get", chord, "vel", chord.velocity, "queue", self.queue_out.qsize(), "time", time.monotonic()) if chord.velocity > 127: chord.velocity = 127 if chord.duration == 0: return for note in chord.notes: if note.number > 127: print("an incorrect note in player") return chord.notes = sorted(chord.notes) if len(chord.notes) == 3: chord.notes.append(Note(chord.notes[0].number + 12)) if track == np.array([]): notes_numbers = np.arange(len(chord.notes)) notes_durations = np.array( [int(128 / len(chord.notes)) for i in range(len(chord.notes))]) track = np.column_stack((notes_numbers, notes_durations)) notes_sum_durations = np.cumsum(track.transpose(), axis=1)[1] if self.last_note_number is not None: note_off = Message('note_off', note=self.last_note_number, velocity=min_velocity, channel=default_channel).bytes() self.midiout.send_message(note_off) self.start_chord = time.monotonic() pair = 0 note_number = track[pair][0] note_on = Message('note_on', note=chord.notes[note_number].number, velocity=chord.velocity, channel=default_channel).bytes() self.midiout.send_message(note_on) while (pair < len(track) - 1): # TODO if time.monotonic() > self.start_chord + max( (self.deadline.value - self.start_chord) * notes_sum_durations[pair] / notes_sum_durations[-1], len_in_s(notes_sum_durations[pair], self.tempo.value)): note_off = Message('note_off', note=chord.notes[note_number].number, velocity=min_velocity, channel=default_channel).bytes() self.midiout.send_message(note_off) pair += 1 note_number = track[pair][0] note_on = Message('note_on', note=chord.notes[note_number].number, velocity=chord.velocity, channel=default_channel).bytes() self.midiout.send_message(note_on) self.last_note_number = chord.notes[note_number].number time.sleep(0.01) def put(self, chord): if type(chord) == Chord: self.queue_out.put(chord) return True return False def set_up_ports(self): """ This is necessary to HEAR the music """ available_ports = self.midiout.get_ports() if available_ports: self.midiout.open_port(default_port) else: self.midiout.open_virtual_port("Tmp virtual output") def set_up_instrument(self, program=default_instrument): program_change = Message('program_change', program=program, channel=default_channel).bytes() self.midiout.send_message(program_change) def set_up_ultrasound_instrument(self, program=default_ultrasound_instrument): program_change = Message('program_change', program=program, channel=default_ultrasound_channel).bytes() self.midiout.send_message(program_change) def set_up_midi_for_file(self): self.midi_for_file.tracks.append(MidiTrack()) def set_tempo(self, tempo=default_tempo): self.tempo.value = tempo def set_deadline(self, deadline=0): self.deadline.value = deadline def set_start_peak(self, start=max_time): self.start_peak.value = start def get_sleeping_time(self): return self.deadline.value - time.monotonic() def get_track(self): return self.midi_for_file.tracks[0] def save_file(self, filename='my track.mid'): self.midi_for_file.save(filename) return filename def run(self): self.running.value = True self.set_up_ports() self.set_up_midi_for_file() self.set_up_instrument() self.set_up_ultrasound_instrument() self.queue_process = Process(target=run_queue_out, args=(self, )) self.queue_process.start() self.queue_process = Process(target=run_peak, args=(self, )) self.queue_process.start() def stop(self): """ All chords that already sound will continue to sound """ self.running.value = False self.queue_process.join() self.queue_process.join() self.queue_out = Queue() queue_out = None running = None tempo = None deadline = None start_peak = None start_chord = None queue_process = None peak_process = None midiout = None midi_for_file = None last_chord = None last_note_number = None
from keras.models import load_model from music21 import midi, instrument, stream, note, chord from rtmidi import MidiOut from rtmidi.midiutil import open_midiinput from rtmidi.midiconstants import NOTE_ON, NOTE_OFF seq_len = 32 bpm = 120 / 60 instru = instrument.Piano() # MIDI Setup midiout = MidiOut() available_ports = midiout.get_ports() if available_ports: midiout.open_port(0) else: midiout.open_virtual_port("My virtual output") log = logging.getLogger('midiin_callback') logging.basicConfig(level=logging.DEBUG) # Load data from training print("\nLoading, please wait...\n", flush=True) vocab_file = "Piano_50.npy" vocab = np.load(os.path.join("vocab_save", vocab_file), allow_pickle=True) notes_vocab = vocab[0] durations_vocab = vocab[1] offsets_vocab = vocab[2] velocities_vocab = vocab[3]
def get_midi_out(device_index: int): midiout = MidiOut() midiout.open_port(device_index) return midiout