def _setup_device(self): encoders = [ make_encoder(21 + index, 'Device_Control_%d' % index) for index in xrange(8) ] self._encoders = tuple(encoders) device = DeviceComponent(device_selection_follows_track_selection=True) device.name = 'Device_Component' self.set_device_component(device) device.set_parameter_controls(self._encoders) self._deviceonoff = self._control_factory.create_device_switch_button() device.set_on_off_button(self._deviceonoff)
def _setup_device_control(self): device_param_controls = [] for index in range(8): encoder = EncoderElement(MIDI_CC_TYPE, 0, 22 + index, Live.MidiMap.MapMode.absolute) device_param_controls.append(encoder) device = DeviceComponent() device.set_parameter_controls(tuple(device_param_controls)) self.set_device_component(device) device.set_on_off_button(ButtonElement(True, MIDI_CC_TYPE, 3, 51))
def _setup_device_control(self): is_momentary = True global device # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...) device = DeviceComponent() device.name = 'Audio Effect Rack' # Button on/off button_on_off = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_device_on_off) device.set_on_off_button(button_on_off) # Audio Effect Rack - 8 modulation controls device_parameter_controls = [] for index in range(8): device_parameter_controls.append(EncoderElement(MIDI_CC_TYPE, midi_channel, midi_device_controls[index], Live.MidiMap.MapMode.absolute)) device.set_parameter_controls(device_parameter_controls) self.set_device_component(device) self._device_selection_follows_track_selection = True # select automatically the device of the selected track
def init_device_params(self): device_param_controls = [] device_bank_buttons = [] for param in self.control_page_cc[:8]: self.rotary_encoder_potis[param] = EncoderElement( MIDI_CC_TYPE, 0, param, Live.MidiMap.MapMode.absolute) self.switch_encoder_buttons[param] = ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 1, param) self.rotary_encoder_potis[param].release_parameter() self.rotary_encoder_potis[param].send_value(0, True) self.rotary_encoder_potis[param].clear_send_cache() device_param_controls.append(self.rotary_encoder_potis[param]) device_bank_buttons.append(self.switch_encoder_buttons[param]) device = DeviceComponent() device.name = 'Device_Component' device.set_parameter_controls(tuple(device_param_controls)) device.set_bank_buttons(tuple(device_bank_buttons)) device.set_on_off_button(ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 1, 56)) self.set_device_component(device)
def init_device_params(self): device_param_controls = [] device_bank_buttons = [] for param in self.control_page_cc[:8]: self.rotary_encoder_potis[param] = EncoderElement( MIDI_CC_TYPE, 0, param, Live.MidiMap.MapMode.absolute) self.switch_encoder_buttons[param] = ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 1, param) self.rotary_encoder_potis[param].release_parameter() self.rotary_encoder_potis[param].send_value(0, True) self.rotary_encoder_potis[param].clear_send_cache() device_param_controls.append(self.rotary_encoder_potis[param]) device_bank_buttons.append(self.switch_encoder_buttons[param]) device = DeviceComponent() device.name = 'Device_Component' device.set_parameter_controls(tuple(device_param_controls)) device.set_bank_buttons(tuple(device_bank_buttons)) device.set_on_off_button( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 56)) self.set_device_component(device)
def _setup_transport_control(self): is_momentary = True # We'll only be using momentary buttons here transport = ShiftableTransportComponent( ) #Instantiate a Transport Component #addtransport = AddlTransportComponent() #Instantiate an AddlTransport Component device_param_controls = [] #effects_knob_cc = [16,20,24,28,17,21,25,29] effects_knob_cc = [17, 21, 25, 29, 18, 22, 26, 30] device = DeviceComponent() for index in range(8): device_param_controls.append( EncoderElement(MIDI_CC_TYPE, CHAN, effects_knob_cc[index], Live.MidiMap.MapMode.absolute)) device.set_parameter_controls(tuple(device_param_controls)) #self.set_device_component(device) #from apc device_bank_buttons = [] #device_param_controls = [] #device_buttons =[16,20,24,28,17,21,25,29]; device_buttons = [17, 21, 25, 29, 18, 22, 26, 30] bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Device_Lock_Button' ) #'Metronome_Button') for index in range(8): device_bank_buttons.append( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, device_buttons[index])) device_bank_buttons[-1].name = bank_button_labels[index] #ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index) #ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute) #ringed_encoder.set_ring_mode_button(ring_mode_button) #ringed_encoder.name = 'Device_Control_' + str(index) #ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button' #device_param_controls.append(ringed_encoder) device.name = 'Device_Component' device.set_bank_buttons(tuple(device_bank_buttons)) detail_view_toggler = DetailViewCntrlComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( device_bank_buttons[0]) device.set_on_off_button(device_bank_buttons[1]) detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3]) detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4]) device.set_lock_button( device_bank_buttons[7] ) #assign device lock to bank_button 8 (in place of metronome)... self.set_device_component(device) #detail_view_toggler.set_shift_button(self._shift_button) #from apc self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 37) """set up the buttons""" play_button = ButtonElement( is_momentary, MIDI_NOTE_TYPE, CHAN, 24 ) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 28) record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 32) nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 27) nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 23) # tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 19) redo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 19) undo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 20) play_button.name = 'Play_Button' stop_button.name = 'Stop_Button' record_button.name = 'Record_Button' nudge_up_button.name = 'Nudge_Up_Button' nudge_down_button.name = 'Nudge_Down_Button' # tap_tempo_button.name = 'Tap_Tempo_Button' redo_button.name = 'Redo_Button' undo_button.name = 'Undo_Button' transport.set_shift_button(self._shift_button) transport.set_play_button(play_button) transport.set_stop_button(stop_button) transport.set_record_button(record_button) transport.set_nudge_buttons(nudge_up_button, nudge_down_button) #addtransport.set_undo_button(undo_button) #addtransport.set_redo_button(redo_button) transport.set_tap_tempo_button(nudge_up_button) #shifted nudge transport.set_quant_toggle_button(device_bank_buttons[5]) transport.set_overdub_button(device_bank_buttons[6]) # transport.set_metronome_button(device_bank_buttons[7]) #transport.set_tempo_encoder(self.prehear_control) #shifted prehear bank_button_translator = ShiftableTranslatorComponent() bank_button_translator.set_controls_to_translate( tuple(device_bank_buttons)) bank_button_translator.set_shift_button(self._shift_button)
def _setup_transport_control(self): is_momentary = True # We'll only be using momentary buttons here transport = ShiftableTransportComponent() #Instantiate a Transport Component #addtransport = AddlTransportComponent() #Instantiate an AddlTransport Component device_param_controls = [] #effects_knob_cc = [16,20,24,28,17,21,25,29] effects_knob_cc = [17,21,25,29,18,22,26,30] device = DeviceComponent() for index in range(8): device_param_controls.append(EncoderElement(MIDI_CC_TYPE, CHAN, effects_knob_cc[index], Live.MidiMap.MapMode.absolute)) device.set_parameter_controls(tuple(device_param_controls)) #self.set_device_component(device) #from apc device_bank_buttons = [] #device_param_controls = [] #device_buttons =[16,20,24,28,17,21,25,29]; device_buttons =[17,21,25,29,18,22,26,30]; bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Device_Lock_Button') #'Metronome_Button') for index in range(8): device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, device_buttons[index])) device_bank_buttons[-1].name = bank_button_labels[index] #ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index) #ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute) #ringed_encoder.set_ring_mode_button(ring_mode_button) #ringed_encoder.name = 'Device_Control_' + str(index) #ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button' #device_param_controls.append(ringed_encoder) device.name = 'Device_Component' device.set_bank_buttons(tuple(device_bank_buttons)) detail_view_toggler = DetailViewCntrlComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0]) device.set_on_off_button(device_bank_buttons[1]) detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3]) detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4]) device.set_lock_button(device_bank_buttons[7]) #assign device lock to bank_button 8 (in place of metronome)... self.set_device_component(device) #detail_view_toggler.set_shift_button(self._shift_button) #from apc self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 37) """set up the buttons""" play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 24) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 28) record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 32) nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 27) nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 23) # tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 19) redo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 19) undo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 20) play_button.name = 'Play_Button' stop_button.name = 'Stop_Button' record_button.name = 'Record_Button' nudge_up_button.name = 'Nudge_Up_Button' nudge_down_button.name = 'Nudge_Down_Button' # tap_tempo_button.name = 'Tap_Tempo_Button' redo_button.name = 'Redo_Button' undo_button.name = 'Undo_Button' transport.set_shift_button(self._shift_button) transport.set_play_button(play_button) transport.set_stop_button(stop_button) transport.set_record_button(record_button) transport.set_nudge_buttons(nudge_up_button, nudge_down_button) #addtransport.set_undo_button(undo_button) #addtransport.set_redo_button(redo_button) transport.set_tap_tempo_button(nudge_up_button) #shifted nudge transport.set_quant_toggle_button(device_bank_buttons[5]) transport.set_overdub_button(device_bank_buttons[6]) # transport.set_metronome_button(device_bank_buttons[7]) #transport.set_tempo_encoder(self.prehear_control) #shifted prehear bank_button_translator = ShiftableTranslatorComponent() bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons)) bank_button_translator.set_shift_button(self._shift_button)
class EncoderDeviceComponent(ControlSurfaceComponent): __module__ = __name__ __doc__ = " Class representing encoder Device component " def __init__(self, mixer, device, parent): ControlSurfaceComponent.__init__(self) assert isinstance(mixer, MixerComponent) self._param_controls = None self._mixer = mixer self._buttons = [] self._lock_button = None self._last_mode = 0 self._is_locked = False self._ignore_buttons = False self._track = None self._strip = None self._parent = parent self._device = device self._alt_device = DeviceComponent() self._alt_device.name = 'Alt_Device_Component' self.song().add_appointed_device_listener(self._on_device_changed) def disconnect(self): self.song().remove_appointed_device_listener(self._on_device_changed) self._param_controls = None self._mixer = None self._buttons = None self._lock_button = None self._track = None self._strip = None self._parent = None self._device = None self._alt_device = None def update(self): pass #self._show_msg_callback("EncoderDeviceComponent update called") def set_controls_and_buttons(self, controls, buttons): assert ((controls == None) or (isinstance(controls, tuple) and (len(controls) == 8))) self._param_controls = controls assert ((buttons == None) or (isinstance(buttons, tuple)) or (len(buttons) == 4)) self._buttons = buttons self.set_lock_button(self._buttons[0]) if self._is_locked == True: self._alt_device.set_parameter_controls(self._param_controls) self._alt_device.set_bank_nav_buttons(self._buttons[2], self._buttons[3]) self._alt_device.set_on_off_button(self._buttons[1]) else: self.on_selected_track_changed() def _on_device_changed(self): if self.is_enabled(): if self._is_locked != True: selected_device = self.song().appointed_device self._alt_device.set_device(selected_device) self._setup_controls_and_buttons() def on_selected_track_changed(self): if self.is_enabled(): if self._is_locked != True: track = self.song().view.selected_track selected_device = track.view.selected_device self._alt_device.set_device(selected_device) self._setup_controls_and_buttons() def _setup_controls_and_buttons(self): if self._buttons != None and self._param_controls != None: if self._alt_device != None: self._alt_device.set_parameter_controls(self._param_controls) self._alt_device.set_bank_nav_buttons(self._buttons[2], self._buttons[3]) self._alt_device.set_on_off_button(self._buttons[1]) self._alt_device._on_on_off_changed() #self._rebuild_callback() def on_enabled_changed(self): self.update() def set_lock_button(self, button): assert ((button == None) or isinstance(button, ButtonElement)) if (self._lock_button != None): self._lock_button.remove_value_listener(self._lock_value) self._lock_button = None self._lock_button = button if (self._lock_button != None): self._lock_button.add_value_listener(self._lock_value) if self._is_locked: self._lock_button.turn_on() else: self._lock_button.turn_off() def _lock_value(self, value): assert (self._lock_button != None) assert (value != None) assert isinstance(value, int) if ((not self._lock_button.is_momentary()) or (value is not 0)): if self._ignore_buttons == False: if self._is_locked: self._is_locked = False self._lock_button.turn_off() self.on_selected_track_changed() else: self._is_locked = True self._lock_button.turn_on()
class LiveStrip_A(ControlSurface): #Control Surface is central base class. acts as container. __module__ = __name__ __doc__ = "Ableton Live control surface script for liveStrip A" def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True #non-throw-away variables ??? #self._suggested_input_port = 'LiveStrip' #??? #self._suggested_output_port = 'LiveStrip' #??? #self._control_is_with_automap = False #for buttons ??? mabye for user-defined mappings self._transport = None #setup a blank transport self._session = None #setup a blank session self._device = None #setup a blank device #self._is_locked = False #for device or track self.setup_button_control() #buttons first - important #self.setup_rotary_control() #then rotary encoders - important self.setup_transport_control() #then transport.. self.setup_session_control() #..then the rest self.setup_device_control() self.assign_button_control( ) #after everything is set up we can then assign the buttons to things. ref this for updating aswell ??? self._end_buttons[0].add_value_listener(self._bt0_value) self._end_buttons[1].add_value_listener(self._bt1_value) self._end_buttons[2].add_value_listener(self._bt2_value) self._end_buttons[3].add_value_listener(self._bt3_value) self.set_highlighting_session_component(self._session) self._suppress_session_highlight = False self.log_message("LiveStrip loaded") #def refresh_state(self): #nothing def disconnect(self): self._suppress_send_midi = True #clean up things self._end_buttons[0].remove_value_listener(self._bt0_value) self._end_buttons[1].remove_value_listener(self._bt1_value) self._end_buttons[2].remove_value_listener(self._bt2_value) self._end_buttons[3].remove_value_listener(self._bt3_value) #create entry in log file then do final control surface disconnect self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + " - LiveStrip disconnected") ControlSurface.disconnect(self) return None def setup_button_control(self): #setup the buttons on the end of the LiveStrip #but does not assign them #prob do something like enter menu mode by selecting 1 & 2 together, ..blink, confirm, ..then use buttons and knobs for selection. is_momentary = True #button setting (throw-away variable) self._end_buttons = [ ButtonElement(is_momentary, 0, settings.MIDI_CHANNEL, settings.END_NOTES[index]) for index in range(4) ] for index in range(4): #self._end_buttons[index] = ButtonElement(is_momentary, 0, settings.MIDI_CHANNEL, settings.END_NOTES[index]) self._end_buttons[index].name = settings.BUTTONS_MAP_LIST[ settings.END_BUTTONS_CURRENT[index]] #def setup_rotary_control(self): #setup the rotary encoders def setup_transport_control(self): #is_momentary = True #button setting (throw-away variable) self._transport = TransportComponent( ) #Instantiate a Transport Component #for index in range(4): #if settings.END_BUTTONS_CURRENT[index] == 4: #BUTTONS_MAP_LIST - play #self._transport.set_play_button(self._end_buttons[index]) #ButtonElement(is_momentary, msg_type, channel, identifier) #for index in range(4): #if settings.END_BUTTONS_CURRENT[index] == 5: #BUTTONS_MAP_LIST - stop #self._transport.set_stop_button(self._end_buttons[index]) def setup_session_control(self): #do i actually need session control ??? ...erm.. ...no, i don't think i do #num_tracks = 1 #8 columns (tracks) - see consts #num_scenes = 8 #8 rows (scenes) - see consts #(num_tracks, num_scenes) a session highlight ("red box") #self.session = SessionComponent(num_tracks,num_scenes) self._session = SessionComponent(settings.NUM_TRACKS, settings.NUM_SCENES) self._session.set_offsets(0, 0) def setup_device_control(self): #is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_param_controls = [] #for index in range(8): # device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) #if None not in device_param_controls: # self._device.set_parameter_controls(tuple(device_param_controls)) #self._device.set_on_off_button(self._note_map[DEVICEONOFF]) #have to hand this a button #for index in range(4): #if settings.END_BUTTONS_CURRENT[index] == 1: #BUTTONS_MAP_LIST - device lock #self._device.set_lock_button(self._end_buttons[index]) #watch out, this way could set several to be the same #for index in range(4): #if settings.END_BUTTONS_CURRENT[index] == 2: #BUTTONS_MAP_LIST - device onOff #self._device.set_on_off_button(self._end_buttons[index]) #watch out, this way could set several to be the same self.set_device_component(self._device) def assign_button_control(self): for index in range(4): self.assign_individual_button_control(index) def assign_individual_button_control(self, index): if settings.END_BUTTONS_CURRENT[ index] == 0: #BUTTONS_MAP_LIST - NONE, or internal to LiveStrip unit. #self._device.set_lock_button(self._end_buttons[index]) #watch out, this way could set several to be the same do_nothing = True elif settings.END_BUTTONS_CURRENT[ index] == 1: #BUTTONS_MAP_LIST - play self._transport.set_play_button( self._end_buttons[index] ) #ButtonElement(is_momentary, msg_type, channel, identifier) elif settings.END_BUTTONS_CURRENT[ index] == 2: #BUTTONS_MAP_LIST - stop self._transport.set_stop_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[ index] == 3: #BUTTONS_MAP_LIST - device lock self._device.set_lock_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[ index] == 4: #BUTTONS_MAP_LIST - device on off self._device.set_on_off_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[index] == 5: #BUTTONS_MAP_LIST - ??? #self._device.set_on_off_button(self._end_buttons[index]) do_nothing = False self._end_buttons[index].name = settings.BUTTONS_MAP_LIST[ settings.END_BUTTONS_CURRENT[index]] #set the name def _bt0_value(self, value): #callback when bt0 is triggered assert value in range(128) self.button_trigger(0, value) self.log_message("_bt0_value triggered %d" % (value)) def _bt1_value(self, value): #callback when bt1 is triggered assert value in range(128) self.button_trigger(1, value) self.log_message("_bt1_value triggered %d" % (value)) def _bt2_value(self, value): #callback when bt2 is triggered assert value in range(128) self.button_trigger(2, value) self.log_message("_bt2_value triggered %d" % (value)) def _bt3_value(self, value): #callback when bt3 is triggered assert value in range(128) self.button_trigger(3, value) self.log_message("_bt3_value triggered %d" % (value)) def button_trigger(self, index, value): if settings.END_BUTTONS_CURRENT[ index] == 0: #BUTTONS_MAP_LIST - NONE, or internal to LiveStrip unit. #self._device.set_lock_button(self._end_buttons[index]) #watch out, this way could set several to be the same do_nothing = True elif settings.END_BUTTONS_CURRENT[ index] == 1: #BUTTONS_MAP_LIST - play if (value != 0): do_nothing = False #self._play_button.turn_on() else: do_nothing = True #self._play_button.turn_off() elif settings.END_BUTTONS_CURRENT[ index] == 2: #BUTTONS_MAP_LIST - stop self._transport.set_stop_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[ index] == 3: #BUTTONS_MAP_LIST - device lock self._device.set_lock_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[ index] == 4: #BUTTONS_MAP_LIST - device on off self._device.set_on_off_button(self._end_buttons[index]) elif settings.END_BUTTONS_CURRENT[index] == 5: #BUTTONS_MAP_LIST - ??? #self._device.set_on_off_button(self._end_buttons[index]) do_nothing = False
class MPD_CZ(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._device_selection_follows_track_selection = True with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True self._control_is_with_automap = False is_momentary = True self._suggested_input_port = 'Akai MPD26' self._suggested_output_port = 'Akai MPD26' self.log("BEFORE mixer") self._setup_mixer_control() self._setup_device_control() # self.clipcontrol(8) self.log("AFTER MIXER") """SESSION ViEW""" global session session = SessionComponent(GRIDSIZE[0], GRIDSIZE[1]) session.name = 'Session_Control' matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' up_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, UP_BUTTON) down_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, DOWN_BUTTON) left_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, LEFT_BUTTON) right_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, RIGHT_BUTTON) # session.set_scene_bank_buttons(down_button, up_button) #enabling these and disabling the below zoom buttons will move one scene/track per button press # session.set_track_bank_buttons(right_button, left_button) # session_zoom = SessionZoomingComponent(session) session_zoom.set_nav_buttons( up_button, down_button, left_button, right_button ) #these make it so you move the maximum number of scenes/tracks per button press. much more useful than moving by single scenes/tracks session_stop_buttons = [] for row in range(GRIDSIZE[0]): button_row = [] scene = session.scene(row) scene.name = 'Scene_' + str(row) scene.set_launch_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, SCENE_BUTTONS[row])) scene.set_triggered_value(2) session_stop_buttons.append( (ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, TRACK_STOPS[row]))) for column in range(GRIDSIZE[1]): button = ConfigurableButtonElement( True, MIDI_NOTE_TYPE, CHANNEL, LAUNCH_BUTTONS[row][column]) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) clip_slot = scene.clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) clip_slot.set_launch_button(button) matrix.add_row(tuple(button_row)) self._suppress_session_highlight = False self._suppress_send_midi = False self.set_highlighting_session_component(session) session.set_mixer(mixer) session.set_stop_track_clip_buttons(tuple(session_stop_buttons)) def log(self, message): sys.stderr.write("LOG: " + message.encode("utf-8")) def _setup_mixer_control(self): num_tracks = GRIDSIZE[ 1] # Here we define the mixer width in tracks (a mixer has only one dimension) global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...) mixer = MixerComponent( num_tracks) #(num_tracks, num_returns, with_eqs, with_filters) mixer.set_track_offset( 0) #Sets start point for mixer strip (offset from left) """set up the mixer buttons""" self.song().view.selected_track = mixer.channel_strip(0)._track #master_volume_control = SliderElement(MIDI_CC_TYPE, 1, 17) for index in range(GRIDSIZE[1]): mixer.channel_strip(index).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, MIX_FADERS[index])) mixer.channel_strip(index).set_arm_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, ARM_BUTTONS[index])) #sets the record arm button mixer.channel_strip(index).set_solo_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, SOLO_BUTTONS[index])) mixer.channel_strip(index).set_mute_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, MUTE_BUTTONS[index])) mixer.channel_strip(index).set_select_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, TRACK_SELECTS[index])) """TRANSPORT CONTROLS""" stop_button = ButtonElement(False, MIDI_CC_TYPE, 0, STOP_BUTTON) play_button = ButtonElement(False, MIDI_CC_TYPE, 0, PLAY_BUTTON) record_button = ButtonElement(False, MIDI_CC_TYPE, 0, RECORD_BUTTON) transport = TransportComponent() transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_overdub_button(record_button) transport.set_overdub_button(record_button) transport.set_seek_buttons( ButtonElement(False, MIDI_CC_TYPE, 0, SEEK_LEFT), ButtonElement(False, MIDI_CC_TYPE, 0, SEEK_RIGHT)) def _setup_device_control(self): is_momentary = True self._device = DeviceComponent() self._channelstrip = ChannelStripComponent() self._device.name = 'Device_Component' device_param_controls = [] for index in range(8): device_param_controls.append( SliderElement(MIDI_CC_TYPE, CHANNEL, MACRO_CONTROLS[index])) self._device.set_parameter_controls(device_param_controls) self._device.set_on_off_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, DEVICE_ON)) self._device.set_lock_button( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, DEVICE_LOCK)) self.set_device_component(self._device) self._device_nav = DeviceNavComponent() self._device_nav.set_device_nav_buttons( ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, PREVIOUS_DEVICE), ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, NEXT_DEVICE)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks) def disconnect(self): """clean things up on disconnect""" ControlSurface.disconnect(self) return None
class NanoKontrolShift(ControlSurface): __module__ = __name__ __doc__ = " NanoKontrolShift controller script " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._suppress_session_highlight = True self._suppress_send_midi = True # Turn off rebuild MIDI map until after we're done setting up self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method. with self.component_guard(): # OBJECTS self.session = None #session object self.mixer = None #mixer object self.view = None #clip/device view object self.device = None #device object self.transport = None #transport object # MODES self._shift_button = None self._shift_button_pressed = False self._alt_button = None self._alt_button_pressed = False self._ctrl_button = None self._ctrl_button_pressed = False # INITIALIZE MIXER, SESSIONS self._setup_session_control() # Setup the session object self._setup_mixer_control() # Setup the mixer object self._setup_view_control() # Setup the clip/view toggler self.session.set_mixer(self.mixer) # Bind mixer to session self._setup_device_control() # Setup the device object self._setup_transport_control() # Setup transport object self.set_device_component(self.device) # Bind device to control surface # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS self._set_modifiers_buttons() self.__update_matrix() # self.set_highlighting_session_component(self.session) for component in self.components: component.set_enabled(True) # self._suppress_session_highlight = True self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up def _setup_session_control(self): self.show_message("#################### SESSION: ON ##############################") is_momentary = True # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX self.session = SessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes) self.session.set_offsets(0, 0) # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up)) # self.session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left)) # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead... def _setup_mixer_control(self): is_momentary = True #CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON) self.mixer = SpecialMixerComponent(num_tracks, 0, False, False) # 4 tracks, 2 returns, no EQ, no filters self.mixer.name = 'Mixer' self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) def _setup_view_control(self): # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE self.view = ViewTogglerComponent(num_tracks, self) def _setup_device_control(self): # CREATE DEVICE TO ASSIGN PARAMETERS BANK self.device = DeviceComponent() self.device.name = 'Device_Component' def _setup_transport_control(self): # CREATE TRANSPORT DEVICE self.transport = SpecialTransportComponent(self) def _on_selected_scene_changed(self): # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track if (track.devices is not None): self._ignore_track_selection = True device_to_select = track.devices[0] self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) self._ignore_track_selection = False """ LED ON, OFF, FLASH WITH SESSION CLIPS """ # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES def __update_matrix(self): for scene_index in range(num_scenes): scene = self.session.scene(scene_index) for track_index in range(num_tracks): clip_slot = scene.clip_slot(track_index) button = clip_slot._launch_button_value.subject value_to_send = -1 if clip_slot._clip_slot != None: if clip_slot.has_clip(): value_to_send = 127 if clip_slot._clip_slot.clip.is_triggered: if clip_slot._clip_slot.clip.will_record_on_start: value_to_send = clip_slot._triggered_to_record_value else: value_to_send = clip_slot._triggered_to_play_value ''' elif clip_slot._clip_slot.clip.is_playing: if clip_slot._clip_slot.clip.is_recording: value_to_send = 127 ######### CLIPS PLAYING WILL FLASH for i in range(2000): if i % 50 == 0: button.send_value(127) else: button.send_value(0) else: for i in range(2000): if i % 50 == 0: button.send_value(127) else: button.send_value(0) ''' elif clip_slot._clip_slot.is_triggered: if clip_slot._clip_slot.will_record_on_start: value_to_send = clip_slot._triggered_to_record_value else: value_to_send = clip_slot._triggered_to_play_value elif clip_slot._clip_slot.is_playing: if clip_slot._clip_slot.is_recording: value_to_send = clip_slot._recording_value else: value_to_send = clip_slot._started_value elif clip_slot._clip_slot.controls_other_clips: value_to_send = 0 ''' if value_to_send in range(128): button.send_value(value_to_send) else: button.turn_off() ''' """ MODIFIERS, MODES, KEYS CONFIG """ #MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS def _clear_controls(self): # TURNING OFF ALL LEDS IN MATRIX self._turn_off_matrix() # SESSION resetsend_controls = [] self.mixer.send_controls = [] for scene_index in range(num_scenes): scene = self.session.scene(scene_index) scene.set_launch_button(None) for track_index in range(num_tracks): clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(None) self.session.set_stop_track_clip_buttons(None) self.session.set_stop_all_clips_button(None) # REMOVE LISTENER TO SESSION MOVES if self.session.offset_has_listener(self.__update_matrix): self.session.remove_offset_listener(self.__update_matrix) self.session.set_stop_all_clips_button(None) # MIXER self.mixer._set_send_nav(None, None) for track_index in range(num_tracks): strip = self.mixer.channel_strip(track_index) strip.set_solo_button(None) strip.set_mute_button(None) strip.set_arm_button(None) resetsend_controls.append(None) strip.set_select_button(None) for i in range(12): self.mixer.send_controls.append(None) strip.set_send_controls(tuple(self.mixer.send_controls)) self.mixer.set_resetsend_buttons(tuple(resetsend_controls)) # VIEW self.view.set_device_nav_buttons(None, None) detailclip_view_controls = [] for track_index in range(num_tracks): detailclip_view_controls.append(None) self.view.set_buttons(tuple(detailclip_view_controls)) # DEVICE PARAMETERS device_param_controls = [] self.device.set_parameter_controls(tuple(device_param_controls)) self.device.set_on_off_button(None) self.device.set_lock_button(None) # TRANSPORT self.transport.set_stop_button(None) self.transport.set_play_button(None) self.transport.set_record_button(None) self.transport._set_quant_toggle_button(None) self.transport.set_metronome_button(None) self.transport._set_tempo_buttons(None, None) self.log_message("Controls Cleared") def _set_normal_mode(self): is_momentary = True self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down)) for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.name = 'Mixer_ChannelStrip_' + str(index) self.mixer._update_send_index(self.mixer.sends_index) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_volumefader_cc[index])) self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute) strip.set_send_controls(tuple(self.mixer.send_controls)) strip._invert_mute_feedback = True ### SET ARM, SOLO, MUTE for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.set_send_controls(tuple(self.mixer.send_controls)) strip.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index])) strip.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index])) strip.set_arm_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index])) # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc)) for i in range(12): self.mixer.send_controls.append(None) self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute) strip.set_send_controls(tuple(self.mixer.send_controls)) strip._invert_mute_feedback = True self.mixer._update_send_index(self.mixer.sends_index) def _set_alt_mode(self): is_momentary = True self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down)) stop_track_controls = [] resetsend_controls = [] button = None buttons = None # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.set_select_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_select_cc[index])) button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, stop_track_cc[index]) stop_track_controls.append(button) buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_resetsend_cc[index]) resetsend_controls.append(buttons) self.session.set_stop_track_clip_buttons(tuple(stop_track_controls)) self.mixer.set_resetsend_buttons(tuple(resetsend_controls)) self.mixer._update_send_index(self.mixer.sends_index) def _set_ctrl_mode(self): # CLIP/DEVICE VIEW TOGGLE is_momentary = True self.view.set_device_nav_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_right_cc)) button = None detailclip_view_controls = [] for index in range(num_tracks): button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, detailclip_view_cc[index]) detailclip_view_controls.append(button) self.view.set_buttons(tuple(detailclip_view_controls)) # DEVICE ON/OFF, LOCK AND PARAMETERS device_param_controls = [] onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, onoff_device_cc) setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, lock_device_cc) for index in range(num_tracks): knob = None knob = EncoderElement(MIDI_CC_TYPE, CHANNEL, device_param_cc[index], Live.MidiMap.MapMode.absolute) device_param_controls.append(knob) if None not in device_param_controls: self.device.set_parameter_controls(tuple(device_param_controls)) self.device.set_on_off_button(onoff_control) self.device.set_lock_button(setlock_control) # TRANSPORT # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc)) # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc)) # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc)) self.transport._set_quant_toggle_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_quantization_cc)) self.transport.set_metronome_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_metronome_cc)) self.transport._set_tempo_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempodown_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempoup_cc)) # SESSION STOP ALL CLIPS AND SCENE LAUNCH self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_stopall_cc)) for index in range(num_scenes): self.session.scene(index).set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_scenelaunch_cc[index])) def _set_modifiers_buttons(self): is_momentary = True self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, shift_mod) self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, alt_mod) self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, ctrl_mod) if (self._shift_button != None): self._shift_button.add_value_listener(self._shift_value) if (self._alt_button != None): self._alt_button.add_value_listener(self._alt_value) if (self._ctrl_button != None): self._ctrl_button.add_value_listener(self._ctrl_value) #INIT NORMAL MODE self._manage_modes(0) # MODIFIERS LISTENERS FUNCS ARE HERE def _shift_value(self, value): assert isinstance(value, int) assert isinstance(self._shift_button, ButtonElement) if value == 127: if self._shift_button_pressed is False: self._unpress_modes() self._shift_button_pressed = True self._manage_modes(0) def _alt_value(self, value): assert isinstance(value, int) assert isinstance(self._alt_button, ButtonElement) if value == 127: if self._alt_button_pressed is False: self._unpress_modes() self._alt_button_pressed = True self._manage_modes(2) def _ctrl_value(self, value): assert isinstance(value, int) assert isinstance(self._ctrl_button, ButtonElement) if value == 127: if self._ctrl_button_pressed is False: self._unpress_modes() self._ctrl_button_pressed = True self._manage_modes(3) def _manage_modes(self, mode_index): if mode_index == 0: self._clear_controls() self._set_normal_mode() # self._shift_button.turn_on() self._alt_button.turn_on() self._ctrl_button.turn_on() self.log_message("NORMAL ON") elif mode_index == 2: self._clear_controls() self._set_alt_mode() self._alt_button.turn_on() self._shift_button.turn_off() self._ctrl_button.turn_off() self.log_message("ALT ON") elif mode_index == 3: self._clear_controls() self._set_ctrl_mode() self._ctrl_button.turn_on() self._shift_button.turn_off() self._alt_button.turn_off() self.log_message("CTRL ON") def _unpress_modes(self): self._shift_button_pressed = False self._alt_button_pressed = False self._ctrl_button_pressed = False def _turn_off_matrix(self): for index in range(24): self._send_midi(tuple([176,index+16,0])) def disconnect(self): """clean things up on disconnect""" self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log closed =--------------") #Create entry in log file self._clear_controls() self.session = None self.mixer = None self.view = None self.device = None self.transport = None # MODES self._shift_button = None self._alt_button = None self._ctrl_button = None # SENDS self.send_button_up = None self.send_button_down = None self.send_controls = [] self.send_reset = [] self.set_device_component(None) ControlSurface.disconnect(self) return None
class nocturn_CZ(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._device_selection_follows_track_selection = True with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True self._control_is_with_automap = False is_momentary = True self._suggested_input_port = 'Akai MPK26' self._suggested_output_port = 'Akai MPK26' self.log("BEFORE mixer") self._setup_mixer_control() self._setup_device_control() # self.clipcontrol(8) self.log("AFTER MIXER") """SESSION ViEW""" global session session = SessionComponent(GRIDSIZE[0],GRIDSIZE[1]) session.name = 'Session_Control' matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' up_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_MIXER, UP_BUTTON) down_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_MIXER, DOWN_BUTTON) left_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_MIXER, LEFT_BUTTON) right_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_MIXER, RIGHT_BUTTON) session.set_scene_bank_buttons(down_button, up_button) session.set_track_bank_buttons(right_button, left_button) # session_zoom = SessionZoomingComponent(session) # session_zoom.set_nav_buttons(up_button,down_button,left_button,right_button) session_stop_buttons = [] self.log("SETTING UP GRID") for row in xrange(GRIDSIZE[1]): button_row = [] self.log("CZ ROW") self.log(str(row)) scene = session.scene(row) scene.name = 'Scene_' + str(row) scene.set_launch_button(ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL, SCENE_BUTTONS[row])) scene.set_triggered_value(2) for column in xrange(GRIDSIZE[0]): self.log("CZ COLUMN") self.log(str(column)) button = ConfigurableButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_MIXER, LAUNCH_BUTTONS[row][column]) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) clip_slot = scene.clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) clip_slot.set_launch_button(button) matrix.add_row(tuple(button_row)) for column in xrange(GRIDSIZE[0]): session_stop_buttons.append((ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_MIXER, TRACK_STOPS[column]))) self._suppress_session_highlight = False self._suppress_send_midi = False self.set_highlighting_session_component(session) session.set_stop_track_clip_buttons(tuple(session_stop_buttons)) session.set_mixer(mixer) def log(self, message): sys.stderr.write("LOG: " + message.encode("utf-8")) def _setup_mixer_control(self): num_tracks = GRIDSIZE[0] # Here we define the mixer width in tracks (a mixer has only one dimension) global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...) mixer = MixerComponent(num_tracks) #(num_tracks, num_returns, with_eqs, with_filters) mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) """set up the mixer buttons""" self.song().view.selected_track = mixer.channel_strip(0)._track master = mixer.master_strip() master.set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, MASTER_VOLUME)) mixer.set_prehear_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, PREHEAR)) for index in xrange(GRIDSIZE[0]): mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, MIX_FADERS[index])) # mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_INST, MIX_FADERS[index])) mixer.channel_strip(index).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, PAN_CONTROLS[index])) mixer.channel_strip(index).set_arm_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, ARM_BUTTONS[index])) #sets the record arm button mixer.channel_strip(index).set_solo_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, SOLO_BUTTONS[index])) mixer.channel_strip(index).set_mute_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, MUTE_BUTTONS[index])) mixer.channel_strip(index).set_select_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, TRACK_SELECTS[index])) mixer.channel_strip(index).set_send_controls([SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][0]), SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][1]), SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][2]), SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][3])]) """TRANSPORT CONTROLS""" stop_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL_MIXER, STOP_BUTTON) play_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL_MIXER, PLAY_BUTTON) record_button = ButtonElement(False,MIDI_CC_TYPE,CHANNEL_MIXER,RECORD_BUTTON) overdub_button = ButtonElement(False,MIDI_CC_TYPE,CHANNEL_MIXER,OVERDUB_BUTTON) transport = TransportComponent() transport.TEMPO_TOP = 188 transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_overdub_button(overdub_button) transport.set_record_button(record_button) transport.set_seek_buttons(ButtonElement(False,MIDI_CC_TYPE,0,SEEK_LEFT),ButtonElement(False,MIDI_CC_TYPE,0,SEEK_RIGHT)) transport.set_tempo_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, TEMPO)) transport.set_metronome_button(ButtonElement(False,MIDI_CC_TYPE,CHANNEL_USER, METRONOME)) transport.set_tap_tempo_button(ButtonElement(False,MIDI_CC_TYPE,CHANNEL_USER,TAP_TEMPO)) def _setup_device_control(self): is_momentary = True self._device = DeviceComponent() self._channelstrip = ChannelStripComponent() self._device.name = 'Device_Component' device_param_controls = [] for index in range(8): device_param_controls.append(SliderElement(MIDI_CC_TYPE, CHANNEL_FX, MACRO_CONTROLS[index])) self._device.set_parameter_controls(device_param_controls) self._device.set_on_off_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, DEVICE_ON)) self._device.set_lock_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, DEVICE_LOCK)) # self._device.set_bank_down_value(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, DEVICE_LOCK)) # self._device.set_bank_up_value(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, DEVICE_ON)) up_bank_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, DEVICE_BANK_UP) down_bank_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, DEVICE_BANK_DOWN) # self._device.set_bank_buttons(down_bank_button, up_bank_button) self.set_device_component(self._device) self._device_nav = DeviceNavComponent() self._device_nav.set_device_nav_buttons(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, PREVIOUS_DEVICE),ButtonElement(True, MIDI_CC_TYPE, CHANNEL_FX, NEXT_DEVICE)) self._device.set_bank_prev_button(down_bank_button) self._device.set_bank_next_button(up_bank_button) # self._track_controller = self.register_component(TrackControllerComponent(control_surface = ControlSurface, implicit_arm = False)) # self.set_next_track_button(ButtonElement()) # self.set_next_track_button(ButtonElement()) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks) def disconnect(self): """clean things up on disconnect""" ControlSurface.disconnect(self) return None
class EncoderDeviceComponent(ControlSurfaceComponent): __module__ = __name__ __doc__ = " Class representing encoder Device component " def __init__(self, mixer, device, parent): ControlSurfaceComponent.__init__(self) assert isinstance(mixer, MixerComponent) self._param_controls = None self._mixer = mixer self._buttons = [] self._lock_button = None self._last_mode = 0 self._is_locked = False self._ignore_buttons = False self._track = None self._strip = None self._parent = parent self._device = device self._alt_device = DeviceComponent() self._alt_device.name = 'Alt_Device_Component' self.song().add_appointed_device_listener(self._on_device_changed) def disconnect(self): self.song().remove_appointed_device_listener(self._on_device_changed) self._param_controls = None self._mixer = None self._buttons = None self._lock_button = None self._track = None self._strip = None self._parent = None self._device = None self._alt_device = None def update(self): pass #self._show_msg_callback("EncoderDeviceComponent update called") def set_controls_and_buttons(self, controls, buttons): assert ((controls == None) or (isinstance(controls, tuple) and (len(controls) == 8))) self._param_controls = controls assert ((buttons == None) or (isinstance(buttons, tuple)) or (len(buttons) == 4)) self._buttons = buttons self.set_lock_button(self._buttons[0]) if self._is_locked == True: self._alt_device.set_parameter_controls(self._param_controls) self._alt_device.set_bank_nav_buttons(self._buttons[2], self._buttons[3]) self._alt_device.set_on_off_button(self._buttons[1]) else: self.on_selected_track_changed() def _on_device_changed(self): if self.is_enabled(): if self._is_locked != True: selected_device= self.song().appointed_device self._alt_device.set_device(selected_device) self._setup_controls_and_buttons() def on_selected_track_changed(self): if self.is_enabled(): if self._is_locked != True: track = self.song().view.selected_track selected_device = track.view.selected_device self._alt_device.set_device(selected_device) self._setup_controls_and_buttons() def _setup_controls_and_buttons(self): if self._buttons != None and self._param_controls != None: if self._alt_device != None: self._alt_device.set_parameter_controls(self._param_controls) self._alt_device.set_bank_nav_buttons(self._buttons[2], self._buttons[3]) self._alt_device.set_on_off_button(self._buttons[1]) self._alt_device._on_on_off_changed() #self._rebuild_callback() def on_enabled_changed(self): self.update() def set_lock_button(self, button): assert ((button == None) or isinstance(button, ButtonElement)) if (self._lock_button != None): self._lock_button.remove_value_listener(self._lock_value) self._lock_button = None self._lock_button = button if (self._lock_button != None): self._lock_button.add_value_listener(self._lock_value) if self._is_locked: self._lock_button.turn_on() else: self._lock_button.turn_off() def _lock_value(self, value): assert (self._lock_button != None) assert (value != None) assert isinstance(value, int) if ((not self._lock_button.is_momentary()) or (value is not 0)): if self._ignore_buttons == False: if self._is_locked: self._is_locked = False self._lock_button.turn_off() self.on_selected_track_changed() else: self._is_locked = True self._lock_button.turn_on()
class LinkedCode(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._reset() # turn off rebuild MIDI map until after setup self.set_suppress_rebuild_requests(True) self._create_buttons() self._create_encoders() self._create_device_components() self._setup_mixer_control() self._setup_transport_control() self._setup_session_control() self._setup_mode_selector_control() self.set_suppress_rebuild_requests(False) def _reset(self): self._send_midi(FactoryReset) self._send_midi(ButtonMap) # self._send_midi(EncosionMap1); self._send_midi(ButtonChannelMap) self._send_midi(EncoderChannelMap) def _create_mode_buttons(self): self.mode_buttons = [] for i in range(MODES): self.mode_buttons.append(ButtonElement(True, MIDI_NOTE_TYPE, CHAN, SIDE_BUTTONS_NOTES[MODES-1-i])) def _create_buttons(self): self._buttons = [] for row in (ROW1_BUTTON_NOTES, ROW2_BUTTON_NOTES, ROW3_BUTTON_NOTES, ROW4_BUTTON_NOTES, BOTTOM_BUTTONS_NOTES): for n in row: self._buttons.append(ButtonElement(True, MIDI_NOTE_TYPE, CHAN, n)) def _create_encoders(self): # hack, placeholder control so we can get to arbitrary parameters # in a device self._dummy_encoder = EncoderElement(MIDI_CC_TYPE, CHAN + 1, 0x7f, Live.MidiMap.MapMode.absolute) self._encoders = [] self._sliders = [] for row in (ROW1_ENCODERS_CCS, ROW2_ENCODERS_CCS, ROW3_ENCODERS_CCS, ROW4_ENCODERS_CCS): for n in row: self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, n, Live.MidiMap.MapMode.absolute)) self._sliders.append(SliderElement(MIDI_CC_TYPE, CHAN, n)) # make a relative encoder. currently not in use, since causes an error when such an encoder is assigned to anything #self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, ROW1_ENCODERS_CCS[7], Live.MidiMap.MapMode.relative_two_compliment)) def _create_device_components(self): self._create_return_devices() self._create_selected_device() self._create_device_view_controls() def _create_return_devices(self): self._device_returns = [] for track in self.song().return_tracks: device = DeviceComponent() try: device.set_device(track.devices[0]) except: self.log_message("no devices on return track") self._device_returns.append(device) if len(self._device_returns) == 2: break def _create_selected_device(self): self._device_selected = DeviceComponent() self.set_device_component(self._device_selected) def _create_device_view_controls(self): self._detail_view_control = DetailViewCntrlComponent() def _setup_mode_selector_control(self): self._create_mode_buttons() self._last_mode = -1 self._unmap_mode_callbacks = (self._unmap_mode_0, self._unmap_mode_1, self._unmap_mode_2, self._unmap_mode_3) self._map_mode_callbacks = (self._map_mode_0, self._map_mode_1, self._map_mode_2, self._map_mode_3) self.mode_selector = ModeSelectorComponent2(MODES) self.mode_selector.add_mode_index_listener(self._mode_changed) # call this last because setting the mode buttons sets the default mode self.mode_selector.set_mode_buttons(tuple(self.mode_buttons)) def _mode_changed(self): if self.mode_selector.mode_index == 3: self._unmap_session_buttons() if self._last_mode != -1: self._unmap_mode_callbacks[self._last_mode]() self._map_mode_callbacks[self.mode_selector.mode_index]() if self._last_mode == -1 or self._last_mode == 3: self._map_session_buttons() self._last_mode = self.mode_selector.mode_index def _map_session_buttons(self): for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_invert_mute_feedback(True) self.mixer.channel_strip(i).set_mute_button(self._buttons[4 * 8 + i]) self.mixer.channel_strip(i).set_select_button(self._buttons[3 * 8 + i]) self.mixer.channel_strip(i).set_arm_button(self._buttons[2 * 8 + i]) self.mixer.channel_strip(i).set_solo_button(self._buttons[8 + i]) stop_track_buttons = [] for i in range(SESSION_TRACKS): stop_track_buttons.append(self._buttons[i]) self.session.set_stop_track_clip_buttons(tuple(stop_track_buttons)) #array size needs to match num_tracks def _unmap_session_buttons(self): for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_mute_button(None) self.mixer.channel_strip(i).set_select_button(None) self.mixer.channel_strip(i).set_arm_button(None) self.mixer.channel_strip(i).set_solo_button(None) self.session.set_stop_track_clip_buttons(None) #array size needs to match num_tracks def _map_mode_0(self): self.log_message("+ mode 1") for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_volume_control(self._sliders[3 * 8 + i]) self.mixer.channel_strip(i).set_send_controls((self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) # or... # self.mixer.channel_strip(i).set_pan_control(self._encoders[2 * 8 + i]) # self.mixer.channel_strip(i).set_send_controls((self._encoders[8 + i], self._encoders[i])) def _unmap_mode_0(self): self.log_message("- mode 1") for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_volume_control(None) # self.mixer.channel_strip(i).set_pan_control(None) self.mixer.channel_strip(i).set_send_controls(None) def _map_mode_1(self): self.log_message("+ mode 2") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls((self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) def _unmap_mode_1(self): self.log_message("- mode 2") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls(()) def _map_mode_2(self): self.log_message("+ mode 3") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls((self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) def _unmap_mode_2(self): self.log_message("- mode 3") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls(()) def _map_mode_3(self): self.log_message("+ mode 4") # self._send_midi(EncosionMap2); for i in range(len(self._device_returns)): # maybe this should be 2, instead of all returns? - LD self._device_returns[i].set_parameter_controls((self._encoders[3 * 8 + i * 2], self._encoders[2 * 8 + i * 2], self._encoders[8 + i * 2], self._encoders[i * 2], self._encoders[3 * 8 + i * 2 + 1], self._encoders[2 * 8 + i * 2 + 1], self._encoders[8 + i * 2 + 1], self._encoders[i * 2 + 1])) self._device_selected.set_parameter_controls((self._encoders[3 * 8 + 2 * 2], self._encoders[2 * 8 + 2 * 2], self._encoders[8 + 2 * 2], self._encoders[2 * 2], self._encoders[3 * 8 + 2 * 2 + 1], self._encoders[2 * 8 + 2 * 2 + 1], self._encoders[8 + 2 * 2 + 1], self._encoders[2 * 2 + 1])) self._device_selected.set_on_off_button(self._buttons[2 * 8 + 5]) self._detail_view_control.set_device_clip_toggle_button(self._buttons[4 * 8 + 4]) self._detail_view_control.set_detail_toggle_button(self._buttons[4 * 8 + 5]) self._detail_view_control.set_device_nav_buttons(self._buttons[3 * 8 + 4], self._buttons[3 * 8 + 5]) for i in range(4): self.mixer.return_strip(i).set_volume_control(self._sliders[(3 - i) * 8 + 6]) for i in range(RETURN_TRACKS): self.mixer.return_strip(i).set_invert_mute_feedback(True) self.mixer.return_strip(i).set_select_button(self._buttons[4 * 8 + i]) self.mixer.return_strip(i).set_mute_button(self._buttons[3 * 8 + i]) self.mixer.master_strip().set_select_button(self._buttons[4 * 8 + 7]) self.mixer.master_strip().set_volume_control(self._sliders[3 * 8 + 7]) self.mixer.set_prehear_volume_control(self._sliders[2 * 8 + 7]) self._transport.set_record_button(self._buttons[3 * 8 + 6]) self._transport.set_play_button(self._buttons[3 * 8 + 7]) self._transport.set_stop_button(self._buttons[2 * 8 + 7]) self._transport.set_nudge_buttons(self._buttons[8 + 7], self._buttons[8 + 6]) self._transport.set_tap_tempo_button(self._buttons[4 * 8 + 6]) self._transport.set_tempo_control(self._encoders[7], self._encoders[15]) self.session.set_stop_all_clips_button(self._buttons[2 * 8 + 6]) self._transport.set_metronome_button(self._buttons[0 * 8 + 6]) self._transport.set_overdub_button(self._buttons[0 * 8 + 7]) def _unmap_mode_3(self): self.log_message("- mode 4") # self._send_midi(EncosionMap1); for i in range(len(self._device_returns)): self._device_returns[i].set_parameter_controls(()) self._device_selected.set_parameter_controls(()) self._device_selected.set_on_off_button(None) self._detail_view_control.set_device_clip_toggle_button(None) self._detail_view_control.set_detail_toggle_button(None) self._detail_view_control.set_device_nav_buttons(None, None) for i in range(4): self.mixer.return_strip(i).set_volume_control(None) for i in range(RETURN_TRACKS): self.mixer.return_strip(i).set_select_button(None) self.mixer.return_strip(i).set_mute_button(None) self.mixer.master_strip().set_select_button(None) self.mixer.master_strip().set_volume_control(None) self._transport.set_record_button(None) self._transport.set_play_button(None) self._transport.set_stop_button(None) self._transport.set_nudge_buttons(None, None) self._transport.set_tap_tempo_button(None) self._transport.set_tempo_control(None, None) self.session.set_stop_all_clips_button(None) self.mixer.set_prehear_volume_control(None) self._transport.set_metronome_button(None) self._transport.set_overdub_button(None) def _setup_mixer_control(self): # MixerComponent(num_tracks, num_returns, ...) self.mixer = MixerComponent(MIXER_TRACKS, RETURN_TRACKS, with_eqs = True, with_filters = False) self.mixer.set_track_offset(0) def _setup_transport_control(self): self._transport = TransportComponent() def _setup_session_control(self): self.session = SessionComponent2(SESSION_TRACKS, SESSION_SCENES, self) self.session.name = "Session_Control" self.session.set_mixer(self.mixer) self.session._link() def disconnect(self): if self.session and self.session._is_linked(): self.session._unlink() ControlSurface.disconnect(self)
class LinkedCode(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._reset() # turn off rebuild MIDI map until after setup self.set_suppress_rebuild_requests(True) self._create_buttons() self._create_encoders() self._create_device_components() self._setup_mixer_control() self._setup_transport_control() self._setup_session_control() self._setup_mode_selector_control() self.set_suppress_rebuild_requests(False) def _reset(self): self._send_midi(FactoryReset) self._send_midi(ButtonMap) # self._send_midi(EncosionMap1); self._send_midi(ButtonChannelMap) self._send_midi(EncoderChannelMap) def _create_mode_buttons(self): self.mode_buttons = [] for i in range(MODES): self.mode_buttons.append( ButtonElement(True, MIDI_NOTE_TYPE, CHAN, SIDE_BUTTONS_NOTES[MODES - 1 - i])) def _create_buttons(self): self._buttons = [] for row in (ROW1_BUTTON_NOTES, ROW2_BUTTON_NOTES, ROW3_BUTTON_NOTES, ROW4_BUTTON_NOTES, BOTTOM_BUTTONS_NOTES): for n in row: self._buttons.append( ButtonElement(True, MIDI_NOTE_TYPE, CHAN, n)) def _create_encoders(self): # hack, placeholder control so we can get to arbitrary parameters # in a device self._dummy_encoder = EncoderElement(MIDI_CC_TYPE, CHAN + 1, 0x7f, Live.MidiMap.MapMode.absolute) self._encoders = [] self._sliders = [] for row in (ROW1_ENCODERS_CCS, ROW2_ENCODERS_CCS, ROW3_ENCODERS_CCS, ROW4_ENCODERS_CCS): for n in row: self._encoders.append( EncoderElement(MIDI_CC_TYPE, CHAN, n, Live.MidiMap.MapMode.absolute)) self._sliders.append(SliderElement(MIDI_CC_TYPE, CHAN, n)) # make a relative encoder. currently not in use, since causes an error when such an encoder is assigned to anything #self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, ROW1_ENCODERS_CCS[7], Live.MidiMap.MapMode.relative_two_compliment)) def _create_device_components(self): self._create_return_devices() self._create_selected_device() self._create_device_view_controls() def _create_return_devices(self): self._device_returns = [] for track in self.song().return_tracks: device = DeviceComponent() try: device.set_device(track.devices[0]) except: self.log_message("no devices on return track") self._device_returns.append(device) if len(self._device_returns) == 2: break def _create_selected_device(self): self._device_selected = DeviceComponent() self.set_device_component(self._device_selected) def _create_device_view_controls(self): self._detail_view_control = DetailViewCntrlComponent() def _setup_mode_selector_control(self): self._create_mode_buttons() self._last_mode = -1 self._unmap_mode_callbacks = (self._unmap_mode_0, self._unmap_mode_1, self._unmap_mode_2, self._unmap_mode_3) self._map_mode_callbacks = (self._map_mode_0, self._map_mode_1, self._map_mode_2, self._map_mode_3) self.mode_selector = ModeSelectorComponent2(MODES) self.mode_selector.add_mode_index_listener(self._mode_changed) # call this last because setting the mode buttons sets the default mode self.mode_selector.set_mode_buttons(tuple(self.mode_buttons)) def _mode_changed(self): if self.mode_selector.mode_index == 3: self._unmap_session_buttons() if self._last_mode != -1: self._unmap_mode_callbacks[self._last_mode]() self._map_mode_callbacks[self.mode_selector.mode_index]() if self._last_mode == -1 or self._last_mode == 3: self._map_session_buttons() self._last_mode = self.mode_selector.mode_index def _map_session_buttons(self): for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_invert_mute_feedback(True) self.mixer.channel_strip(i).set_mute_button(self._buttons[4 * 8 + i]) self.mixer.channel_strip(i).set_select_button(self._buttons[3 * 8 + i]) self.mixer.channel_strip(i).set_arm_button(self._buttons[2 * 8 + i]) self.mixer.channel_strip(i).set_solo_button(self._buttons[8 + i]) stop_track_buttons = [] for i in range(SESSION_TRACKS): stop_track_buttons.append(self._buttons[i]) self.session.set_stop_track_clip_buttons( tuple(stop_track_buttons)) #array size needs to match num_tracks def _unmap_session_buttons(self): for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_mute_button(None) self.mixer.channel_strip(i).set_select_button(None) self.mixer.channel_strip(i).set_arm_button(None) self.mixer.channel_strip(i).set_solo_button(None) self.session.set_stop_track_clip_buttons( None) #array size needs to match num_tracks def _map_mode_0(self): self.log_message("+ mode 1") for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_volume_control( self._sliders[3 * 8 + i]) self.mixer.channel_strip(i).set_send_controls( (self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) # or... # self.mixer.channel_strip(i).set_pan_control(self._encoders[2 * 8 + i]) # self.mixer.channel_strip(i).set_send_controls((self._encoders[8 + i], self._encoders[i])) def _unmap_mode_0(self): self.log_message("- mode 1") for i in range(MIXER_TRACKS): self.mixer.channel_strip(i).set_volume_control(None) # self.mixer.channel_strip(i).set_pan_control(None) self.mixer.channel_strip(i).set_send_controls(None) def _map_mode_1(self): self.log_message("+ mode 2") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls( (self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) def _unmap_mode_1(self): self.log_message("- mode 2") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls(()) def _map_mode_2(self): self.log_message("+ mode 3") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls( (self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i])) def _unmap_mode_2(self): self.log_message("- mode 3") for i in range(SESSION_TRACKS): self.session.device(i).set_parameter_controls(()) def _map_mode_3(self): self.log_message("+ mode 4") # self._send_midi(EncosionMap2); for i in range( len(self._device_returns )): # maybe this should be 2, instead of all returns? - LD self._device_returns[i].set_parameter_controls( (self._encoders[3 * 8 + i * 2], self._encoders[2 * 8 + i * 2], self._encoders[8 + i * 2], self._encoders[i * 2], self._encoders[3 * 8 + i * 2 + 1], self._encoders[2 * 8 + i * 2 + 1], self._encoders[8 + i * 2 + 1], self._encoders[i * 2 + 1])) self._device_selected.set_parameter_controls( (self._encoders[3 * 8 + 2 * 2], self._encoders[2 * 8 + 2 * 2], self._encoders[8 + 2 * 2], self._encoders[2 * 2], self._encoders[3 * 8 + 2 * 2 + 1], self._encoders[2 * 8 + 2 * 2 + 1], self._encoders[8 + 2 * 2 + 1], self._encoders[2 * 2 + 1])) self._device_selected.set_on_off_button(self._buttons[2 * 8 + 5]) self._detail_view_control.set_device_clip_toggle_button( self._buttons[4 * 8 + 4]) self._detail_view_control.set_detail_toggle_button( self._buttons[4 * 8 + 5]) self._detail_view_control.set_device_nav_buttons( self._buttons[3 * 8 + 4], self._buttons[3 * 8 + 5]) for i in range(4): self.mixer.return_strip(i).set_volume_control( self._sliders[(3 - i) * 8 + 6]) for i in range(RETURN_TRACKS): self.mixer.return_strip(i).set_invert_mute_feedback(True) self.mixer.return_strip(i).set_select_button(self._buttons[4 * 8 + i]) self.mixer.return_strip(i).set_mute_button(self._buttons[3 * 8 + i]) self.mixer.master_strip().set_select_button(self._buttons[4 * 8 + 7]) self.mixer.master_strip().set_volume_control(self._sliders[3 * 8 + 7]) self.mixer.set_prehear_volume_control(self._sliders[2 * 8 + 7]) self._transport.set_record_button(self._buttons[3 * 8 + 6]) self._transport.set_play_button(self._buttons[3 * 8 + 7]) self._transport.set_stop_button(self._buttons[2 * 8 + 7]) self._transport.set_nudge_buttons(self._buttons[8 + 7], self._buttons[8 + 6]) self._transport.set_tap_tempo_button(self._buttons[4 * 8 + 6]) self._transport.set_tempo_control(self._encoders[7], self._encoders[15]) self.session.set_stop_all_clips_button(self._buttons[2 * 8 + 6]) self._transport.set_metronome_button(self._buttons[0 * 8 + 6]) self._transport.set_overdub_button(self._buttons[0 * 8 + 7]) def _unmap_mode_3(self): self.log_message("- mode 4") # self._send_midi(EncosionMap1); for i in range(len(self._device_returns)): self._device_returns[i].set_parameter_controls(()) self._device_selected.set_parameter_controls(()) self._device_selected.set_on_off_button(None) self._detail_view_control.set_device_clip_toggle_button(None) self._detail_view_control.set_detail_toggle_button(None) self._detail_view_control.set_device_nav_buttons(None, None) for i in range(4): self.mixer.return_strip(i).set_volume_control(None) for i in range(RETURN_TRACKS): self.mixer.return_strip(i).set_select_button(None) self.mixer.return_strip(i).set_mute_button(None) self.mixer.master_strip().set_select_button(None) self.mixer.master_strip().set_volume_control(None) self._transport.set_record_button(None) self._transport.set_play_button(None) self._transport.set_stop_button(None) self._transport.set_nudge_buttons(None, None) self._transport.set_tap_tempo_button(None) self._transport.set_tempo_control(None, None) self.session.set_stop_all_clips_button(None) self.mixer.set_prehear_volume_control(None) self._transport.set_metronome_button(None) self._transport.set_overdub_button(None) def _setup_mixer_control(self): # MixerComponent(num_tracks, num_returns, ...) self.mixer = MixerComponent(MIXER_TRACKS, RETURN_TRACKS, with_eqs=True, with_filters=False) self.mixer.set_track_offset(0) def _setup_transport_control(self): self._transport = TransportComponent() def _setup_session_control(self): self.session = SessionComponent2(SESSION_TRACKS, SESSION_SCENES, self) self.session.name = "Session_Control" self.session.set_mixer(self.mixer) self.session._link() def disconnect(self): if self.session and self.session._is_linked(): self.session._unlink() ControlSurface.disconnect(self)
class midi_twister_110(ControlSurface): def __init__(self, c_instance): super(midi_twister_110, self).__init__(c_instance) with self.component_guard(): global active_mode active_mode = "_mode1" self._set_active_mode() self.show_message("Modified by XXPW") def _mode1(self): self.show_message("_mode1 is active") # mixer global mixer num_tracks = 32 num_returns = 7 self.mixer = MixerComponent(num_tracks, num_returns) self.mixer.set_track_offset(0) self.song().view.selected_track = self.mixer.channel_strip(0)._track # sends send0_controls = ( SliderElement(MIDI_CC_TYPE, 0, 32), SliderElement(MIDI_CC_TYPE, 0, 36), SliderElement(MIDI_CC_TYPE, 0, 40), None, None, None, None, None, ) self.mixer.channel_strip(0).set_send_controls(tuple(send0_controls)) self.mixer.channel_strip(0).set_volume_control( SliderElement(MIDI_CC_TYPE, 0, 44)) send1_controls = ( SliderElement(MIDI_CC_TYPE, 0, 33), SliderElement(MIDI_CC_TYPE, 0, 37), SliderElement(MIDI_CC_TYPE, 0, 41), None, None, None, None, None, ) self.mixer.channel_strip(1).set_send_controls(tuple(send1_controls)) self.mixer.channel_strip(1).set_volume_control( SliderElement(MIDI_CC_TYPE, 0, 45)) send2_controls = ( SliderElement(MIDI_CC_TYPE, 0, 34), SliderElement(MIDI_CC_TYPE, 0, 38), SliderElement(MIDI_CC_TYPE, 0, 42), None, None, None, None, None, ) self.mixer.channel_strip(2).set_send_controls(tuple(send2_controls)) self.mixer.channel_strip(2).set_volume_control( SliderElement(MIDI_CC_TYPE, 0, 46)) send3_controls = ( SliderElement(MIDI_CC_TYPE, 0, 35), SliderElement(MIDI_CC_TYPE, 0, 39), SliderElement(MIDI_CC_TYPE, 0, 43), None, None, None, None, None, ) self.mixer.channel_strip(3).set_send_controls(tuple(send3_controls)) self.mixer.channel_strip(3).set_volume_control( SliderElement(MIDI_CC_TYPE, 0, 47)) # session global _session num_tracks = 4 num_scenes = 3 session_buttons = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] self._pads = [ ButtonElement(1, MIDI_CC_TYPE, 1, session_buttons[index]) for index in range(num_tracks * num_scenes) ] self._grid = ButtonMatrixElement(rows=[ self._pads[(index * num_tracks):(index * num_tracks) + num_tracks] for index in range(num_scenes) ]) self._session = SessionComponent(num_tracks, num_scenes) self._session.set_clip_launch_buttons(self._grid) self.set_highlighting_session_component(self._session) # session track stop stop_track_buttons = [12, 13, 14, 15] self._track_stop_buttons = [ ButtonElement(1, MIDI_CC_TYPE, 1, stop_track_buttons[index]) for index in range(num_tracks) ] self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) # session navigation self.session_left = ButtonElement(1, MIDI_CC_TYPE, 3, 8) self._session.set_page_left_button(self.session_left) self.session_left.add_value_listener(self._reload_active_devices, identify_sender=False) self.session_right = ButtonElement(1, MIDI_CC_TYPE, 3, 11) self._session.set_page_right_button(self.session_right) self.session_right.add_value_listener(self._reload_active_devices, identify_sender=False) self.session_up = ButtonElement(1, MIDI_CC_TYPE, 3, 10) self._session.set_page_up_button(self.session_up) self.session_up.add_value_listener(self._reload_active_devices, identify_sender=False) self.session_down = ButtonElement(1, MIDI_CC_TYPE, 3, 13) self._session.set_page_down_button(self.session_down) self.session_down.add_value_listener(self._reload_active_devices, identify_sender=False) self._session._link() self._session.set_mixer(self.mixer) #self._session.set_mixer(self.mixer) self._mode1_devices() self.add_device_listeners() # button: next device self.next_device = ButtonElement(0, MIDI_CC_TYPE, 1, 25) self.next_device.add_value_listener(self._next_device_value, identify_sender=False) # button: prev device self.previous_device = ButtonElement(1, MIDI_CC_TYPE, 1, 24) self.previous_device.add_value_listener(self._prev_device_value, identify_sender=False) # transport global transport self.transport = TransportComponent() self.transport.name = 'Transport' loop_button = ButtonElement(1, MIDI_CC_TYPE, 1, 50) loop_button.name = 'loop_button' self.transport.set_loop_button(loop_button) stop_button = ButtonElement(1, MIDI_CC_TYPE, 1, 49) stop_button.name = 'stop_button' self.transport.set_stop_button(stop_button) play_button = ButtonElement(1, MIDI_CC_TYPE, 1, 48) play_button.name = 'play_button' self.transport.set_play_button(play_button) # button: track navigation right self.track_navigation_right = ButtonElement(1, MIDI_CC_TYPE, 3, 17) self.track_navigation_right.add_value_listener( self._track_navigation_right_track_nav, identify_sender=False) # button: track navigation left self.track_navigation_left = ButtonElement(1, MIDI_CC_TYPE, 3, 14) self.track_navigation_left.add_value_listener( self._track_navigation_left_track_nav, identify_sender=False) def _remove_mode1(self): # mixer global mixer self._remove_mode1_devices() self.remove_device_listeners() send0_controls = ( None, None, None, None, None, None, None, None, ) self.mixer.channel_strip(0).set_send_controls(tuple(send0_controls)) send1_controls = ( None, None, None, None, None, None, None, None, ) self.mixer.channel_strip(1).set_send_controls(tuple(send1_controls)) send2_controls = ( None, None, None, None, None, None, None, None, ) self.mixer.channel_strip(2).set_send_controls(tuple(send2_controls)) send3_controls = ( None, None, None, None, None, None, None, None, ) self.mixer.channel_strip(3).set_send_controls(tuple(send3_controls)) # session global _session self._session.set_clip_launch_buttons(None) self.set_highlighting_session_component(None) self._session.set_mixer(None) self._session.set_stop_all_clips_button(None) # session track stop self._track_stop_buttons = None self._session.set_stop_track_clip_buttons(None) # session scene launch self._scene_launch_buttons = None self._session.set_scene_launch_buttons(None) # session navigation self.session_left.remove_value_listener(self._reload_active_devices) self._session.set_page_left_button(None) self.session_right.remove_value_listener(self._reload_active_devices) self._session.set_page_right_button(None) self.session_up.remove_value_listener(self._reload_active_devices) self._session.set_page_up_button(None) self.session_down.remove_value_listener(self._reload_active_devices) self._session.set_page_down_button(None) self._session = None self.next_device.remove_value_listener(self._next_device_value) self.next_device = None self.previous_device.remove_value_listener(self._prev_device_value) self.previous_device = None # transport global transport self.transport.set_loop_button(None) self.transport.set_stop_button(None) self.transport.set_play_button(None) self.transport = None self.track_navigation_right.remove_value_listener( self._track_navigation_right_track_nav) self.track_navigation_right = None self.track_navigation_left.remove_value_listener( self._track_navigation_left_track_nav) self.track_navigation_left = None def _mode1_devices(self): global mixer global _session # device self.mixer.selected_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, 0, 28)) self.mixer.selected_strip().set_pan_control( SliderElement(MIDI_CC_TYPE, 0, 29)) self.mixer.selected_strip().set_mute_button( ButtonElement(1, MIDI_CC_TYPE, 1, 28)) self.mixer.selected_strip().set_solo_button( ButtonElement(1, MIDI_CC_TYPE, 1, 29)) if (len(self.mixer.selected_strip()._track.devices) > 0): global device_tracktype_selected__chain_number_selected self.device_tracktype_selected__chain_number_selected = DeviceComponent( ) device_controls = ( SliderElement(MIDI_CC_TYPE, 0, 16), SliderElement(MIDI_CC_TYPE, 0, 17), SliderElement(MIDI_CC_TYPE, 0, 18), SliderElement(MIDI_CC_TYPE, 0, 19), SliderElement(MIDI_CC_TYPE, 0, 20), SliderElement(MIDI_CC_TYPE, 0, 21), SliderElement(MIDI_CC_TYPE, 0, 22), SliderElement(MIDI_CC_TYPE, 0, 23), ) self.device_tracktype_selected__chain_number_selected.set_parameter_controls( tuple(device_controls)) self.set_device_component( self.device_tracktype_selected__chain_number_selected) self.device_tracktype_selected__chain_number_selected.set_on_off_button( ButtonElement(1, MIDI_CC_TYPE, 1, 26)) self.device_tracktype_selected__chain_number_selected.set_bank_nav_buttons( ButtonElement(0, MIDI_CC_TYPE, 1, 31), ButtonElement(1, MIDI_CC_TYPE, 1, 33)) def _remove_mode1_devices(self): global mixer global _session # device if (hasattr(self, 'device_tracktype_selected__chain_number_selected')): global device_tracktype_selected__chain_number_selected device_controls = ( None, None, None, None, None, None, None, None, ) self.device_tracktype_selected__chain_number_selected.set_parameter_controls( tuple(device_controls)) self.device_tracktype_selected__chain_number_selected.set_on_off_button( None) self.device_tracktype_selected__chain_number_selected.set_bank_nav_buttons( None, None) self.set_device_component( self.device_tracktype_selected__chain_number_selected) def add_device_listeners(self): global mixer num_of_tracks = len(self.song().tracks) value = "add device listener" for index in range(num_of_tracks): self.song().tracks[index].add_devices_listener( self._reload_active_devices) def remove_device_listeners(self): global mixer num_of_tracks = len(self.song().tracks) value = "remove device listener" for index in range(num_of_tracks): self.song().tracks[index].remove_devices_listener( self._reload_active_devices) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._display_reset_delay = 0 value = "selected track changed" self._reload_active_devices(value) def _reload_active_devices(self, value=None): self._remove_active_devices() self._set_active_devices() def _set_active_devices(self): global active_mode # activate mode if (active_mode == "_mode1") and (hasattr(self, '_mode1_devices')): self._mode1_devices() def _remove_active_devices(self): global active_mode # remove activate mode if (active_mode == "_mode1") and (hasattr(self, '_mode1_devices')): self._remove_mode1_devices() def _next_device_value(self, value): if value > 0: self._device = self.song().view.selected_track.view.selected_device if self._device is not None: self.song().view.select_device( self.song().view.selected_track.devices[ self.selected_device_idx() + 1]) def _prev_device_value(self, value): if value > 0: self._device = self.song().view.selected_track.view.selected_device if self._device is not None: self.song().view.select_device( self.song().view.selected_track.devices[ self.selected_device_idx() - 1]) def selected_device_idx(self): self._device = self.song().view.selected_track.view.selected_device return self.tuple_index(self.song().view.selected_track.devices, self._device) def _track_navigation_right_track_nav(self, value): if value > 0: self.song().view.selected_track = self.song().tracks[ self.selected_track_idx() + 1] def _track_navigation_left_track_nav(self, value): if value > 0: self.song().view.selected_track = self.song().tracks[ self.selected_track_idx() - 1] def selected_track_idx(self): return self.tuple_index(self.song().tracks, self.song().view.selected_track) def _set_active_mode(self): global active_mode # activate mode if active_mode == "_mode1": self._mode1() def _remove_active_mode(self): global active_mode # remove activate mode if active_mode == "_mode1": self._remove_mode1() def _activate_mode1(self, value): global active_mode if value > 0: self._remove_active_mode() active_mode = "_mode1" self._set_active_mode() def _activate_shift_mode1(self, value): global active_mode if value > 0: self._remove_active_mode() self._mode1() else: self._remove_mode1() self._set_active_mode() def tuple_index(self, tuple, obj): for i in xrange(0, len(tuple)): if (tuple[i] == obj): return i return (False) def disconnect(self): super(midi_twister_110, self).disconnect()
class X1MK2(ControlSurface): __doc__ = " Script for Traktor X1MK2 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in X1MK2._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._color_skin = make_rgb_skin() #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._to_notify = [] self._clip_map = [] self._note_map = [] self._ctrl_map = [] self._enc_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._clip_map = None self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in X1MK2._active_instances: X1MK2._active_instances.append(self) X1MK2._combine_active_instances() def _do_uncombine(self): if ((self in X1MK2._active_instances) and X1MK2._active_instances.remove(self)): self._session.unlink() X1MK2._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(SESSION_WIDTH, SESSION_HEIGHT, self.log_message, enable_skinning = True) self._session.set_rgb_mode(color_palette = CLIP_COLOR_TABLE(self.log_message), color_table = None, clip_slots_only = True) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ] self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(SESSION_WIDTH)] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(SESSION_HEIGHT): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(SESSION_WIDTH): button = self._clip_map[CLIPNOTEMAP[scene_index][track_index]] button.num_delayed_messages = 3 delete_button = self._note_map[DELETECLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) clip_slot.set_launch_button(button) self._to_notify.append(clip_slot) clip_slot.set_delete_button(delete_button) # # clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb]) #set its triggered to play color # # clip_slot.set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])#set its triggered to record color # # clip_slot.set_stopped_value(CLIP_STOP[self._rgb]) #set its stop color # clip_slot.set_started_value(13) #set its started color # clip_slot.set_recording_value(11) #set its recording value self.log_message('Clip %s:%s' % (clip_slot.name, clip_slot._launch_button_value.subject.message_identifier())) #self._session_zoom = SpecialZoomingComponent(self._session) #self._session_zoom.name = 'Session_Overview' #self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True #Setup mixer using the VCM600's MixerComponent which includes EQ and Filter components for tracks self._mixer = MixerComponent(SESSION_WIDTH, self) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME]) for track in range(SESSION_WIDTH): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) #Setup EQs using the VCM600s TrackEQComponent eq = self._mixer.track_eq(track) eq.name = 'Mixer_EQ_' + str(track) eq.set_gain_controls(tuple([self._enc_map[EQGAINS[track][0]],self._enc_map[EQGAINS[track][1]],self._enc_map[EQGAINS[track][2]]])) #set the encoders for eq gains eq.set_cut_buttons(tuple([self._note_map[EQCUTS[track][0]],self._note_map[EQCUTS[track][1]],self._note_map[EQCUTS[track][2]]])) eq.set_enabled(True) #setup filters using VCM600s TrackFilterComponent filter = self._mixer.track_filter(track) filter.name = 'Mixer_Filter_' + str(track) filter.set_filter_controls(self._enc_map[FILTERS[track][0]],self._enc_map[FILTERS[track][1]]) filter.set_device_on_off(self._note_map[FILTER_ON[track]],self.log_message) filter.set_enabled(True) # for index in range(len(filter._track.devices)): # device = filter._track.devices[-1 * (index + 1)] # self.log_message('Device %s: %s / %s' % (index, device.class_name, device.name)) # fx1 = self._mixer.track_fx1(track) fx1.name = 'Mixer_FX1_' + str(track) fx1.set_on_off_button(self._note_map[FX1_ON[track]]) fx1.set_enabled(True) fx2 = self._mixer.track_fx2(track) fx2.set_on_off_button(self._note_map[FX2_ON[track]]) fx2.set_enabled = True #Set strip buttons strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] ) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) # self.log_message('Track %s' % track) # self.log_message('EQ Track %s' % self._mixer.track_eq(track.)._track) # self.log_message('EQ Track Devices' % self._mixer.track_eq(0)._device.class_name) # def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True rgb_skin = make_rgb_skin() for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note,) button.name = 'Button Note_' + str(note) button.is_rgb = True self._note_map.append(button) self._note_map.append(None) #add None to the end of the list, selectable with [-1] for note in range(128): clip_button = ColorButtonElement(self.log_message,is_momentary, MESSAGETYPE, BUTTONCHANNEL, note, skin = rgb_skin) clip_button.name = 'Clip Note_' + str(note) button.num_delayed_messages = 3 self._clip_map.append(clip_button) self._clip_map.append(None) #add None if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for i in range(128): self._ctrl_map.append(None) self._enc_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None) for enc in range(128): encoder = EncoderElement(MIDI_CC_TYPE, SLIDERCHANNEL, enc, Live.MidiMap.MapMode.absolute) encoder.name = "Encoder_" + str(enc) self._enc_map.append(encoder) self._enc_map.append(None) self.log_message('Note Map: %s' % self._note_map) self.log_message('Ctrl Map: %s' % self._ctrl_map) self.log_message('Enc Map: %s' % self._enc_map) def notify(self): for component in self._to_notify: component.update() def update_display(self): with self.component_guard(): with self._is_sending_scheduled_messages(): self._task_group.update(0.1) self.notify()
class JAMP_alpha(ControlSurface): __doc__ = " Script for JAMP_alpha in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in JAMP_alpha._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._note_map = [] self._ctrl_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in JAMP_alpha._active_instances: JAMP_alpha._active_instances.append(self) JAMP_alpha._combine_active_instances() def _do_uncombine(self): if ((self in JAMP_alpha._active_instances) and JAMP_alpha._active_instances.remove(self)): self._session.unlink() JAMP_alpha._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(4, 4) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [ self._note_map[SCENELAUNCH[index]] for index in range(4) ] self._track_stop_buttons = [ self._note_map[TRACKSTOP[index]] for index in range(4) ] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button( self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(4): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(4): button = self._note_map[CLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control( self._ctrl_map[MASTERVOLUME]) for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button( self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons( self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT]) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = ( col, row, DRUM_PADS[row * 4 + col], PADCHANNEL, ) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note) button.name = 'Note_' + str(note) self._note_map.append(button) self._note_map.append( None) #add None to the end of the list, selectable with [-1] if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for ctrl in range(128): self._ctrl_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None)
class FCB1020(ControlSurface): __doc__ = " Script for FCB1010 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in FCB1020._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._note_map = [] self._ctrl_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in FCB1020._active_instances: FCB1020._active_instances.append(self) FCB1020._combine_active_instances() def _do_uncombine(self): if ((self in FCB1020._active_instances) and FCB1020._active_instances.remove(self)): self._session.unlink() FCB1020._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(8, 5) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ] self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(8) ] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) self._session.set_stop_track_clip_value(2) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(5): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(8): button = self._note_map[CLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME]) for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] ) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note) button.name = 'Note_' + str(note) self._note_map.append(button) self._note_map.append(None) #add None to the end of the list, selectable with [-1] if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for ctrl in range(128): self._ctrl_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None)
class BCR2000plus(ControlSurface): __doc__ = u" Script for FCB1010 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in BCR2000plus._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._note_map_scenes = [] self._note_map_buttons = [] self._ctrl_map_sliders = [] self._note_map_trk_stop_buttons = [] self._note_map_trk_sel_buttons = [] self._note_map_trk_mute_buttons = [] self._note_map_trk_solo_buttons = [] self._note_map_trk_rec_buttons = [] self._ctrl_map_trk_volume = [] self._ctrl_map_trk_pan = [] self._ctrl_map_senda = [] self._ctrl_map_sendb = [] self._ctrl_map_sendc = [] self._note_map_bank_buttons = [] self._ctrl_map_parameter = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map_scenes = None self._note_map_buttons = None self._ctrl_map_sliders = None self._note_map_trk_stop_buttons = None self._note_map_trk_sel_buttons = None self._note_map_trk_mute_buttons = None self._note_map_trk_solo_buttons = None self._note_map_trk_rec_buttons = None self._ctrl_map_trk_volume = None self._ctrl_map_trk_pan = None self._ctrl_map_senda = None self._ctrl_map_sendb = None self._ctrl_map_sendc = None self._note_map_bank_buttons = None self._ctrl_map_parameter = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in BCR2000plus._active_instances: BCR2000plus._active_instances.append(self) BCR2000plus._combine_active_instances() def _do_uncombine(self): if ((self in BCR2000plus._active_instances) and BCR2000plus._active_instances.remove(self)): self._session.unlink() BCR2000plus._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(TRACK_NUMBER, MATRIX_DEPTH) self._session.name = u'Session_Control' self._session.set_track_bank_buttons(self._note_map_buttons[25], self._note_map_buttons[24]) self._session.set_scene_bank_buttons(self._note_map_buttons[27], self._note_map_buttons[26]) self._session.set_select_buttons(self._note_map_buttons[34], self._note_map_buttons[35]) self._scene_launch_buttons = [ self._note_map_scenes[index] for index in range(MATRIX_DEPTH) ] self._track_stop_buttons = [ self._note_map_trk_stop_buttons[index] for index in range(TRACK_NUMBER) ] self._session.set_stop_all_clips_button(self._note_map_buttons[38]) self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) self._session.selected_scene().name = u'Selected_Scene' self._session.selected_scene().set_launch_button( self._note_map_buttons[36]) self._session.set_slot_launch_button(self._note_map_buttons[37]) for scene_index in range(MATRIX_DEPTH): scene = self._session.scene(scene_index) scene.name = u'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(TRACK_NUMBER): if (CLIPNOTEMAP[scene_index][track_index] == -1): button = None else: button = ButtonElement( is_momentary, CLIPNOTEMAP_TYPE[scene_index][track_index], CLIPNOTEMAP_CH[scene_index][track_index], CLIPNOTEMAP[scene_index][track_index]) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + u'_Clip_Slot_' + str( scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = u'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map_buttons[28], self._note_map_buttons[29], self._note_map_buttons[30], self._note_map_buttons[31]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(TRACK_NUMBER) self._mixer.name = u'Mixer' self._mixer.master_strip().name = u'Master_Channel_Strip' self._mixer.master_strip().set_select_button( self._note_map_buttons[39]) self._mixer.selected_strip().name = u'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map_buttons[33], self._note_map_buttons[32]) self._mixer.set_crossfader_control(self._ctrl_map_sliders[2]) self._mixer.set_prehear_volume_control(self._ctrl_map_sliders[1]) self._mixer.master_strip().set_volume_control( self._ctrl_map_sliders[0]) for track in range(TRACK_NUMBER): strip = self._mixer.channel_strip(track) strip.name = u'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map_trk_rec_buttons[track]) strip.set_solo_button(self._note_map_trk_solo_buttons[track]) strip.set_mute_button(self._note_map_trk_mute_buttons[track]) strip.set_select_button(self._note_map_trk_sel_buttons[track]) strip.set_volume_control(self._ctrl_map_trk_volume[track]) strip.set_pan_control(self._ctrl_map_trk_pan[track]) strip.set_send_controls( (self._ctrl_map_senda[track], self._ctrl_map_sendb[track], self._ctrl_map_sendc[track])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = u'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(PARAMS_NUMBER): device_param_controls.append(self._ctrl_map_parameter[index]) for index in range(BANKS_NUMBER): device_bank_buttons.append(self._note_map_bank_buttons[index]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map_buttons[17]) self._device.set_bank_nav_buttons(self._note_map_buttons[20], self._note_map_buttons[21]) self._device.set_lock_button(self._note_map_buttons[16]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = u'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( self._note_map_buttons[15]) detail_view_toggler.set_detail_toggle_button( self._note_map_buttons[14]) detail_view_toggler.set_device_nav_buttons(self._note_map_buttons[18], self._note_map_buttons[19]) transport = SpecialTransportComponent() transport.name = u'Transport' transport.set_play_button(self._note_map_buttons[0]) transport.set_stop_button(self._note_map_buttons[1]) transport.set_record_button(self._note_map_buttons[2]) transport.set_nudge_buttons(self._note_map_buttons[4], self._note_map_buttons[5]) transport.set_undo_button(self._note_map_buttons[6]) transport.set_redo_button(self._note_map_buttons[7]) transport.set_tap_tempo_button(self._note_map_buttons[3]) transport.set_quant_toggle_button(self._note_map_buttons[13]) transport.set_overdub_button(self._note_map_buttons[11]) transport.set_metronome_button(self._note_map_buttons[12]) transport.set_tempo_control(self._ctrl_map_sliders[3]) transport.set_loop_button(self._note_map_buttons[8]) transport.set_seek_buttons(self._note_map_buttons[22], self._note_map_buttons[23]) transport.set_punch_buttons(self._note_map_buttons[9], self._note_map_buttons[10]) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(PAD_Y_NUMBER): for col in range(PAD_X_NUMBER): pad = ( col, row, DRUM_PADS[row * 4 + col], PADCHANNEL, ) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True # SCENELAUNCH Buttons for scene_id in range(MATRIX_DEPTH): if (SCENELAUNCH[scene_id] == -1): button = None else: button = ButtonElement(is_momentary, SCENELAUNCH_TYPE[scene_id], SCENELAUNCH_CH[scene_id], SCENELAUNCH[scene_id]) button.name = u'Scene_' + str(scene_id) self._note_map_scenes.append(button) # BUTTON_VECTOR Buttons for button_id in range(NUMBER_BUTTONS): if (BUTTON_VECTOR[button_id] == -1): button = None else: if (button_id == 0): button = ButtonElement(False, BUTTON_VECTOR_TYPE[button_id], BUTTON_VECTOR_CH[button_id], BUTTON_VECTOR[button_id]) else: button = ButtonElement(is_momentary, BUTTON_VECTOR_TYPE[button_id], BUTTON_VECTOR_CH[button_id], BUTTON_VECTOR[button_id]) button.name = u'Global_Button_' + str(button_id) self._note_map_buttons.append(button) # SLIDER_VECTOR Sliders for slider_id in range(NUMBER_SLIDERS): if (SLIDER_VECTOR[slider_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, SLIDER_VECTOR_CH[slider_id], SLIDER_VECTOR[slider_id]) control.name = u'Global_Slider_' + str(slider_id) self._ctrl_map_sliders.append(control) # TRACKSTOP Buttons for track_id in range(TRACK_NUMBER): if (TRACKSTOP[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSTOP_TYPE[track_id], TRACKSTOP_CH[track_id], TRACKSTOP[track_id]) button.name = u'Trk_Stop_Button_' + str(track_id) self._note_map_trk_stop_buttons.append(button) # TRACKSEL Buttons for track_id in range(TRACK_NUMBER): if (TRACKSEL[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSEL_TYPE[track_id], TRACKSEL_CH[track_id], TRACKSEL[track_id]) button.name = u'Trk_Sel_Button_' + str(track_id) self._note_map_trk_sel_buttons.append(button) # TRACKMUTE Buttons for track_id in range(TRACK_NUMBER): if (TRACKMUTE[track_id] == -1): button = None else: button = ButtonElement(False, TRACKMUTE_TYPE[track_id], TRACKMUTE_CH[track_id], TRACKMUTE[track_id]) button.name = u'Trk_Mute_Button_' + str(track_id) self._note_map_trk_mute_buttons.append(button) # TRACKSOLO Buttons for track_id in range(TRACK_NUMBER): if (TRACKSOLO[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSOLO_TYPE[track_id], TRACKSOLO_CH[track_id], TRACKSOLO[track_id]) button.name = u'Trk_Solo_Button_' + str(track_id) self._note_map_trk_solo_buttons.append(button) # TRACKREC Buttons for track_id in range(TRACK_NUMBER): if (TRACKREC[track_id] == -1): button = None else: button = ButtonElement(False, TRACKREC_TYPE[track_id], TRACKREC_CH[track_id], TRACKREC[track_id]) button.name = u'Trk_Rec_Button_' + str(track_id) self._note_map_trk_rec_buttons.append(button) # TRACKVOL Sliders for track_id in range(TRACK_NUMBER): if (TRACKVOL[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKVOL_CH[track_id], TRACKVOL[track_id]) control.name = u'Trk_Vol_Slider_' + str(track_id) self._ctrl_map_trk_volume.append(control) # TRACKPAN Sliders for track_id in range(TRACK_NUMBER): if (TRACKPAN[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKPAN_CH[track_id], TRACKPAN[track_id]) control.name = u'Trk_Pan_Slider_' + str(track_id) self._ctrl_map_trk_pan.append(control) # TRACKSENDA Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDA[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDA_CH[track_id], TRACKSENDA[track_id]) control.name = u'Trk_SendA_Slider_' + str(track_id) self._ctrl_map_senda.append(control) # TRACKSENDB Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDB[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDB_CH[track_id], TRACKSENDB[track_id]) control.name = u'Trk_SendB_Slider_' + str(track_id) self._ctrl_map_sendb.append(control) # TRACKSENDC Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDC[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDC_CH[track_id], TRACKSENDC[track_id]) control.name = u'Trk_SendC_Slider_' + str(track_id) self._ctrl_map_sendc.append(control) # DEVICEBANK Buttons for bank_id in range(BANKS_NUMBER): if (DEVICEBANK[bank_id] == -1): button = None else: button = ButtonElement(is_momentary, DEVICEBANK_TYPE[bank_id], DEVICEBANK_CH[bank_id], DEVICEBANK[bank_id]) button.name = u'Bank_Button_' + str(bank_id) self._note_map_bank_buttons.append(button) # PARAMCONTROL Sliders for param_id in range(PARAMS_NUMBER): if (PARAMCONTROL[param_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, PARAMCONTROL_CH[param_id], PARAMCONTROL[param_id]) control.name = u'Slider_Param_' + str(param_id) self._ctrl_map_parameter.append(control)
class NanoKontrolShift(ControlSurface): __module__ = __name__ __doc__ = " NanoKontrolShift controller script " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._suppress_session_highlight = True self._suppress_send_midi = True # Turn off rebuild MIDI map until after we're done setting up self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log opened =--------------" ) # Writes message into Live's main log file. This is a ControlSurface method. with self.component_guard(): # OBJECTS self.session = None # session object self.mixer = None # mixer object self.view = None # clip/device view object self.device = None # device object self.transport = None # transport object # MODES self._shift_button = None self._shift_button_pressed = False self._alt_button = None self._alt_button_pressed = False self._ctrl_button = None self._ctrl_button_pressed = False # INITIALIZE MIXER, SESSIONS self._setup_session_control() # Setup the session object self._setup_mixer_control() # Setup the mixer object self._setup_view_control() # Setup the clip/view toggler self.session.set_mixer(self.mixer) # Bind mixer to session self._setup_device_control() # Setup the device object self._setup_transport_control() # Setup transport object self.set_device_component( self.device) # Bind device to control surface # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS self._set_modifiers_buttons() self.__update_matrix() self.set_highlighting_session_component(self.session) for component in self.components: component.set_enabled(True) # self._suppress_session_highlight = True self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up def _setup_session_control(self): self.show_message( "#################### SESSION: ON ##############################") is_momentary = True # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX self.session = SessionComponent(num_tracks, num_scenes) # (num_tracks, num_scenes) self.session.set_offsets(0, 0) # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up)) self.session.set_track_bank_buttons( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left) ) # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead... def _setup_mixer_control(self): is_momentary = True # CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON) self.mixer = SpecialMixerComponent( num_tracks, 0, False, False) # 4 tracks, 2 returns, no EQ, no filters self.mixer.name = 'Mixer' self.mixer.set_track_offset( 0) # Sets start point for mixer strip (offset from left) def _setup_view_control(self): # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE self.view = ViewTogglerComponent(num_tracks, self) def _setup_device_control(self): # CREATE DEVICE TO ASSIGN PARAMETERS BANK self.device = DeviceComponent() self.device.name = 'Device_Component' def _setup_transport_control(self): # CREATE TRANSPORT DEVICE self.transport = SpecialTransportComponent(self) def _on_selected_scene_changed(self): # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track if (track.devices is not None): self._ignore_track_selection = True device_to_select = track.devices[0] self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) self._ignore_track_selection = False """ LED ON, OFF, FLASH WITH SESSION CLIPS """ # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES def __update_matrix(self): for scene_index in range(num_scenes): scene = self.session.scene(scene_index) for track_index in range(num_tracks): clip_slot = scene.clip_slot(track_index) button = clip_slot._launch_button_value.subject value_to_send = -1 if clip_slot._clip_slot != None: if clip_slot.has_clip(): value_to_send = 127 if clip_slot._clip_slot.clip.is_triggered: if clip_slot._clip_slot.clip.will_record_on_start: value_to_send = clip_slot._triggered_to_record_value else: value_to_send = clip_slot._triggered_to_play_value ''' elif clip_slot._clip_slot.clip.is_playing: if clip_slot._clip_slot.clip.is_recording: value_to_send = 127 ######### CLIPS PLAYING WILL FLASH for i in range(2000): if i % 50 == 0: button.send_value(127) else: button.send_value(0) else: for i in range(2000): if i % 50 == 0: button.send_value(127) else: button.send_value(0) ''' elif clip_slot._clip_slot.is_triggered: if clip_slot._clip_slot.will_record_on_start: value_to_send = clip_slot._triggered_to_record_value else: value_to_send = clip_slot._triggered_to_play_value elif clip_slot._clip_slot.is_playing: if clip_slot._clip_slot.is_recording: value_to_send = clip_slot._recording_value else: value_to_send = clip_slot._started_value elif clip_slot._clip_slot.controls_other_clips: value_to_send = 0 ''' if value_to_send in range(128): button.send_value(value_to_send) else: button.turn_off() ''' """ MODIFIERS, MODES, KEYS CONFIG """ # MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS def _clear_controls(self): # TURNING OFF ALL LEDS IN MATRIX self._turn_off_matrix() # SESSION resetsend_controls = [] self.mixer.send_controls = [] for scene_index in range(num_scenes): scene = self.session.scene(scene_index) scene.set_launch_button(None) for track_index in range(num_tracks): clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(None) self.session.set_stop_track_clip_buttons(None) self.session.set_stop_all_clips_button(None) # REMOVE LISTENER TO SESSION MOVES if self.session.offset_has_listener(self.__update_matrix): self.session.remove_offset_listener(self.__update_matrix) self.session.set_stop_all_clips_button(None) # MIXER self.mixer._set_send_nav(None, None) for track_index in range(num_tracks): strip = self.mixer.channel_strip(track_index) strip.set_solo_button(None) strip.set_mute_button(None) strip.set_arm_button(None) resetsend_controls.append(None) strip.set_select_button(None) for i in range(12): self.mixer.send_controls.append(None) strip.set_send_controls(tuple(self.mixer.send_controls)) self.mixer.set_resetsend_buttons(tuple(resetsend_controls)) # VIEW self.view.set_device_nav_buttons(None, None) detailclip_view_controls = [] for track_index in range(num_tracks): detailclip_view_controls.append(None) self.view.set_buttons(tuple(detailclip_view_controls)) # DEVICE PARAMETERS device_param_controls = [] self.device.set_parameter_controls(tuple(device_param_controls)) self.device.set_on_off_button(None) self.device.set_lock_button(None) # TRANSPORT self.transport.set_stop_button(None) self.transport.set_play_button(None) self.transport.set_record_button(None) self.transport._set_quant_toggle_button(None) self.transport.set_metronome_button(None) self.transport._set_tempo_buttons(None, None) self.log_message("Controls Cleared") def _set_normal_mode(self): is_momentary = True self.mixer._set_send_nav( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down)) for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.name = 'Mixer_ChannelStrip_' + str(index) self.mixer._update_send_index(self.mixer.sends_index) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_volumefader_cc[index])) self.mixer.send_controls[self.mixer.sends_index] = EncoderElement( MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute) strip.set_send_controls(tuple(self.mixer.send_controls)) strip._invert_mute_feedback = True ### SET ARM, SOLO, MUTE for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.set_send_controls(tuple(self.mixer.send_controls)) strip.set_solo_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index])) strip.set_mute_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index])) strip.set_arm_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index])) # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc)) for i in range(12): self.mixer.send_controls.append(None) self.mixer.send_controls[self.mixer.sends_index] = EncoderElement( MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute) strip.set_send_controls(tuple(self.mixer.send_controls)) strip._invert_mute_feedback = True self.mixer._update_send_index(self.mixer.sends_index) def _set_alt_mode(self): is_momentary = True self.mixer._set_send_nav( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down)) stop_track_controls = [] resetsend_controls = [] button = None buttons = None # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.set_select_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_select_cc[index])) button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, stop_track_cc[index]) stop_track_controls.append(button) buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_resetsend_cc[index]) resetsend_controls.append(buttons) self.session.set_stop_track_clip_buttons(tuple(stop_track_controls)) self.mixer.set_resetsend_buttons(tuple(resetsend_controls)) self.mixer._update_send_index(self.mixer.sends_index) def _set_ctrl_mode(self): # CLIP/DEVICE VIEW TOGGLE is_momentary = True self.view.set_device_nav_buttons( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_right_cc)) button = None detailclip_view_controls = [] for index in range(num_tracks): button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, detailclip_view_cc[index]) detailclip_view_controls.append(button) self.view.set_buttons(tuple(detailclip_view_controls)) # DEVICE ON/OFF, LOCK AND PARAMETERS device_param_controls = [] onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, onoff_device_cc) setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, lock_device_cc) for index in range(num_tracks): knob = None knob = EncoderElement(MIDI_CC_TYPE, CHANNEL, device_param_cc[index], Live.MidiMap.MapMode.absolute) device_param_controls.append(knob) if None not in device_param_controls: self.device.set_parameter_controls(tuple(device_param_controls)) self.device.set_on_off_button(onoff_control) self.device.set_lock_button(setlock_control) # TRANSPORT # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc)) # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc)) # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc)) self.transport._set_quant_toggle_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_quantization_cc)) self.transport.set_metronome_button( ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_metronome_cc)) self.transport._set_tempo_buttons( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempodown_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempoup_cc)) # SESSION STOP ALL CLIPS AND SCENE LAUNCH self.session.set_stop_all_clips_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_stopall_cc)) for index in range(num_scenes): self.session.scene(index).set_launch_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_scenelaunch_cc[index])) def _set_modifiers_buttons(self): is_momentary = True self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, shift_mod) self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, alt_mod) self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, ctrl_mod) if (self._shift_button != None): self._shift_button.add_value_listener(self._shift_value) if (self._alt_button != None): self._alt_button.add_value_listener(self._alt_value) if (self._ctrl_button != None): self._ctrl_button.add_value_listener(self._ctrl_value) # INIT NORMAL MODE self._manage_modes(0) # MODIFIERS LISTENERS FUNCS ARE HERE def _shift_value(self, value): assert isinstance(value, int) assert isinstance(self._shift_button, ButtonElement) if value == 127: if self._shift_button_pressed is False: self._unpress_modes() self._shift_button_pressed = True self._manage_modes(0) def _alt_value(self, value): assert isinstance(value, int) assert isinstance(self._alt_button, ButtonElement) if value == 127: if self._alt_button_pressed is False: self._unpress_modes() self._alt_button_pressed = True self._manage_modes(2) def _ctrl_value(self, value): assert isinstance(value, int) assert isinstance(self._ctrl_button, ButtonElement) if value == 127: if self._ctrl_button_pressed is False: self._unpress_modes() self._ctrl_button_pressed = True self._manage_modes(3) def _manage_modes(self, mode_index): if mode_index == 0: self._clear_controls() self._set_normal_mode() # self._shift_button.turn_on() self._alt_button.turn_on() self._ctrl_button.turn_on() self.log_message("NORMAL ON") elif mode_index == 2: self._clear_controls() self._set_alt_mode() self._alt_button.turn_on() self._shift_button.turn_off() self._ctrl_button.turn_off() self.log_message("ALT ON") elif mode_index == 3: self._clear_controls() self._set_ctrl_mode() self._ctrl_button.turn_on() self._shift_button.turn_off() self._alt_button.turn_off() self.log_message("CTRL ON") def _unpress_modes(self): self._shift_button_pressed = False self._alt_button_pressed = False self._ctrl_button_pressed = False def _turn_off_matrix(self): for index in range(24): self._send_midi(tuple([176, index + 16, 0])) def disconnect(self): """clean things up on disconnect""" self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log closed =--------------" ) # Create entry in log file self._clear_controls() self.session = None self.mixer = None self.view = None self.device = None self.transport = None # MODES self._shift_button = None self._alt_button = None self._ctrl_button = None # SENDS self.send_button_up = None self.send_button_down = None self.send_controls = [] self.send_reset = [] self.set_device_component(None) ControlSurface.disconnect(self) return None