Exemple #1
0
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
Exemple #2
0
 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
Exemple #3
0
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
Exemple #4
0
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}')
Exemple #6
0
                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]))
Exemple #7
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]
Exemple #8
0
def list_mididevices():
    midiout = MidiOut()
    ports = midiout.get_ports()
    for idx, port in enumerate(ports):
        print(f'{idx}: {port}')