#!/usr/bin/env python3 import sys import time import rtmidi # MIDI port name. The first port that contains this string will be used. port_name = 'Launchpad X MIDI 1' ### Helper functions def get_midi_port(midi, name): '''Returns rtmidi port index for a given port name''' for idx, port in enumerate(midi.get_ports()): if port_name in port: return idx ### MIDI messages midi_colors = { 'green': 21 } midi_syx_prefix = [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c] def midi_daw_mode(mode): '''Set DAW mode, mode=0 to enable, mode=1 to disable.''' return midi_syx_prefix + [0x10, mode, 0xf7] def midi_select_layout(layout): '''Select layout: session (0), note (1), custom (4-7), faders (13), programmer (127)''' return midi_syx_prefix + [0x00, layout, 0xf7] def midi_setup_faders(orientation, polarity, cc, color): '''Setup fader mode. orientation=0 for vertical, orientation=1 for horizontal polarity=0 for unipolar, polarity=1 for bipolar (single value or 8-element list) cc is control change to send (single start value or 8-element list) color is the color (single value or 8-element list) ''' if not hasattr(polarity, '__iter__'): polarity = [polarity] * 8 if not hasattr(cc, '__iter__'): cc = range(cc, cc + 8) if not hasattr(color, '__iter__'): color = [color] * 8 faders = zip(range(0,8), polarity, cc, color) faders = [y for x in faders for y in x] # flatten return midi_syx_prefix + [0x01, 0x00, orientation] + faders + [0xf7] def midi_fader_mode(): return midi_syx_prefix + [0x00, 0x0d, 0xf7] ### MIDI in callback current_mode = 'session' def midiin_callback(event, midiout): global current_mode message, dt = event # handle mode selection if message == [0xb0, 0x5f, 127]: # session button if current_mode == 'session': # switch to fader mode is done by software midiout.send_message(midi_select_layout(13)) current_mode = 'fader' else: current_mode = 'session' elif message == [0xb0, 0x60, 127]: # note button current_mode = 'note' elif message == [0xb0, 0x61, 127]: # custom button current_mode = 'custom' # handle other buttons when in a specific mode elif current_mode == 'fader': pass # @todo multiple fader banks ### Main def main(): midiout = rtmidi.MidiOut() midiout_idx = get_midi_port(midiout, port_name) if not midiout_idx: sys.stderr.write("Device not found (output port)\n") sys.exit(1) midiout.open_port(midiout_idx, name='Launchpad X Helper') midiin = rtmidi.MidiIn() midiin_idx = get_midi_port(midiin, port_name) if not midiin_idx: sys.stderr.write("Device not found (input port)\n") sys.exit(1) midiin.open_port(midiin_idx, name='Launchpad X Helper') midiin.set_callback(midiin_callback, midiout) # Enable session mode, enter session mode, setup faders midiout.send_message(midi_daw_mode(1)) midiout.send_message(midi_select_layout(0)) midiout.send_message(midi_setup_faders(0, 0, 100, midi_colors['green'])) print("Entering main loop. Press Control-C to exit.") try: while True: time.sleep(1) except KeyboardInterrupt: print('') finally: print("Exit.") midiin.close_port() midiout.send_message(midi_daw_mode(0)) midiout.close_port() if __name__ == '__main__': main()