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 getDeviceList(self): midiin = MidiIn() midiout = MidiOut() try: return (midiin.get_ports(), midiout.get_ports()) except Exception as e: if DEBUG == True: print(e) return False
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
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
class Device: MIDI_IN = None MIDI_OUT = None MIDI_PORT_COUNT = 0 IS_FIRST_CONNECTION = True UPDATE_LIST = [] KEY_BINDINGS = {} PULSE_AUDIO = PulseAudioHelper() XORG = XorgHelper() def __init__(self, name='Generic Device', regex=None): self.NAME = name self.DEVICE_REGEX = regex self.UPDATE_LIST.append(self.update_midi_connection_on_reconnect) def __enter__(self): self.MIDI_IN = MidiIn() self.MIDI_OUT = MidiOut() return self def __exit__(self, _type, _value, _traceback): del self.MIDI_IN, self.MIDI_OUT def __repr__(self): return self.NAME def update(self, ELAPSED_TIME): for update in self.UPDATE_LIST: update(ELAPSED_TIME) def send_signal(self, channel, key, payload): self.MIDI_OUT.send_message([channel, key, payload]) def update_midi_connection_on_reconnect(self, _elapsed_time): current_port_count = len([ x for x in self.MIDI_OUT.get_ports() if not re.search(r'[rR]t[Mm]idi', x) ]) if current_port_count != self.MIDI_PORT_COUNT: self.MIDI_PORT_COUNT = current_port_count self.activate() def activate(self): if self.DEVICE_REGEX is not None: self.activate_ports() def activate_ports(self): activated = False self.MIDI_IN.close_port() self.MIDI_OUT.close_port() if not self.IS_FIRST_CONNECTION: print(f'{self} disconnected!') sleep(1.0) for midi in (self.MIDI_IN, self.MIDI_OUT): port_number = None for i, port_name in enumerate(midi.get_ports()): if re.search(self.DEVICE_REGEX, port_name): port_number = i break if port_number is not None: midi.open_port(port_number) activated = True if activated: self.IS_FIRST_CONNECTION = False print(f'{self} connected!') self.MIDI_IN.set_callback(self.input_callback) def input_callback(self, midi_signal_in, *_args, **_kwargs): byte_signal = midi_signal_in[0] key = str(byte_signal[1]) if key in self.KEY_BINDINGS.keys(): self.KEY_BINDINGS[key](byte_signal) else: self.animation_callback(byte_signal) def animation_callback(self, byte_signal): print(f'{self}:{byte_signal}')
vars(self)['data'] = SysexData(value) else: vars(self)[name] = value __setattr__ = _setattr def bytes(self): """Encode message and return as a list of integers.""" return encode_message(vars(self)) midi_in = MidiIn() midi_out = MidiOut() in_ports = midi_in.get_ports() out_ports = midi_out.get_ports() print("IN ports:", in_ports) print("OUT ports:", out_ports) def call_obs_api(command='pause-toggle'): url = f'http://localhost:28000/{command}' print("Calling:", url) response = requests.get(url).json() print("OBS RESPONSE:", response) def __callback(msg_data, data): print("GOT DATA") note_in = Message.from_bytes(msg_data[0]) # print(msg_data, data, Message.from_bytes(msg_data[0]))
from collections import deque import numpy as np 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]
def list_mididevices(): midiout = MidiOut() ports = midiout.get_ports() for idx, port in enumerate(ports): print(f'{idx}: {port}')