示例#1
0
 def togglePlay(self, note):
     print("isPlaying: " + str(transport.isPlaying()))
     if (transport.isPlaying() == 0):
         transport.start()
         print("Starting Playback")
     elif (transport.isPlaying() == 1):
         transport.stop()
         print("Stopping Playback")
def beatChange(beat):
    global last_transport
    if bar_progresses_set and INIT_COMPLETE:
        transport_on = transport.isPlaying()
        if beat == 1 and last_transport == transport_on:
            toNextSet()
        last_transport = transport_on
示例#3
0
def redraw(lights):

    # When playing, display peak metre
    if transport.isPlaying():
        setPeaks(lights)

    return
示例#4
0
    def Sync(self, flags):
        """ Syncs up all visual indicators on keyboard with changes from FL Studio. """
        # Update buttons
        if flags & midi.HW_Dirty_LEDs:
            led_map = {
                ArturiaLights.ID_TRANSPORTS_RECORD:
                ArturiaLights.AsOnOffByte(transport.isRecording()),
                ArturiaLights.ID_TRANSPORTS_LOOP:
                ArturiaLights.AsOnOffByte(ui.isLoopRecEnabled()),
                ArturiaLights.ID_GLOBAL_METRO:
                ArturiaLights.AsOnOffByte(ui.isMetronomeEnabled()),
                ArturiaLights.ID_GLOBAL_SAVE:
                ArturiaLights.AsOnOffByte(transport.getLoopMode() == 1),
                ArturiaLights.ID_GLOBAL_UNDO:
                ArturiaLights.AsOnOffByte(general.getUndoHistoryLast() == 0),
                ArturiaLights.ID_TRACK_SOLO:
                ArturiaLights.AsOnOffByte(
                    channels.isChannelSolo(channels.selectedChannel())),
                ArturiaLights.ID_TRACK_MUTE:
                ArturiaLights.AsOnOffByte(
                    channels.isChannelMuted(channels.selectedChannel())),
                ArturiaLights.ID_TRANSPORTS_STOP:
                ArturiaLights.AsOnOffByte(not transport.isPlaying()),
                ArturiaLights.ID_TRANSPORTS_PLAY:
                ArturiaLights.AsOnOffByte(transport.getSongPos() > 0),
                ArturiaLights.ID_GLOBAL_OUT:
                ArturiaLights.AsOnOffByte(
                    arrangement.selectionEnd() > arrangement.selectionStart()),
                ArturiaLights.ID_NAVIGATION_LEFT:
                ArturiaLights.AsOnOffByte(ui.getVisible(midi.widChannelRack)),
                ArturiaLights.ID_NAVIGATION_RIGHT:
                ArturiaLights.AsOnOffByte(ui.getVisible(midi.widMixer)),
                ArturiaLights.ID_OCTAVE_PLUS:
                ArturiaLights.LED_OFF,
                ArturiaLights.ID_OCTAVE_MINUS:
                ArturiaLights.LED_OFF,
            }
            self._lights.SetLights(led_map)
            self._encoders.Refresh()

        # Update display
        channel_name = channels.getChannelName(channels.selectedChannel())
        pattern_number = patterns.patternNumber()
        pattern_name = patterns.getPatternName(pattern_number)
        update = (
            flags & (
                1024  # HW_Dirty_Patterns
                | 2048  # HW_Dirty_Tracks
                | 16384  # HW_Dirty_Names
                | 32  # HW_Dirty_FocusedWindow   (channel selection)
            )) > 0
        self._paged_display.SetPageLines(
            'main',
            line1='[%d:%d] %s' %
            (channels.selectedChannel() + 1, pattern_number, channel_name),
            line2='%s' % pattern_name,
            update=update)
示例#5
0
     def UpdateLEDs(self):

        if device.isAssigned():
            playstatus = [transport.isPlaying()]
            recstatus = [transport.isRecording()]
            loopstatus = [transport.getLoopMode()]
            metrostatus = [ui.isMetronomeEnabled()]
            prestatus = [ui.isPrecountEnabled()]
            quanstatus = [ui.getSnapMode()]
            mutestatusc = [channels.isChannelMuted(0)]
            solostatusc = [channels.isChannelSolo(0)]
            mutestatusm = [mixer.isTrackEnabled(mixer.trackNumber())]
            solostatusm = [mixer.isTrackSolo(mixer.trackNumber())]

            for a in playstatus:
              if a == 0: #not playing
                  KompleteDataOut(0x14, 0x01) #stop on

              elif a == 1: #playing
                  KompleteDataOut(0x14, 0x00) #stop off

            for b in recstatus:
               if b == 0: #not recording
                  KompleteDataOut(0x12, 0x00)

               elif b == 1: #recording
                  KompleteDataOut(0x12, 0x01)

            for c in loopstatus:
               if c == 0: #loop mood
                  KompleteDataOut(0x16, 0x00)

               elif c == 1: #playlist mode
                  KompleteDataOut(0x16, 0x01)

            for d in metrostatus:
               if d == 0: #metro off
                  KompleteDataOut(0x17, 0x00)

               elif d == 1: #metro on
                  KompleteDataOut(0x17, 0x01)

            for e in prestatus:
              if e == 0: #pre count on
                  KompleteDataOut(0x13, 0x00) 

              elif e == 1: #pre count off
                  KompleteDataOut(0x13, 0x01) 

            for f in quanstatus:
              if f == 3: #quantize off
                  KompleteDataOut(0x22, 0x00)

              elif f != 1: #quantize on
                  KompleteDataOut(0x22, 0x01)
    def handle_play_press(self, event, play):
        """ Put play press code here.
        """
        transport.start()
        if transport.isPlaying() == 1:
            self.output = "Transport: Play"
        else:
            self.output = "Transport: Paused at " + transport.getSongPosHint()
        self.set_hint_message(self.output)
        print("Pressed play button.")

        event.handled = True
    def Sync(self):
        """ Syncs up all visual indicators on keyboard with changes from FL Studio. """
        # Update buttons
        active_index = channels.selectedChannel()
        led_map = {
            ArturiaLights.ID_TRANSPORTS_RECORD: ArturiaLights.AsOnOffByte(transport.isRecording()),
            ArturiaLights.ID_TRANSPORTS_LOOP: ArturiaLights.AsOnOffByte(ui.isLoopRecEnabled()),
            ArturiaLights.ID_GLOBAL_METRO: ArturiaLights.AsOnOffByte(ui.isMetronomeEnabled()),
            ArturiaLights.ID_GLOBAL_SAVE: ArturiaLights.AsOnOffByte(transport.getLoopMode() == 1),
            ArturiaLights.ID_GLOBAL_UNDO: ArturiaLights.AsOnOffByte(general.getUndoHistoryLast() == 0),
            ArturiaLights.ID_TRACK_SOLO: ArturiaLights.AsOnOffByte(channels.isChannelSolo(active_index)),
            ArturiaLights.ID_TRACK_MUTE: ArturiaLights.AsOnOffByte(channels.isChannelMuted(active_index)),
            ArturiaLights.ID_TRANSPORTS_STOP: ArturiaLights.AsOnOffByte(not transport.isPlaying()),
            ArturiaLights.ID_TRANSPORTS_PLAY: ArturiaLights.AsOnOffByte(transport.getSongPos() > 0),
            ArturiaLights.ID_GLOBAL_OUT: ArturiaLights.AsOnOffByte(
                arrangement.selectionEnd() > arrangement.selectionStart()),
        }
        self._lights.SetLights(led_map)

        # Update selected channel
        bank_lights = [ArturiaLights.LED_OFF] * 9
        if active_index < len(bank_lights):
            bank_lights[active_index] = ArturiaLights.LED_ON
        self._lights.SetBankLights(bank_lights)

        # Update display
        channel_name = channels.getChannelName(active_index)
        pattern_number = patterns.patternNumber()
        pattern_name = patterns.getPatternName(pattern_number)

        # Update knob mode
        if self._encoders.GetCurrentMode() == ArturiaInputControls.INPUT_MODE_CHANNEL_PLUGINS:
            plugin_name = plugins.getPluginName(active_index) if plugins.isValid(active_index) else ''
            self._encoders.SetKnobMode(plugin_name)
            self._encoders.SetSliderMode(plugin_name)

        if channel_name.startswith('Analog Lab'):
            channel_name='Analog Lab'

        self._paged_display.SetPageLines(
            'main',
            line1='[%d:%d] %s' % (active_index + 1, pattern_number, channel_name),
            line2='%s' % pattern_name)
        self._encoders.Refresh()
 def Refresh(self):
     # Don't update lights if recording
     if not transport.isRecording() and not transport.isPlaying():
         self._update_lights()
示例#9
0
 def toggleLoopMode(self, note):
     if (transport.isPlaying() == 0
         ):  #Only toggle loop mode if not already playing
         transport.setLoopMode()
         print("Song/Pattern Mode toggled")
示例#10
0
 def toggleRecord(self, note):
     if (transport.isPlaying() == 0
         ):  # Only enable recording if not already playing
         transport.record()
         print("Toggle recording")
示例#11
0
    def updateLEDs(self):
        if device.isAssigned():
            # play button
            if transport.isPlaying() and transport.getLoopMode():
                self.updateLED(CONTROLS.BUTTONS.PLAY, COLORS.RGB.GREEN,
                               ANIMATIONS.BLINKING.QUARTER)
            elif transport.isPlaying():
                self.updateLED(CONTROLS.BUTTONS.PLAY, COLORS.RGB.ORANGE,
                               ANIMATIONS.BLINKING.QUARTER)
            else:
                self.updateLED(CONTROLS.BUTTONS.PLAY)

            # record button
            if transport.isRecording():
                self.updateLED(CONTROLS.BUTTONS.RECORD, COLORS.RGB.RED)
            else:
                self.updateLED(CONTROLS.BUTTONS.RECORD)

            # double loop [song/pattern] button
            if transport.getLoopMode():
                self.updateLED(CONTROLS.BUTTONS.DOUBLE_LOOP)
            else:
                self.updateLED(CONTROLS.BUTTONS.DOUBLE_LOOP, COLORS.BW.WHITE)

            # metronome button
            if ui.isMetronomeEnabled():
                self.updateLED(CONTROLS.BUTTONS.METRONOME, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.METRONOME)

            # device [channel rack] button
            if ui.getFocused(midi.widChannelRack):
                self.updateLED(CONTROLS.BUTTONS.DEVICE, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.DEVICE)

            # mix [mixer] button
            if ui.getFocused(midi.widMixer):
                self.updateLED(CONTROLS.BUTTONS.MIX, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.MIX)

            # clip [playlist] button
            if ui.getFocused(midi.widPlaylist):
                self.updateLED(CONTROLS.BUTTONS.CLIP, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.CLIP)

            # browse [browser] button
            # if ui.getFocused(midi.widBrowser):
            #     self.updateLED(CONTROLS.BUTTONS.BROWSE, COLORS.BW.WHITE)
            # else:
            #     self.updateLED(CONTROLS.BUTTONS.BROWSE)

            # layout button
            if ui.getFocused(midi.widPlaylist):
                if self.playlist.layout == LAYOUTS.PLAYLIST.PATTERNS:
                    self.updateLED(CONTROLS.BUTTONS.LAYOUT, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.LAYOUT)

            # quantize/snap button
            if ui.getSnapMode() != 3:
                self.updateLED(CONTROLS.BUTTONS.QUANTIZE, COLORS.BW.WHITE)
            else:
                self.updateLED(CONTROLS.BUTTONS.QUANTIZE)

            # numbered upper buttons
            for idx, button in enumerate(CONTROLS.BUTTONS_UPPER, 1):
                if ui.getFocused(midi.widMixer):
                    if (idx == self.mixer.encodersTarget):
                        self.updateLED(button, COLORS.RGB.WHITE)
                    else:
                        self.updateLED(button)
                elif ui.getFocused(midi.widChannelRack):
                    if (idx == self.channels.encodersTarget):
                        self.updateLED(button, COLORS.RGB.ORANGE)
                    else:
                        self.updateLED(button)
                elif ui.getFocused(midi.widPlaylist):
                    if (idx == self.playlist.encodersTarget):
                        self.updateLED(button, COLORS.RGB.GREEN)
                    else:
                        self.updateLED(button)
                else:
                    self.updateLED(button)

            # pads
            for idx, pad in enumerate(CONTROLS.PADS_64):
                self.updateLED(pad, 0)
                if ui.getFocused(midi.widMixer):
                    idx += 1  # do not include the master track (0)
                    if idx < mixer.trackCount():
                        self.updateLED(
                            pad, getClosestColor(mixer.getTrackColor(idx)))
                        if mixer.isTrackSelected(
                                idx) and not mixer.isTrackEnabled(idx):
                            self.updateLED(pad, COLORS.RGB.GREEN)
                            self.updateLED(pad, COLORS.RGB.RED,
                                           ANIMATIONS.BLINKING.HALF)
                        elif mixer.isTrackSelected(idx):
                            self.updateLED(pad, COLORS.RGB.GREEN)
                            self.updateLED(
                                pad, getClosestColor(mixer.getTrackColor(idx)),
                                ANIMATIONS.PULSING.HALF)
                        elif not mixer.isTrackEnabled(idx):
                            self.updateLED(pad, COLORS.RGB.RED,
                                           ANIMATIONS.PULSING.HALF)
                elif ui.getFocused(midi.widChannelRack):
                    if idx < channels.channelCount():
                        self.updateLED(
                            pad,
                            getClosestColor(channels.getChannelColor(idx)))
                        if channels.isChannelSelected(
                                idx) and not channels.isChannelMuted(
                                    idx):  # NOTE asked this bug to be fixed!
                            self.updateLED(pad, COLORS.RGB.GREEN)
                            self.updateLED(pad, COLORS.RGB.RED,
                                           ANIMATIONS.BLINKING.HALF)
                        elif channels.isChannelSelected(idx):
                            self.updateLED(pad, COLORS.RGB.GREEN)
                            self.updateLED(
                                pad,
                                getClosestColor(channels.getChannelColor(idx)),
                                ANIMATIONS.PULSING.HALF)
                        elif not channels.isChannelMuted(
                                idx):  # NOTE asked this bug to be fixed!
                            self.updateLED(pad, COLORS.RGB.RED,
                                           ANIMATIONS.PULSING.HALF)
                elif ui.getFocused(midi.widPlaylist):
                    idx += 1  # NOTE asked this bug to be fixed!
                    if idx <= patterns.patternCount():
                        # self.updateLED(pad, getClosestColor(patterns.getPatternColor(idx)))
                        # if patterns.isPatternSelected(idx) and not patterns.isPatternEnabled(idx):
                        #     self.updateLED(pad, COLORS.RGB.GREEN)
                        #     self.updateLED(pad, COLORS.RGB.RED, ANIMATIONS.BLINKING.HALF)
                        # elif patterns.isPatternSelected(idx):
                        #     self.updateLED(pad, COLORS.RGB.GREEN)
                        #     self.updateLED(pad, getClosestColor(patterns.getPatternColor(idx)), ANIMATIONS.PULSING.HALF)
                        # elif not patterns.isPatternEnabled(idx):
                        #     self.updateLED(pad, COLORS.RGB.RED, ANIMATIONS.PULSING.HALF)
                        if (idx == patterns.patternNumber()):
                            # self.updateLED(pad, getClosestColor(patterns.getPatternColor(idx)))
                            self.updateLED(pad, COLORS.RGB.GREEN)
                            self.updateLED(pad, COLORS.RGB.RED,
                                           ANIMATIONS.PULSING.HALF)
                        else:
                            self.updateLED(
                                pad,
                                getClosestColor(patterns.getPatternColor(idx)))
def TOnRefresh(HW_Dirty_LEDs):
    """ Wrapper for the OnRefresh thread. """
    # PLAY button
    if transport.isPlaying() == True:
        nihia.buttonSetLight("PLAY", 1)

    elif transport.isPlaying() == False:
        nihia.buttonSetLight("PLAY", 0)

    # STOP button
    if transport.isPlaying() == True:
        nihia.buttonSetLight("STOP", 0)

    elif transport.isPlaying() == False:
        nihia.buttonSetLight("STOP", 1)

    # REC button
    if transport.isRecording() == True:
        nihia.buttonSetLight("REC", 1)

    elif transport.isRecording() == False:
        nihia.buttonSetLight("REC", 0)

    # COUNT-IN button
    if ui.isPrecountEnabled() == True:
        nihia.buttonSetLight("COUNT_IN", 1)

    elif ui.isPrecountEnabled() == False:
        nihia.buttonSetLight("COUNT_IN", 0)

    # CLEAR button (moved to OnIdle, since OnRefresh isn't called when focused window changes)

    # LOOP button
    if ui.isLoopRecEnabled() == True:
        nihia.buttonSetLight("LOOP", 1)

    elif ui.isLoopRecEnabled() == False:
        nihia.buttonSetLight("LOOP", 0)

    # METRO button
    if ui.isMetronomeEnabled() == True:
        nihia.buttonSetLight("METRO", 1)

    elif ui.isMetronomeEnabled() == False:
        nihia.buttonSetLight("METRO", 0)

    # MUTE button
    if mixer.isTrackMuted(mixer.trackNumber()) == True:
        nihia.buttonSetLight("MUTE_SELECTED", 1)

    elif mixer.isTrackMuted(mixer.trackNumber()) == False:
        nihia.buttonSetLight("MUTE_SELECTED", 0)

    # SOLO button
    if mixer.isTrackSolo(mixer.trackNumber()) == True:
        nihia.buttonSetLight("SOLO_SELECTED", 1)

    elif mixer.isTrackSolo(mixer.trackNumber()) == False:
        nihia.buttonSetLight("SOLO_SELECTED", 0)

    # Update mixer but peak meters
    updateMixer()

    # Tell the device if a mixer track is selected or not
    # It enables the ability to control mixer tracks using the 4D Encoder on S-Series keyboards
    # Disabled due to lack of awareness on how it is enabled and disabled correctly
    # if ui.getFocused(midi.widMixer) == True:
    #     nihia.mixerSendInfoSelected("SELECTED", "GENERIC")
    #
    # if ui.getFocused(midi.widMixer) == False:
    #     nihia.mixerSendInfoSelected("SELECTED", "EMPTY")

    # Check if the selected plugin is a Komplete Kontrol instance
    if (plugins.isValid(
            channels.channelNumber()) == True):  # Checks if plugin exists
        # If it does, sends the instance ID
        if plugins.getPluginName(
                channels.channelNumber()) == "Komplete Kontrol":
            nihia.mixerSendInfo("KOMPLETE_INSTANCE",
                                0,
                                info=plugins.getParamName(
                                    0, channels.channelNumber()))

        # If it doesn't, tells the keyboard about it
        else:
            nihia.mixerSendInfo("KOMPLETE_INSTANCE", 0, info="")

    else:
        nihia.mixerSendInfo("KOMPLETE_INSTANCE", 0, info="")
def OnMidiIn(event):
    """ Wrapper for the OnMidiIn thread. """
    # Play button
    if event.data1 == nihia.buttons.get("PLAY"):
        event.handled = True
        transport.start()

    # Restart button
    elif event.data1 == nihia.buttons.get("RESTART"):
        event.handled = True
        transport.setLoopMode()

    # Record button
    elif event.data1 == nihia.buttons.get("REC"):
        event.handled = True
        transport.record()

    # Count-In button
    elif event.data1 == nihia.buttons.get("COUNT_IN"):
        event.handled = True

        # Defines the standard behaviour (just to toggle "Countdown before recording" on/off)
        if COUNT_IN_BEHAVIOUR == 0:
            transport.globalTransport(midi.FPT_CountDown, 1)

        # Defines behaviour of the button if the user chooses the Maschine-alike behaviour
        if COUNT_IN_BEHAVIOUR == 1:

            # Toggles recording on if it isn't enabled already
            if transport.isRecording() == 0:
                transport.record()

            # Toggles countdown before recording on if it isn't enabled already
            if ui.isPrecountEnabled() == 0:
                transport.globalTransport(midi.FPT_CountDown, 1)

            # Stops playback if FL Studio is playing
            if transport.isPlaying() == True:
                transport.stop()

            # Then turns playback on again. This time record and countdown before recording will be activated
            transport.start()

    # Stop button
    elif event.data1 == nihia.buttons.get("STOP"):
        event.handled = True
        transport.stop()

    # Clear button
    # This one in other DAWs (in Maschine, specifically) this button is meant to clear the MIDI clip you're
    # on so you can record again on it without having to use a mouse to delete all of the notes on the clip before
    # recording again
    #
    # However, since the MIDI API on FL Studio doesn't allow control over the piano roll specifically, for now it will only just
    # emulate the delete button (which does the same)
    elif event.data1 == nihia.buttons.get("CLEAR"):
        event.handled = True
        ui.delete()

    # Loop button (toggles loop recording on/off)
    elif event.data1 == nihia.buttons.get("LOOP"):
        event.handled = True
        transport.globalTransport(midi.FPT_LoopRecord, 1)

    # Metronome button
    elif event.data1 == nihia.buttons.get("METRO"):
        event.handled = True
        transport.globalTransport(midi.FPT_Metronome, 1)

    # Tempo button
    elif event.data1 == nihia.buttons.get("TEMPO"):
        event.handled = True
        transport.globalTransport(midi.FPT_TapTempo, 1)

    # Undo button
    elif event.data1 == nihia.buttons.get("UNDO"):
        event.handled = True
        general.undoUp()

    # Redo button
    elif event.data1 == nihia.buttons.get("REDO"):
        event.handled = True
        general.undo()

    # Quantize button
    # TODO: Not imlpemented yet in FL Studio MIDI API
    #
    # Instead, it changes between FL windows
    # TODO: The code is correctly written, but the ui.showWindow() method has a bug that causes the Piano roll and Browser windows not to
    # appear when invoked. It has been said it should be fixed in a future update.
    # -----------------------------------------------------------------------------------------------------------------------------------
    # if event.data1 == nihia.buttons.get("QUANTIZE"):
    #     global window
    #     window += 1

    #     if window <= 4:
    #         ui.showWindow(window)
    #         print("if reached")
    #     elif window > 4:
    #         window = 0
    #         ui.showWindow(window)
    # -----------------------------------------------------------------------------------------------------------------------------------
    #
    # Alternative implementation: Emulate the Fn buttons
    elif event.data1 == nihia.buttons.get("QUANTIZE"):
        event.handled = True
        global window2
        window2 += 1

        # Normal behaviour if the action ID is between the desired range
        if window2 <= 68 and window2 != 67:
            transport.globalTransport(window2, 1)

        # Skips the 67 value which calls the full screen plugin picker and calls the mixer instead
        elif window2 == 67:
            window2 += 1
            transport.globalTransport(window2, 1)

        # Once window value is out of range, it sets it again to the first value in range
        elif window2 > 68:
            window2 = 64
            transport.globalTransport(window2, 1)

    # Automation button
    # Enables and disables the recording automation events
    # TODO: Not implemented yet in FL Studio MIDI API
    #
    # Instead, it shows the full-screen plugin browser
    elif event.data1 == nihia.buttons.get("AUTO"):
        event.handled = True
        transport.globalTransport(midi.FPT_F8, 1)

    # Mute button - A-Series
    elif event.data1 == nihia.buttons.get("MUTE_SELECTED"):
        event.handled = True
        mixer.muteTrack(mixer.trackNumber())

    # Solo button - A-Series
    elif event.data1 == nihia.buttons.get("SOLO_SELECTED"):
        event.handled = True
        mixer.soloTrack(mixer.trackNumber())

    # Mute button - S-Series
    elif event.data1 == nihia.buttons.get("MUTE"):
        event.handled = True
        mixerMuteSoloHandler("MUTE", event.data2, mixer.trackNumber())

    # Solo button - S-Series
    elif event.data1 == nihia.buttons.get("SOLO"):
        event.handled = True
        mixerMuteSoloHandler("SOLO", event.data2, mixer.trackNumber())

    # 4D Encoder +
    elif event.data1 == nihia.buttons.get(
            "ENCODER_GENERAL") and event.data2 == nihia.buttons.get("PLUS"):
        event.handled = True

        # Mixer navigation (right)
        if ui.getFocused(midi.widMixer) == True:
            ui.right()

        # Playback jogging
        elif (ui.getFocused(midi.widPianoRoll) == True) or (ui.getFocused(
                midi.widPlaylist) == True):
            transport.setSongPos(
                transport.getSongPos(midi.SONGLENGTH_S) + 1, midi.SONGLENGTH_S)

        # General navigation
        else:
            ui.down()

    # 4D Encoder -
    elif event.data1 == nihia.buttons.get(
            "ENCODER_GENERAL") and event.data2 == nihia.buttons.get("MINUS"):
        event.handled = True

        # Mixer navigation
        if ui.getFocused(midi.widMixer) == True:
            ui.left()

        elif (ui.getFocused(midi.widPianoRoll) == True) or (ui.getFocused(
                midi.widPlaylist) == True):
            transport.setSongPos(
                transport.getSongPos(midi.SONGLENGTH_S) - 1, midi.SONGLENGTH_S)

        # General navigation
        else:
            ui.up()

    # 4D Encoder + (selected track volume)
    elif event.data1 == nihia.buttons.get(
            "ENCODER_VOLUME_SELECTED") and event.data2 == nihia.buttons.get(
                "PLUS"):
        event.handled = True
        mixer.setTrackVolume(mixer.trackNumber(),
                             mixer.getTrackVolume(mixer.trackNumber()) + 0.01)

    # 4D Encoder - (selected track volume)
    elif event.data1 == nihia.buttons.get(
            "ENCODER_VOLUME_SELECTED") and event.data2 == nihia.buttons.get(
                "MINUS"):
        event.handled = True
        mixer.setTrackVolume(mixer.trackNumber(),
                             mixer.getTrackVolume(mixer.trackNumber()) - 0.01)

    # 4D Encoder + (selected track pan)
    elif event.data1 == nihia.buttons.get(
            "ENCODER_PAN_SELECTED") and event.data2 == nihia.buttons.get(
                "PLUS"):
        event.handled = True
        mixer.setTrackPan(mixer.trackNumber(),
                          mixer.getTrackPan(mixer.trackNumber()) + 0.01)

    # 4D Encoder + (selected track pan)
    elif event.data1 == nihia.buttons.get(
            "ENCODER_PAN_SELECTED") and event.data2 == nihia.buttons.get(
                "MINUS"):
        event.handled = True
        mixer.setTrackPan(mixer.trackNumber(),
                          mixer.getTrackPan(mixer.trackNumber()) - 0.01)

    # 4D Encoder up
    elif event.data1 == encoderHandler(
            "Y") and event.data2 == nihia.buttons.get("UP"):
        event.handled = True
        ui.up()

    # 4D Encoder down
    elif event.data1 == encoderHandler(
            "Y") and event.data2 == nihia.buttons.get("DOWN"):
        event.handled = True
        ui.down()

    # 4D Encoder (using FPT because ui.left doesn't work on the playlist)
    elif event.data1 == encoderHandler(
            "X") and event.data2 == nihia.buttons.get("LEFT"):
        event.handled = True
        if ui.getFocused(midi.widMixer) == True:
            # This one doesn't move the mixer view as you get to the border
            # ----------------------------------------------------
            # mixer.setTrackNumber(mixer.trackNumber() - 1)
            # ----------------------------------------------------
            ui.left()

        else:
            ui.left()

    # 4D Encoder (using FPT because ui.right doesn't work on the playlist)
    elif event.data1 == encoderHandler(
            "X") and event.data2 == nihia.buttons.get("RIGHT"):
        event.handled = True
        if ui.getFocused(midi.widMixer) == True:
            # This one doesn't move the mixer view as you get to the border
            # ----------------------------------------------------
            # mixer.setTrackNumber(mixer.trackNumber() + 1)
            # ----------------------------------------------------
            ui.right()

        else:
            ui.right()

    # 4D Encoder button
    elif event.data1 == nihia.buttons.get("ENCODER_BUTTON"):
        event.handled = True
        ui.enter()

    # 4D Encoder button (shifted)
    elif event.data1 == nihia.buttons.get("ENCODER_BUTTON_SHIFTED"):
        event.handled = True
        transport.globalTransport(midi.FPT_Menu, 1)

    # Knobs
    # Normal knobs - increase values
    elif event.data1 == nihia.knobs.get(
            "KNOB_1A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(0, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_2A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(1, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_3A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(2, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_4A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(3, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_5A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(4, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_6A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(5, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_7A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(6, "VOLUME", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_8A") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(7, "VOLUME", "INCREASE", mixer.trackNumber())

    # Normal knobs - decrease values
    elif event.data1 == nihia.knobs.get(
            "KNOB_1A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(0, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_2A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(1, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_3A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(2, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_4A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(3, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_5A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(4, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_6A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(5, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_7A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(6, "VOLUME", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_8A") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(7, "VOLUME", "DECREASE", mixer.trackNumber())

    # Shifted knobs - increase values
    elif event.data1 == nihia.knobs.get(
            "KNOB_1B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(0, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_2B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(1, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_3B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(2, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_4B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(3, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_5B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(4, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_6B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        adjustMixer(5, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_7B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(6, "PAN", "INCREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_8B") and event.data2 == nihia.knobs.get("INCREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(7, "PAN", "INCREASE", mixer.trackNumber())

    # Shifted knobs - decrease values
    elif event.data1 == nihia.knobs.get(
            "KNOB_1B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(0, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_2B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(1, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_3B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(2, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_4B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(3, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_5B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(4, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_6B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        adjustMixer(5, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_7B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(6, "PAN", "DECREASE", mixer.trackNumber())

    elif event.data1 == nihia.knobs.get(
            "KNOB_8B") and event.data2 == nihia.knobs.get("DECREASE"):
        event.handled = True
        # Handles track group 15 exception
        if math.trunc(1 / 8 * mixer.trackNumber()) == 15:
            return
        else:
            adjustMixer(7, "PAN", "DECREASE", mixer.trackNumber())
    def OnRefresh(self, flags):

        if device.isAssigned():
            print("On Refresh")

            i = mixer.trackNumber()

            Volume = mixer.getTrackVolume(i)
            sVol = self.scaleValue(Volume, 1, 127)
            self.UpdateKnobs(self.KNOB.VOL, sVol)
            self.UpdateLEDs(self.KNOB.VOL, self.COLOR.BRIGHT_GREEN,
                            self.ANI.SOLID)

            Pan = 1 + (mixer.getTrackPan(i))
            sPan = self.scaleValue(Pan, 2, 127)
            self.UpdateKnobs(self.KNOB.PAN, sPan)

            if mixer.isTrackSolo(i):
                self.UpdateLEDs(self.BTN.SOLO, self.COLOR.GREEN_YELLOW,
                                self.ANI.PULSE)
            else:
                if (Pan < 1):
                    self.UpdateLEDs(self.KNOB.PAN, self.COLOR.YELLOW,
                                    self.ANI.SOLID)
                elif (Pan > 1):
                    self.UpdateLEDs(self.KNOB.PAN, self.COLOR.RED,
                                    self.ANI.SOLID)
                else:
                    self.UpdateLEDs(self.KNOB.PAN, self.COLOR.BRIGHT_GREEN,
                                    self.ANI.SOLID)

            if mixer.isTrackEnabled(i):
                self.UpdateLEDs(self.BTN.MUTE, self.COLOR.BRIGHT_GREEN,
                                self.ANI.SOLID)
            else:
                self.UpdateLEDs(self.BTN.MUTE, self.COLOR.GREEN_YELLOW,
                                self.ANI.PULSE)

            if mixer.isTrackArmed(i):
                self.UpdateLEDs(self.KNOB.VOL, self.COLOR.RED, self.ANI.PULSE)

            color = mixer.getTrackColor(i)

            if transport.isPlaying():
                self.UpdateLEDs(self.BTN.PLAY, self.COLOR.GREEN,
                                self.ANI.PULSE)
                self.UpdateLEDs(self.BTN.STOP, self.COLOR.GREEN,
                                self.ANI.SOLID)
            else:
                self.UpdateLEDs(self.BTN.PLAY, self.COLOR.DARK_BLUE,
                                self.ANI.SOLID)
                self.UpdateLEDs(self.BTN.STOP, self.COLOR.DARK_BLUE,
                                self.ANI.SOLID)

            if transport.isRecording():
                self.UpdateLEDs(self.BTN.RECORD, self.COLOR.RED,
                                self.ANI.PULSE)
            else:
                self.UpdateLEDs(self.BTN.RECORD, self.COLOR.YELLOW,
                                self.ANI.SOLID)

            if transport.getLoopMode():
                self.UpdateLEDs(self.BTN.LOOP_MODE, self.COLOR.BRIGHT_GREEN,
                                self.ANI.SOLID)
            else:
                self.UpdateLEDs(self.BTN.LOOP_MODE, self.COLOR.LIGHT_ORANGE,
                                self.ANI.SOLID)
示例#15
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)))