def displayTime(self):
     if transport.getLoopMode():
         timeText = arrangement.currentTimeHint(1,
                                                arrangement.currentTime(0))
     else:
         timeText = transport.getSongPosHint()
     self.lcdText(timeText, resetTimeDisplay=False)
 def OnTransportsPausePlay(self, event):
     debug.log('OnTransportsPausePlay', 'Dispatched', event=event)
     song_mode = transport.getLoopMode() == 1
     if song_mode:
         self._show_and_focus(midi.widPlaylist)
     else:
         self._show_and_focus(midi.widPianoRoll)
     transport.globalTransport(midi.FPT_Play, midi.FPT_Play, event.pmeFlags)
示例#3
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)
示例#4
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)
示例#5
0
 def add_time_marker(unused_param_value):
     """Add time marker"""
     window_active = ui.getVisible(midi.widPianoRoll) and ui.getFocused(
         midi.widPianoRoll)
     window_active |= ui.getVisible(midi.widPlaylist) and ui.getFocused(
         midi.widPlaylist)
     if not window_active:
         window = midi.widPlaylist if transport.getLoopMode(
         ) else midi.widPianoRoll
         ui.showWindow(window)
         ui.setFocused(window)
     Actions.fl_windows_shortcut('t', ctrl=1)
示例#6
0
    def redraw(self, lights):
        """Draws beat light onto top right pad

        Args:
            lights (LightMap): Lighting object during redraw
        """

        if transport.getLoopMode():
            bar_col = lightingconsts.BEAT_SONG_BAR
            beat_col = lightingconsts.BEAT_SONG_BEAT
        else:
            bar_col = lightingconsts.BEAT_PAT_BAR
            beat_col = lightingconsts.BEAT_PAT_BEAT

        if self.beat is 1: lights.setPadColour(8, 0, bar_col)  # Bar
        elif self.beat is 2: lights.setPadColour(8, 0, beat_col)  # Beat
示例#7
0
 def OnTransportsPausePlay(self, event):
     debug.log('OnTransportsPausePlay', 'Dispatched', event=event)
     if self._is_pressed(event):
         self._button_mode |= arturia_macros.PLAY_BUTTON
         self._button_hold_action_committed = False
     else:
         self._button_mode &= ~arturia_macros.PLAY_BUTTON
         if self._button_hold_action_committed:
             # Update event happened so do not process button release.
             return
         song_mode = transport.getLoopMode() == 1
         if config.ENABLE_PIANO_ROLL_FOCUS_DURING_RECORD_AND_PLAYBACK:
             if song_mode:
                 self._show_and_focus(midi.widPlaylist)
             else:
                 self._show_and_focus(midi.widPianoRoll)
         transport.globalTransport(midi.FPT_Play, midi.FPT_Play,
                                   event.pmeFlags)
    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()
示例#9
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)))
示例#10
0
 def _is_pattern_mode(self):
     return transport.getLoopMode() == 0
    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)
示例#12
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)))