def _setup_mixer_control(self): is_momentary = True num_tracks = 8 num_returns = 7 mixer = MixerComponent(num_tracks, num_returns) for track in range(num_tracks): strip = mixer.channel_strip(track) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, 15, 54 - track)) strip.set_pan_control(SliderElement(MIDI_CC_TYPE, 15, 80 - track)) strip.set_mute_button( ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117 - track)) strip.set_invert_mute_feedback(True) for track in range(num_returns): strip = mixer.return_strip(track) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, 15, 10 + track)) mixer.set_bank_buttons( ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 108), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109)) mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 15, 9)) mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, 15, 46)) session = SessionComponent(0, 0) session.set_select_buttons( ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 95), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 92)) session.selected_scene().set_launch_button( ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 91))
def _setup_mixer_control(self): is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant num_tracks = 7 # 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, 0) #(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 mixer.selected_strip().set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 64)) #mixer.selected_strip().set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44)) mixer.selected_strip().set_arm_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 72)) track_select_notes = [65, 73, 66, 74, 67, 75, 68, 76] #more note numbers need to be added if num_scenes is increased slider_select_notes = [23, 22, 15, 14, 5, 7, 6, 4] pan_select_notes = [21, 20, 13, 12, 3, 1, 0, 2] master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 4) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 76) prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 26, Live.MidiMap.MapMode.absolute) crossfader = SliderElement(MIDI_CC_TYPE, 0, 24) for index in range(num_tracks): mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, track_select_notes[index])) mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, slider_select_notes[index])) mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, pan_select_notes[index], Live.MidiMap.MapMode.absolute)) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' master_select_button.name = 'Master_Select_Button' prehear_control.name = 'Prehear_Volume_Control' mixer.set_crossfader_control(crossfader) mixer.set_prehear_volume_control(prehear_control) mixer.master_strip().set_volume_control(master_volume_control) mixer.master_strip().set_select_button(master_select_button)
def _setup_mixer_control(self): is_momentary = True mixer = MixerComponent(NUM_TRACKS, 2, with_eqs=True, with_filters=True) for track in range(NUM_TRACKS): strip = mixer.channel_strip(track) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 23)) strip.set_pan_control( EncoderElement(MIDI_CC_TYPE, track, 10, Live.MidiMap.MapMode.absolute)) strip.set_send_controls( (EncoderElement(MIDI_CC_TYPE, track, 19, Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, track, 20, Live.MidiMap.MapMode.absolute))) strip.set_solo_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 64)) strip.set_mute_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 63)) strip.set_crossfade_toggle( ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 65)) eq = mixer.track_eq(track) eq.set_gain_controls( tuple([ EncoderElement(MIDI_CC_TYPE, track, 18 - index, Live.MidiMap.MapMode.absolute) for index in range(3) ])) eq.set_cut_buttons( tuple([ ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 62 - index) for index in range(3) ])) filter = mixer.track_filter(track) filter.set_filter_controls( EncoderElement(MIDI_CC_TYPE, track, 22, Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, track, 21, Live.MidiMap.MapMode.absolute)) for ret_track in range(2): strip = mixer.return_strip(ret_track) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, 12, 22 + ret_track)) strip.set_pan_control( EncoderElement(MIDI_CC_TYPE, 12, 20 + ret_track, Live.MidiMap.MapMode.absolute)) strip.set_mute_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 78 + ret_track)) mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 12, 8)) mixer.set_prehear_volume_control( EncoderElement(MIDI_CC_TYPE, 12, 24, Live.MidiMap.MapMode.absolute)) mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, 12, 7)) mixer.master_strip().set_pan_control( EncoderElement(MIDI_CC_TYPE, 12, 10, Live.MidiMap.MapMode.absolute)) return mixer
def _setup_mixer_control(self): is_momentary = True mixer = MixerComponent(NUM_TRACKS, 2, with_eqs=True, with_filters=True) for track in range(NUM_TRACKS): strip = mixer.channel_strip(track) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 23)) strip.set_pan_control(EncoderElement(MIDI_CC_TYPE, track, 10, Live.MidiMap.MapMode.absolute)) strip.set_send_controls((EncoderElement(MIDI_CC_TYPE, track, 19, Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, track, 20, Live.MidiMap.MapMode.absolute))) strip.set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 64)) strip.set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 63)) strip.set_crossfade_toggle(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 65)) eq = mixer.track_eq(track) eq.set_gain_controls(tuple([ EncoderElement(MIDI_CC_TYPE, track, (18 - index), Live.MidiMap.MapMode.absolute) for index in range(3) ])) eq.set_cut_buttons(tuple([ ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, (62 - index)) for index in range(3) ])) filter = mixer.track_filter(track) filter.set_filter_controls(EncoderElement(MIDI_CC_TYPE, track, 22, Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, track, 21, Live.MidiMap.MapMode.absolute)) for ret_track in range(2): strip = mixer.return_strip(ret_track) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, 12, (22 + ret_track))) strip.set_pan_control(EncoderElement(MIDI_CC_TYPE, 12, (20 + ret_track), Live.MidiMap.MapMode.absolute)) strip.set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, (78 + ret_track))) mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 12, 8)) mixer.set_prehear_volume_control(EncoderElement(MIDI_CC_TYPE, 12, 24, Live.MidiMap.MapMode.absolute)) mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 12, 7)) mixer.master_strip().set_pan_control(EncoderElement(MIDI_CC_TYPE, 12, 10, Live.MidiMap.MapMode.absolute)) return mixer
def _setup_mixer_control(self): is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant num_tracks = 4 # 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, 2, with_eqs=True, with_filters=False) #(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 #mute_notes = [1,5,9,13] #solo_notes = [2,6,10,14] #arm_notes = [3,7,11,15] track_select_notes = [38,39,40,41]#more note numbers need to be added if num_scenes is increased send_ccs = [2,6,10,14,1,5,9,13] pan_ccs = [3,7,11,15] slider_ccs = [4,8,12,16] for index in range(num_tracks): mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, track_select_notes[index])) mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHAN, slider_ccs[index])) mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHAN, pan_ccs[index], Live.MidiMap.MapMode.absolute)) #put send A and send B controllers into an array, which is then "tupled" for set_send_controls: send_controlers = [EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index], Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index+num_tracks], Live.MidiMap.MapMode.absolute)] mixer.channel_strip(index).set_send_controls(tuple(send_controlers)) crossfader = SliderElement(MIDI_CC_TYPE, CHAN, 28) master_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 32) returna_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 19) returna_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 20) returnb_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 23) returnb_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 24) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 31) prehear_control = EncoderElement(MIDI_CC_TYPE, CHAN, 30, Live.MidiMap.MapMode.absolute) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' returna_pan_control.name = 'ReturnA_Pan_Control' returna_volume_control.name = 'ReturnA_Volume_Control' returnb_pan_control.name = 'ReturnB_Pan_Control' returnb_volume_control.name = 'ReturnB_Volume_Control' master_select_button.name = 'Master_Select_Button' prehear_control.name = 'Prehear_Volume_Control' mixer.set_crossfader_control(crossfader) mixer.master_strip().set_volume_control(master_volume_control) mixer.master_strip().set_select_button(master_select_button) mixer.set_prehear_volume_control(prehear_control) mixer.return_strip(0).set_pan_control(returna_pan_control) mixer.return_strip(0).set_volume_control(returna_volume_control) mixer.return_strip(1).set_pan_control(returnb_pan_control) mixer.return_strip(1).set_volume_control(returnb_volume_control)
def _setup_mixer_control(self): is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant num_tracks = 7 # 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, 0) #(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 mixer.selected_strip().set_mute_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 64)) #mixer.selected_strip().set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44)) mixer.selected_strip().set_arm_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 72)) track_select_notes = [ 65, 73, 66, 74, 67, 75, 68, 76 ] #more note numbers need to be added if num_scenes is increased slider_select_notes = [23, 22, 15, 14, 5, 7, 6, 4] pan_select_notes = [21, 20, 13, 12, 3, 1, 0, 2] master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 4) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 76) prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 26, Live.MidiMap.MapMode.absolute) crossfader = SliderElement(MIDI_CC_TYPE, 0, 24) for index in range(num_tracks): mixer.channel_strip(index).set_select_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, track_select_notes[index])) mixer.channel_strip(index).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, slider_select_notes[index])) mixer.channel_strip(index).set_pan_control( EncoderElement(MIDI_CC_TYPE, CHANNEL, pan_select_notes[index], Live.MidiMap.MapMode.absolute)) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' master_select_button.name = 'Master_Select_Button' prehear_control.name = 'Prehear_Volume_Control' mixer.set_crossfader_control(crossfader) mixer.set_prehear_volume_control(prehear_control) mixer.master_strip().set_volume_control(master_volume_control) mixer.master_strip().set_select_button(master_select_button)
def _setup_mixer_control(self): is_momentary = True num_tracks = 8 num_returns = 7 mixer = MixerComponent(num_tracks, num_returns) for track in range(num_tracks): strip = mixer.channel_strip(track) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 54 - track)) strip.set_pan_control(SliderElement(MIDI_CC_TYPE, 15, 80 - track)) strip.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117 - track)) strip.set_invert_mute_feedback(True) for track in range(num_returns): strip = mixer.return_strip(track) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 10 + track)) mixer.set_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 108), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109)) mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 15, 9)) mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 46)) session = SessionComponent(0, 0) session.set_select_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 95), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 92)) session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 91))
class Codex(Codec): def __init__(self, c_instance, *a, **k): self._shifted = False super(Codex, self).__init__(c_instance, *a, **k) with self.component_guard(): self._setup_alt_mixer() self._setup_alt_device_selector() self._setup_alt_send_reset() self._setup_alt_device_control() self.log_message( '<<<<<<<<<<<<<<<<<<<<<<<<< Codex subclass log opened >>>>>>>>>>>>>>>>>>>>>>>>>' ) self.schedule_message(1, self._mode_update) def _setup_alt_device_selector(self): self._alt_device_selector = NewDeviceSelectorComponent(self) self._alt_device_selector.name = 'Alt_Device_Selector' def _setup_alt_send_reset(self): self._alt_send_reset = ResetSendsComponent(self) self._alt_send_reset.name = 'Alt_Reset_Sends' """these two secondary DeviceComponents are only set up if the MONOHM_LINK flag in Map is turned on""" def _setup_alt_device_control(self): self._device1 = NewDeviceComponent() self._device1.name = 'Device_Component1' self._device2 = NewDeviceComponent() self._device2.name = 'Device_Component2' def _setup_alt_mixer(self): is_momentary = True self._num_tracks = (8) #A mixer is one-dimensional self._mixer2 = MixerComponent(8, 4, False, False) self._mixer2.name = 'Mixer' #self._mixer2.set_track_offset(4) #Sets start point for mixer strip (offset from left) for index in range(8): self._mixer2.channel_strip( index).name = 'Mixer_ChannelStrip_' + str(index) self._mixer2.channel_strip(index)._invert_mute_feedback = True """Mode Functions""" def _enable_alt(self): if self._main_mode._mode_index == 0: for encoder, _ in self._encoder_matrix.submatrix[:, 0:2].iterbuttons( ): encoder.set_enabled(False) encoder.reset() self._alt_enabled = True self._mode_update() super(Codex, self)._enable_alt() def _disable_alt(self): if self._main_mode._mode_index == 0: self._button_matrix.submatrix[:, 0:2].reset() for encoder, _ in self._encoder_matrix.submatrix[:, 0:2].iterbuttons( ): encoder.set_enabled(True) super(Codex, self)._disable_alt() def _deassign_all(self): self._alt_send_reset.set_buttons(tuple([None for index in range(4)])) self._alt_send_reset.set_enabled(False) self._alt_device_selector.set_buttons(None) self._alt_device_selector.set_enabled(False) self._mixer2.selected_strip().set_send_controls(None) for index in range(8): self._mixer2.channel_strip(index).set_volume_control(None) self._mixer2.channel_strip(index).set_select_button(None) self._mixer2.channel_strip(index).set_mute_button(None) self._dial[index][2].release_parameter() for index in range(3): self._mixer2.return_strip(index).set_volume_control(None) self._device1.set_enabled(False) self._device1._parameter_controls = None self._device2.set_enabled(False) self._device2._parameter_controls = None self._mixer2.return_strip(0).set_send_controls(None) self._mixer2.return_strip(1).set_send_controls(None) self._mixer2.return_strip(2).set_send_controls(None) super(Codex, self)._deassign_all() def _assign_volume(self): if self._alt_enabled: inputs = self.find_inputs() if not inputs is None: for index in range(4): self._dial[index][2].connect_to(inputs.parameters[index + 1]) self._dial[6][2].connect_to(inputs.parameters[5]) xfade = self.find_perc_crossfader() if not xfade is None: self._dial[7][3].connect_to(xfade) self._alt_device_selector.set_matrix( self._button_matrix.submatrix[:, 0:2]) self._alt_device_selector.set_enabled(True) self._mixer2.return_strip(0).set_send_controls( [None, self._dial[4][2]]) self._mixer2.return_strip(1).set_send_controls( [self._dial[5][2], None]) else: self._alt_send_reset.set_buttons( tuple([ self._button[4][2], self._button[5][2], self._button[6][2], self._button[7][2] ])) self._alt_send_reset.set_enabled(True) self._mixer2.selected_strip().set_send_controls([ self._dial[0][2], self._dial[1][2], self._dial[2][2], self._dial[3][2] ]) for index in range(3): self._mixer2.return_strip(index).set_volume_control( self._dial[index + 4][2]) self._mixer2.set_crossfader_control(self._dial[7][2]) self._device1.set_parameter_controls( tuple([ self._dial[index % 4][int(index / 4)] for index in range(8) ])) self._device2.set_parameter_controls( tuple([ self._dial[(index % 4) + 4][int(index / 4)] for index in range(8) ])) self._device1.set_enabled(True) self._device2.set_enabled(True) self._find_devices() self._device1.update() self._device2.update() for index in range(8): self._mixer2.channel_strip(index).set_select_button( self._column_button[index]) for index in range(8): self._mixer2.channel_strip(index).set_volume_control( self._dial[index][3]) self._mixer2.channel_strip(index).set_mute_button( self._button[index][3]) self._mixer2.update() self.request_rebuild_midi_map() #self._mixer2.set_track_offset(TROLL_OFFSET) def find_inputs(self): found_device = None tracks = self.song().tracks for track in tracks: if track.name == 'Inputs': for device in track.devices: if bool(device.can_have_chains ) and device.name == 'Inputs': found_device = device return found_device def find_perc_crossfader(self): found_parameter = None tracks = self.song().tracks for track in tracks: if track.name == 'Perc': for device in track.devices: if bool(device.can_have_chains) and device.name == 'Perc': for parameter in device.parameters: if parameter.name == 'XFade': found_parameter = parameter return found_parameter """this method is used to find the devices the alt controls will latch to""" def _find_devices(self): if self._device1: if len(self.song().return_tracks) > 0: if len(self.song().return_tracks[0].devices) > 0: if self._device1._locked_to_device: self._device1.set_lock_to_device( False, self._device1._device) self._device1.set_lock_to_device( True, self.song().return_tracks[0].devices[0]) if self._device2: if len(self.song().return_tracks) > 1: if len(self.song().return_tracks[1].devices) > 0: if self._device2._locked_to_device: self._device2.set_lock_to_device( False, self._device2._device) self._device2.set_lock_to_device( True, self.song().return_tracks[1].devices[0])
class Codex(Codec): def __init__(self, c_instance, *a, **k): self._shifted = False super(Codex, self).__init__(c_instance, *a, **k) with self.component_guard(): self._setup_alt_mixer() self._setup_alt_device_selector() self._setup_alt_send_reset() self._setup_alt_device_control() self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codex subclass log opened >>>>>>>>>>>>>>>>>>>>>>>>>') self.schedule_message(1, self._mode_update) def _setup_alt_device_selector(self): self._alt_device_selector = NewDeviceSelectorComponent(self) self._alt_device_selector.name = 'Alt_Device_Selector' def _setup_alt_send_reset(self): self._alt_send_reset = ResetSendsComponent(self) self._alt_send_reset.name = 'Alt_Reset_Sends' """these two secondary DeviceComponents are only set up if the MONOHM_LINK flag in Map is turned on""" def _setup_alt_device_control(self): self._device1 = NewDeviceComponent() self._device1.name = 'Device_Component1' self._device2 = NewDeviceComponent() self._device2.name = 'Device_Component2' def _setup_alt_mixer(self): is_momentary = True self._num_tracks = (8) #A mixer is one-dimensional self._mixer2 = MixerComponent(8, 4, False, False) self._mixer2.name = 'Mixer' #self._mixer2.set_track_offset(4) #Sets start point for mixer strip (offset from left) for index in range(8): self._mixer2.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) self._mixer2.channel_strip(index)._invert_mute_feedback = True """Mode Functions""" def _enable_alt(self): if self._main_mode._mode_index == 0: for encoder, _ in self._encoder_matrix.submatrix[:, 0:2].iterbuttons(): encoder.set_enabled(False) encoder.reset() self._alt_enabled = True self._mode_update() super(Codex, self)._enable_alt() def _disable_alt(self): if self._main_mode._mode_index == 0: self._button_matrix.submatrix[:, 0:2].reset() for encoder, _ in self._encoder_matrix.submatrix[:, 0:2].iterbuttons(): encoder.set_enabled(True) super(Codex, self)._disable_alt() def _deassign_all(self): self._alt_send_reset.set_buttons(None) self._alt_send_reset.set_enabled(False) self._alt_device_selector.set_buttons(None) self._alt_device_selector.set_enabled(False) self._mixer2.selected_strip().set_send_controls(None) for index in range(8): self._mixer2.channel_strip(index).set_volume_control(None) self._mixer2.channel_strip(index).set_select_button(None) self._mixer2.channel_strip(index).set_mute_button(None) self._dial[index][2].release_parameter() for index in range(3): self._mixer2.return_strip(index).set_volume_control(None) self._device1.set_enabled(False) self._device1._parameter_controls = None self._device2.set_enabled(False) self._device2._parameter_controls = None self._mixer2.return_strip(0).set_send_controls(None) self._mixer2.return_strip(1).set_send_controls(None) self._mixer2.return_strip(2).set_send_controls(None) super(Codex, self)._deassign_all() def _assign_volume(self): if self._alt_enabled: inputs = self.find_inputs() if not inputs is None: for index in range(4): self._dial[index][2].connect_to(inputs.parameters[index+1]) self._dial[6][2].connect_to(inputs.parameters[5]) xfade = self.find_perc_crossfader() if not xfade is None: self._dial[7][3].connect_to(xfade) self._alt_device_selector.set_matrix(self._button_matrix.submatrix[:, 0:2]) self._alt_device_selector.set_enabled(True) self._mixer2.return_strip(0).set_send_controls([None, self._dial[4][2]]) self._mixer2.return_strip(1).set_send_controls([self._dial[5][2], None]) else: self._alt_send_reset.set_buttons(self._button_matrix.submatrix[4:, 2]) self._alt_send_reset.set_enabled(True) self._mixer2.selected_strip().set_send_controls([self._dial[0][2], self._dial[1][2], self._dial[2][2], self._dial[3][2]]) for index in range(3): self._mixer2.return_strip(index).set_volume_control(self._dial[index+4][2]) self._mixer2.set_crossfader_control(self._dial[7][2]) self._device1.set_parameter_controls(tuple([self._dial[index%4][int(index/4)] for index in range(8)])) self._device2.set_parameter_controls(tuple([self._dial[(index%4)+4][int(index/4)] for index in range(8)])) self._device1.set_enabled(True) self._device2.set_enabled(True) self._find_devices() self._device1.update() self._device2.update() for index in range(8): self._mixer2.channel_strip(index).set_select_button(self._column_button[index]) for index in range(8): self._mixer2.channel_strip(index).set_volume_control(self._dial[index][3]) self._mixer2.channel_strip(index).set_mute_button(self._button[index][3]) self._mixer2.update() self.request_rebuild_midi_map() #self._mixer2.set_track_offset(TROLL_OFFSET) def find_inputs(self): found_device = None tracks = self.song().tracks for track in tracks: if track.name == 'Inputs': for device in track.devices: if bool(device.can_have_chains) and device.name.endswith('Inputs'): found_device = device return found_device def find_perc_crossfader(self): found_parameter = None tracks = self.song().tracks for track in tracks: if track.name == 'Perc': for device in track.devices: if bool(device.can_have_chains) and device.name == 'Perc': for parameter in device.parameters: if parameter.name == 'XFade': found_parameter = parameter return found_parameter """this method is used to find the devices the alt controls will latch to""" def _find_devices(self): if self._device1: if len(self.song().return_tracks) > 0: if len(self.song().return_tracks[0].devices) > 0: if self._device1._locked_to_device: self._device1.set_lock_to_device(False, self._device1._device) self._device1.set_lock_to_device(True, self.song().return_tracks[0].devices[0]) if self._device2: if len(self.song().return_tracks) > 1: if len(self.song().return_tracks[1].devices) > 0: if self._device2._locked_to_device: self._device2.set_lock_to_device(False, self._device2._device) self._device2.set_lock_to_device(True, self.song().return_tracks[1].devices[0]) # #
class Tweaker(ControlSurface): __module__ = __name__ __doc__ = " Tweaker control surface script " def __init__(self, c_instance, *a, **k): super(Tweaker, self).__init__(c_instance, *a, **k) with self.component_guard(): self._update_linked_device_selection = None self._tweaker_version_check = '0.3' self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log opened =--------------") self._timer = 0 self.flash_status = 1 self._last_selected_strip_number = 0 self._device_selection_follows_track_selection = False #self._pad_translations = PAD_TRANSLATION self._linked_session = None self._mixer_offset = 0 self._nav_lock = True self._setup_controls() self._setup_transport_control() self._setup_device_control() self._setup_mixer_control() self._setup_session_control() self._setup_crossfader() self._setup_modes() self._setup_pads() self._setup_navigation_lock() self._setup_arrange_session_toggle() #self.assign_main_configuration() #self.request_rebuild_midi_map() #self._mixer._reassign_tracks() #this is to update rebuild the cf_assign closure, otherwise the colors aren't correct #self.schedule_message(30, self._detect_devices) self.show_message('Tweaker Control Surface Loaded') self.show_message('Tweaker Control Surface Loaded') #self._shift_value(0) #this updates the pads so that they transmit to Live on the assigned PAD_CHANNEL...also, lights shift button self.assign_main_configuration() #self.schedule_message(2, self._shift_value, 0) self.schedule_message(3, self._mixer._reassign_tracks) """script initialization methods""" def _setup_controls(self): is_momentary = True self._grid = [None for index in range(8)] for column in range(8): self._grid[column] = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column + (row * 8) + 1, 'Grid_' + str(column) + '_' + str(row), self) for row in range(4)] self._button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_BUTTONS[index], 'Button_' + str(index), self) for index in range(len(TWEAKER_BUTTONS))] self._nav = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_NAVS[index], 'Nav_' + str(index), self) for index in range(len(TWEAKER_NAVS))] self._encoder_button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_ENCODER_BUTTONS[index], 'Encoder_Button_' + str(index), self) for index in range(len(TWEAKER_ENCODER_BUTTONS))] self._dial = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_DIALS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_DIALS))] self._fader = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_FADERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_FADERS))] self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._encoder = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_ENCODERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_ENCODERS))] self._pad = [TweakerMonoButtonElement(False, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_PADS[index], 'Pad_' + str(index), self) for index in range(len(TWEAKER_PADS))] for index in range(4): self._pad[index].set_enabled(False) self._pad[index].set_channel(PAD_CHANNEL) self._pad[index].set_identifier(index + 4) self._pad[index+4].set_enabled(False) self._pad[index+4].set_channel(PAD_CHANNEL) self._pad[index+4].set_identifier(index) self._pad_pressure = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_PAD_PRESSURES[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_PADS))] for index in range(8): self._pad_pressure[index]._last_sent = 0 self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' for row in range(4): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode self._send_midi(tuple([240, 0, 1, 106, 1, 6, 127 , 127, 25, 0, 15, 0, 9, PAD_SENSITIVITY, 247])) #set pads to sensitivity set in Map file def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' def _setup_mixer_control(self): is_momentary = True self._num_tracks = (2) #A mixer is one-dimensional; self._mixer = MixerComponent(2, 0, False, False) self._mixer.name = 'Mixer' self._mixer.tracks_to_use = self._mixer_tracks_to_use(self._mixer) self._device_navigator = [None for index in range(2)] self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) for index in range(2): self._mixer.channel_strip(index).set_volume_control(self._fader[index]) self._mixer.channel_strip(index)._on_cf_assign_changed = self._channelstrip_on_cf_assign_changed(self._mixer.channel_strip(index)) self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) #mixer.track_filter(index).name = 'Mixer_TrackFilter_' + str(index) self._mixer.channel_strip(index)._invert_mute_feedback = True self._mixer.channel_strip(index)._device_component = self._device[index] self._mixer.channel_strip(index).update = self._channelstrip_update(self._mixer.channel_strip(index)) self._mixer.channel_strip(index)._select_value = self._channelstrip_select_value(self._mixer.channel_strip(index), index) self._device_navigator[index] = DetailViewControllerComponent(self, self._mixer.channel_strip(index)) self._device_navigator[index].name = 'Device_Navigator_'+str(index) self._mixer.channel_strip(0).set_track = self._channelstrip_set_track(self._mixer.channel_strip(0), self._channelstrip1_cb) self._mixer.channel_strip(1).set_track = self._channelstrip_set_track(self._mixer.channel_strip(1), self._channelstrip2_cb) self.song().view.selected_track = self._mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error #self._mixer._reassign_tracks() def _setup_session_control(self): is_momentary = True num_tracks = NUM_TRACKS num_scenes = NUM_SCENES self._session = SessionComponent(num_tracks, num_scenes) self._session.name = "Session" self._session.set_offsets(0, 0) self._session.set_stop_track_clip_value(STOP_CLIP) self._scene = [None for index in range(3)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY) clip_slot.set_triggered_to_record_value(CLIP_TRG_REC) clip_slot.set_stopped_value(CLIP_STOP) clip_slot.set_started_value(CLIP_STARTED) clip_slot.set_recording_value(CLIP_RECORDING) self._session._stop_track_value = self._session_stop_track_value(self._session) self._session._on_fired_slot_index_changed = self._session_on_fired_slot_index_changed(self._session) self._session._change_offsets = self._session_change_offsets(self._session) self._session.update = self._session_update(self._session) #self._session.add_offset_listener(self._update_navigation_view) self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_stopped_value(ZOOM_STOPPED) self._session_zoom.set_playing_value(ZOOM_PLAYING) self._session_zoom.set_selected_value(ZOOM_SELECTED) #self._session_zoom.set_enabled(True) def _setup_device_control(self): self._device = [None for index in range(2)] for index in range(2): self._device[index] = DeviceComponent() self._device[index].name = 'Device_Component_'+str(index) self._device[index].set_enabled(True) self._device[index]._number_of_parameter_banks = self._device_number_of_parameter_banks(self._device[index]) self._device[index]._assign_parameters = self._device_assign_parameters(self._device[index]) self._device[index]._device_banks = DEVICE_DICT self._device[index]._device_best_banks = DEVICE_BOB_DICT self._device[index]._device_bank_names = BANK_NAME_DICT def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def _setup_modes(self): self._pad_offset = PadOffsetComponent(self) self._pad_offset._set_protected_mode_index(0) self._pad_offset.set_enabled(False) def _setup_pads(self): for pad in self._pad_pressure: pad.add_value_listener(self._light_pad, True) def _setup_navigation_lock(self): if(self._encoder_button[0].value_has_listener(self._nav_lock_value)): self._encoder_button[0].remove_value_listener(self._nav_lock_value) self._encoder_button[0].add_value_listener(self._nav_lock_value) def _setup_arrange_session_toggle(self): if(self._nav[1].value_has_listener(self._arrange_session_value)): self._nav[1].remove_value_listener(self._arrange_session_value) self._nav[1].add_value_listener(self._arrange_session_value) """configuration methods""" def assign_main_configuration(self): for column in range(7): for row in range(3): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) self._session.set_stop_track_clip_buttons(tuple([self._grid[index][3] for index in range(7)])) for row in range(3): self._scene[row].set_launch_button(self._grid[7][row]) self._device[0].set_parameter_controls(tuple([self._encoder[index+1] for index in range(3)])) self._device[0].set_enabled(True) self._device[1].set_parameter_controls(tuple([self._encoder[index+4] for index in range(3)])) self._device[1].set_enabled(True) for track in range(2): self._mixer.channel_strip(track).set_volume_control(self._fader[track]) self._mixer.channel_strip(track).set_solo_button(self._button[track*3]) self._button[track*3].set_on_off_values(SOLO, 0) self._mixer.channel_strip(track).set_arm_button(self._button[1 + (track*3)]) self._button[1 + (track*3)].set_on_off_values(ARM, 0) self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)]) self._mixer.master_strip().set_volume_control(self._dial[1]) self._mixer.set_prehear_volume_control(self._dial[0]) self._session.set_track_bank_buttons(self._nav[4], self._nav[3]) self._session.set_scene_bank_buttons(self._nav[2], self._nav[0]) self._session_zoom.set_zoom_button(self._grid[7][3]) self._session_zoom.set_nav_buttons(self._nav[0], self._nav[2], self._nav[3], self._nav[4]) self._session_zoom.set_button_matrix(self._matrix) self._device[0].set_on_off_button(self._encoder_button[1]) self._device_navigator[0].set_device_nav_buttons(self._encoder_button[2], self._encoder_button[3]) self._device[1].set_on_off_button(self._encoder_button[4]) self._device_navigator[1].set_device_nav_buttons(self._encoder_button[5], self._encoder_button[6]) for track in range(2): self._update_device(self._mixer.channel_strip(track)) #self._device.set_bank_nav_buttons(self._menu[0], self._menu[3]) self.assign_track_selector(self._encoder[0]) #for index in range(8): # self._pad[index].send_value(1, True) # self._pad[index].set_channel(1) # self._pad[index].set_identifier(index) # self._pad[index].set_enabled(False) #this has to happen for translate to work if not self._grid[7][3].value_has_listener(self._shift_value): self._grid[7][3].add_value_listener(self._shift_value) self._grid[7][3].send_value(127, True) self.request_rebuild_midi_map() """Tweaker custom methods""" def _shift_value(self, value): self._pad_offset.set_enabled(value>0) if value > 0: self._update_navigation_view() for pad in self._pad: pad.use_default_message() pad.set_enabled(True) self._pad_offset.set_mode_buttons(tuple(self._pad)) self.schedule_message(1, self._pad_offset.update) if self._session.is_enabled(): #self._update_navigation_view() #self.schedule_message(1, self._update_navigation_veiw) self._update_navigation_view() self._grid[7][3].send_value(SHIFT_ON) for track in range(2): self._mixer.channel_strip(track).set_crossfade_toggle(None) self._mixer.channel_strip(track).set_select_button(self._button[2 + (track*3)]) else: self._pad_offset.set_mode_buttons(None) for index in range(4): self._pad[index].set_enabled(False) self._pad[index].set_channel(PAD_CHANNEL) self._pad[index].set_identifier(index + 4 + (self._pad_offset._mode_index * 8)) self._pad[index+4].set_enabled(False) self._pad[index+4].set_channel(PAD_CHANNEL) self._pad[index+4].set_identifier(index + (self._pad_offset._mode_index * 8)) self._grid[7][3].send_value(SHIFT_OFF) for track in range(2): self._mixer.channel_strip(track).set_select_button(None) self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)]) def assign_track_selector(self, encoder): assert isinstance(encoder, EncoderElement) if not encoder.value_has_listener(self._track_selector_value): encoder.add_value_listener(self._track_selector_value) def deassign_track_selector(self, encoder): if encoder.value_has_listener(self._track_selector_value): encoder.remove_value_listener(self._track_selector_value) def _nav_lock_value(self, value): if value > 0: if self._nav_lock: self._mixer_offset = self._mixer_offset + self._session._track_offset self._mixer.set_track_offset(self._mixer_offset) else: if self._mixer_offset in range(self._session._track_offset, self._session._track_offset + 5): self._mixer_offset = self._mixer_offset - self._session._track_offset elif self._mixer_offset < self._session._track_offset: self._mixer_offset = 0 else: self._mixer_offset = min(self._session._track_offset+5, len(self._session.tracks_to_use())-2) self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset) self._nav_lock = not self._nav_lock self._session.update() def _arrange_session_value(self, value): if value > 0: if (self.application().view.is_view_visible('Arranger')): self.application().view.show_view('Session') else: self.application().view.show_view('Arranger') def _track_selector_value(self, value): if(value is 1): if self._nav_lock: self._mixer_offset = min(self._mixer_offset + 1, min(NUM_TRACKS - 2, len(self._session.tracks_to_use())-self._session._track_offset-2)) else: self._mixer_offset = min(self._mixer_offset + 1, len(self._session.tracks_to_use())-2) elif(value is 127): self._mixer_offset = max(self._mixer_offset - 1, 0) if self._nav_lock: self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset) #self._session.set_offsets(self._session._track_offset) ?? else: self._mixer.set_track_offset(self._mixer_offset) self._session.update() if self._mixer.channel_strip(self._last_selected_strip_number)._track != None: self.song().view.selected_track = self._mixer.channel_strip(self._last_selected_strip_number)._track if self._linked_session != None: if self._linked_session._is_linked(): self._linked_session._unlink() self._linked_session.set_offsets(self._mixer._track_offset, self._linked_session._scene_offset) self._linked_session._link() def _update_navigation_view(self): dif = self._mixer._track_offset - self._session._track_offset for index in range(7): #if (index + self._session._track_offset) in range(len(self._session.tracks_to_use())): if (index + self._session._track_offset) in range(0, len(self.song().visible_tracks)): self._grid[index][3].send_value(NAV_COLORS[int(index in range(dif, dif + 2))], True) elif (index + self._session._track_offset) in range(len(self.song().visible_tracks), len(self._session.tracks_to_use())): self._grid[index][3].send_value(RETURN_NAV_COLORS[int(index in range(dif, dif + 2))], True) else: self._grid[index][3].send_value(0, True) self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode def _update_device(self, channelstrip): for control in channelstrip._device_component._parameter_controls: control.send_value(0, True) if channelstrip._device_component._on_off_button != None: channelstrip._device_component._on_off_button.turn_off() if not channelstrip._track is None: if not channelstrip._device_component._device in channelstrip._track.devices: track = channelstrip._track device_to_select = track.view.selected_device if (device_to_select == None) and (len(track.devices) > 0): device_to_select = track.devices[0] elif channelstrip._device_component and not type(channelstrip._device_component) is type(None): channelstrip._device_component.set_device(device_to_select) else: channelstrip._device_component.set_device(None) else: pass else: channelstrip._device_component.set_device(None) channelstrip._device_component._on_on_off_changed() def _light_pad(self, value, sender): if not self._pad_offset.is_enabled(): if value > sender._last_sent: if self._pad[self._pad_pressure.index(sender)]._last_sent_value < 1: self._pad[self._pad_pressure.index(sender)].send_value(127, True) else: self._pad[self._pad_pressure.index(sender)].send_value(0, True) sender._last_sent = value """called on timer""" def update_display(self): super(Tweaker, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, TweakerMonoButtonElement): control.flash(self._timer) """m4l bridge""" def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if (not display_string): return (' ' * NUM_CHARS_PER_DISPLAY_STRIP) if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))): display_string = display_string[:-2] if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)): for um in [' ', 'i', 'o', 'u', 'e', 'a']: while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)): um_pos = display_string.rfind(um, 1) display_string = (display_string[:um_pos] + display_string[(um_pos + 1):]) else: display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u'' for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)): ret += ' ' else: ret += display_string[i] ret += ' ' return ret def notification_to_bridge(self, name, value, sender): if(isinstance(sender, MonoEncoderElement2)): self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) def touched(self): if(self._shift_mode._mode_index < 2): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched +=1 def check_touch(self): if(self._shift_mode._mode_index < 2): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) def handle_sysex(self, midi_bytes): pass """general functionality""" def disconnect(self): """clean things up on disconnect""" #self._update_linked_device_selection = None if self._session.offset_has_listener(self._update_navigation_view): self._session.remove_offset_listener(self._update_navigation_view) if(self._nav[1].value_has_listener(self._arrange_session_value)): self._nav[1].remove_value_listener(self._arrange_session_value) if(self._encoder_button[0].value_has_listener(self._nav_lock_value)): self._encoder_button[0].remove_value_listener(self._nav_lock_value) for pad in self._pad_pressure: if pad.value_has_listener(self._light_pad): pad.remove_value_listener(self._light_pad) if self._grid[7][3].value_has_listener(self._shift_value): self._grid[7][3].remove_value_listener(self._shift_value) if self._session._is_linked(): self._session._unlink() self.deassign_track_selector(self._encoder[0]) self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log closed =--------------") #Create entry in log file super(Tweaker, self).disconnect() return None def _get_num_tracks(self): return self.num_tracks def _on_selected_track_changed(self): super(Tweaker, self)._on_selected_track_changed() if self._session.is_enabled(): self._session.update() for index in range(2): self._update_device(self._mixer.channel_strip(index)) self._mixer.on_selected_track_changed() def connect_script_instances(self, instanciated_scripts): link = False for s in instanciated_scripts: if '_tweaker_version' in dir(s): if s._tweaker_version == self._tweaker_version_check: link = True break if link == True: if not self._session._is_linked(): self._session._link() """SessionComponent overrides""" def _session_update(self, session): def _update(): SessionComponent.update(session) if session.is_enabled(): self._update_navigation_view() return _update def _session_change_offsets(self, session): def _change_offsets(track_increment, scene_increment): offsets_changed = (track_increment != 0) or (scene_increment != 0) if offsets_changed: session._track_offset += track_increment session._scene_offset += scene_increment assert (session._track_offset >= 0) assert (session._scene_offset >= 0) if (session._mixer != None): if(self._nav_lock): if (session.track_offset() + self._mixer_offset) > (len(session.tracks_to_use())-2): self._mixer_offset = max(len(session.tracks_to_use()) - session._track_offset - 2, 0) session._mixer.set_track_offset(max(0, session.track_offset() + self._mixer_offset)) session._reassign_tracks() if offsets_changed: session._reassign_scenes() # this is replaced by notify_offset() in Live9 #for callback in session._offset_callbacks: # this is replaced by notify_offset() in Live9 # callback() session.notify_offset() self._update_navigation_view() if self._mixer.channel_strip(self._last_selected_strip_number)._track != None: self.song().view.selected_track = self._mixer.channel_strip(self._last_selected_strip_number)._track if ((session.width() > 0) and (session.height() > 0)): session._do_show_highlight() return _change_offsets def _session_on_fired_slot_index_changed(self, session): def _on_fired_slot_index_changed(index): tracks_to_use = tuple(self.song().visible_tracks) + tuple(self.song().return_tracks) track_index = index + session.track_offset() if session.is_enabled() and session._stop_track_clip_buttons != None: if index < len(session._stop_track_clip_buttons): button = session._stop_track_clip_buttons[index] if button != None: if(track_index < len(tracks_to_use)) and (tracks_to_use[track_index].clip_slots) and (tracks_to_use[track_index].fired_slot_index == -2): button.send_value(session._stop_track_clip_value) #elif index in range(len(session.tracks_to_use())): # dif = self._mixer._track_offset - self._session._track_offset # button.send_value(NAV_COLORS[int(index in range(dif, dif + 2))], True) #else: # button.turn_off() else: self._update_navigation_view() return _on_fired_slot_index_changed def _session_stop_track_value(self, session): def _stop_track_value(value, sender): assert (session._stop_track_clip_buttons != None) assert (list(session._stop_track_clip_buttons).count(sender) == 1) assert (value in range(128)) if session.is_enabled(): if ((value is not 0) or (not sender.is_momentary())): tracks = session.tracks_to_use() track_index = (list(session._stop_track_clip_buttons).index(sender) + session.track_offset()) if (track_index in range(len(tracks))) and (tracks[track_index] in session.song().tracks): tracks[track_index].stop_all_clips() sender.send_value(3, True) self.schedule_message(10, self._update_navigation_view) return _stop_track_value """ChannelStripComponent overrides""" def _channelstrip_update(self, channelstrip): def _update(): ChannelStripComponent.update(channelstrip) self._update_device(channelstrip) return _update def _channelstrip_set_track(self, channelstrip, cb): def _set_track(track): assert ((track == None) or isinstance(track, Live.Track.Track)) if channelstrip._track != None and isinstance(channelstrip._track, Live.Track.Track): if channelstrip._track.devices_has_listener(cb): channelstrip._track.remove_devices_listener(cb) if (track != None): track.add_devices_listener(cb) ChannelStripComponent.set_track(channelstrip, track) return _set_track def _channelstrip_select_value(self, channelstrip, index): def _select_value(value): ChannelStripComponent._select_value(channelstrip, value) self._last_selected_strip_number = index return _select_value def _channelstrip_on_cf_assign_changed(self, channel_strip): def _on_cf_assign_changed(): if (channel_strip.is_enabled() and (channel_strip._crossfade_toggle != None)): if (channel_strip._track != None) and (channel_strip._track in chain(self.song().tracks, self.song().return_tracks)): if channel_strip._track.mixer_device.crossfade_assign == 1: #modified channel_strip._crossfade_toggle.turn_off() elif channel_strip._track.mixer_device.crossfade_assign == 0: channel_strip._crossfade_toggle.send_value(CROSSFADE_A) else: channel_strip._crossfade_toggle.send_value(CROSSFADE_B) return _on_cf_assign_changed def _channelstrip1_cb(self): self._on_selected_track_changed() def _channelstrip2_cb(self): self._on_selected_track_changed() """MixerComponent overrides""" def _mixer_tracks_to_use(self, mixer): def tracks_to_use(): return tuple(self.song().visible_tracks) + tuple(self.song().return_tracks) return tracks_to_use """SessionComponent overrides""" def _device_number_of_parameter_banks(self, device): def _number_of_parameter_banks(): return number_of_parameter_banks(device._device) #added return _number_of_parameter_banks def _device_assign_parameters(self, device): def _assign_parameters(): assert device.is_enabled() assert (device._device != None) assert (device._parameter_controls != None) device._bank_name = ('Bank ' + str(device._bank_index + 1)) #added if (device._device.class_name in device._device_banks.keys()): #modified assert (device._device.class_name in device._device_best_banks.keys()) banks = device._device_banks[device._device.class_name] bank = None if (not device._is_banking_enabled()): banks = device._device_best_banks[device._device.class_name] device._bank_name = 'Best of Parameters' #added if (len(banks) > device._bank_index): bank = banks[device._bank_index] if device._is_banking_enabled(): #added if device._device.class_name in device._device_bank_names.keys(): #added device._bank_name[device._bank_index] = device._device_bank_names[device._device.class_name] #added *recheck assert ((bank == None) or (len(bank) >= len(device._parameter_controls))) for index in range(len(device._parameter_controls)): parameter = None if (bank != None): parameter = get_parameter_by_name(device._device, bank[index]) if (parameter != None): device._parameter_controls[index].connect_to(parameter) else: device._parameter_controls[index].release_parameter() else: parameters = device._device_parameters_to_map() num_controls = len(device._parameter_controls) index = (device._bank_index * num_controls) for control in device._parameter_controls: if (index < len(parameters)): control.connect_to(parameters[index]) else: control.release_parameter() index += 1 return _assign_parameters
class KorgKaossDJ(ControlSurface): __module__ = __name__ __doc__ = " Korg Kaoss DJ controller script " def __init__(self, c_instance): """everything except the '_on_selected_track_changed' override and 'disconnect' runs from here""" ControlSurface.__init__(self, c_instance) self._selected_track = None self._current_clip = None with self.component_guard(): self._create_controls() self._setup_transport_control( ) # Run the transport setup part of the script self._setup_loop_control() self._setup_scrub_control() self._setup_fx_control() self._setup_mixer_control() # Setup the mixer object self._setup_session_control() # Setup the session object def _create_controls(self): # ------ SLIDER self._crossfader_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_CENTER, 23) self._left_volume_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_LEFT, 24) self._right_volume_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_RIGHT, 24) self._left_tempo_fader = SliderElement(MIDI_CC_TYPE, CHANNEL_LEFT, 25) self._right_tempo_fader = SliderElement(MIDI_CC_TYPE, CHANNEL_RIGHT, 25) # ------ BUTTONS self._left_play_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 27) self._right_play_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 27) self._left_prelisten_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 25) self._right_prelisten_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 25) self._left_fx_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 24) self._right_fx_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 24) self._left_A_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 14) self._right_B_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 14) self._left_shift_button = ButtonElement( True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 26, name='Shift_Button', resource_type=PrioritizedResource) self._right_shift_button = ButtonElement( True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 26, name='Shift_Button', resource_type=PrioritizedResource) self._left_sync_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 29) self._right_sync_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 29) self._left_cue_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 30) self._right_cue_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 30) self._left_sync_button_shift = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 47) self._right_sync_button_shift = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 47) self._left_cue_button_shift = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 48) self._right_cue_button_shift = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 48) for i in range(3): for side, channel in zip(['_left', '_right'], [CHANNEL_LEFT, CHANNEL_RIGHT]): setattr(self, side + '_loop_' + str(i + 1), ButtonElement(True, MIDI_NOTE_TYPE, channel, 15 + i)) setattr(self, side + '_loop_' + str(i + 1) + '_shift', ButtonElement(True, MIDI_NOTE_TYPE, channel, 40 + i)) setattr(self, side + '_hotcue_' + str(i + 1), ButtonElement(True, MIDI_NOTE_TYPE, channel, 18 + i)) setattr(self, side + '_hotcue_' + str(i + 1) + '_shift', ButtonElement(True, MIDI_NOTE_TYPE, channel, 43 + i)) setattr(self, side + '_nolight_' + str(i + 1), ButtonElement(True, MIDI_NOTE_TYPE, channel, 21 + i)) # ------ ENCODER # browser self._center_browse_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_CENTER, 30, Live.MidiMap.MapMode.relative_smooth_two_compliment) # gain left self._left_gain_encoder = EncoderElement(MIDI_CC_TYPE, CHANNEL_LEFT, 26, Live.MidiMap.MapMode.absolute) # gain right self._right_gain_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_RIGHT, 26, Live.MidiMap.MapMode.absolute) # middle light off -> does not send on-off messages! self._left_jogwheel_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_LEFT, 14, Live.MidiMap.MapMode.relative_smooth_two_compliment) self._right_jogwheel_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_RIGHT, 14, Live.MidiMap.MapMode.relative_smooth_two_compliment) self._left_jogwheel_encoder_shift = EncoderElement( MIDI_CC_TYPE, CHANNEL_LEFT, 15, Live.MidiMap.MapMode.relative_smooth_two_compliment) self._right_jogwheel_encoder_shift = EncoderElement( MIDI_CC_TYPE, CHANNEL_RIGHT, 15, Live.MidiMap.MapMode.relative_smooth_two_compliment) # middle light on -> sends on-off message on channel 31! self._left_jogwheel_encoder_active = EncoderElement( MIDI_CC_TYPE, CHANNEL_LEFT, 16, Live.MidiMap.MapMode.relative_smooth_two_compliment) self._left_jogwheel_encoder_active_button = ButtonElement( True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 31) self._right_jogwheel_encoder_active = EncoderElement( MIDI_CC_TYPE, CHANNEL_RIGHT, 16, Live.MidiMap.MapMode.relative_smooth_two_compliment) self._right_jogwheel_encoder_active_button = ButtonElement( True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 31) # FX touchpad (same for both channels so we need to read only one) self._touchpad_x_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_LEFT, 12, Live.MidiMap.MapMode.absolute) self._touchpad_y_encoder = EncoderElement( MIDI_CC_TYPE, CHANNEL_LEFT, 13, Live.MidiMap.MapMode.absolute) self._touchpad_x_encoder_shift = EncoderElement( MIDI_CC_TYPE, CHANNEL_CENTER, 17, Live.MidiMap.MapMode.absolute) self._touchpad_y_encoder_shift = EncoderElement( MIDI_CC_TYPE, CHANNEL_CENTER, 18, Live.MidiMap.MapMode.absolute) # hi-mid-lo encoders _device_MSG_IDS = [27, 28, 29] self._device_encoders = ButtonMatrixElement( rows=[[ EncoderElement(MIDI_CC_TYPE, CHANNEL_LEFT, MSG_ID, Live.MidiMap.MapMode.absolute) for MSG_ID in _device_MSG_IDS ], [ EncoderElement(MIDI_CC_TYPE, CHANNEL_RIGHT, MSG_ID, Live.MidiMap.MapMode.absolute) for MSG_ID in _device_MSG_IDS ]]) def _setup_loop_control(self): # set looping function ality to Loop- and HotCue buttons self._looper_left = LooperComponent(self, assign_track=0, move_increment=4, increase_factor=(0, 2), decrease_factor=(0, 2), start_loop_length=32, quantize_start=4) self._looper_right = LooperComponent(self, assign_track=1, move_increment=4, increase_factor=(0, 2), decrease_factor=(0, 2), start_loop_length=32, quantize_start=1) self._looper_left_fine = LooperComponent(self, assign_track=0, move_increment=1, increase_factor=(1, 1), decrease_factor=(1, 1), start_loop_length=16, quantize_start=1) self._looper_right_fine = LooperComponent(self, assign_track=1, move_increment=1, increase_factor=(1, 1), decrease_factor=(1, 1), start_loop_length=16, quantize_start=1) self._looper_left.set_loop_decrease_button(self._left_loop_1) self._looper_left.set_loop_start_button(self._left_loop_2) self._looper_left.set_loop_increase_button(self._left_loop_3) self._looper_left.set_loop_move_left_button(self._left_loop_1_shift) self._looper_left.set_loop_toggle_button(self._left_loop_2_shift) self._looper_left.set_loop_move_right_button(self._left_loop_3_shift) self._looper_left_fine.set_loop_decrease_button(self._left_hotcue_1) self._looper_left_fine.set_loop_start_button(self._left_hotcue_2) self._looper_left_fine.set_loop_increase_button(self._left_hotcue_3) self._looper_left_fine.set_loop_move_left_button( self._left_hotcue_1_shift) self._looper_left_fine.set_loop_toggle_button( self._left_hotcue_2_shift) self._looper_left_fine.set_loop_move_right_button( self._left_hotcue_3_shift) self._looper_right.set_loop_decrease_button(self._right_loop_1) self._looper_right.set_loop_start_button(self._right_loop_2) self._looper_right.set_loop_increase_button(self._right_loop_3) self._looper_right.set_loop_move_left_button(self._right_loop_1_shift) self._looper_right.set_loop_toggle_button(self._right_loop_2_shift) self._looper_right.set_loop_move_right_button(self._right_loop_3_shift) self._looper_right_fine.set_loop_decrease_button(self._right_hotcue_1) self._looper_right_fine.set_loop_start_button(self._right_hotcue_2) self._looper_right_fine.set_loop_increase_button(self._right_hotcue_3) self._looper_right_fine.set_loop_move_left_button( self._right_hotcue_1_shift) self._looper_right_fine.set_loop_toggle_button( self._right_hotcue_2_shift) self._looper_right_fine.set_loop_move_right_button( self._right_hotcue_3_shift) def _setup_scrub_control(self): self._scrub_left = ScrubComponent(self, assign_track=LEFT_STRIP_ID, increment_scrub=1, increment_fine=0.1) self._scrub_right = ScrubComponent(self, assign_track=RIGHT_STRIP_ID, increment_scrub=1, increment_fine=0.1) self._scrub_left.set_move_position_button(self._left_jogwheel_encoder) self._scrub_left.set_move_position_coarse_button( self._left_jogwheel_encoder_shift) self._scrub_left.set_scrub_position_button( self._left_jogwheel_encoder_active) self._scrub_left.set_scrub_on_off_button( self._left_jogwheel_encoder_active_button) self._scrub_right.set_move_position_button( self._right_jogwheel_encoder) self._scrub_right.set_move_position_coarse_button( self._right_jogwheel_encoder_shift) self._scrub_right.set_scrub_position_button( self._right_jogwheel_encoder_active) self._scrub_right.set_scrub_on_off_button( self._right_jogwheel_encoder_active_button) def _setup_fx_control(self): self._fx_left = FXComponent(self, assign_track=LEFT_STRIP_ID) self._fx_left.set_touchpad_x_button(self._touchpad_x_encoder) self._fx_left.set_touchpad_y_button(self._touchpad_y_encoder) self._fx_left.set_touchpad_x_shift_button( self._touchpad_x_encoder_shift) self._fx_left.set_touchpad_y_shift_button( self._touchpad_y_encoder_shift) self._fx_left.set_fx_on_off_button(self._left_fx_button) self._fx_left.set_gain_encoder_button(self._left_gain_encoder) self._fx_left.set_warping_button(self._left_sync_button_shift) self._fx_left.set_warp_mode_button(self._left_sync_button) self._fx_left.set_pitch_down_button(self._left_nolight_1) self._fx_left.set_pitch_up_button(self._left_nolight_3) self._fx_right = FXComponent(self, assign_track=RIGHT_STRIP_ID) self._fx_right.set_touchpad_x_button(self._touchpad_x_encoder) self._fx_right.set_touchpad_y_button(self._touchpad_y_encoder) self._fx_right.set_touchpad_x_shift_button( self._touchpad_x_encoder_shift) self._fx_right.set_touchpad_y_shift_button( self._touchpad_y_encoder_shift) self._fx_right.set_fx_on_off_button(self._right_fx_button) self._fx_right.set_gain_encoder_button(self._right_gain_encoder) self._fx_right.set_warping_button(self._right_sync_button_shift) self._fx_right.set_warp_mode_button(self._right_sync_button) def _setup_transport_control(self): """set up the sliders""" self._transport = TransportComponent(self, name=u'Transport', is_enabled=False) #set tempo-fader self._transport.set_tempo_control( self._left_tempo_fader, fine_control=self._right_tempo_fader) #(control, fine_control) self._transport.set_enabled(True) def _setup_mixer_control(self): self._mixer = MixerComponent(num_tracks=2, num_returns=0, name=u'Mixer', is_enabled=False) self._mixer.set_crossfader_control(self._crossfader_slider) # set volume sliders self._mixer.channel_strip(LEFT_STRIP_ID).set_volume_control( self._left_volume_slider) self._mixer.channel_strip(RIGHT_STRIP_ID).set_volume_control( self._right_volume_slider) # set prelisten buttons self._mixer.channel_strip(LEFT_STRIP_ID).set_solo_button( self._left_prelisten_button) self._mixer.channel_strip(RIGHT_STRIP_ID).set_solo_button( self._right_prelisten_button) # use fx buttons to select a track self._mixer.channel_strip(LEFT_STRIP_ID).set_select_button( self._left_A_button) self._mixer.channel_strip(RIGHT_STRIP_ID).set_select_button( self._right_B_button) self._mixer.set_enabled(True) def _setup_session_control(self): self._session = SessionComponent(num_tracks=2, num_scenes=1, name=u'Session', is_enabled=False) # set horizontal scene selector (this is why we import SessionComponent from _Arturia!) self._session.set_scene_select_control(self._center_browse_encoder) # set launch-buttons for scene self._session.selected_scene().clip_slot(0).set_launch_button( self._left_play_button) self._session.selected_scene().clip_slot(1).set_launch_button( self._right_play_button) # hightlite the current selection self.set_highlighting_session_component(self._session) self._session.set_enabled(True) # ----------- add functionality to turn playing-light on-off def update_lights(track, button): playing_clip_idx = track.playing_slot_index if playing_clip_idx >= 0: button.turn_on() else: button.turn_off() def update_playlight_left(): track = self.song().tracks[LEFT_STRIP_ID] update_lights(track, self._left_play_button) def update_playlight_right(): track = self.song().tracks[RIGHT_STRIP_ID] update_lights(track, self._right_play_button) self.song().tracks[LEFT_STRIP_ID].add_playing_slot_index_listener( update_playlight_left) self.song().tracks[RIGHT_STRIP_ID].add_playing_slot_index_listener( update_playlight_right) # override the selected scene change behaviour of the playing light self.song().view.add_selected_scene_listener(update_playlight_left) self.song().view.add_selected_scene_listener(update_playlight_right)
def _setup_mixer_control(self): is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant num_tracks = 4 # 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, 2, with_eqs=True, with_filters=False ) #(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 #mute_notes = [1,5,9,13] #solo_notes = [2,6,10,14] #arm_notes = [3,7,11,15] track_select_notes = [ 38, 39, 40, 41 ] #more note numbers need to be added if num_scenes is increased send_ccs = [2, 6, 10, 14, 1, 5, 9, 13] pan_ccs = [3, 7, 11, 15] slider_ccs = [4, 8, 12, 16] for index in range(num_tracks): mixer.channel_strip(index).set_select_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, track_select_notes[index])) mixer.channel_strip(index).set_volume_control( SliderElement(MIDI_CC_TYPE, CHAN, slider_ccs[index])) mixer.channel_strip(index).set_pan_control( EncoderElement(MIDI_CC_TYPE, CHAN, pan_ccs[index], Live.MidiMap.MapMode.absolute)) #put send A and send B controllers into an array, which is then "tupled" for set_send_controls: send_controlers = [ EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index], Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index + num_tracks], Live.MidiMap.MapMode.absolute) ] mixer.channel_strip(index).set_send_controls( tuple(send_controlers)) crossfader = SliderElement(MIDI_CC_TYPE, CHAN, 28) master_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 32) returna_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 19) returna_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 20) returnb_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 23) returnb_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 24) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 31) prehear_control = EncoderElement(MIDI_CC_TYPE, CHAN, 30, Live.MidiMap.MapMode.absolute) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' returna_pan_control.name = 'ReturnA_Pan_Control' returna_volume_control.name = 'ReturnA_Volume_Control' returnb_pan_control.name = 'ReturnB_Pan_Control' returnb_volume_control.name = 'ReturnB_Volume_Control' master_select_button.name = 'Master_Select_Button' prehear_control.name = 'Prehear_Volume_Control' mixer.set_crossfader_control(crossfader) mixer.master_strip().set_volume_control(master_volume_control) mixer.master_strip().set_select_button(master_select_button) mixer.set_prehear_volume_control(prehear_control) mixer.return_strip(0).set_pan_control(returna_pan_control) mixer.return_strip(0).set_volume_control(returna_volume_control) mixer.return_strip(1).set_pan_control(returnb_pan_control) mixer.return_strip(1).set_volume_control(returnb_volume_control)