def OnIdle(self): # refresh meters if device.isAssigned(): f = False for m in range(0, len(self.ColT) - 1): self.ColT[m].Tag = utils.Limited(self.ColT[m].Peak, 0, self.MeterMax) self.ColT[m].Peak = 0 if self.ColT[m].Tag == 0: if self.ColT[m].ZPeak: continue else: self.ColT[m].ZPeak = True else: self.ColT[m].ZPeak = f device.midiOutMsg(midi.MIDI_CHANAFTERTOUCH + (self.ColT[m].Tag << 8) + (m << 12)) # temp message if self.TempMsgDirty: self.UpdateTempMsg() self.TempMsgDirty = False if (self.TempMsgCount > 0) & (self.SliderHoldCount <= 0) & (not ui.isInPopupMenu()): self.TempMsgCount -= 1 if self.TempMsgCount == 0: self.UpdateTempMsg()
def OnDeInit(): print("deinit") device.midiOutMsg(midi.MIDI_NOTEON + (25 << 8) + (0 << 16)) device.midiOutMsg(midi.MIDI_NOTEON + (26 << 8) + (0 << 16)) for i in range(0, 8): device.midiOutMsg(midi.MIDI_NOTEON + ((i * 3) + 1 << 8) + (0 << 16)) device.midiOutMsg(midi.MIDI_NOTEON + ((i * 3) + 2 << 8) + (0 << 16)) device.midiOutMsg(midi.MIDI_NOTEON + ((i * 3) + 3 << 8) + (0 << 16))
def UpdateLEDs(self, Index, Color, ANI): #print("Update LEDs") #print("LED Output: i=", Index," color=", Color," ANI=", ANI) device.midiOutMsg(1 + (midi.MIDI_CONTROLCHANGE) + (Index << 8) + (Color << 16)) device.midiOutMsg(5 + (midi.MIDI_CONTROLCHANGE) + (Index << 8) + (ANI << 16))
def OnInit(): global selectedBank #Make the selectedBank Variable selectedBank = 1 #Default the bank selector to 1 clearAllLEDs( ) #Clear LEDs that may have been left on by other programs force-closing device.midiOutMsg(0x90 + (0x40 << 8) + (0x01 << 16)) #Turn on the LED for bank 1 lightFPC( ) #Turn on the 4*4 matrix for the FPC controller in the top corner.
def UpdateKnobs(self, Index, Value): #print("Update KNOB") if (self.KNOB.PAN == Index): if (64 < Value < 65): Value = 65 if (64 > Value > 63): Value = 63 Value = int(Value) #print("Knob Output: i=", Index, ", val=", Value) device.midiOutMsg(0 + midi.MIDI_CONTROLCHANGE + (Index << 8) + (Value << 16))
def sendCompleteMidiMessage(message, str_event_out=""): """Sends a MIDI message to the controller, in completed form (as one int). Args: message (int): MIDI message str_event_out (str, optional): What to print about the message. Defaults to "". """ debugLog( "Dispatched external MIDI message " + str_event_out + " (" + str(message) + ")", consts.DEBUG.DISPATCH_EVENT) device.midiOutMsg(message)
def setPatchBank(bank): #This allows us to set the patch bank we are using global selectedBank #Makes the variable accessable everywhere if bank < 80: #See if we are in the bottom row selectedBank = bank - 63 #perform the expression needed to convert from midi to mixer channel data clearAllLEDs() #Clears the LEDs that are on lightFPC() #Reilluminates the FPC device.midiOutMsg(0x90 + (bank << 8) + (0x01 << 16)) #Turns on the appropriate LED if bank > 80: #See if we are in the side row selectedBank = bank - 73 #perform the expression needed to convert from midi to mixer channel data clearAllLEDs() #Clears all of the LEDs lightFPC() #Reilluminates the FPC device.midiOutMsg(0x90 + (bank << 8) + (0x01 << 16)) return selectedBank #Return the selected bank as an integer.
def updateLED(self, control, color=None, animation=0): if device.isAssigned(): control_type, control_name, control_id, control_note_or_color = control.split( ".") control_id = int(control_id) control_note_or_color = int(control_note_or_color) isRGB = bool(control_note_or_color) if color is None: if isRGB: color = COLORS.RGB.DARK_GRAY else: color = COLORS.BW.DARK_GRAY status = midi.MIDI_CONTROLCHANGE + animation if control_type == "Button" else midi.MIDI_NOTEON + animation data1 = eval(f"{hex(control_id)} << 8") data2 = eval(f"{hex(color)} << 16") device.midiOutMsg(status + data1 + data2)
def UpdateMeterMode(self): # force vertical (activity) meter mode for free controls page self.CurMeterMode = self.MeterMode if device.isAssigned(): #clear peak indicators for m in range(0, len(self.ColT) - 1): device.midiOutMsg(midi.MIDI_CHANAFTERTOUCH + (0xF << 8) + (m << 12)) # disable all meters for m in range (0, 8): device.midiOutSysex(bytes([0xF0, 0x00, 0x00, 0x66, 0x15, 0x20, m, 0, 0xF7])) # reset stuff if self.CurMeterMode > 0: self.TempMsgCount = -1 else: self.TempMsgCount = 500 // 48 + 1 self.EmptyLastMsgT() self.MeterMax = 0xD + int(self.CurMeterMode == 1) # $D for horizontal, $E for vertical meters self.ActivityMax = 0xD - int(self.CurMeterMode == 1) * 6 # meter split marks if self.CurMeterMode == 0: s2 = ''; for m in range(0, len(self.ColT) - 1): s2 = s2 + ' .' self.SendMsg(s2, 1); else: self.UpdateTextDisplay() if device.isAssigned(): # horizontal/vertical meter mode device.midiOutSysex(bytes([0xF0, 0x00, 0x00, 0x66, 0x15, 0x21, int(self.CurMeterMode > 0), 0xF7])) # enable all meters if self.CurMeterMode == 2: n = 1 else: n = 1 + 2; for m in range(0, 8): device.midiOutSysex(bytes([0xF0, 0x00, 0x00, 0x66, 0x15, 0x20, m, n, 0xF7]))
def setDrumStationaryColor(led, color): setLEDOff(led) device.midiOutMsg((led & 0xFFF0) + 0x9 + (color << 16))
def setStationaryGrayscaleColor(led, color): setLEDOff(led) device.midiOutMsg((led & 0xFFF0) + 0xF + (color << 16))
def setFaderMode(mode): device.midiOutMsg(0x000ABF + (mode << 16))
def setPotMode(mode): device.midiOutMsg(0x0009BF + (mode << 16))
def _feedback(self, value): device.midiOutMsg((0xB0 + self.channel) + (self.ccNumber << 8) + (value << 16)) self.last_feedback_value = value
def setLEDOff(led): device.midiOutMsg((led & 0xFFF0) + 0x0) device.midiOutMsg((led & 0xFFF0) + 0x1) device.midiOutMsg((led & 0xFFF0) + 0x2) device.midiOutMsg((led & 0xFFF0) + 0xF) device.midiOutMsg((led & 0xFFF0) + 0x9) device.midiOutMsg((led & 0xFFF0) + 0xA) device.midiOutMsg((led & 0xFFF0) + 0xB)
def lightFPC(): fpcpadsbase = [60, 52, 44, 36] for x in range(0, len(fpcpadsbase)): for y in range(0, 4): device.midiOutMsg(0x90 + (fpcpadsbase[x] + y << 8) + (ledColour(selectedColour) << 16))
def clearAllLEDs(): LEDNumber = 0 for LEDNumber in range(0, 89): device.midiOutMsg(0x90 + (LEDNumber << 8) + (0x00 << 16))
def sendMidiBytes(byte1, byte2, byte3): msg = byte1 + (byte2 << 8) + (byte3 << 16) #print(device.getName) device.midiOutMsg(msg)
def switch_moment(event): """handles momentary witch midi events""" if event.data1 == button["pad_mode_toggle"]: # This Rotates through pad modes - standard, step sequencer, pad to channel Switch.mode_toggle += 1 if Switch.mode_toggle == 4: Switch.mode_toggle = 0 print('Pad Mode: ' + mode[Switch.mode_toggle]) ui.setHintMsg(mode[Switch.mode_toggle]) elif event.midiId == 224: # pitch wheel Switch.pitch_num = event.data2 if Switch.shift_status == True: print(data.notes_list[int(mapvalues(Switch.pitch_num, 0, 11, 0, 244))]) elif event.data1 == button["play"]: transport.start() event.handled = True elif event.data1 == button["offset_range"]: Switch.offset_iter += 1 if Switch.offset_iter == 2: # 2 here will limit to 32 steps, knobs. Changing to 4 will allow up to 64 steps, knobs. Switch.offset_iter = 0 ui.setHintMsg("Offset Range: " + str(Switch.offset_iter)) elif event.data1 == button["stop"]: print('Stop') transport.stop() event.handled = True elif event.data1 == button["record"]: print('Record') transport.record() event.handled = True elif event.data1 == button["pattern_down"]: if ui.getFocused(5): print("Previous Preset") ui.previous() else: print('Pattern Down') transport.globalTransport(midi.FPT_PatternJog, -1) event.handled = True elif event.data1 == button["pattern_up"]: if ui.getFocused(5): print("Next Preset") ui.next() else: print('Pattern Up') transport.globalTransport(midi.FPT_PatternJog, 1) event.handled = True # Set mod wheel to control channels when channels focused and tracks when mixer elif event.data1 == button["mod_wheel"]: if ui.getFocused(0): mixer.setTrackNumber(int(mapvalues(event.data2, 0, 64, 0, 127))) ui.scrollWindow(midi.widMixer, mixer.trackNumber()) elif ui.getFocused(1): print("Channel Number: " + str(channels.selectedChannel())) channels.selectOneChannel(int(round(mapvalues(event.data2, channels.channelCount()-1, 0, 0, 127), 0))) elif event.data1 == 72: print(channels.getChannelColor(channels.selectedChannel())) Switch.color_num += 1 if Switch.color_num == len(colors): Switch.color_num = 0 if ui.getFocused(1): channels.setChannelColor(channels.selectedChannel(), colors[Switch.color_num]) elif ui.getFocused(0): mixer.setTrackColor(mixer.trackNumber(), colors[Switch.color_num]) event.handled = True elif event.data1 == button["enter"]: if ui.getFocused(4): print("Select Browser Item") ui.selectBrowserMenuItem() event.handled = True elif ui.getFocused(1): print("Mute Channel") channels.muteChannel(channels.selectedChannel()) elif ui.getFocused(0): print("Mute Track") mixer.muteTrack(mixer.trackNumber()) else: print('enter') ui.enter() event.handled = True elif event.data1 in range(59, 64) and config.PATTERN_JUMP_ON: # Sets jump to pattern patterns.jumpToPattern(event.data1 - 58) event.handled = True elif event.data1 in range(75, 80) and config.PATTERN_JUMP_ON: patterns.jumpToPattern(event.data1 - 69) event.handled = True elif event.data1 == button["solo"]: print('Solo') if ui.getFocused(0): mixer.soloTrack(mixer.trackNumber()) elif ui.getFocused(1): channels.soloChannel(channels.selectedChannel()) elif event.data1 == button["view_plugin_picker"]: print('View Plugin Picker') transport.globalTransport(midi.FPT_F8, 67) event.handled = True elif event.data1 == button["song_mode_toggle"]: print('Toggle Song and Pattern Mode') transport.setLoopMode() event.handled = True elif event.data1 == button["view_playlist"]: print('View Playlist') transport.globalTransport(midi.FPT_F5, 65) event.handled = True elif event.data1 == button["view_piano_roll"]: print('View Piano Roll') transport.globalTransport(midi.FPT_F7, 66) event.handled = True elif event.data1 == button["view_channel_rack"]: print('View Channel Rack') transport.globalTransport(midi.FPT_F6, 65) event.handled = True elif event.data1 == button["view_mixer"]: print('View Mixer') transport.globalTransport(midi.FPT_F9, 68) event.handled = True # Toggle through step parameter options - pitch, pan etc. No Shift control right now. elif event.data1 == button["step_parameter"]: if ui.getFocused(1) and Switch.mode_toggle == 1: print('Toggle Step Parameter') Switch.parameter += 1 if Switch.parameter == 7: Switch.parameter = 0 print(Switch.parameter) ui.setHintMsg(parameters[Switch.parameter]) elif ui.getFocused(0): Switch.mixer_num += 1 if Switch.mixer_num == 2: Switch.mixer_num = 0 print('Mixer Mode: ' + str(Switch.mixer_num)) ui.setHintMsg(mixer_choice[Switch.mixer_num]) event.handled = True elif event.data1 == button["open_channel_sampler"]: print('Open Sampler Channel') channels.showCSForm(channels.channelNumber(), -1) event.handled = True elif event.data1 == button["left"]: print('Left') ui.left() event.handled = True elif event.data1 == button["down"]: print('Down') ui.down() event.handled = True elif event.data1 == button["right"]: print('Right') ui.right() event.handled = True elif event.data1 == button["save"]: print('Save') transport.globalTransport(midi.FPT_Save, 92) # If mixer is open and mute mode selected, top row will mute respective track elif event.data1 == button["undo"]: print('Undo') transport.globalTransport(midi.FPT_Undo, 20) device.midiOutMsg(144, 1, 63, 80) event.handled = True elif event.data1 == button["escape"]: print('Escape') ui.escape() event.handled = True elif event.data1 == button["up"]: print('Up') ui.up() event.handled = True elif event.data1 == button["rotate_window"]: print('Rotate Window') ui.nextWindow() event.handled = True elif event.data1 == button["browser"]: print('Browser') if Switch.shift_status == False: if ui.getFocused(4): ui.hideWindow(4) event.handled = True else: ui.showWindow(4) ui.setFocused(4) event.handled = True elif event.data1 == button["step_rec"]: if ui.getFocused(0): mixer.armTrack(mixer.trackNumber()) print("Toggle Track Rec") else: transport.globalTransport(midi.FPT_StepEdit, 114) print('Step Record') event.handled = True elif event.data1 == button["quantize"]: print('quantize') channels.quickQuantize(channels.channelNumber()) event.handled = True elif event.data1 == button["link_chan"]: print('link channel') mixer.linkTrackToChannel(0) elif event.data1 == button["rand_steps"]: print("Random") print(f'Pitch Bend: {event.pitchBend}') for i in range(patterns.getPatternLength(patterns.patternNumber())): channels.setGridBit(channels.channelNumber(), i, 0) for z in range (patterns.getPatternLength(patterns.patternNumber())): y = num_gen() if y > ( Switch.pitch_num * 516): channels.setGridBit(channels.channelNumber(), z, 1) else: pass event.handled = True elif event.data1 == button["rand_notes"]: print("Randomize Notes") Switch.note_gen() event.handled = True
def sendMessage(message_bytes): (status, byte1, byte2) = message_bytes device.midiOutMsg(status + (byte1 << 8) + (byte2 << 16))
def Reset(self): if device.isAssigned(): device.midiOutMsg(0xB0) device.midiOutMsg(0x0300B0)
def sendMidiBytes(byte1, byte2, byte3): msg = byte1 + (byte2 << 8) + (byte3 << 16) device.midiOutMsg(msg)
def setDrumFlashingColor(led, color): setLEDOff(led) device.midiOutMsg((led & 0xFFF0) + 0xA + (color << 16))
def enableDAWMode(): device.midiOutMsg(0x7F0C9F)
def setDrumPulsingColor(led, color): setLEDOff(led) device.midiOutMsg((led & 0xFFF0) + 0xB + (color << 16))
def disableDAWMode(): device.midiOutMsg(0x000C9F)
def SendAssignmentMsg(self, Msg): s_ansi = Msg + chr(0) #AnsiString(Msg); if device.isAssigned(): for m in range(1, 3): device.midiOutMsg(midi.MIDI_CONTROLCHANGE + ((0x4C - m) << 8) + (ord(s_ansi[m]) << 16))
def setPadMode(mode): device.midiOutMsg(0x0003BF + (mode << 16))
def sendMidiCommand(self, note, colorCode): device.midiOutMsg(midi.MIDI_NOTEON + (note << 8) + (colorCode << 16))
def SetLaunchPixel(self, row, col, color): Key = (0x10 * row) + col device.midiOutMsg(midi.MIDI_NOTEON + (Key << 8) + (color << 16))