예제 #1
0
def play_a_note(midi_out: MidiOut, instrument: Instrument):
    note_on = midi_cmd(0x9, instrument.ch)
    note_off = midi_cmd(0x8, instrument.ch)
    midi_out.send_message([note_on, 60, 80])
    time.sleep(0.5)
    midi_out.send_message([note_off, 60, 0])
    time.sleep(0.1)
예제 #2
0
def silence(port: MidiOut,
            *,
            stop: bool = True,
            channels: Iterable[int] = ALL_CHANNELS) -> None:
    if stop:
        port.send_message([STOP])
    for channel in channels:
        port.send_message([CONTROL_CHANGE | channel, ALL_NOTES_OFF, 0])
예제 #3
0
def send_config_to_device(config: MPK_MINI_MK2, preset: int,
                          midi_out: MidiOut) -> None:
    config[0].preset = preset
    data = MPK_MINI_MK2.build(config)
    assert data[0] == 0xF0 and data[-1] == 0xF7
    midi_out.send_message(data)
    data_hex = str(binascii.hexlify(bytearray(data)), 'utf-8')
    logging.debug(f'- SENT {len(data)} BYTES. SYSEX:\n{data_hex}')
예제 #4
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
예제 #5
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
예제 #6
0
def move_knob(midi_out: MidiOut, knob_message: list):
    for i in range(knob_message[2], -1, -1):
        knob_message[2] = i
        midi_out.send_message(knob_message)
        time.sleep(0.01)
    print('Up --> Down...DONE')

    for i in range(0, 128):
        knob_message[2] = i
        midi_out.send_message(knob_message)
        time.sleep(0.01)
    print('Down --> Up...DONE')
예제 #7
0
    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
예제 #8
0
async def play(outport: rtmidi.MidiOut, inptable: MidiTable, noloops=1):
    """An asynchronous implementation of a table player.

    Multiple miditable objects and ports can be asynchronously
    targeted for concurrent output with proper synchronization."""
    miditable = MidiTable(inptable)
    tempo = bpm2tempo(120)  # default tempo
    for i in range(noloops):
        for msg in miditable:
            if msg['del_t'] > 0:
                delta = tick2second(msg['del_t'], tempo)
                await asyncio.sleep(delta)

            if msg['mtype'] == Mtypes.TEMPO:
                tempo = metaclasses.TempoSet.decoder(msg['data'])
            elif msg['mtype'] in CHAN_MTYPES:
                outport.send_message(msg['data'])
예제 #9
0
 def list_ports():
     midi_in = None
     midi_out = None
     try:
         api_out = MidiOut()
         api_in = MidiIn()
         ports = api_in.get_ports()
         return ports
     except:
         print("Unable to open MIDI ports")
     return
예제 #10
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
예제 #11
0
    def setup_output(self):
        api_out = MidiOut()
        port_out = self.get_mixer_port(api_out)
        try:
            midi_out, port_name = open_midioutput(port_out, interactive=False)
        except InvalidPortError:
            return
        except NoDevicesError:
            return

        self.api_out = api_out
        self.output = midi_out
        return port_name
 def _open_midi(self):
     """Starts MIDI without opening a port"""
     self.__log.info("Opening MIDI interfaces")
     try:
         self._midi_out = MidiOut()
         self._midi_in = MidiIn()
         #Note: if you need to catch SysEx, MIDI clock, and active sense
         #messages, then use the method: ignore_types as follows:
         #self._midi_in.ignore_types(sysex = False, timing = False,
         #             active_sense = False)
         #They are ignored by default. I don't need this right now, so the
         #standard behaviour is OK for me
     except:
         error = traceback.format_exc()
         self.__log.info(error)
         self._free_midi()
         return False
     self.__log.debug("MIDI interfaces were opened")
     return True
예제 #13
0
파일: lsdev.py 프로젝트: ambv/aiotone
from miniaudio import Backend, Devices
from rtmidi import MidiIn, MidiOut

print("- Audio devices")
for backend in Backend:
    try:
        devices = Devices([backend]).get_playbacks()
        print(f"  - {backend}")
        for device in devices:
            name = device["name"]
            print(f"    🔊 {name}")
    except:
        pass

print("- MIDI inputs")
for port in MidiIn().get_ports():
    print(f"  🎶 {port}")

print("- MIDI outputs")
for port in MidiOut().get_ports():
    print(f"  🎶 {port}")

print(
    """
Note that this script can display a lot of error or warning messages
from other libraries when trying to open backends that don't exist,
or when probing interfaces on some backends. Pay attention only to
the lines with 🔊 and 🎶!
"""
)
예제 #14
0
def send_pitch_bend(touchpad: TouchpadInputDevice, x: int, midiout: MidiOut) -> None:
    pbend = min(16383, int(16384 * touchpad.normalize_x(x)))
    msg = [PITCH_BEND, pbend & 0x7F, (pbend >> 7) & 0x7F]
    midiout.send_message(msg)
    print(pbend // 260 * " ", msg)
예제 #15
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
예제 #16
0
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}')
예제 #17
0
import time
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]
예제 #18
0
 def __enter__(self):
     self.MIDI_IN = MidiIn()
     self.MIDI_OUT = MidiOut()
     return self
예제 #19
0
def get_midi_out(device_index: int):
    midiout = MidiOut()
    midiout.open_port(device_index)
    return midiout
예제 #20
0
def send_all_notes_off(port: rtmidi.MidiOut):
    for ch in range(16):
        port.send_message((MTYPE_SPECS[Mtypes.CC].status | ch,
                           ALL_NOTES_OFF,
                           0))
예제 #21
0
        else:
            check_value(name, value)
            if name == 'data':
                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):
예제 #22
0
def send_sysex_from_hex_string(hex_string: str, midi_out: MidiOut) -> None:
    data = bytearray.fromhex(hex_string)
    assert data[0] == 0xF0 and data[-1] == 0xF7
    midi_out.send_message(data)
    data_hex = str(binascii.hexlify(bytearray(data)), 'utf-8')
    logging.debug(f'- SENT {len(data)} BYTES. SYSEX:\n{data_hex}')
예제 #23
0
def set_instrument(midi_out: MidiOut, instrument: Instrument):
    cc = midi_cmd(0xB, instrument.ch)
    pc = midi_cmd(0xC, instrument.ch)
    midi_out.send_message([pc, instrument.pc])
    midi_out.send_message([cc, 0, instrument.cc])
예제 #24
0
def list_mididevices():
    midiout = MidiOut()
    ports = midiout.get_ports()
    for idx, port in enumerate(ports):
        print(f'{idx}: {port}')
예제 #25
0
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])
예제 #26
0
from serial import Serial
from time import time, sleep
from rtmidi import MidiIn, MidiOut
from _thread import start_new_thread


mode = 0
pir_mode_color = [False, False, True]


open_ports = []
LEDs = []
PIRs = []

m_out = MidiOut().open_virtual_port("Python PIR Output")
melody_in = MidiIn().open_virtual_port("Python Melody Input")
drum_in = MidiIn().open_virtual_port("Python Drum Input")

last_drum = 0
DRUM_TIMEOUT = 0.1
PIR_TIMEOUT = 0.7


stair_modes = [
    [48, 50, 52, 53, 55, 57, 59, 60],
    [
        [48, 52, 55],
        [50, 53, 57],
        [52, 55, 59],
        [53, 57, 60],
        [55, 59, 62],