def OnUpdatePlugin(self, delta):
     # Indicator to notify user that preset is in process of being set.
     self._request_plugin_window_focus()
     if delta > 0:
         ui.next()
     elif delta < 0:
         ui.previous()
Example #2
0
def processMenuMode(command):
    if command.is_lift:
        coord = [command.coord_X, command.coord_Y]

        # Next/prev track
        if coord == [0, 0]:
            ui.previous()
            command.handle("Channel Rack: Previous channel")
        elif coord == [0, 1]:
            ui.next()
            command.handle("Channel Rack: Next channel")

        # Cut, Copy, Paste
        elif coord == [2, 0]:
            ui.cut()
            command.handle("UI: Cut")
        elif coord == [3, 0]:
            ui.copy()
            command.handle("UI: Copy")
        elif coord == [4, 0]:
            ui.paste()
            command.handle("UI: Paste")

        # To piano roll
        elif coord == [7, 1]:
            ui.showWindow(internal.consts.WINDOW_PIANO_ROLL)
            command.handle("Sent to pianoroll")

        # Plugin window
        elif coord == [6, 1]:
            channels.showEditor(channels.channelNumber())
            command.handle("Opened plugin window")
Example #3
0
 def OnUpdatePlugin(self, delta):
     # Indicator to notify user that preset is in process of being set.
     self._request_plugin_window_focus()
     if SCRIPT_VERSION >= 10:
         idx = channels.selectedChannel()
         if delta > 0:
             plugins.nextPreset(idx)
         elif delta < 0:
             plugins.prevPreset(idx)
     else:
         if delta > 0:
             ui.next()
         elif delta < 0:
             ui.previous()
Example #4
0
    def handlePadPress(self, event):
        # print(f"self.handlePadPress called for {event.status} {event.data1} {event.data2}")

        """ Cancel pad input if it happens too soon after the last pad input """
        pad_input_timestamp = time.perf_counter()
        current_input_mode = self.getInputMode()

        target = self.getPadById(event.data1)
        value = True
        if target:
            self.setTarget(target)
            self.updatePadPressedStateById(target.id, value)
            self.updatePadToggleStateById(target.id)
            self.setLastPadPressed(target)
            if self.MODE_CHANGE_UNLOCKED:
                self.checkForModeChange(target, pad_input_timestamp)
        else:
            print(f"self.handlePadPress error:\n  Pad not found for {event.data1}.")
            return None
        if current_input_mode != self.getInputMode():
            event.handled = True
            return None
        print(f"{target.name} pressed")

        """
        Start custom events here.
        """

        if self.getInputMode() == 'ui':

            if target == self.getPadByNumber(16):
                self.cycleWindowFocus(1)
            elif target == self.getPadByNumber(15):
                self.cycleWindowFocus(-1)
            elif target == self.getPadByNumber(12):
                ui.next()
                self.LAST_PAD_PRESSED_TIMESTAMP = time.perf_counter()
            elif target == self.getPadByNumber(11):
                ui.previous()
                self.LAST_PAD_PRESSED_TIMESTAMP = time.perf_counter()

        """
    def handle_backward_press(self, event, backward):
        """ Put backward press code here.
        """
        # Mixer Mode
        if ui.getFocused(0) == 1:
            ui.previous()
            self.output = "Mixer: Selected next track: " + helpers.getMixerTrackName(
                self.selected_track - 1)

        # Edison is focused
        elif ui.getFocusedPluginName() == "Edison":
            ui.jog(-1)
            self.output = "Jog Back"

        # Default Mode
        else:
            self.output = "Previous"
            ui.previous()

        self.set_hint_message(self.output)
        print("Pressed backward button.")

        event.handled = True
Example #6
0
    def handlePressureChange(self, event):
        # print(f"self.handlePressureChange called for {event.status} {event.data1} {event.data2}")

        # BUG WARNING - pressure assignment only happens to the most recent pad pressed (see notes at top of file)
        #   - until fixed, the assumption is that self.getTarget() would return the pad whose pressure is changing.
        self.setTarget(self.getLastPadPressed())
        self.setTargetPressure(event.data1)
        target = self.getTarget()
        value = event.data1
        print(f"{target.name} pressure changed to {value}")

        """
        Start custom events here.
        """

        if self.getInputMode() == 'ui':
            if self.LAST_PAD_PRESSED == self.getPadByNumber(12):
                if (time.perf_counter() - self.LAST_PAD_PRESSED_TIMESTAMP) > (PAD_BUFFER * 2.5):
                    ui.next()
            elif self.LAST_PAD_PRESSED == self.getPadByNumber(11):
                if (time.perf_counter() - self.LAST_PAD_PRESSED_TIMESTAMP) > (PAD_BUFFER * 2.5):
                    ui.previous()

        """
Example #7
0
	def switch_moment(event):
		"""handles momentary witch midi events"""
		if event.data1 == button["pad_mode_toggle"]:				# This Rotates through pad modes - standard, step sequencer, pad to channel		
			Switch.mode_toggle += 1
			if Switch.mode_toggle == 4:
				Switch.mode_toggle = 0
			print('Pad Mode: ' + mode[Switch.mode_toggle])
			ui.setHintMsg(mode[Switch.mode_toggle])

		elif event.midiId == 224: 								# pitch wheel
			Switch.pitch_num = event.data2	
			if Switch.shift_status == True:
				print(data.notes_list[int(mapvalues(Switch.pitch_num, 0, 11, 0, 244))])

		elif event.data1 == button["play"]:			
			transport.start()
			event.handled = True

		elif event.data1 == button["offset_range"]:
			Switch.offset_iter += 1
			if Switch.offset_iter == 2:     								# 2 here will limit to 32 steps, knobs. Changing to 4 will allow up to 64 steps, knobs. 
				Switch.offset_iter = 0
			ui.setHintMsg("Offset Range: " + str(Switch.offset_iter))
	
		elif event.data1 == button["stop"]:
			print('Stop')
			transport.stop()
			event.handled = True						
																	
		elif event.data1 == button["record"]:			
			print('Record')
			transport.record()
			event.handled = True

		elif event.data1 == button["pattern_down"]:
			if ui.getFocused(5):
				print("Previous Preset")
				ui.previous()
			else:
				print('Pattern Down')
				transport.globalTransport(midi.FPT_PatternJog, -1)
				event.handled = True
					
		elif event.data1 == button["pattern_up"]:
			if ui.getFocused(5):
				print("Next Preset")
				ui.next()
			else:
				print('Pattern Up')
				transport.globalTransport(midi.FPT_PatternJog, 1)
				event.handled = True
																	# Set mod wheel to control channels when channels focused and tracks when mixer
		elif event.data1 == button["mod_wheel"]:					
			if ui.getFocused(0):
				mixer.setTrackNumber(int(mapvalues(event.data2, 0, 64, 0, 127)))
				ui.scrollWindow(midi.widMixer, mixer.trackNumber())
			elif ui.getFocused(1):
				print("Channel Number: " + str(channels.selectedChannel()))
				channels.selectOneChannel(int(round(mapvalues(event.data2, channels.channelCount()-1, 0, 0, 127), 0)))				

		elif event.data1 == 72:
			print(channels.getChannelColor(channels.selectedChannel())) 
			Switch.color_num += 1
			if Switch.color_num == len(colors):
				Switch.color_num = 0
			if ui.getFocused(1):
				channels.setChannelColor(channels.selectedChannel(), colors[Switch.color_num])
			elif ui.getFocused(0):
				mixer.setTrackColor(mixer.trackNumber(), colors[Switch.color_num])
			event.handled = True
		
		elif event.data1 == button["enter"]:
			if ui.getFocused(4):
				print("Select Browser Item")
				ui.selectBrowserMenuItem()		
				event.handled = True
			elif ui.getFocused(1):
				print("Mute Channel")
				channels.muteChannel(channels.selectedChannel())
			elif ui.getFocused(0):
				print("Mute Track")
				mixer.muteTrack(mixer.trackNumber())
			else:
				print('enter')
				ui.enter()
				event.handled = True

		elif event.data1 in range(59, 64) and config.PATTERN_JUMP_ON:						# Sets jump to pattern
			patterns.jumpToPattern(event.data1 - 58)
			event.handled = True		

		elif event.data1 in range(75, 80) and config.PATTERN_JUMP_ON:
			patterns.jumpToPattern(event.data1 - 69)
			event.handled = True

		elif event.data1 == button["solo"]:
			print('Solo')
			if ui.getFocused(0):
				mixer.soloTrack(mixer.trackNumber())
			elif ui.getFocused(1):
				channels.soloChannel(channels.selectedChannel())

		elif event.data1 == button["view_plugin_picker"]:
			print('View Plugin Picker')
			transport.globalTransport(midi.FPT_F8, 67)
			event.handled = True	
			
		elif event.data1 == button["song_mode_toggle"]:			
			print('Toggle Song and Pattern Mode')
			transport.setLoopMode()
			event.handled = True
			
		elif event.data1 == button["view_playlist"]:			
			print('View Playlist')
			transport.globalTransport(midi.FPT_F5, 65)
			event.handled = True
			
		elif event.data1 == button["view_piano_roll"]:
			print('View Piano Roll')
			transport.globalTransport(midi.FPT_F7, 66)
			event.handled = True
		
		elif event.data1 == button["view_channel_rack"]:
			print('View Channel Rack')
			transport.globalTransport(midi.FPT_F6, 65)
			event.handled = True
			
		elif event.data1 == button["view_mixer"]:
			print('View Mixer')
			transport.globalTransport(midi.FPT_F9, 68)
			event.handled = True
																	# Toggle through step parameter options - pitch, pan etc. No Shift control right now. 
		elif event.data1 == button["step_parameter"]:
			
			if ui.getFocused(1) and Switch.mode_toggle == 1:
				print('Toggle Step Parameter')
				Switch.parameter += 1
				if Switch.parameter == 7:
					Switch.parameter = 0
				print(Switch.parameter)
				ui.setHintMsg(parameters[Switch.parameter])

			elif ui.getFocused(0):
				Switch.mixer_num += 1
				if Switch.mixer_num == 2:
					Switch.mixer_num = 0
				print('Mixer Mode: ' + str(Switch.mixer_num))
				ui.setHintMsg(mixer_choice[Switch.mixer_num])
			event.handled = True

		elif event.data1 == button["open_channel_sampler"]:			
			print('Open Sampler Channel')
			channels.showCSForm(channels.channelNumber(), -1)
			event.handled = True					
							
		elif event.data1 == button["left"]:							
			print('Left')
			ui.left()
			event.handled = True	
		
		elif event.data1 == button["down"]:							
			print('Down')
			ui.down()
			event.handled = True				
			
		elif event.data1 == button["right"]:						
			print('Right')
			ui.right()
			event.handled = True			

		elif event.data1 == button["save"]:
			print('Save')
			transport.globalTransport(midi.FPT_Save, 92)
																	# If mixer is open and mute mode selected, top row will mute respective track 
		elif event.data1 == button["undo"]:					
				print('Undo')
				transport.globalTransport(midi.FPT_Undo, 20)
				device.midiOutMsg(144, 1, 63, 80)
				event.handled = True

		elif event.data1 == button["escape"]:
			print('Escape')
			ui.escape()
			event.handled = True
		
		elif event.data1 == button["up"]:
			print('Up')
			ui.up()
			event.handled = True			

		elif event.data1 == button["rotate_window"]:				
			print('Rotate Window')
			ui.nextWindow()
			event.handled = True

		elif event.data1 == button["browser"]:				
			print('Browser')
			if Switch.shift_status == False:
				if ui.getFocused(4):
					ui.hideWindow(4)
					event.handled = True
				else:
					ui.showWindow(4)
					ui.setFocused(4)
					event.handled = True
			
		elif event.data1 == button["step_rec"]:	
			if ui.getFocused(0):
				mixer.armTrack(mixer.trackNumber())	
				print("Toggle Track Rec")
			else:			
				transport.globalTransport(midi.FPT_StepEdit, 114)
				print('Step Record')
				event.handled = True							

		elif event.data1 == button["quantize"]:
			print('quantize')
			channels.quickQuantize(channels.channelNumber())
			event.handled = True

		elif event.data1 == button["link_chan"]:
			print('link channel')
			mixer.linkTrackToChannel(0)

		elif event.data1 == button["rand_steps"]:
			print("Random")
			print(f'Pitch Bend: {event.pitchBend}')
			for i in range(patterns.getPatternLength(patterns.patternNumber())):
				channels.setGridBit(channels.channelNumber(), i, 0)
			for z in range (patterns.getPatternLength(patterns.patternNumber())):
				y = num_gen()
				if y > ( Switch.pitch_num * 516):
					channels.setGridBit(channels.channelNumber(), z, 1)
				else:
					pass
			event.handled = True

		elif event.data1 == button["rand_notes"]:
			print("Randomize Notes")
			Switch.note_gen()
			event.handled = True
Example #8
0
    def OnMidiMsg(self, event):
        event.handled = False

        # FOR PRINTING DATA ON SCRIPT OUTPUT

        print("status: {}, port: {}, midiId: {}, data1: {}, data2: {}".format(
            event.status, event.port, event.midiId, event.data1, event.data2))

        # CONTROL CHANGE EVENT FOR BUTTONS OF MIDI
        if event.midiId == midi.MIDI_CONTROLCHANGE:
            if event.data2 > 0:

                if event.data1 == Play:
                    print('Playback')
                    transport.start()
                    ui.setHintMsg("Play/Pause")
                    event.handled = True
                elif event.data1 == Record:
                    print('Record')
                    transport.record()
                    ui.setHintMsg("Record")
                    event.handled = True
                elif event.data1 == Stop:
                    print('Stop')
                    transport.stop()
                    ui.setHintMsg("Stop")
                    event.handled = True
                elif event.data1 == ToggleLoop:
                    print('Toggle Loop')
                    transport.setLoopMode()
                    ui.setHintMsg("Pattern/Song")
                    event.handled = True

                elif event.data1 == Left:
                    print('Previous Tab')
                    transport.globalTransport(midi.FPT_WindowJog, -1)
                    ui.setHintMsg("Previous Tab")
                    event.handled = True
                elif event.data1 == Right:
                    print('Next Tab')
                    transport.globalTransport(midi.FPT_WindowJog, 1)
                    ui.setHintMsg("Next Tab")
                    event.handled = True

                elif event.data1 == Up:
                    print('Undo Up')
                    general.undoUp()
                    ui.setHintMsg("Undo Up")
                    event.handled = True
                elif event.data1 == Down:
                    print('Undo Down/ReDo')
                    general.restoreUndo()
                    ui.setHintMsg("Undo Down/ReDo")
                    event.handled = True

                elif event.data1 in Knobs:
                    mixer.setTrackVolume(
                        mixer.trackNumber() + Knobs.index(event.data1),
                        event.data2 / 127)
                    event.handled = True

        #MIDI NOTE ON/OFF FOR NOTE EVENTS
        elif event.midiId == midi.MIDI_NOTEON:
            if (event.pmeFlags & midi.PME_System != 0):

                if event.data1 == Playlist:
                    print('Playlist')
                    transport.globalTransport(midi.FPT_F5, 1)
                    ui.setHintMsg("Playlist")
                    event.handled = True
                elif event.data1 == ChannelRack:
                    print('ChannelRack')
                    transport.globalTransport(midi.FPT_F6, 1)
                    ui.setHintMsg("ChannelRack")
                    event.handled = True
                elif event.data1 == PianoRoll:
                    print('PianoRoll')
                    transport.globalTransport(midi.FPT_F7, 1)
                    ui.setHintMsg("PianoRoll")
                    event.handled = True
                elif event.data1 == Mixer:
                    print('Mixer')
                    transport.globalTransport(midi.FPT_F9, 1)
                    ui.setHintMsg("Mixer")
                    event.handled = True

                elif event.data1 == Previous:
                    print('Previous')
                    ui.previous()
                    ui.setHintMsg("Previous")
                    event.handled = True
                elif event.data1 == Next:
                    print('Next')
                    ui.next()
                    ui.setHintMsg("Next")
                    event.handled = True

                elif event.data1 == Mute:
                    print('Mute')
                    channels.muteChannel(channels.channelNumber())
                    ui.setHintMsg("Mute")
                    event.handled = True
                elif event.data1 == Solo:
                    print('Solo')
                    channels.soloChannel(channels.channelNumber())
                    ui.setHintMsg("Solo")
                    event.handled = True

                elif event.data1 == PatternUp:
                    print('Pattern Up')
                    transport.globalTransport(midi.FPT_PatternJog, -1)
                    ui.setHintMsg("Pattern Up")
                    event.handled = True
                elif event.data1 == PatternDown:
                    print('Pattern Down')
                    transport.globalTransport(midi.FPT_PatternJog, 1)
                    ui.setHintMsg("Pattern Down")
                    event.handled = True

                elif event.data1 == Overdub:
                    print('Overdub')
                    transport.globalTransport(midi.FPT_Overdub, 1)
                    ui.setHintMsg("Overdub")
                    event.handled = True
                elif event.data1 == LoopRecord:
                    print('Loop Record')
                    transport.globalTransport(midi.FPT_LoopRecord, 1)
                    ui.setHintMsg("Loop Record")
                    event.handled = True

                elif event.data1 == SnapUp:
                    print('Snap -1')
                    transport.globalTransport(midi.FPT_SnapMode, -1)
                    ui.setHintMsg("Snap -1")
                    event.handled = True
                elif event.data1 == SnapDown:
                    print('Snap +1')
                    transport.globalTransport(midi.FPT_SnapMode, 1)
                    ui.setHintMsg("Snap +1")
                    event.handled = True

                elif event.data1 == TapTempo:
                    print('Tap Tempo')
                    transport.globalTransport(midi.FPT_TapTempo, 1)
                    ui.setHintMsg("Tap Tempo")
                    event.handled = True
                elif event.data1 == Metro:
                    print('Metronome')
                    transport.globalTransport(midi.FPT_Metronome, 1)
                    ui.setHintMsg("Metronome")
                    event.handled = True
def process(command):

    command.actions.addProcessor("Default Processor")

    #---------------------------------
    # Transport functions
    #---------------------------------
    if command.type == eventconsts.TYPE_TRANSPORT:
        # Play-pause: only on lift
        if command.id == eventconsts.TRANSPORT_PLAY and command.is_lift:
            transport.start()
            command.actions.appendAction("Play/Pause Transport")
            command.handled = True

        # Stop: only on lift
        if command.id == eventconsts.TRANSPORT_STOP and command.is_lift:
            transport.stop()
            command.actions.appendAction("Stop Transport")
            command.handled = True

        # Loop: only on lift
        if command.id == eventconsts.TRANSPORT_LOOP and command.is_lift:
            transport.setLoopMode()
            command.actions.appendAction("Toggle Loop Mode")
            command.handled = True

        # Record: only on lift
        if command.id == eventconsts.TRANSPORT_RECORD and command.is_lift:
            transport.record()
            command.actions.appendAction("Toggle Recording")
            command.handled = True

        # Skip forward: start on press, stop on lift, faster on double press?
        if command.id == eventconsts.TRANSPORT_FORWARD:
            speed = 1
            command.actions.appendAction("Fast Forward")
            if command.is_double_click:
                speed = 2
                command.actions.appendAction("[2x Speed]")

            if command.is_lift is False:
                transport.continuousMove(speed, 2)
            if command.is_lift is True:
                transport.continuousMove(speed, 0)
                command.actions.appendAction("Stopped")
            command.handled = True

        # Skip back: start on press, stop on lift, faster on double press?
        if command.id == eventconsts.TRANSPORT_BACK:
            speed = -1
            command.actions.appendAction("Rewind")
            if command.is_double_click:
                speed = -2
                command.actions.appendAction("[2x Speed]")

            if command.is_lift is False:
                transport.continuousMove(speed, 2)
            if command.is_lift is True:
                transport.continuousMove(speed, 0)
                command.actions.appendAction("Stopped")
            command.handled = True

        # Next Track: next UI element
        if command.id == eventconsts.TRANSPORT_TRACK_NEXT and command.is_lift:
            ui.next()
            command.actions.appendAction("Next UI Element")
            command.handled = True

        # Prev Track: prev UI element
        if command.id == eventconsts.TRANSPORT_TRACK_PREVIOUS and command.is_lift:
            ui.previous()
            command.actions.appendAction("Previous UI Element")
            command.handled = True
Example #10
0
    def OnMidiIn(self, event):
        # print ("Event: {:X} {:X} {:2X} {} {:2X}".format(event.status, event.data1, event.data2,  EventNameT[(event.status - 0x80) // 16] + ': '+  utils.GetNoteName(event.data1), int(hex(event.data2), 16)))

        # Create output string
        output = ""

        event.handled = False
        global loopDown
        global loopInterrupt

        # Set has snapped flag
        hasSnapped = False

        # Process Long Presses:

        # Stop Button
        if (event.status is 0xB0 and event.data1 is 0x2E):
            global stop_PressTime
            global stop_LiftTime

            # Press - Start timer
            if event.data2 is 0x7F:
                stop_PressTime = time.perf_counter()
            # Lift - Stop timer
            elif event.data2 is 0x00:
                stop_LiftTime = time.perf_counter()
                if (stop_LiftTime - stop_PressTime) >= LONG_PRESS_TIME:
                    ui.escape()
                    output += "UI: Escape"
                    event.handled = True

        if event.handled is True:
            handleOutput(output)
            return

        # In popup
        if ui.isInPopupMenu() is 1 and loopDown is False:
            output += "[In popup menu] "
            # Currently this is always inactive?

        if event.handled is True:
            handleOutput(output)
            return

        # In Playlist
        if ui.getFocused(2) is 1 and loopDown is False:

            # Forward Button
            if (event.status is 0xB0 and event.data1 is 0x30):
                # Press - No action if markers exist
                if event.data2 is 0x7F and arrangement.getMarkerName(
                        0) is not "":
                    event.handled = True
                # Lift - Skip to next marker, only if markers exist
                elif event.data2 is 0x00 and arrangement.getMarkerName(
                        0) is not "":
                    transport.markerJumpJog(1)
                    output += "Transport: Jump to next marker"
                    event.handled = True

            # Back Button
            if (event.status is 0xB0 and event.data1 is 0x2F):
                # Press - No action if markers exist
                if event.data2 is 0x7F and arrangement.getMarkerName(
                        0) is not "":
                    event.handled = True
                # Lift - Skip to previous marker, only if markers exist
                elif event.data2 is 0x00 and arrangement.getMarkerName(
                        0) is not "":
                    transport.markerJumpJog(-1)
                    output += "Transport: Jump to previous marker"
                    event.handled = True

        if event.handled is True:
            handleOutput(output)
            return

        # In Mixer
        if ui.getFocused(0) is 1 and loopDown is False:
            selectedTrack = mixer.trackNumber()

            # Record Button
            if (event.status is 0xB0 and event.data1 is 0x2C):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Toggle track arm
                elif event.data2 is 0x00:
                    mixer.armTrack(selectedTrack)
                    if mixer.isTrackArmed(selectedTrack) is 1:
                        output += "Mixer: Armed track: " + getMixerTrackName(
                            selectedTrack)
                    else:
                        output += "Mixer: Disarmed track: " + getMixerTrackName(
                            selectedTrack)
                    event.handled = True

            # Forward Button
            if (event.status is 0xB0 and event.data1 is 0x30):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Next track
                elif event.data2 is 0x00:
                    ui.next()
                    output += "Mixer: Selected next track: " + getMixerTrackName(
                        selectedTrack + 1)

                    event.handled = True

            # Back Button
            if (event.status is 0xB0 and event.data1 is 0x2F):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Previous track
                elif event.data2 is 0x00:
                    ui.previous()
                    output += "Mixer: Selected previous track: " + getMixerTrackName(
                        selectedTrack - 1)

                    event.handled = True

            # Fader, knob and buttons #9 act on the selected track

            # Upper button 9
            if (event.status is 0xB0 and
                (event.data1 is 0x1F or event.data1 is 0x4B
                 or event.data1 is 0x73)) or (event.status is 0xB8
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or event.status is 0xB8:
                    output += mixerToggleSolo(selectedTrack)
                    event.handled = True

            # Lower button 9
            if (event.status is 0xB0 and
                (event.data1 is 0x29 or event.data1 is 0x54
                 or event.data1 is 0x7C)) or (event.status is 0xB8
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or event.status is 0xB8:
                    output += mixerToggleMute(selectedTrack)
                    event.handled = True

            # Fader 9 - Selected volume
            if (event.status is 0xB0 and
                (event.data1 is 0x0D or event.data1 is 0x38
                 or event.data1 is 0x5D)) or (event.status is 0xB8
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(selectedTrack, event.data2)
                event.handled = True

            # Knob 9 - Selected pan
            if (event.status is 0xB0 and
                (event.data1 is 0x16 or event.data1 is 0x42
                 or event.data1 is 0x6A)) or (event.status is 0xB8
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(selectedTrack, event.data2)
                event.handled = True

            # Faders, knobs and buttons #1-8 act on tracks 1-8 respectively

            # Upper button 1
            if (event.status is 0xB0 and
                (event.data1 is 0x17 or event.data1 is 0x43
                 or event.data1 is 0x6B)) or (event.status is 0xB0
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB0
                                           and event.data1 is 0x10
                                           and event.data2 is 0x7F):
                    output += mixerToggleSolo(1)
                    event.handled = True

            # Lower button 1
            if (event.status is 0xB0 and
                (event.data1 is 0x21 or event.data1 is 0x4C
                 or event.data1 is 0x74)) or (event.status is 0xB0
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB0
                                           and event.data1 is 0x11
                                           and event.data2 is 0x7F):
                    output += mixerToggleMute(1)
                    event.handled = True

            # Upper button 2
            if (event.status is 0xB0 and
                (event.data1 is 0x18 or event.data1 is 0x44
                 or event.data1 is 0x6C)) or (event.status is 0xB1
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB1
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(2)
                    event.handled = True

            # Lower button 2
            if (event.status is 0xB0 and
                (event.data1 is 0x22 or event.data1 is 0x4D
                 or event.data1 is 0x75)) or (event.status is 0xB1
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB2
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(2)
                    event.handled = True

            # Upper button 3
            if (event.status is 0xB0 and
                (event.data1 is 0x19 or event.data1 is 0x45
                 or event.data1 is 0x6D)) or (event.status is 0xB2
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB2
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(3)
                    event.handled = True

            # Lower button 3
            if (event.status is 0xB0 and
                (event.data1 is 0x23 or event.data1 is 0x4E
                 or event.data1 is 0x76)) or (event.status is 0xB2
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB2
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(3)
                    event.handled = True

            # Upper button 4
            if (event.status is 0xB0 and
                (event.data1 is 0x1A or event.data1 is 0x46
                 or event.data1 is 0x6E)) or (event.status is 0xB3
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB3
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(4)
                    event.handled = True

            # Lower button 4
            if (event.status is 0xB0 and
                (event.data1 is 0x24 or event.data1 is 0x4F
                 or event.data1 is 0x77)) or (event.status is 0xB3
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB3
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(4)
                    event.handled = True

            # Upper button 5
            if (event.status is 0xB0 and
                (event.data1 is 0x1B or event.data1 is 0x47
                 or event.data1 is 0x6F)) or (event.status is 0xB4
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB4
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(5)
                    event.handled = True

            # Lower button 5
            if (event.status is 0xB0 and
                (event.data1 is 0x25 or event.data1 is 0x50
                 or event.data1 is 0x78)) or (event.status is 0xB4
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB4
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(5)
                    event.handled = True

            # Upper button 6
            if (event.status is 0xB0 and
                (event.data1 is 0x1C or event.data1 is 0x48
                 or event.data1 is 0x70)) or (event.status is 0xB5
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB5
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(6)
                    event.handled = True

            # Lower button 6
            if (event.status is 0xB0 and
                (event.data1 is 0x26 or event.data1 is 0x51
                 or event.data1 is 0x79)) or (event.status is 0xB5
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB5
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(6)
                    event.handled = True

            # Upper button 7
            if (event.status is 0xB0 and
                (event.data1 is 0x1D or event.data1 is 0x49
                 or event.data1 is 0x71)) or (event.status is 0xB6
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB6
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(7)
                    event.handled = True

            # Lower button 7
            if (event.status is 0xB0 and
                (event.data1 is 0x27 or event.data1 is 0x52
                 or event.data1 is 0x7A)) or (event.status is 0xB6
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB6
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(7)
                    event.handled = True

            # Upper button 8
            if (event.status is 0xB0 and
                (event.data1 is 0x1E or event.data1 is 0x4A
                 or event.data1 is 0x72)) or (event.status is 0xB7
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB7
                                           and event.data1 is 0x10):
                    output += mixerToggleSolo(8)
                    event.handled = True

            # Lower button 8
            if (event.status is 0xB0 and
                (event.data1 is 0x28 or event.data1 is 0x53
                 or event.data1 is 0x7B)) or (event.status is 0xB7
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or (event.status is 0xB7
                                           and event.data1 is 0x11):
                    output += mixerToggleMute(8)
                    event.handled = True

            # Fader 1 - Track 1 volume
            if event.status is 0xB0 and (event.data1 is 0x02
                                         or event.data1 is 0x2A
                                         or event.data1 is 0x55
                                         or event.data1 is 0x07):
                output += mixerAdjustFader(1, event.data2)
                event.handled = True

            # Knob 1 - Track 1 pan
            if event.status is 0xB0 and (event.data1 is 0x0E
                                         or event.data1 is 0x39
                                         or event.data1 is 0x5E
                                         or event.data1 is 0x0A):
                output += mixerAdjustPan(1, event.data2)
                event.handled = True

            # Fader 2 - Track 2 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x03 or event.data1 is 0x2B
                 or event.data1 is 0x56)) or (event.status is 0xB1
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(2, event.data2)
                event.handled = True

            # Knob 2 - Track 2 pan
            if (event.status is 0xB0 and
                (event.data1 is 0x0F or event.data1 is 0x3A
                 or event.data1 is 0x5F)) or (event.status is 0xB1
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(2, event.data2)
                event.handled = True

            # Fader 3 - Track 3 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x04 or event.data1 is 0x32
                 or event.data1 is 0x57)) or (event.status is 0xB2
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(3, event.data2)
                event.handled = True

            # Knob 3 - Track 3 pan
            if ((event.status is 0xB0 and
                 (event.data1 is 0x10 or event.data1 is 0x3B
                  or event.data1 is 0x60)) or
                (event.status is 0xB2
                 and event.data1 is 0x0A)) and event.handled is False:
                output += mixerAdjustPan(3, event.data2)
                event.handled = True

            # Fader 4 - Track 4 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x05 or event.data1 is 0x33
                 or event.data1 is 0x58)) or (event.status is 0xB3
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(4, event.data2)
                event.handled = True

            # Knob 4 - Track 4 pan
            if ((event.status is 0xB0 and
                 (event.data1 is 0x11 or event.data1 is 0x3C
                  or event.data1 is 0x61)) or
                (event.status is 0xB3
                 and event.data1 is 0x0A)) and event.handled is False:
                output += mixerAdjustPan(4, event.data2)
                event.handled = True

            # Fader 5 - Track 5 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x06 or event.data1 is 0x34
                 or event.data1 is 0x59)) or (event.status is 0xB4
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(5, event.data2)
                event.handled = True

            # Knob 5 - Track 5 pan
            if (event.status is 0xB0 and
                (event.data1 is 0x12 or event.data1 is 0x3D
                 or event.data1 is 0x66)) or (event.status is 0xB4
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(5, event.data2)
                event.handled = True

            # Fader 6 - Track 6 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x08 or event.data1 is 0x35
                 or event.data1 is 0x5A)) or (event.status is 0xB5
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(1, event.data2)
                event.handled = True

            # Knob 6 - Track 6 pan
            if (event.status is 0xB0 and
                (event.data1 is 0x13 or event.data1 is 0x3E
                 or event.data1 is 0x67)) or (event.status is 0xB5
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(6, event.data2)
                event.handled = True

            # Fader 7 - Track 7 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x09 or event.data1 is 0x36
                 or event.data1 is 0x5B)) or (event.status is 0xB6
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(1, event.data2)
                event.handled = True

            # Knob 7 - Track 7 pan
            if (event.status is 0xB0 and
                (event.data1 is 0x14 or event.data1 is 0x3F
                 or event.data1 is 0x68)) or (event.status is 0xB6
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(7, event.data2)
                event.handled = True

            # Fader 8 - Track 8 volume
            if (event.status is 0xB0 and
                (event.data1 is 0x0C or event.data1 is 0x37
                 or event.data1 is 0x5C)) or (event.status is 0xB7
                                              and event.data1 is 0x07):
                output += mixerAdjustFader(1, event.data2)
                event.handled = True

            # Knob 8 - Track 8 pan
            if (event.status is 0xB0 and
                (event.data1 is 0x15 or event.data1 is 0x41
                 or event.data1 is 0x69)) or (event.status is 0xB7
                                              and event.data1 is 0x0A):
                output += mixerAdjustPan(8, event.data2)
                event.handled = True

        if event.handled is True:
            handleOutput(output)
            return

        # In Channel rack
        if ui.getFocused(1) is 1 and loopDown is False:
            selectedChannel = channels.channelNumber()

            # Forward Button
            if (event.status is 0xB0 and event.data1 is 0x30):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Next track
                elif event.data2 is 0x00:
                    ui.next()
                    mixerTrackSelect(channels.channelNumber())
                    output += "Channel rack: Select next track: " + getChannelName(
                        channels.channelNumber())

                    event.handled = True

            # Back Button
            if (event.status is 0xB0 and event.data1 is 0x2F):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Previous track
                elif event.data2 is 0x00:
                    ui.previous()
                    mixerTrackSelect(channels.channelNumber())
                    output += "Channel rack: Select previous track: " + getChannelName(
                        channels.channelNumber())

                    event.handled = True

            # Fader, knob and buttons #9 act on the selected channel

            # Upper button 9
            if (event.status is 0xB0 and
                (event.data1 is 0x1F or event.data1 is 0x4B
                 or event.data1 is 0x73)) or (event.status is 0xB8
                                              and event.data1 is 0x10):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Solo channel (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or event.status is 0xB8:
                    output += channelToggleSolo(selectedChannel)
                    event.handled = True

            # Lower button 9
            if (event.status is 0xB0 and
                (event.data1 is 0x29 or event.data1 is 0x54
                 or event.data1 is 0x7C)) or (event.status is 0xB8
                                              and event.data1 is 0x11):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Mute track (in scene 4, the buttons toggle automatically)
                if event.data2 is 0x00 or event.status is 0xB8:
                    output += channelToggleMute(selectedChannel)
                    event.handled = True

            # Fader 9 - Selected volume
            if (event.status is 0xB0 and
                (event.data1 is 0x0D or event.data1 is 0x38
                 or event.data1 is 0x5D)) or (event.status is 0xB8
                                              and event.data1 is 0x07):
                output += channelAdjustVolume(selectedChannel, event.data2)
                event.handled = True

            # Knob 9 - Selected pan
            if (event.status is 0xB0 and
                (event.data1 is 0x16 or event.data1 is 0x42
                 or event.data1 is 0x6A)) or (event.status is 0xB8
                                              and event.data1 is 0x0A):
                output += channelAdjustPan(selectedChannel, event.data2)
                event.handled = True

            # Maybe include step editor here (when I figure out lights)

        if event.handled is True:
            handleOutput(output)
            return

        # In Browser
        if ui.getFocused(4) is 1 and loopDown is False:

            # Play Button
            if (event.status is 0xB0 and event.data1 is 0x2D):
                # Press - Play sample/expand menu
                if event.data2 is 0x7F:
                    ui.next()
                    ui.previous()
                    ui.right()
                    output += "Browser: Select"
                    event.handled = True
                # Lift - No action
                elif event.data2 is 0x00:
                    event.handled = True

            # Forward Button
            if (event.status is 0xB0 and event.data1 is 0x30):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Next item
                elif event.data2 is 0x00:
                    ui.next()
                    output += "Browser: Next"

                    event.handled = True

            # Back Button
            if (event.status is 0xB0 and event.data1 is 0x2F):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Previous item
                elif event.data2 is 0x00:
                    ui.previous()
                    output += "Browser: Previous"

                    event.handled = True

            # Stop Button
            if (event.status is 0xB0 and event.data1 is 0x2E):
                # Press - No action
                if event.data2 is 0x7F:
                    event.handled = True
                # Lift - Collapse menu
                elif event.data2 is 0x00:
                    ui.left()
                    output += "Browser: Collapse"

                    event.handled = True

        if event.handled is True:
            handleOutput(output)
            return

        # Default Actions:

        # Play Button
        if (event.status is 0xB0 and event.data1 is 0x2D):
            loopInterrupt = True
            # Press - No action
            if event.data2 is 0x7F:
                event.handled = True
            # Lift - Play/Pause
            elif event.data2 is 0x00:
                transport.start()
                if transport.isPlaying() is 1: output += "Transport: Play"
                else: output += "Transport: Pause"

                event.handled = True

        # Stop Button
        if (event.status is 0xB0 and event.data1 is 0x2E):
            loopInterrupt = True
            # Press - No action
            if event.data2 is 0x7F:
                event.handled = True
            # Lift - Stop
            elif event.data2 is 0x00:
                transport.stop()
                output += "Transport: Stop"

                event.handled = True

        # Forward Button
        if (event.status is 0xB0 and event.data1 is 0x30):
            loopInterrupt = True
            # Press - Start FF
            if event.data2 is 0x7F:
                transport.fastForward(2)
                event.handled = True
                output += "Transport: Fast Forward: Begin"
            # Lift - End FF
            elif event.data2 is 0x00:
                transport.fastForward(0)
                output += "Transport: Fast Forward: End"
                event.handled = True

        # Back Button
        if (event.status is 0xB0 and event.data1 is 0x2F):
            # Press - Start Rew
            if event.data2 is 0x7F:
                transport.rewind(2)
                event.handled = True
                output += "Transport: Rewind: Begin"
            # Lift - End Rew
            elif event.data2 is 0x00:
                transport.rewind(0)
                output += "Transport: Rewind: End"
                event.handled = True

        # Record Button
        if (event.status is 0xB0 and event.data1 is 0x2C):
            loopInterrupt = True
            # Press - No action
            if event.data2 is 0x7F:
                event.handled = True
            # Lift - Toggle Recording
            elif event.data2 is 0x00:
                transport.record()
                if transport.isRecording() is 1:
                    output += "Transport: Recording Enabled"
                else:
                    output += "Transport: Recording Disabled"
                event.handled = True

        # Loop Button
        if (event.status is 0xB0 and event.data1 is 0x31):
            # Press - Set Loop flags
            if event.data2 is 0x7F:
                # Set flags for loop modifier commands
                loopDown = True
                loopInterrupt = False
                event.handled = True

            # Lift - Toggle Loop if no action taken
            elif event.data2 is 0x00:
                event.handled = True
                loopDown = False
                if loopInterrupt is False:
                    transport.setLoopMode()
                    if transport.getLoopMode() is 1:
                        output += "Transport: Loop Mode: Song"
                    else:
                        output += "Transport: Loop Mode: Pattern"

        # Scene Change
        """
		if event.status is 0xF0:
			global scene
			scene += 1
			if scene is 5:
				scene = 1

			windowToShow = -1
			if scene is 1: 
				windowToShow = 2 # Playlist
				output += "Scene: Playlist"
			if scene is 2: 
				windowToShow = 1 # Channel Rack
				output += "Scene: Channel Rack"
			if scene is 3: 
				windowToShow = 3 # Piano roll
				output += "Scene: Piano Roll"
			if scene is 4: 
				windowToShow = 0 # Mixer
				output += "Scene: Mixer"

			ui.showWindow(windowToShow)
			event.handled = True
		"""

        if event.handled is True:
            handleOutput(output)
            return

        # Event not recognised
        if event.handled is False:
            print("Unknown Event: {:X} {:X} {:2X} {} {:2X}".format(
                event.status, event.data1, event.data2,
                EventNameT[(event.status - 0x80) // 16] + ': ' +
                utils.GetNoteName(event.data1), int(hex(event.data2), 16)))