def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = 'Impulse' self._suggested_output_port = 'Impulse' self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39) self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8) self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._preview_button.add_value_listener(self._preview_value) self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_name_display() device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10) mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9) device_button.name = 'Encoder_Device_Mode' mixer_button.name = 'Encoder_Mixer_Mode' self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders) self._encoder_modes.set_device_mixer_buttons(device_button, mixer_button) self._string_to_display = None for component in self.components: component.set_enabled(False) return
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 = [3, 2, 1, 0, 5, 4, 6, 7] #pan_select_notes = [21, 20, 13, 12, 3, 1, 0, 2] master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 7) #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)
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) # add side buttons as channel 4 # button = ButtonElement(is_momentary, MESSAGETYPE, SIDE_BUTTONS_CHANNEL, TOP_LEFT_SIDE_BTN_VAL) # self._side_buttons.append(button) # button = ButtonElement(is_momentary, MESSAGETYPE, SIDE_BUTTONS_CHANNEL, BTM_LEFT_SIDE_BTN_VAL) # self._side_buttons.append(button) # button = ButtonElement(is_momentary, MESSAGETYPE, SIDE_BUTTONS_CHANNEL, TOP_RITE_SIDE_BTN_VAL) # self._side_buttons.append(button) # button = ButtonElement(is_momentary, MESSAGETYPE, SIDE_BUTTONS_CHANNEL, BTM_RITE_SIDE_BTN_VAL) # self._side_buttons.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)
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) # CC Hold, CC Toggle shift_bank_button = ButtonElement(is_momentary, MESSAGETYPE, SHIFTBANKCHANNEL, note) shift_bank_button.name = 'Note_' + str(note) self._shift_bank_map.append(shift_bank_button) # Shift Bank shift_encoder = ButtonElement(is_momentary, 1, ENCODERSHIFTCHANNEL, note) shift_encoder.name = 'Note_' + str(note) self._shift_encoder_map.append(shift_encoder) # Shift Encoder Hold self._note_map.append( None) #add None to the end of the list, selectable with [-1] self._shift_encoder_map.append(None) self._shift_bank_map.append(None) 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) # Standard Encoder self._ctrl_map.append(None)
def disconnect(self): if self._parameter_to_map_to is not None: if hasattr(self._parameter_to_map_to, 'name'): self._parameter_to_map_to.remove_value_listener( self._on_value_changed) SliderElement.disconnect(self) return
def _setup_mixer_control(self): is_momentary = True """ Instantiate a Mixer Component """ global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...) mixer = MixerComponent(mixer_num_tracks, 2, with_eqs=True, with_filters=True) # (num_tracks, num_returns, with_eqs, with_filters) mixer.set_track_offset(0) # Sets start point for mixer strip (offset from left) self.song().view.selected_track = 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 """ Buttons and Sliders association """ # Master channel mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, midi_channel, midi_mixer_volume_master)) # sets the continuous controller for volume # Other channels, same size as mixer_num_tracks # Set volume control, solo and mute buttons for index in range(mixer_num_tracks): # launch_button assignment must match number of scenes mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, midi_channel, midi_mixer_volume_channels[index])) # sets the continuous controller for volume mixer.channel_strip(index).set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_mixer_solo_channels[index])) # sets the solo button mixer.channel_strip(index).set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_mixer_mute_channels[index])) # sets the mute ("activate") button """ Buttons to select track """ button_next_track = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_track_select_next) button_previous_track = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_track_select_previous) mixer.set_select_buttons(button_next_track, button_previous_track) """ Listeners """ # When selected track if changed self.song().view.add_selected_track_listener(self.on_track_selected)
def _setup_mixer_control(self): is_momentary = True mixer = MixerComponent(NUM_TRACKS, 2) 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 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 MaschineMk2(Maschine): """Control Script for Maschine Studio""" __module__ = __name__ _gated_buttons = [] def __init__(self, c_instance): super(MaschineMk2, self).__init__(c_instance) def create_pad_button(self, scene_index, track_index, color_source): return PadColorButton(True, 0, scene_index, track_index, color_source) def create_gated_button(self, identifier, hue): button = GatedColorButton(True, MIDI_CC_TYPE, identifier, hue) self._gated_buttons.append(button) return button def _init_maschine(self): self._jogwheel = KnobSection(self._modeselect, self._editsection) self._note_repeater.registerKnobHandler(self._jogwheel) self._mixer.set_touch_mode(2) self._device_component.set_touch_mode(2) self.prehear_knob = SliderElement(MIDI_CC_TYPE, 0, 41) self.prehear_knob.connect_to( self.song().master_track.mixer_device.cue_volume) def to_color_edit_mode(self, active): if self._editsection.is_color_edit() != active: self._jogwheel.invoke_color_mode(active and 1 or 0) def use_layered_buttons(self): return True def _final_init(self): debug_out('########## LIVE 9 MASCHINE Mk2 V 2.02 ############# ') def _click_measure(self): pass def apply_preferences(self): super(MaschineMk2, self).apply_preferences() pref_dict = self._pref_dict if 'color_mode' in pref_dict: value = pref_dict['color_mode'] self._session.set_color_mode(value) self._session._c_mode_button.send_value(value == True and 127 or 0, True) else: self._session.set_color_mode(False) self._session._c_mode_button.send_value(0, True) def store_preferences(self): super(MaschineMk2, self).store_preferences() self._pref_dict['color_mode'] = self._session.is_color_mode() def preferences_name(self): return 'MaschineMk2' def cleanup(self): for button in self._gated_buttons: button.switch_off()
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): is_momentary = True self._suggested_input_port = 'Oxygen' self._suggested_output_port = 'Oxygen' self._has_slider_section = True self._device_selection_follows_track_selection = True self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 57) self._shift_button.add_value_listener(self._shift_value) self._mixer = SpecialMixerComponent(NUM_TRACKS) self._mute_solo_buttons = [] self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 111) self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 110) self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 41) for index in range(NUM_TRACKS): self._mute_solo_buttons.append(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 49 + index)) self._mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index)) self._shift_value(0) self._mixer.master_strip().set_volume_control(self._master_slider) self._mixer.selected_strip().set_volume_control(None) device = DeviceComponent() device.set_parameter_controls(tuple([ EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index, Live.MidiMap.MapMode.absolute) for index in range(8) ])) self.set_device_component(device) ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 115) rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 114) loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 113) transport = TransportComponent() transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116)) transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117)) transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118)) session = SessionComponent(0, 0) transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = 'DirectLink' self._suggested_output_port = 'DirectLink' self._waiting_for_first_response = True self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_pressed = False self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 13) self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 111) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 110) self._device_bank_buttons = None self._device_navigation = None self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._next_nav_button.name = 'Next_Track_Button' self._prev_nav_button.name = 'Prev_Track_Button' self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._shift_button.add_value_listener(self._shift_value) self._setup_mixer() self._setup_transport_and_session() self._setup_device() self._setup_display() for component in self.components: component.set_enabled(False)
def __init__(self, hyperion, mod_num, *a, **kw): super(HyperionChan, self).__init__(*a, **kw) self.hyperion = hyperion self.mod_num = mod_num self._track_selector_encoder = EncoderElement(MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 0x15, Live.MidiMap.MapMode.relative_smooth_binary_offset) # Right encoder on Hyperion self._track_selector_encoder.add_value_listener(self._on_track_selector_encoder) self._fader = SliderElement(MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 0x25) self._pots = [ EncoderElement(MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 0x1E + num, Live.MidiMap.MapMode.absolute, name='Pot{}'.format(num)) for num in range(8) ] self._btns = [ ButtonElement(True, MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 1 + num, name='Btn{}'.format(num)) for num in range(8) ] self._enc_right_btn = ButtonElement(True, MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 10, name='EncRightBtn') self._enc_right_btn.add_value_listener(self._on_enc_right_btn) #self._cs = ChannelStripComponent() #self._cs.set_volume_control(self._fader) self._vu_slider = SliderElement(MIDI_CC_TYPE, MIDI_MASTER_CH + 1 + mod_num, 60) self._vu = VUMeter(self) self._track = None tracks = self._get_all_tracks(self.hyperion.song().tracks) if len(tracks) > self.mod_num: self._bind_to_track(tracks[self.mod_num]) else: self._bind_to_track(None)
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 _load_MIDI_map(self): # Midi messages can be either "Toggle" or "Momentary". # # A toggle message consists of a single message with value 127, while a # momentary message first sends 127, followed by 0. # # Set this flag according to which kind of messages you're using. 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)
def __init__(self, button_index, monochrome = False, *a, **k): super(PadMode, self).__init__(button_index, *a, **k) self._note_display_mode = ND_KEYBOARD1 self.current_scale_index = 0 self._scale = None self._base_note = 0 self._octave = 0.55 self.current_scale_index = 0 self._in_edit_mode = False self._editmode = None self._is_monochrome = monochrome self._color_edit_assign = monochrome and self.assign_edit_mono or self.assign_edit_color self.assign_transpose(SCALES[self.current_scale_index]) is_momentary = True self.octave_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 120) self.octave_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 121) self.base_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 124) self.base_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 125) self.scale_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 118) self.scale_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 119) self._adjust_scale.subject = SliderElement(MIDI_CC_TYPE, 2, 116) self._adjust_octav.subject = SliderElement(MIDI_CC_TYPE, 2, 115) self._adjust_basem.subject = SliderElement(MIDI_CC_TYPE, 2, 117) self._do_oct_down.subject = self.octave_down_button self._do_oct_up.subject = self.octave_up_button self._do_base_down.subject = self.base_down_button self._do_base_up.subject = self.base_up_button self._do_scale_down.subject = self.scale_down_button self._do_scale_up.subject = self.scale_up_button self._seg_display = None
def _setup_mixer_control(self): is_momentary = True mixer = MixerComponent(1) mixer.selected_strip().set_mute_button( SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[9])) mixer.selected_strip().set_solo_button( SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[13])) mixer.set_select_buttons( SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[15]), SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[14])) send_faders = [] NUM_CONTROLLABLE_SENDS = 4 for index in range(NUM_CONTROLLABLE_SENDS): send_faders.append( SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[index + 2])) mixer.selected_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[0])) mixer.selected_strip().set_pan_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[1])) mixer.selected_strip().set_send_controls(tuple(send_faders)) mixer.set_prehear_volume_control( EncoderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[6], Live.MidiMap.MapMode.absolute)) mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[7])) return mixer
def _setup_mixer_control(self): #set up the mixer self.mixer = MixerComponent( NUM_TRACKS, 2) #(num_tracks, num_returns, with_eqs, with_filters) self.mixer.set_track_offset( 0) #sets start point for mixer strip (offset from left) self.mixer.selected_strip().set_arm_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C)) self.mixer.set_select_buttons( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 2), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 4)) self.mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[3])) #self.mixer.master_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[7])) #set the selected strip to the first track, so that we don't assign a button to arm the master track, which would cause an assertion error self.song().view.selected_track = self.mixer.channel_strip(0)._track self.mixer.selected_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[0])) #self.mixer.selected_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[4])) selected_track = self.song().view.selected_track all_tracks = ((self.song().tracks + self.song().return_tracks) + (self.song().master_track, )) currentTrackIndex = list(all_tracks).index(selected_track) if currentTrackIndex < len(all_tracks) - 1: self.mixer.channel_strip(currentTrackIndex + 1).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[1])) #self.mixer.channel_strip(currentTrackIndex + 1).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[5])) if currentTrackIndex < len(all_tracks) - 2: self.mixer.channel_strip(currentTrackIndex + 2).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[2]))
def doStuff(self,x): try: data, addr = self.sock.recvfrom(64) # buffer size is 1024 byte addressPattern = data[:data.find("\0")] #data = data.split(',i') #v = struct.unpack('>i',data[1][2:(2+4)])[0] data = data.split(',ii') v = struct.unpack('>ii',data[1][1:]) track_number = v[0] midi_cc = v[1] b = SliderElement(1, 0, midi_cc) song = self.song() if (addressPattern == "/pan"): b.connect_to(song.tracks[track_number].mixer_device.panning) elif (addressPattern == "/volume"): b.connect_to(song.tracks[track_number].mixer_device.volume) self.show_message(addressPattern) except socket.error: pass
def _set_up_mixer(self): is_momentary = True self._mixer = MaschineMixerComponent(8) self.send_sliders = [] for track in range(8): self.send_sliders.append( SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, SEND_CC_OFF + track)) for track in range(8): strip = self._mixer.channel_strip(track) strip.set_arm_button( StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, ARM_CC_OFF + track)) strip.set_solo_button( StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, SOLO_CC_OFF + track)) strip.set_mute_button( StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, MUTE_CC_OFF + track)) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, LEVEL_CC_OFF + track)) strip.set_pan_control( SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, PAN_CC_OFF + track)) strip.set_select_button( StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, SELECT_CC_OFF + track)) st = tuple([self.send_sliders[track]]) strip.set_send_controls(st) self.send_slider_toggle_button = StateButton(False, MIDI_CC_TYPE, 0, 90) self._do_toggle_send.subject = self.send_slider_toggle_button self._session.set_mixer(self._mixer)
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.selected_strip().name = 'Selected_Channel_Strip' self._solo_buttons = [] for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) solo_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50, self) self._solo_buttons.append(solo_button) mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) solo_button.name = str(track) + '_Solo_Button' mute_button.name = str(track) + '_Mute_Button' strip.set_solo_button(solo_button) strip.set_mute_button(mute_button) strip.set_shift_button(self._shift_button) strip.set_invert_mute_feedback(True) master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) master_volume_control.name = 'Master_Volume_Control' prehear_control.name = 'Prehear_Volume_Control' self._mixer.set_prehear_volume_control(prehear_control) self._mixer.master_strip().set_volume_control(master_volume_control)
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.selected_strip().name = 'Selected_Channel_Strip' for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50) solo_button.name = str(track) + '_Solo_Button' mute_button.name = str(track) + '_Mute_Button' strip.set_solo_button(solo_button) strip.set_mute_button(mute_button) strip.set_shift_button(self._shift_button) strip.set_invert_mute_feedback(True) master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) prehear_control = EncoderElement( MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) master_volume_control.name = 'Master_Volume_Control' prehear_control.name = 'Prehear_Volume_Control' self._mixer.set_prehear_volume_control(prehear_control) self._mixer.master_strip().set_volume_control(master_volume_control)
def _set_initial_mode(self): is_momentary = True ### MIXER for index in range(num_tracks): strip = self.mixer.channel_strip(index) strip.name = 'Mixer_ChannelStrip_' + str(index) strip.set_volume_control( SliderElement(MIDI_CC_TYPE, data_channel, mixer_volume_cc[index])) strip._invert_mute_feedback = True self.mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, data_channel, mixer_master_cc)) self.transport.set_stop_button( ButtonElement(False, MIDI_CC_TYPE, data_channel, transport_stop_cc)) self.transport.set_play_button( ButtonElement(False, MIDI_CC_TYPE, data_channel, transport_play_cc)) self.transport.set_record_button( ButtonElement(False, MIDI_CC_TYPE, data_channel, transport_record_cc)) self.log("color: " + str(self.session.tracks_to_use()[0].color)) self.log("color: " + str(self.session.tracks_to_use()[1].color)) self.log("color: " + str(self.session.tracks_to_use()[2].color)) self.log("color: " + str(self.session.tracks_to_use()[3].color)) self._send_midi([0x09, 0x09, 0x09, 0x09])
def __init__(self, note_repeat=None, *a, **k): super(NoteRepeatComponent, self).__init__(*a, **a) self._note_repeat = note_repeat self._adjust_cfg_value.subject = SliderElement(MIDI_CC_TYPE, 2, 105) self._note_repeat_button = ButtonElement(True, MIDI_CC_TYPE, 0, 102) self._do_note_repeat.subject = self._note_repeat_button self._cfg_adjust_button = ButtonElement(True, MIDI_CC_TYPE, 2, 106) self._cfg_adjust_button.add_value_listener(self._do_cfg_button) self._cfg_down = False self._hold_mode = False self.nr_down = False self._current_nr_button = None self._do_change_nr_1.subject = SliderElement(MIDI_CC_TYPE, 1, 76) self._do_change_nr_2.subject = SliderElement(MIDI_CC_TYPE, 1, 77) self._do_change_nr_3.subject = SliderElement(MIDI_CC_TYPE, 1, 78) self._do_change_nr_4.subject = SliderElement(MIDI_CC_TYPE, 1, 79) def createButton(ccindenfier, nr_freq): button = ButtonElement(True, MIDI_CC_TYPE, 1, ccindenfier) button.add_value_listener(self._select_value, True) button.active = False button.freq = nr_freq button.cfg = False button.hold = False return button def createCfgButton(ccindenfier, nr_freq_idx): button = ButtonElement(True, MIDI_CC_TYPE, 2, ccindenfier) button.add_value_listener(self._select_value, True) button.active = False button.fr_idx = nr_freq_idx button.freq = CFG_REPEAT_FREQUENCIES[nr_freq_idx] button.cfg = True button.hold = False return button continue self._cfg_buttons = [ createCfgButton(assign[0], assign[1]) for assign in CTRL_CFG_TO_FREQ ] for button in self._cfg_buttons: if not button.active or 1: pass button.send_value(0, True) self.nr_frq = CTRL_TO_FREQ[4][1] self._note_repeat.repeat_rate = (1 / self.nr_frq) * 4 continue self.buttons = [ createButton(assign[0], assign[1]) for assign in CTRL_TO_FREQ ] self.buttons[4].active = True self._previous_button = self.buttons[4] self._last_active_button = self.buttons[4] for button in self.buttons: if not button.active or 1: pass button.send_value(0, True)
def _init_maschine(self): self._jogwheel = KnobSection(self._modeselect, self._editsection) self._note_repeater.registerKnobHandler(self._jogwheel) self._mixer.set_touch_mode(2) self._device_component.set_touch_mode(2) self.prehear_knob = SliderElement(MIDI_CC_TYPE, 0, 41) self.prehear_knob.connect_to( self.song().master_track.mixer_device.cue_volume)
def _setup_transport(self): is_momentary = True transport = TransportComponent() studiotransport = MaschineTransport() playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108) stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110) recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109) overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107) metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104) eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98) playButton.name = 'Play' stopButton.name = 'Stop' recordButton.name = 'Record' overdubButton.name = 'Overdub' metrononmeButton.name = 'Metronome' transport.set_play_button(playButton) transport.set_stop_button(stopButton) transport.set_record_button(recordButton) transport.set_overdub_button(overdubButton) transport.set_metronome_button(metrononmeButton) studiotransport.set_session_auto_button(eventRecButton) studiotransport.set_arrangement_overdub_button( StateButton(is_momentary, MIDI_CC_TYPE, 0, 106)) studiotransport.set_back_arrange_button( StateButton(is_momentary, MIDI_CC_TYPE, 0, 105)) transport.set_nudge_buttons( StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50)) punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52) punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53) punchinbutton.name = 'Punch In' punchoutbutton.name = 'Punch Out' transport.set_punch_buttons(punchinbutton, punchoutbutton) transport.set_loop_button( StateButton(is_momentary, MIDI_CC_TYPE, 1, 54)) self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98) self._do_song_follow.subject = self.song_follow_button self._song_follow_changed.subject = self.song().view self._song_follow_changed() self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59) self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58) transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button) self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105) self.xfadeKnob.connect_to( self.song().master_track.mixer_device.crossfader) self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99) self.master_knob.connect_to( self.song().master_track.mixer_device.volume) self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88) self._do_tap_tempo.subject = self.tap_button self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55) self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56) self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57) self._do_toggle_cue.subject = self.cue_add_delete_button self._do_toggle_prev_cue.subject = self.cue_prev_button self._do_toggle_next_cue.subject = self.cue_next_button
def _setup_transport_control(self): is_momentary = True transport = TransportComponent() transport.set_play_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 80)) transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 81)) transport.set_nudge_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 86), ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 85)) transport.set_loop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 84)) transport.set_punch_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 82), ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 83)) transport.set_tempo_control(SliderElement(MIDI_CC_TYPE, 12, 26), SliderElement(MIDI_CC_TYPE, 12, 25))
def _set_up_machine_knobs(self): master_track = self.song().master_track self.prehear_knob = SliderElement(MIDI_CC_TYPE, 0, 43) self.prehear_knob.connect_to( self.song().master_track.mixer_device.cue_volume) self._stop_tap_button = ButtonElement(True, MIDI_CC_TYPE, 1, 111) self._do_combined_stop_tap.subject = self._stop_tap_button self._undo__redo_button = ButtonElement(True, MIDI_CC_TYPE, 2, 85) self._do_undo_redo.subject = self._undo__redo_button
def release_parameter(self): """ Overrides standard to update mapping type on parameter disconnect and clear out observers. """ self._on_parameter_changed.subject = None self._on_property_value_changed.subject = None SliderElement.release_parameter(self) self._smoother.set_parameter(None) self._parameter_to_map_to = None self._update_mapping_type() return
def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(self, 8) #added self for parent self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80) master_select_button.name = 'Master_Select_Button' self._mixer.master_strip().set_select_button(master_select_button) #set in ShiftableSelectorComponent instead if used for Note Mode self._mixer.selected_strip().name = 'Selected_Channel_Strip' select_buttons = [] #added arm_buttons = [] #added sliders = [] #added for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) #volume_control = SliderElement(MIDI_CC_TYPE, track, 7) #set in ShiftableSelectorComponent instead #arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48) #see below solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) solo_button.name = str(track) + '_Solo_Button' strip.set_solo_button(solo_button) if track < 4: mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50) mute_button.name = str(track) + '_Mute_Button' strip.set_mute_button(mute_button) strip.set_invert_mute_feedback(True) strip.set_shift_button(self._shift_button) select_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51)) #added select_buttons[-1].name = str(track) + '_Select_Button' #added #strip.set_select_button(select_buttons[-1]) #added arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)) #added arm_buttons[-1].name = str(track) + '_Arm_Button' #added sliders.append(SliderElement(MIDI_CC_TYPE, track, 7)) #added sliders[-1].name = str(track) + '_Volume_Control' #added self._crossfader = SliderElement(MIDI_CC_TYPE, 0, 15) master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) self._crossfader.name = 'Crossfader' #not used in APC20 master_volume_control.name = 'Master_Volume_Control' self._prehear_control.name = 'Prehear_Volume_Control' self._mixer.set_shift_button(self._shift_button) #added for shifting prehear self._mixer.set_crossfader_control(self._crossfader) #not used in APC20 self._mixer.set_prehear_volume_control(self._prehear_control) #functionality overridden in SpecialMixerComponent self._mixer.master_strip().set_volume_control(master_volume_control) self._slider_modes = SliderModesComponent(self._mixer, tuple(sliders)) #added from APC20 script self._slider_modes.name = 'Slider_Modes' #added from APC20 script matrix_modes = MatrixModesComponent(self._matrix, self._session, self._session_zoom, tuple(self._track_stop_buttons), self) #added new matrix_modes.name = 'Matrix_Modes' #added new # Original method args for ShiftableSelectorComponent: (self, select_buttons, master_button, arm_buttons, matrix, session, zooming, mixer, transport, slider_modes, mode_callback) #self._shift_modes = ShiftableSelectorComponent(tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, transport, slider_modes, self._send_introduction_message) self._shift_modes = ShiftableSelectorComponent(self, tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, self._slider_modes, matrix_modes) #, self._send_introduction_message) #also added self for _parent self._shift_modes.name = 'Shift_Modes' self._shift_modes.set_mode_toggle(self._shift_button)
def connect_to(self, parameter): """ Overrides standard so that mapping type can be properly updated on parameter assignment. Also handles setting up observers. """ self._on_parameter_changed.subject = None self._on_parameter_name_changed.subject = None SliderElement.connect_to(self, parameter) self._smoother.set_parameter(self._parameter_to_map_to) self._on_parameter_changed.subject = self._parameter_to_map_to self._on_parameter_name_changed.subject = self._parameter_to_map_to self._update_mapping_type() return
def connect_to(self, param): if self._parameter_to_map_to is not None: try: self._parameter_to_map_to.remove_value_listener(self._on_value_changed) except: pass SliderElement.connect_to(self, param) if param is not None: if not self._parameter_to_map_to.value_has_listener(self._on_value_changed): self._parameter_to_map_to.add_value_listener(self._on_value_changed) self._send_param_val(True)
def _setup_transport(self): is_momentary = True transport = TransportComponent() studiotransport = MaschineTransport() playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108) stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110) recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109) overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107) metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104) eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98) playButton.name = 'Play' stopButton.name = 'Stop' recordButton.name = 'Record' overdubButton.name = 'Overdub' metrononmeButton.name = 'Metronome' transport.set_play_button(playButton) transport.set_stop_button(stopButton) transport.set_record_button(recordButton) transport.set_overdub_button(overdubButton) transport.set_metronome_button(metrononmeButton) studiotransport.set_session_auto_button(eventRecButton) studiotransport.set_arrangement_overdub_button(StateButton(is_momentary, MIDI_CC_TYPE, 0, 106)) studiotransport.set_back_arrange_button(StateButton(is_momentary, MIDI_CC_TYPE, 0, 105)) transport.set_nudge_buttons(StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50)) punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52) punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53) punchinbutton.name = 'Punch In' punchoutbutton.name = 'Punch Out' transport.set_punch_buttons(punchinbutton, punchoutbutton) transport.set_loop_button(StateButton(is_momentary, MIDI_CC_TYPE, 1, 54)) self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98) self._do_song_follow.subject = self.song_follow_button self._song_follow_changed.subject = self.song().view self._song_follow_changed() self.prehear_knob = SliderElement(MIDI_CC_TYPE, 0, 41) self.prehear_knob.connect_to(self.song().master_track.mixer_device.cue_volume) self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59) self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58) transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button) self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105) self.xfadeKnob.connect_to(self.song().master_track.mixer_device.crossfader) self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99) self.master_knob.connect_to(self.song().master_track.mixer_device.volume) self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88) self._do_tap_tempo.subject = self.tap_button self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55) self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56) self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57) self._do_toggle_cue.subject = self.cue_add_delete_button self._do_toggle_prev_cue.subject = self.cue_prev_button self._do_toggle_next_cue.subject = self.cue_next_button
def _MG_setup(self): mixer = MixerComponent(8) mixer.set_track_offset( 0) #Sets start point for mixer strip (offset from left) transport = TransportComponent() mixer.set_track_offset(0) for i in xrange(len(KNOBS)): #set the functions of the knobs volume_knob = SliderElement(MIDI_CC_TYPE, 0, KNOBS[i]) pan_knob = SliderElement(MIDI_CC_TYPE, 1, KNOBS[i]) send_a = SliderElement(MIDI_CC_TYPE, 2, KNOBS[i]) send_b = SliderElement(MIDI_CC_TYPE, 3, KNOBS[i]) send_c = SliderElement(MIDI_CC_TYPE, 4, KNOBS[i]) send_d = SliderElement(MIDI_CC_TYPE, 5, KNOBS[i]) send_e = SliderElement(MIDI_CC_TYPE, 6, KNOBS[i]) send_f = SliderElement(MIDI_CC_TYPE, 7, KNOBS[i]) mixer.channel_strip(i).set_volume_control(volume_knob) mixer.channel_strip(i).set_pan_control(pan_knob) mixer.channel_strip(i).set_send_controls( [send_a, send_b, send_c, send_d, send_e, send_f]) # scenes are locked to channel 14 transport.set_overdub_button( ButtonElement(False, MIDI_CC_TYPE, 0, SCENES[0])) transport.set_stop_button( ButtonElement(False, MIDI_CC_TYPE, 0, SCENES[1]))
def _create_controls(self): self._device_encoders = ButtonMatrixElement(rows=[[ EncoderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier, Live.MidiMap.MapMode.relative_smooth_binary_offset, name=b'Device_Encoder_%d_%d' % (col_index, row_index)) for col_index, identifier in enumerate(row) ] for row_index, row in enumerate((ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[4:8]))]) self._horizontal_scroll_encoder = EncoderElement( MIDI_CC_TYPE, ENCODER_CHANNEL, ENCODER_MSG_IDS[(-2)], Live.MidiMap.MapMode.relative_smooth_binary_offset, name=b'Horizontal_Scroll_Encoder') self._vertical_scroll_encoder = EncoderElement( MIDI_CC_TYPE, ENCODER_CHANNEL, ENCODER_MSG_IDS[(-1)], Live.MidiMap.MapMode.relative_smooth_binary_offset, name=b'Vertical_Scroll_Encoder') self._volume_sliders = ButtonMatrixElement(rows=[[ SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier) for identifier in SLIDER_MSG_IDS[:-1] ]]) self._master_slider = SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, SLIDER_MSG_IDS[(-1)]) def make_keylab_button(name): button = ButtonElement(True, MIDI_CC_TYPE, 0, get_button_identifier_by_name(name), name=name.title()) return button for button_name in BUTTON_HARDWARE_AND_MESSAGE_IDS.keys(): setattr(self, b'_' + button_name, make_keylab_button(button_name)) self._pads = ButtonMatrixElement(rows=[[ ButtonElement(True, MIDI_CC_TYPE, PAD_CHANNEL, col_index + row_offset, name=b'Pad_%d_%d' % (col_index, row_index)) for col_index in xrange(4) ] for row_index, row_offset in enumerate(xrange(48, 35, -4))])
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = "DirectLink" self._suggested_output_port = "DirectLink" self._waiting_for_first_response = True self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_pressed = False self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 13) self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 111) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 110) self._device_bank_buttons = None self._device_navigation = None self._shift_button.name = "Shift_Button" self._master_slider.name = "Master_Volume_Control" self._next_nav_button.name = "Next_Track_Button" self._prev_nav_button.name = "Prev_Track_Button" self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._shift_button.add_value_listener(self._shift_value) self._setup_mixer() self._setup_transport_and_session() self._setup_device() self._setup_display() for component in self.components: component.set_enabled(False) return
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)
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = 'Impulse' self._suggested_output_port = 'Impulse' self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39) self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8) self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._preview_button.add_value_listener(self._preview_value) self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_name_display() device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10) mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9) device_button.name = 'Encoder_Device_Mode' mixer_button.name = 'Encoder_Mixer_Mode' self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders) self._encoder_modes.set_device_mixer_buttons(device_button, mixer_button) self._string_to_display = None for component in self.components: component.set_enabled(False)
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.selected_strip().name = 'Selected_Channel_Strip' self._solo_buttons = [] # added a self._select_buttons = [] # added a for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) volume_control = EncoderElement(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute) # 'Slider_' + str(track), track, self) arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48) solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50, str(track) + '_Solo_Button', self) self._solo_buttons.append(solo_button) # added a mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) select_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, str(track) + '_Select_Button', self) self._select_buttons.append(select_button) # added a #volume_control.name = str(track) + '_Volume_Control' arm_button.name = str(track) + '_Arm_Button' #solo_button.name = str(track) + '_Solo_Button' mute_button.name = str(track) + '_Mute_Button' #select_button.name = str(track) + '_Select_Button' strip.set_volume_control(volume_control) strip.set_arm_button(arm_button) strip.set_solo_button(solo_button) strip.set_mute_button(mute_button) strip.set_select_button(select_button) strip.set_shift_button(self._shift_button) strip.set_invert_mute_feedback(True) crossfader = SliderElement(MIDI_CC_TYPE, 0, 15) self._crossfader = crossfader self._crossfader.name = 'Crossfader' master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80) self._master_select_button = master_select_button prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' master_select_button.name = 'Master_Select_Button' prehear_control.name = 'Prehear_Volume_Control' self._mixer.set_crossfader_control(crossfader) self._mixer.set_prehear_volume_control(prehear_control) self._mixer.master_strip().set_volume_control(master_volume_control) self._mixer.master_strip().set_select_button(master_select_button)
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 __init__(self, *a, **k): super(AudioClipEditComponent, self).__init__(*a, **k) self._loop_start_slider = SliderElement(MIDI_CC_TYPE, 2, 60) self._action_loop_start.subject = self._loop_start_slider self._loop_end_slider = SliderElement(MIDI_CC_TYPE, 2, 61) self._action_loop_end.subject = self._loop_end_slider self._mark_start_slider = SliderElement(MIDI_CC_TYPE, 2, 62) self._action_mark_start.subject = self._mark_start_slider self._mark_end_slider = SliderElement(MIDI_CC_TYPE, 2, 63) self._action_mark_end.subject = self._mark_end_slider self._pitch_c_slider = SliderElement(MIDI_CC_TYPE, 2, 64) self._pitch_f_slider = SliderElement(MIDI_CC_TYPE, 2, 65) self._gain_slider = SliderElement(MIDI_CC_TYPE, 2, 66) self._action_pitch_c.subject = self._pitch_c_slider self._action_pitch_f.subject = self._pitch_f_slider self._action_gain.subject = self._gain_slider self._loop_inc_slider = SliderElement(MIDI_CC_TYPE, 2, 67) self._action_loop_inc.subject = self._loop_inc_slider self._loop_move_button = ButtonElement(False, MIDI_CC_TYPE, 2, 74) self._action_mv_loop.subject = self._loop_move_button self._loop_set_button = ButtonElement(False, MIDI_CC_TYPE, 2, 70) self._action_loop_toggle.subject = self._loop_set_button self._warp_set_button = ButtonElement(False, MIDI_CC_TYPE, 2, 71) self._action_warp_toggle.subject = self._warp_set_button self._zoom_scroll_button = ButtonElement(False, MIDI_CC_TYPE, 2, 73) self._action_scroll_mode.subject = self._zoom_scroll_button self.selected_clip_slot = None self.inc_index = 4 self.loop_inc = INC_STEPS[self.inc_index] self.start_inc = INC_STEPS[self.inc_index] self.mv_loop = False self._on_pitch_c_changed.subject = None self._on_pitch_f_changed.subject = None self._on_gain_changed.subject = None self._scroll_mode = False self.update_selected_clip()
def _init_mixer_component(self): is_momentary = True global mixer mixer = MixerComponent(8) mixer.name = 'Mixer' mixer.set_track_offset(0) self.song().view.selected_track = mixer.channel_strip(0)._track for track in range(8): #self.log_message("Adding track " + str(track)) strip = mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) volume_control = SliderElement(MIDI_CC_TYPE, track, VOL_CC) snd_A_control = SliderElement(MIDI_CC_TYPE, track, SND_A_CC) snd_B_control = SliderElement(MIDI_CC_TYPE, track, SND_B_CC) pan_control = SliderElement(MIDI_CC_TYPE, track, PAN_CC) arm_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, track, ARM_CC) select_button = ButtonElement(is_momentary, MIDI_CC_TYPE, track, SEL_CC) mute_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, track, MUTE_CC) volume_control.name = str(track) + '_Volume_Control' snd_A_control.name = str(track) + '_Send_A_Control' snd_B_control.name = str(track) + '_Send_B_Control' pan_control.name = str(track) + '_Pan_Control' arm_button.name = str(track) + '_arm_Button' select_button.name = str(track) + '_Select_Button' mute_button.name = str(track) + '_Mute_Button' strip.set_volume_control(volume_control) strip.set_send_controls([snd_A_control, snd_B_control]) strip.set_pan_control(pan_control) strip.set_arm_button(arm_button) strip.set_select_button(select_button) strip.set_mute_button(mute_button) return mixer
def _setup_mixer_control(self): is_momentary = True ## Quirksmode self.arm_buttons = [] self._mixer = SpecialMixerComponent(self, 8) #added self for parent self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.selected_strip().name = 'Selected_Channel_Strip' for track in range(8): self.strip = self._mixer.channel_strip(track) self.strip.name = 'Channel_Strip_' + str(track) volume_control = SliderElement(MIDI_CC_TYPE, track, 7) arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48) solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50) select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51) volume_control.name = str(track) + '_Volume_Control' arm_button.name = str(track) + '_Arm_Button' solo_button.name = str(track) + '_Solo_Button' mute_button.name = str(track) + '_Mute_Button' select_button.name = str(track) + '_Select_Button' self.strip.set_volume_control(volume_control) ##Quirksmode self.arm_buttons.append(arm_button) self.strip.set_arm_button(arm_button) self.strip.set_solo_button(solo_button) self.strip.set_mute_button(mute_button) self.strip.set_select_button(select_button) self.strip.set_shift_button(self._shift_button) self.strip.set_invert_mute_feedback(True) crossfader = SliderElement(MIDI_CC_TYPE, 0, 15) master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80) ##self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) crossfader.name = 'Crossfader' master_volume_control.name = 'Master_Volume_Control' master_select_button.name = 'Master_Select_Button' ##self._prehear_control.name = 'Prehear_Volume_Control' self._mixer.set_crossfader_control(crossfader) ##self._mixer.set_prehear_volume_control(self._prehear_control) self._mixer.master_strip().set_volume_control(master_volume_control) self._mixer.master_strip().set_select_button(master_select_button)
def _setup_transport(self): is_momentary = True transport = TransportComponent() playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108) stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110) recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109) overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107) metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104) playButton.name = 'Play' stopButton.name = 'Stop' recordButton.name = 'Record' overdubButton.name = 'Overdub' metrononmeButton.name = 'Metronome' transport.set_play_button(playButton) transport.set_stop_button(stopButton) transport.set_record_button(recordButton) transport.set_overdub_button(overdubButton) transport.set_metronome_button(metrononmeButton) transport.set_nudge_buttons(StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50)) punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52) punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53) punchinbutton.name = 'Punch In' punchoutbutton.name = 'Punch Out' transport.set_punch_buttons(punchinbutton, punchoutbutton) transport.set_loop_button(StateButton(is_momentary, MIDI_CC_TYPE, 1, 54)) self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59) self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58) transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button) self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 100) self.xfadeKnob.connect_to(self.song().master_track.mixer_device.crossfader) self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88) self.tap_button.add_value_listener(self._do_tap_tempo) self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55) self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56) self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57) self.cue_add_delete_button.add_value_listener(self._do_toggle_cue) self.cue_prev_button.add_value_listener(self._do_toggle_prev_cue) self.cue_next_button.add_value_listener(self._do_toggle_next_cue)
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.selected_strip().name = "Selected_Channel_Strip" for track in range(8): strip = self._mixer.channel_strip(track) strip.name = "Channel_Strip_" + str(track) volume_control = SliderElement(MIDI_CC_TYPE, track, 7) arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48) solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49) mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50) select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51) volume_control.name = str(track) + "_Volume_Control" arm_button.name = str(track) + "_Arm_Button" solo_button.name = str(track) + "_Solo_Button" mute_button.name = str(track) + "_Mute_Button" select_button.name = str(track) + "_Select_Button" strip.set_volume_control(volume_control) strip.set_arm_button(arm_button) strip.set_solo_button(solo_button) strip.set_mute_button(mute_button) strip.set_select_button(select_button) strip.set_shift_button(self._shift_button) strip.set_invert_mute_feedback(True) crossfader = SliderElement(MIDI_CC_TYPE, 0, 15) master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14) master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80) self.prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment) self._mixer.set_shift_button(self._shift_button) # added for shifting prehear crossfader.name = "Crossfader" master_volume_control.name = "Master_Volume_Control" master_select_button.name = "Master_Select_Button" self.prehear_control.name = "Prehear_Volume_Control" self._mixer.set_crossfader_control(crossfader) self._mixer.set_prehear_volume_control(self.prehear_control) self._mixer.master_strip().set_volume_control(master_volume_control) self._mixer.master_strip().set_select_button(master_select_button)
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._instance = c_instance self._has_slider_section = True self.log_message("Midilooper initializing...") # register_sender(self) self._session = SessionComponent(NUM_TRACKS, NUM_ROWS) self._session.name = 'Session_Control' self._mixer = MixerComponent(NUM_TRACKS, NUM_RETURNS) for track in range(NUM_TRACKS): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) # encoder = EncoderElement(MIDI_CC_TYPE, 0, 20 + track, Live.MidiMap.MapMode.absolute) control = SliderElement(MIDI_CC_TYPE, 0, 20+track) control.name = str(track) + '_Volume_Control' strip.set_volume_control(control) for track in range(NUM_RETURNS): strip = self._mixer.return_strip(track) control = SliderElement(MIDI_CC_TYPE, 0, 40+track) control.name = str(track) + '_Return_Control' strip.set_volume_control(control) strip = self._mixer.master_strip() strip.name = 'Master_Channel_Strip' control = SliderElement(MIDI_CC_TYPE, 0, 50) control.name = 'Master_Volume_Control' strip.set_volume_control(control) self._session.set_offsets(0, 0); self._session.set_mixer(self._mixer) for row in range(NUM_ROWS): scene = self._session.scene(row) for track in range(NUM_TRACKS): slot = scene.clip_slot(track) button = ButtonElement(True, MIDI_NOTE_TYPE, track, 36+row) slot.set_launch_button(button) self.set_highlighting_session_component(self._session) self.request_rebuild_midi_map() self.log_message("Midilooper initialized.")
def make_slider(channel, cc, name): element = SliderElement(MIDI_CC_TYPE, channel, cc) element.name = name return element
def make_slider(cc_no, name): slider = SliderElement(MIDI_CC_TYPE, 0, cc_no) slider.set_feedback_delay(-1) slider.name = name return slider
def set_led_slider(self, track): self.slider = SliderElement(MIDI_CC_TYPE, SLIDER_CHANNEL, track + 1)
class VUMeter(ControlSurfaceComponent): _active_instances = [] def __init__(self, parent): ControlSurfaceComponent.__init__(self) VUMeter._active_instances.append(self) self.slider = None self._parent = parent self._vu_meter = None self.frames = [0.0] * RMS_FRAMES self.increments = CHANNEL_SCALE_INCREMENTS self.top = CHANNEL_SCALE_MAX self.bottom = CHANNEL_SCALE_MIN self.multiplier = self.calculate_multiplier(self.top, self.bottom, self.increments) self.current_level = 0 def disconnect(self): VUMeter._active_instances.remove(self) if self._vu_meter != None: self._vu_meter.remove_output_meter_left_listener(self.observe) self._vu_meter = None def observe(self): new_frame = self.mean_peak() self.store_frame(new_frame) self.level = self.scale(new_frame) if self.level != self.current_level: self.current_level = self.level self.send_vu_value(self.level) else: None def store_frame(self, frame): self.frames.pop(0) self.frames.append(frame) def rms(self, frames): return math.sqrt(sum((frame * frame for frame in frames)) / len(frames)) def mean_peak(self): return (self._vu_meter.output_meter_left + self._vu_meter.output_meter_right) / 2 def scale(self, value): if value > self.top: value = self.top elif value < self.bottom: value = self.bottom value = value - self.bottom value = value * self.multiplier return int(round(value)) def calculate_multiplier(self, top, bottom, increments): return increments / (top - bottom) def set_vu_meter(self, track): self.set_led_slider(track) self._vu_meter = self.song().tracks[track] if self._vu_meter != None: self._vu_meter.add_output_meter_left_listener(self.observe) else: None def set_led_slider(self, track): self.slider = SliderElement(MIDI_CC_TYPE, SLIDER_CHANNEL, track + 1) def send_vu_value(self, level): if level != None: if level < 1: None else: self.slider.send_value(level, True) else: None def update(self): pass
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 __init__(self, parent): self._parent = parent self.master_track = parent.song().master_track self.the_slider = SliderElement(MIDI_CC_TYPE, 1, 86) self.the_slider.add_value_listener(self._do_main_slider, True) self.volume_button = None self._set_volume_button(StateButton(True, MIDI_CC_TYPE, 1, 80)) self.xfade_button = None self._set_xfade_button(StateButton(True, MIDI_CC_TYPE, 1, 99)) self.swing_button = None self._set_swing_button(StateButton(True, MIDI_CC_TYPE, 1, 81)) self.mode = KN2_MODE_VOLUME self.previous_mode = -1 self.tempo_button = None self._set_tempo_button(StateButton(True, MIDI_CC_TYPE, 1, 82)) self.push_button = None self._set_push_button(StateButton(True, MIDI_CC_TYPE, 1, 87)) self.clipn_v_button = None self.clipn_h_button = None self._set_clipn_h_button(StateButton(True, MIDI_CC_TYPE, 1, 90)) self._set_clipn_v_button(StateButton(True, MIDI_CC_TYPE, 1, 91)) self.toggle_buttons = [self.volume_button, self.xfade_button, self.swing_button, self.tempo_button, self.clipn_h_button, self.clipn_v_button] self.shift_button = None self._set_shift_button(StateButton(True, MIDI_CC_TYPE, 1, 85)) self.shift_on = False self.scroll_mod_left_button = None self.scroll_mod_right_button = None self._set_scroll_mod_left_button(ButtonElement(True, MIDI_CC_TYPE, 0, 105)) self._set_scroll_mod_right_button(ButtonElement(True, MIDI_CC_TYPE, 0, 106)) self._prev_mode = KN2_MODE_VOLUME self.lrmode = LR_CONTROL_CLIP self.loop_div_index = 0 self.loop_incdex = 4.0 self.arrow_mode_button = ColorButton(True, MIDI_CC_TYPE, 30) self.arrow_mode_button.add_value_listener(self.toggle_arrow_mode) self.arrow_mode_button.send_value(1, True) self.navflags = 0 self.octave_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 70) self.octave_mod_button.add_value_listener(self._action_octave) self.scale_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 71) self.scale_mod_button.add_value_listener(self._action_scale) self.basenote_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 72) self.basenote_mod_button.add_value_listener(self._action_base_note) self.pad_to_mainknob_mode = 0 self.octave_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 120) self.octave_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 121) self.scale_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 118) self.scale_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 119) self.basent_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 124) self.basent_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 125) self.octave_dwn_button.add_value_listener(self._action_oct_down) self.octave_upp_button.add_value_listener(self._action_oct_up) self.scale_dwn_button.add_value_listener(self._action_scale_down) self.scale_upp_button.add_value_listener(self._action_scale_up) self.basent_dwn_button.add_value_listener(self._action_base_down) self.basent_upp_button.add_value_listener(self._action_base_up) self._measure_left_click = 0 self._measure_right_click = 0 self.mode_assign_map = {KN2_MODE_VOLUME: (self.chg_volume, 0, 'Master Knob controls MASTER Volume', KN2_MODE_CUE), KN2_MODE_CUE: (self.chg_cue, 0, 'Master Knob controls Cue Level', KN2_MODE_VOLUME), KN2_MODE_TEMPO_COARSE: (self.chg_tempo, 3, 'Master Knob controls TEMPO Coarse', KN2_MODE_TEMPO_FINE), KN2_MODE_TEMPO_FINE: (self.chg_tempo_fine, 3, 'Master Knob controls TEMPO Fine', KN2_MODE_TEMPO_COARSE), KN2_MODE_XFADE: (self.chg_xfade, 1, 'Master Knob controls Crossfader', -1), KN2_MODE_QUANT: (self.chg_quant, 2, 'Master Knob controls Recording Quantize', KN2_MODE_CLIP_QUANT), KN2_MODE_CLIP_QUANT: (self.chg_clip_q, 2, 'Master Knob controls Clip Start Quantize', KN2_MODE_QUANT), KN2_MODE_CLIPN_HOR: (self.nav_c_hor, 4, 'Master Knob Clip View horizontally', -1), KN2_MODE_CLIPN_VER: (self.nav_c_ver, 5, 'Master Knob Clip View vertically', -1), KN2_MODE_GENERAL: (self.chg_general, -1, None, -1), KN2_P_SCALES: (self.modify_pad_scaling, -1, None, -1)}
def _set_up_machine_knobs(self): master_track = self.song().master_track self.master_volume = SliderElement(MIDI_CC_TYPE, 0, 40) self.prehear = SliderElement(MIDI_CC_TYPE, 0, 41) self.master_volume.connect_to(master_track.mixer_device.volume) self.prehear.connect_to(master_track.mixer_device.cue_volume)
def __init__(self, parent): self._parent = parent self.master_track = parent.song().master_track self.volume_button = None self._set_volume_button(StateButton(True, MIDI_CC_TYPE, 3, 110)) self.the_slider = SliderElement(MIDI_CC_TYPE, 1, 86) self.the_slider.add_value_listener(self._do_main_slider, True) self.xfade_button = None self._set_xfade_button(StateButton(True, MIDI_CC_TYPE, 3, 116)) self.swing_button = None self._set_swing_button(StateButton(True, MIDI_CC_TYPE, 3, 111)) self.mode = KN2_MODE_VOLUME self.previous_mode = -1 self.tempo_button = None self._set_tempo_button(StateButton(True, MIDI_CC_TYPE, 3, 112)) self.push_button = None self._set_push_button(StateButton(True, MIDI_CC_TYPE, 1, 87)) self.clipn_v_button = None self.clipn_h_button = None self._set_clipn_h_button(StateButton(True, MIDI_CC_TYPE, 3, 114)) self._set_clipn_v_button(StateButton(True, MIDI_CC_TYPE, 3, 115)) self.toggle_buttons = [ self.volume_button, self.xfade_button, self.swing_button, self.tempo_button, self.clipn_h_button, self.clipn_v_button, ] self.shift_button = None self._set_shift_button(StateButton(True, MIDI_CC_TYPE, 3, 113)) self.shift_on = False self.scroll_mod_left_button = None self.scroll_mod_right_button = None self._set_scroll_mod_left_button(StateButton(True, MIDI_CC_TYPE, 0, 105)) self._set_scroll_mod_right_button(StateButton(True, MIDI_CC_TYPE, 0, 106)) self._prev_mode = KN2_MODE_VOLUME self.lrmode = LR_CONTROL_CLIP self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143 self.loop_div_index = 0 self.loop_incdex = 4.0 self.arrow_mode_button = ColorButton(True, MIDI_CC_TYPE, 30) self.arrow_mode_button.add_value_listener(self.toggle_arrow_mode) self.arrow_mode_button.send_color(LR_MODE_HUES[self.lrmode]) self.arrow_mode_button.send_value(127, True) self.navflags = 0 self.octave_mod_button = StateButton(True, MIDI_CC_TYPE, 1, 70) self.octave_mod_button.add_value_listener(self._action_octave) self.scale_mod_button = StateButton(True, MIDI_CC_TYPE, 1, 71) self.scale_mod_button.add_value_listener(self._action_scale) self.basenote_mod_button = StateButton(True, MIDI_CC_TYPE, 1, 72) self.basenote_mod_button.add_value_listener(self._action_base_note) self.keycolor_mod_button = StateButton(True, MIDI_CC_TYPE, 1, 73) self.keycolor_mod_button.add_value_listener(self._action_key_color) self.pad_to_mainknob_mode = 0 self._measure_left_click = 0 self._measure_right_click = 0 self.mode_assign_map = { KN2_MODE_VOLUME: (self.chg_volume, 0, "Master Knob controls MASTER Volume", KN2_MODE_CUE), KN2_MODE_CUE: (self.chg_cue, 0, "Master Knob controls Cue Level", KN2_MODE_VOLUME), KN2_MODE_TEMPO_COARSE: (self.chg_tempo, 3, "Master Knob controls TEMPO Coarse", KN2_MODE_TEMPO_FINE), KN2_MODE_TEMPO_FINE: (self.chg_tempo_fine, 3, "Master Knob controls TEMPO Fine", KN2_MODE_TEMPO_COARSE), KN2_MODE_XFADE: (self.chg_xfade, 1, "Master Knob controls Crossfader", -1), KN2_MODE_QUANT: (self.chg_quant, 2, "Master Knob controls Recording Quantize", KN2_MODE_CLIP_QUANT), KN2_MODE_CLIP_QUANT: (self.chg_clip_q, 2, "Master Knob controls Clip Start Quantize", KN2_MODE_QUANT), KN2_MODE_CLIPN_HOR: (self.nav_c_hor, 4, "Master Knob Clip View horizontally", -1), KN2_MODE_CLIPN_VER: (self.nav_c_ver, 5, "Master Knob Clip View vertically", -1), KN2_MODE_GENERAL: (self.chg_general, -1, None, -1), KN2_P_SCALES: (self.modify_pad_scaling, -1, None, -1), }
class AudioClipEditComponent(CompoundComponent): """ classdocs """ def __init__(self, *a, **k): super(AudioClipEditComponent, self).__init__(*a, **k) self._loop_start_slider = SliderElement(MIDI_CC_TYPE, 2, 60) self._action_loop_start.subject = self._loop_start_slider self._loop_end_slider = SliderElement(MIDI_CC_TYPE, 2, 61) self._action_loop_end.subject = self._loop_end_slider self._mark_start_slider = SliderElement(MIDI_CC_TYPE, 2, 62) self._action_mark_start.subject = self._mark_start_slider self._mark_end_slider = SliderElement(MIDI_CC_TYPE, 2, 63) self._action_mark_end.subject = self._mark_end_slider self._pitch_c_slider = SliderElement(MIDI_CC_TYPE, 2, 64) self._pitch_f_slider = SliderElement(MIDI_CC_TYPE, 2, 65) self._gain_slider = SliderElement(MIDI_CC_TYPE, 2, 66) self._action_pitch_c.subject = self._pitch_c_slider self._action_pitch_f.subject = self._pitch_f_slider self._action_gain.subject = self._gain_slider self._loop_inc_slider = SliderElement(MIDI_CC_TYPE, 2, 67) self._action_loop_inc.subject = self._loop_inc_slider self._loop_move_button = ButtonElement(False, MIDI_CC_TYPE, 2, 74) self._action_mv_loop.subject = self._loop_move_button self._loop_set_button = ButtonElement(False, MIDI_CC_TYPE, 2, 70) self._action_loop_toggle.subject = self._loop_set_button self._warp_set_button = ButtonElement(False, MIDI_CC_TYPE, 2, 71) self._action_warp_toggle.subject = self._warp_set_button self._zoom_scroll_button = ButtonElement(False, MIDI_CC_TYPE, 2, 73) self._action_scroll_mode.subject = self._zoom_scroll_button self.selected_clip_slot = None self.inc_index = 4 self.loop_inc = INC_STEPS[self.inc_index] self.start_inc = INC_STEPS[self.inc_index] self.mv_loop = False self._on_pitch_c_changed.subject = None self._on_pitch_f_changed.subject = None self._on_gain_changed.subject = None self._scroll_mode = False self.update_selected_clip() @subject_slot("value") def _action_scroll_mode(self, value): if value > 0: self._scroll_mode = True else: self._scroll_mode = False @subject_slot("value") def _action_warp_toggle(self, value): if value > 0: if self.selected_clip_slot and self.selected_clip_slot.has_clip: clip = self.selected_clip_slot.clip if clip.is_audio_clip: clip.warping = not clip.warping self._warp_set_button.send_value(clip.warping and 127 or 0, True) @subject_slot("value") def _action_loop_toggle(self, value): if value > 0: if self.selected_clip_slot and self.selected_clip_slot.has_clip: clip = self.selected_clip_slot.clip clip.looping = not clip.looping self._loop_set_button.send_value(clip.looping and 127 or 0, True) @subject_slot("value") def _action_loop_inc(self, value): if not (value == 1 and 1): inc = -1 val = self.inc_index + inc self.inc_index = val >= 0 and val < len(INC_STEPS) and val self.loop_inc = INC_STEPS[val] self.start_inc = INC_STEPS[val] self.canonical_parent.timed_message(2, "Loop Adjust: " + INC_DISP[val]) self.canonical_parent.show_message("Loop Adjust: " + INC_DISP[val]) @subject_slot("value") def _action_mv_loop(self, value): if value > 0: if self.mv_loop: self._loop_move_button.send_value(0, True) self.mv_loop = False else: self._loop_move_button.send_value(127, True) self.mv_loop = True @subject_slot("value") def _action_mark_start(self, value): if self._scroll_mode: scroll = value == 1 and 3 or 2 self.application().view.scroll_view(scroll, "Detail/Clip", False) elif not (value == 1 and 1): inc = -1 clip = self.selected_clip_slot and self.selected_clip_slot.has_clip and self.selected_clip_slot.clip ls = clip.start_marker le = clip.end_marker ls = max(0, min(le - self.start_inc, ls + inc * self.start_inc)) clip.start_marker = ls bars_to_measure(ls, clip.signature_denominator, clip.signature_numerator) self.canonical_parent.timed_message( 2, "Clip Start: " + bars_to_measure(ls, clip.signature_denominator, clip.signature_numerator) ) @subject_slot("value") def _action_mark_end(self, value): if self._scroll_mode: scroll = value == 1 and 3 or 2 self.application().view.zoom_view(scroll, "Detail/Clip", False) elif not (value == 1 and 1): inc = -1 clip = self.selected_clip_slot and self.selected_clip_slot.has_clip and self.selected_clip_slot.clip ls = clip.start_marker le = clip.end_marker le = max(ls + self.start_inc, le + inc * self.start_inc) clip.end_marker = le self.canonical_parent.timed_message( 2, "Clip End: " + bars_to_measure(le, clip.signature_denominator, clip.signature_numerator) ) @subject_slot("value") def _action_loop_start(self, value): if not (value == 1 and 1): inc = -1 if self.selected_clip_slot and self.selected_clip_slot.has_clip: clip = self.selected_clip_slot.clip ls = clip.loop_start le = clip.loop_end if self.mv_loop: diff = le - ls ls = max(0, ls + inc * self.loop_inc) clip.loop_end = inc > 0 and ls + diff clip.end_marker = ls + diff clip.loop_start = ls clip.start_marker = ls else: clip.loop_start = ls clip.start_marker = ls clip.loop_end = ls + diff clip.end_marker = ls + diff self.canonical_parent.timed_message(2, loop_str(clip)) else: ls = max(0, min(le - self.loop_inc, ls + inc * self.loop_inc)) clip.loop_start = ls self.canonical_parent.timed_message(2, loop_str(clip)) @subject_slot("value") def _action_loop_end(self, value): if not (value == 1 and 1): inc = -1 if self.selected_clip_slot and self.selected_clip_slot.has_clip: clip = self.selected_clip_slot.clip ls = clip.loop_start le = clip.loop_end le = max(ls + self.loop_inc, le + inc * self.loop_inc) clip.loop_end = le clip.end_marker = self.mv_loop and le self.canonical_parent.timed_message(2, loop_str(clip)) def update(self): pass @subject_slot("value") def _action_pitch_c(self, value): cs = self.selected_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: cs.clip.pitch_coarse = midi_to_pitchc(value) @subject_slot("value") def _action_pitch_f(self, value): cs = self.selected_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: cs.clip.pitch_fine = midi_to_pitchf(value) @subject_slot("value") def _action_gain(self, value): cs = self.selected_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: cs.clip.gain = midi_to_gain(value) def _update_clip_name(self): cs = self.song().view.highlighted_clip_slot if not cs: track = self.song().view.selected_track self.canonical_parent.send_to_display("Rt Trck: " + track.name, 3) elif cs.has_clip: self.canonical_parent.send_to_display(cs.clip.is_audio_clip and "A" or "M" + ":" + cs.clip.name, 3) else: track = cs.canonical_parent index = list(track.clip_slots).index(cs) scene = self.song().scenes[index] self.canonical_parent.send_to_display("E<" + str(scene.name) + "> T:" + track.name, 3) @subject_slot("has_clip") def _on_has_clip_changed(self): self._update_clip_name() @subject_slot("name") def _on_name_changed(self): self._update_clip_name() def update_selected_clip(self): cs = self.song().view.highlighted_clip_slot if cs != self.selected_clip_slot: self.selected_clip_slot = cs self._update_clip_name() if cs and cs.has_clip and cs.clip.is_audio_clip: self._on_pitch_c_changed.subject = cs.clip self._on_pitch_f_changed.subject = cs.clip self._on_gain_changed.subject = cs.clip self._on_warp_changed.subject = cs.clip self._gain_slider.send_value(gain_to_midi(cs.clip.gain)) self._pitch_c_slider.send_value(pitchc_to_midi(cs.clip.pitch_coarse)) self._pitch_f_slider.send_value(pitchf_to_midi(cs.clip.pitch_fine)) self._warp_set_button.send_value(cs.clip.warping and 127 or 0, True) else: self._on_pitch_c_changed.subject = None self._on_pitch_f_changed.subject = None self._on_gain_changed.subject = None self._on_warp_changed.subject = None self._on_loop_changed.subject = None if cs and cs.has_clip: self._on_loop_changed.subject = cs.clip self._on_name_changed.subject = cs.clip self._loop_set_button.send_value(cs.clip.looping and 127 or 0, True) else: self._on_name_changed.subject = None self._on_loop_changed.subject = None self._on_has_clip_changed.subject = cs def on_selected_track_changed(self): self.update_selected_clip() def on_selected_scene_changed(self): self.update_selected_clip() @subject_slot("looping") def _on_loop_changed(self): cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip: self._loop_set_button.send_value(cs.clip.looping and 127 or 0, True) @subject_slot("warping") def _on_warp_changed(self): cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: self._warp_set_button.send_value(cs.clip.warping and 127 or 0, True) @subject_slot("pitch_coarse") def _on_pitch_c_changed(self): cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: self._pitch_c_slider.send_value(pitchc_to_midi(cs.clip.pitch_coarse)) @subject_slot("pitch_fine") def _on_pitch_f_changed(self): cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: self._pitch_f_slider.send_value(pitchf_to_midi(cs.clip.pitch_fine)) @subject_slot("gain") def _on_gain_changed(self): cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip and cs.clip.is_audio_clip: self._gain_slider.send_value(gain_to_midi(cs.clip.gain))
class MaschineMk2(ControlSurface): __module__ = __name__ __doc__ = 'Control Script for Maschine Mk2 and Maschine Mikro Mk2' def __init__(self, c_instance): ControlSurface.__init__(self, c_instance, False) with self.component_guard(): self._suppress_send_midi = True self.togglecolor = (10, 30, 50, 70, 90) self.toggleindex = 0 self._c_ref = c_instance self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143 self._c_inst = c_instance is_momentary = True self._active = True self._modifier_down = False self._return_mode = 0 self._returntopad = False self._mode = CLIP_MODE self.init_slot = 0 self.init_done = False self._midi_pause_count = 0 self.nav_index = 0 self._base_note = 0 self._octave = 0.55 self._scale_select_mode = MODE_PRESS_NONE self.send_slider_index = 0 self._pad_mode = PM_OFF self._note_display_mode = ND_KEYBOARD1 self._set_suppress_rebuild_requests(True) self._scenematrix = SceneMatrix(self) self._master_knob = Mk2KnobControl(self) self._device = self._set_up_device_control() self.show_message(str('')) self.request_rebuild_midi_map() self._set_global_buttons() self._set_mode_buttons() self._setup_transport() self._set_modecontrol() self._set_up_session() self._set_up_mixer() self._set_up_timer() self._set_up_machine_knobs() self.current_scale_index = 0 self.assign_transpose(SCALES[self.current_scale_index]) self.set_highlighting_session_component(self._session) self._navigate_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 127) self._navigate_button.add_value_listener(self._do_focus_navigate) self.display_update_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 86) self.display_update_button.add_value_listener(self._a_display_update) self._set_suppress_rebuild_requests(False) self.song().view.add_detail_clip_listener(self.clip_handle) self.song().add_visible_tracks_listener(self.clip_handle) self.song().add_scenes_listener(self.clip_handle) self.application().view.add_view_focus_changed_listener(self.focus_changed) self.log_message('########## LIVE 9 MASCHINE MK2 V 1.02 #############') self._suppress_send_midi = False def _set_up_mixer(self): is_momentary = True self._mixer = MixerComponent(8) self.send_sliders = [] for track in range(8): self.send_sliders.append(SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, SEND_CC_OFF + track)) for track in range(8): strip = self._mixer.channel_strip(track) strip.set_arm_button(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, ARM_CC_OFF + track)) strip.set_solo_button(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, SOLO_CC_OFF + track)) strip.set_mute_button(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, MUTE_CC_OFF + track)) strip.set_volume_control(SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, LEVEL_CC_OFF + track)) strip.set_pan_control(SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, PAN_CC_OFF + track)) strip.set_select_button(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, SELECT_CC_OFF + track)) st = tuple([self.send_sliders[track]]) strip.set_send_controls(st) self.send_slider_toggle_button = StateButton(False, MIDI_CC_TYPE, 0, 90) self.send_slider_toggle_button.add_value_listener(self._do_toggle_send) self._session.set_mixer(self._mixer) def _set_global_buttons(self): is_momentary = True self._undo_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 85) self._undo_button.add_value_listener(self._do_undo) self._redo_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 87) self._redo_button.add_value_listener(self._do_redo) self._armsolomode_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 89) self._armsolomode_button.add_value_listener(self._do_armsolo_mode) self._fire_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 9) self._fire_button.add_value_listener(self._do_fire_button) self.track_left_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 120) self.track_right_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 121) self.track_left_button.add_value_listener(self._a_trk_left) self.track_right_button.add_value_listener(self._a_trk_right) self.test_button = StateButton(True, MIDI_CC_TYPE, 5, 60) self.note_repeat_button = StateButton(True, MIDI_CC_TYPE, 5, 61) self.test_button.add_value_listener(self.do_test) self.note_repeat_button.add_value_listener(self.do_note_repeat) self.reset_test_button = StateButton(True, MIDI_CC_TYPE, 5, 62) self.reset_test_button.add_value_listener(self.do_reset) def _set_mode_buttons(self): self.xfade_assign_button = StateButton(True, MIDI_CC_TYPE, 0, 116) self._pad_select_button = StateButton(False, MIDI_CC_TYPE, 0, 117) self._pad_solo_button = StateButton(False, MIDI_CC_TYPE, 0, 118) self._mute_button = StateButton(False, MIDI_CC_TYPE, 0, 119) self._pad_scale_up = GatedColorButton(True, MIDI_CC_TYPE, 83, 0) self._pad_scale_down = GatedColorButton(True, MIDI_CC_TYPE, 94, 16) self._pad_select_button.add_value_listener(self._do_pad_select_multi) self._mute_button.add_value_listener(self._do_mute_button) self._pad_solo_button.add_value_listener(self._do_pad_solo_multi) self.xfade_assign_button.add_value_listener(self._do_xfade_assign) self._pad_scale_up.add_value_listener(self._do_pad_note_up) self._pad_scale_down.add_value_listener(self._do_pad_note_down) def set_appointed_device(self, device): with self.component_guard(): self._device_component.set_device(device) def _set_up_device_control(self): is_momentary = True device = MaschineDeviceComponent(self) device.set_device_changed_listener(self._handle_device_changed) device.set_device_parm_listener(self._hande_device_parm_changed) param_controls = [] for index in range(8): param_controls.append(SliderElement(MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_CC_OFF + index)) device.set_parameter_controls(tuple(param_controls)) device.set_on_off_button(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_BUTTON_CC_OFF)) device.set_bank_nav_buttons(StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_BUTTON_CC_OFF + 4), ButtonElement(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_BUTTON_CC_OFF + 5)) self._device_nav_button_left = StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_BUTTON_CC_OFF + 6) self._device_nav_button_right = StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, DEVICE_BUTTON_CC_OFF + 7) self._device_nav_button_left.add_value_listener(self._nav_value_left) self._device_nav_button_right.add_value_listener(self._nav_value_right) device.name = 'Device_Component' self.set_device_component(device) return device def _setup_transport(self): is_momentary = True transport = TransportComponent() playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108) stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110) recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109) overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107) metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104) playButton.name = 'Play' stopButton.name = 'Stop' recordButton.name = 'Record' overdubButton.name = 'Overdub' metrononmeButton.name = 'Metronome' transport.set_play_button(playButton) transport.set_stop_button(stopButton) transport.set_record_button(recordButton) transport.set_overdub_button(overdubButton) transport.set_metronome_button(metrononmeButton) transport.set_nudge_buttons(StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50)) punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52) punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53) punchinbutton.name = 'Punch In' punchoutbutton.name = 'Punch Out' transport.set_punch_buttons(punchinbutton, punchoutbutton) transport.set_loop_button(StateButton(is_momentary, MIDI_CC_TYPE, 1, 54)) self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59) self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58) transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button) self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 100) self.xfadeKnob.connect_to(self.song().master_track.mixer_device.crossfader) self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88) self.tap_button.add_value_listener(self._do_tap_tempo) self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55) self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56) self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57) self.cue_add_delete_button.add_value_listener(self._do_toggle_cue) self.cue_prev_button.add_value_listener(self._do_toggle_prev_cue) self.cue_next_button.add_value_listener(self._do_toggle_next_cue) def _set_up_machine_knobs(self): master_track = self.song().master_track self.master_volume = SliderElement(MIDI_CC_TYPE, 0, 40) self.prehear = SliderElement(MIDI_CC_TYPE, 0, 41) self.master_volume.connect_to(master_track.mixer_device.volume) self.prehear.connect_to(master_track.mixer_device.cue_volume) def _set_up_session(self): is_momentary = True self._session = MaschineSessionComponent() self._session.add_offset_listener(self.notify_track_scroll) nhue = COLOR_HUE_NAV self.nav_buttons = (GatedColorButton(True, MIDI_CC_TYPE, 92, nhue), GatedColorButton(True, MIDI_CC_TYPE, 81, nhue), GatedColorButton(True, MIDI_CC_TYPE, 93, nhue), GatedColorButton(True, MIDI_CC_TYPE, 91, nhue)) self._session.set_scene_bank_buttons(self.nav_buttons[0], self.nav_buttons[1]) self._session.set_track_bank_buttons(self.nav_buttons[2], self.nav_buttons[3]) self._session.set_stop_all_clips_button(StateButton(is_momentary, MIDI_CC_TYPE, 0, 111)) track_stop_buttons = [ StateButton(is_momentary, MIDI_CC_TYPE, BASIC_CHANNEL, index + STOP_CC_OFF) for index in range(4) ] self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons)) self._init_matrix() self._set_up_buttons() self._session._link() self._session.set_advance(STEP4) def _set_up_buttons(self): self._bmatrix = ButtonMatrixElement() for scene_index in range(4): button_row = [] scene = self._session.scene(scene_index) for track_index in range(4): button = self._matrix[scene_index][track_index] clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(button) clip_slot.set_triggered_to_play_value(1) clip_slot.set_triggered_to_record_value(1) clip_slot.set_started_value(1) clip_slot.set_recording_value(1) clip_slot.set_stopped_value(1) self._bmatrix.add_row(tuple(button_row)) def _init_matrix(self): is_momentary = True self._button_sequence = [] self._matrix = [] for scene_index in range(4): button_row = [] for track_index in range(4): button = VarButtonElement(is_momentary, 0, scene_index, track_index, self) partner = TwinButton(is_momentary, 1, button) partner.add_value_listener(self.ox, True) button_row.append(button) self._matrix.append(tuple(button_row)) for scene_index in [3, 2, 1, 0]: for track_index in range(4): self._button_sequence.append(self._matrix[scene_index][track_index]) self._session.set_matrix(self._matrix) def set_pad_translations(self, pad_translations): ControlSurface.set_pad_translations(pad_translations) def refresh_state(self): ControlSurface.refresh_state(self) self._update_hardware() def ox(self, value, button): if not isinstance(button, TwinButton): raise AssertionError self._mode == PAD_MODE and button.fire(value) def _update_hardware(self): self._session.update() self._set_suppress_rebuild_requests(True) self._set_mode() self._master_knob.update() if self._scenematrix.soloexclusive: self._armsolomode_button.send_value(1, True) else: self._armsolomode_button.send_value(0, True) self._master_knob.start_up() self._pad_scale_up.activate() self._pad_scale_down.activate() self.current_scale_to_display() self.send_to_display(KEY_COLOR_MODES_STRINGS[self._note_display_mode], 1) for scene_index in range(4): scene = self._session.scene(scene_index) for track_index in range(4): button = self._matrix[scene_index][track_index] button.refresh() self._set_suppress_rebuild_requests(False) def get_color(self, value, track_index, scene_index): if not self._active: return if self._mode == SCENE_MODE or self._mode == CONTROL_MODE or self._pad_mode == PM_ON: element = self._scenematrix.get_element(scene_index, track_index) return element.get_color(value) elif self._mode == CLIP_MODE: scene = self._session.scene(scene_index) clip_slot = scene.clip_slot(track_index)._clip_slot cindex = 0 if value == 0: cindex = 1 if clip_slot != None: if clip_slot.has_clip: if clip_slot.clip.is_recording or clip_slot.clip.will_record_on_start: return PColor.CLIP_RECORD[cindex] if clip_slot.clip.is_playing: return PColor.CLIP_PLAY[cindex] elif clip_slot.clip.is_triggered: return PColor.CLIP_PLAY[cindex] else: return PColor.CLIP_STOPPED[cindex] elif clip_slot.will_record_on_start: return PColor.CLIP_RECORD[cindex] elif clip_slot.is_playing: return PColor.CLIP_GROUP_PLAY[cindex] elif clip_slot.controls_other_clips: return PColor.CLIP_GROUP_CONTROL[cindex] elif clip_slot.is_triggered: return PColor.CLIP_GROUP_TRIGGER[cindex] elif self._mode == PAD_MODE: button = self._matrix[scene_index][track_index] return self.get_color_by_note_mode(button.get_identifier(), value > 0) def step_key_color_mode(self): self._note_display_mode = (self._note_display_mode + 1) % len(KEY_COLOR_MODES_STRINGS) self.show_message('Pad Mode Key Color = ' + KEY_COLOR_MODES_STRINGS[self._note_display_mode]) self.send_to_display('Colors: ' + KEY_COLOR_MODES_STRINGS[self._note_display_mode], 1) if self._mode == PAD_MODE: for note_index in range(16): button = self._button_sequence[note_index] button.send_color_direct(self.get_color_by_note_mode(button.get_identifier(), False)) def get_color_by_note_mode(self, midi_note, on): if self._note_display_mode == ND_BASE_OTHER: interval = (midi_note + 12 - self._base_note) % 12 if on: return INTERVAL_COLOR_MAP[interval][0] else: return INTERVAL_COLOR_MAP[interval][1] elif on: return KEY_COLOR_MAP[midi_note % 12][0] else: return KEY_COLOR_MAP[midi_note % 12][1] def _send_midi(self, midi_bytes, **keys): self._c_ref.send_midi(midi_bytes) if self._midi_pause_count == 2: time.sleep(0.002) self._midi_pause_count = 0 else: self._midi_pause_count = self._midi_pause_count + 1 return True def clip_handle(self): if self._mode == SCENE_MODE or self._mode == CONTROL_MODE or self._modifier_down: self._scenematrix.update() def _a_display_update(self, value): if not self.display_update_button != None: raise AssertionError raise value in range(128) or AssertionError (value != 0 or not self.display_update_button.is_momentary()) and self._update_hardware() self.show_message('Maschine Display Updated') def _set_up_timer(self): self.blink_state = 1 def update_display(self): with self.component_guard(): with self._is_sending_scheduled_messages(): self._task_group.update(0.1) if self._mode == CLIP_MODE and not self._modifier_down: if self.blink_state == 0: self._session.notify(1, 0) elif self.blink_state == 1: self._session.notify(1, 1) elif self.blink_state == 3: self._session.notify(2, 0) elif self.blink_state == 4: self._session.notify(2, 1) elif self._mode == PAD_MODE: pass elif self.blink_state == 0: self._scenematrix.notify_scene_mode(1) elif self.blink_state == 2: self._scenematrix.notify_scene_mode(0) self.blink_state = (self.blink_state + 1) % 4 self.init_slot += 1 def _invoke_track_edit(self, mode): self._deassign_matrix() self._scenematrix.assign() self._scenematrix.set_mode(mode) self._pad_mode = PM_ON self.request_rebuild_midi_map() self._scenematrix.update() def _set_modecontrol(self): is_momentary = True self.scene_mode_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 112) self.clip_mode_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 113) self.pad_mode_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 114) self.control_mode_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 115) self.xfade_assign_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 116) self.scene_mode_button.add_value_listener(self._a_mode_scene) self.clip_mode_button.add_value_listener(self._a_mode_clip) self.pad_mode_button.add_value_listener(self._a_mode_pad) self.control_mode_button.add_value_listener(self._a_mode_control) def _set_mode(self, mode = None): if mode == None: mode = self._mode if mode == SCENE_MODE: self.clip_mode_button.send_value(OFF_VALUE, True) self.pad_mode_button.send_value(OFF_VALUE, True) self.control_mode_button.send_value(OFF_VALUE, True) self.scene_mode_button.send_value(ON_VALUE, True) elif mode == CLIP_MODE: self.scene_mode_button.send_value(OFF_VALUE, True) self.pad_mode_button.send_value(OFF_VALUE, True) self.control_mode_button.send_value(OFF_VALUE, True) self.clip_mode_button.send_value(ON_VALUE, True) elif mode == PAD_MODE: self.scene_mode_button.send_value(OFF_VALUE, True) self.clip_mode_button.send_value(OFF_VALUE, True) self.control_mode_button.send_value(OFF_VALUE, True) self.pad_mode_button.send_value(ON_VALUE, True) elif mode == CONTROL_MODE: self.scene_mode_button.send_value(OFF_VALUE, True) self.clip_mode_button.send_value(OFF_VALUE, True) self.pad_mode_button.send_value(OFF_VALUE, True) self.control_mode_button.send_value(ON_VALUE, True) def _reset_matrix(self): for scene_index in range(4): scene = self._session.scene(scene_index) for track_index in range(4): button = self._matrix[scene_index][track_index] clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(button) def update_button_matrix(self): self._session.update() for scene_index in range(4): scene = self._session.scene(scene_index) for track_index in range(4): button = self._matrix[scene_index][track_index] clip_slot = scene.clip_slot(track_index) if clip_slot._clip_slot != None and clip_slot._clip_slot.clip != None: button.send_value(1, True) else: button.send_value(0, True) def _deassign_matrix(self): for scene_index in range(4): scene = self._session.scene(scene_index) for track_index in range(4): clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(None) def _from_pad_mode(self, matrix_mode): self._mode = SCENE_MODE self._register_buttons() self._scenematrix.assign() self._scenematrix.set_mode(matrix_mode) self._set_suppress_rebuild_requests(True) self.request_rebuild_midi_map() self._scenematrix.update() self._set_suppress_rebuild_requests(False) def _enter_pad_mode(self): self._set_mode(PAD_MODE) if self._mode == CLIP_MODE: self._deassign_matrix() elif self._mode == SCENE_MODE: self._scenematrix.deassign() elif self._mode == CONTROL_MODE: self._scenematrix.deassign() self._master_knob.exit_matrix_mode() self._mode = PAD_MODE self._set_suppress_rebuild_requests(True) for row in range(4): for column in range(4): button = self._matrix[row][column] button.send_value(0, True) button.set_to_notemode(True) self._forwarding_registry[MIDI_NOTE_ON_STATUS, button.get_identifier()] = button self._forwarding_registry[MIDI_NOTE_OFF_STATUS, button.get_identifier()] = button self._set_suppress_rebuild_requests(False) def _register_buttons(self, update = False): self._set_suppress_rebuild_requests(True) for row in range(4): for column in range(4): button = self._matrix[row][column] button.set_to_notemode(False) if update: button.send_value(127, True) fwkey = [MIDI_NOTE_ON_STATUS] fwkey.append(button.get_identifier()) self._forwarding_registry[tuple(fwkey)] = button self._forwarding_registry[MIDI_NOTE_OFF_STATUS, button.get_identifier()] = button self._set_suppress_rebuild_requests(False) def _back_to_clip_mode(self): self._pad_mode = PM_OFF self._scenematrix.set_mode(SCENE_MODE_NORMAL) self._scenematrix.deassign() self._set_up_clip_matrix() def _set_up_clip_matrix(self): for row in range(4): for column in range(4): button = self._matrix[row][column] button.set_to_notemode(False) self._set_suppress_rebuild_requests(True) self.request_rebuild_midi_map() self._reset_matrix() self.update_button_matrix() self._set_suppress_rebuild_requests(False) def _enter_scene_mode(self): self._set_mode(SCENE_MODE) if self._mode == CLIP_MODE: self._deassign_matrix() elif self._mode == CONTROL_MODE: self._master_knob.exit_matrix_mode() elif self._mode == PAD_MODE: self._register_buttons() self._mode = SCENE_MODE self._scenematrix.assign() self._scenematrix.set_mode(SCENE_MODE_NORMAL) self._return_mode = SCENE_MODE_NORMAL self.request_rebuild_midi_map() def _enter_clip_mode(self): self._set_suppress_rebuild_requests(True) self._set_mode(CLIP_MODE) if self._mode == SCENE_MODE: self._scenematrix.deassign() elif self._mode == CONTROL_MODE: self._master_knob.exit_matrix_mode() self._mode = CLIP_MODE self._set_up_clip_matrix() self.request_rebuild_midi_map() self._set_suppress_rebuild_requests(False) def _enter_control_mode(self): self._set_mode(CONTROL_MODE) if self._mode == CLIP_MODE: self._deassign_matrix() elif self._mode == PAD_MODE: self._mode = CONTROL_MODE self._register_buttons() self._mode = CONTROL_MODE self._set_suppress_rebuild_requests(True) self._scenematrix.set_mode(SCENE_MODE_CONTROL) self._return_mode = SCENE_MODE_CONTROL self._scenematrix.assign() self._master_knob.switch_to_matrix_mode() self._set_suppress_rebuild_requests(False) self.request_rebuild_midi_map() self._scenematrix.update() def _a_mode_scene(self, value): if not self.scene_mode_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.show_message('SCENE MODE') self._enter_scene_mode() def _a_mode_clip(self, value): if not self.clip_mode_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.show_message('CLIP MODE') self._enter_clip_mode() def _a_mode_pad(self, value): if not self.pad_mode_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.show_message('PAD MODE') self._enter_pad_mode() def _a_mode_control(self, value): if not self.control_mode_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.show_message('CONTROL MODE') self._enter_control_mode() def _do_pad_select_multi(self, value): if not value in range(128): raise AssertionError self._modifier_down = value != 0 if self._mode == PAD_MODE or self._returntopad: value != 0 and self._from_pad_mode(SCENE_MODE_SELECT) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == CLIP_MODE: if value != 0: self._invoke_track_edit(SCENE_MODE_SELECT) else: self._back_to_clip_mode() elif self._mode != PAD_MODE: if value == 0: self._scenematrix.set_mode(self._return_mode) else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_SELECT) def _do_mute_button(self, value): if not self._mute_button != None: raise AssertionError if not value in range(128): raise AssertionError self._modifier_down = value != 0 (self._mode == PAD_MODE or self._returntopad) and value != 0 and self._from_pad_mode(SCENE_MODE_MUTE) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == SCENE_MODE or self._mode == CONTROL_MODE: if value == 0: self._scenematrix.set_mode(self._return_mode) self._pad_mode = PM_OFF else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_MUTE) self._pad_mode = PM_ON elif self._mode == CLIP_MODE: if value > 0: self._invoke_track_edit(SCENE_MODE_MUTE) else: self._back_to_clip_mode() self._pad_mode = PM_OFF def _do_pad_solo_multi(self, value): if not value in range(128): raise AssertionError self._modifier_down = value != 0 if self._mode == PAD_MODE or self._returntopad: value != 0 and self._from_pad_mode(SCENE_MODE_SOLO) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == CLIP_MODE: if value != 0: self._invoke_track_edit(SCENE_MODE_SOLO) else: self._back_to_clip_mode() elif self._mode != PAD_MODE: if value == 0: self._scenematrix.set_mode(self._return_mode) else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_SOLO) def _do_xfade_assign(self, value): if not self.xfade_assign_button != None: raise AssertionError if not value in range(128): raise AssertionError (self._mode == PAD_MODE or self._returntopad) and value != 0 and self._from_pad_mode(SCENE_MODE_XFADE) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == CLIP_MODE: if value != 0: self._invoke_track_edit(SCENE_MODE_XFADE) else: self._back_to_clip_mode() elif self._mode == SCENE_MODE or self._mode == CONTROL_MODE: if value == 0: self._scenematrix.set_mode(self._return_mode) else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_XFADE) def _do_pad_note_up(self, value): if not self._pad_scale_up != None: raise AssertionError if not value in range(128): raise AssertionError self._pad_scale_up.send_value(value, True) self._modifier_down = value != 0 (self._mode == PAD_MODE or self._returntopad) and value != 0 and self._from_pad_mode(SCENE_MODE_ARM) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == CLIP_MODE: self.show_message('Arm tracks with pads') if value != 0: self._invoke_track_edit(SCENE_MODE_ARM) else: self._back_to_clip_mode() elif self._mode == SCENE_MODE or self._mode == CONTROL_MODE: self.show_message('Arm tracks with pads') if value == 0: self._scenematrix.set_mode(self._return_mode) else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_ARM) def _do_pad_note_down(self, value): if not self._pad_scale_down != None: raise AssertionError if not value in range(128): raise AssertionError self._pad_scale_down.send_value(value, True) self._modifier_down = value != 0 (self._mode == PAD_MODE or self._returntopad) and value != 0 and self._from_pad_mode(SCENE_MODE_STOP) self._returntopad = True else: self._returntopad = False self._enter_pad_mode() elif self._mode == CLIP_MODE: self.show_message('Stop tracks with pads') if value != 0: self._invoke_track_edit(SCENE_MODE_STOP) else: self._back_to_clip_mode() elif self._mode == SCENE_MODE or self._mode == CONTROL_MODE: self.show_message('Stop tracks with pads') if value == 0: self._scenematrix.set_mode(self._return_mode) else: if self._scenematrix.in_main_mode(): self._return_mode = self._scenematrix.mode self._scenematrix.set_mode(SCENE_MODE_STOP) def modify_track_offset(self, delta): self._scenematrix.mod_track_offset(delta) def modify_scene_offset(self, delta): self._scenematrix.mod_scene_offset(delta) def move_view_horizontal(self, delta): if delta == 1: self._session.bank_right() else: self._session.bank_left() if self._mode == CONTROL_MODE: self._scenematrix.update() def inc_octave(self, inc): scale = SCALES[self.current_scale_index] octave = scale.to_octave(self._octave) newoctave = octave + inc if newoctave < 0: newoctave = 0 elif newoctave > scale.octave_range: newoctave = scale.octave_range self._octave = scale.to_relative(newoctave, self._octave) scale = SCALES[self.current_scale_index] self.show_message(' OCTAVE ' + BASE_NOTE[self._base_note] + str(newoctave - 2) + ' to ' + scale.name) self.current_scale_to_display() def inc_base_note(self, inc): newbase = self._base_note + inc if newbase < 0: self._base_note = 0 elif newbase > 11: self._base_note = 11 else: self._base_note = newbase scale = SCALES[self.current_scale_index] self.show_message(' Base Note ' + BASE_NOTE[self._base_note] + ' to ' + scale.name) self.current_scale_to_display() def current_scale_to_display(self): scale = SCALES[self.current_scale_index] text = scale.name + ' ' + BASE_NOTE[self._base_note] + str(scale.to_octave(self._octave)) self.send_to_display(text) def inc_scale(self, inc): nr_of_scales = len(SCALES) newindex = self.current_scale_index + inc if newindex < 0: newindex = 0 elif newindex >= nr_of_scales: newindex = nr_of_scales - 1 else: self.current_scale_index += inc newscale = SCALES[self.current_scale_index] self.show_message(' PAD Scale ' + newscale.name + ' ' + BASE_NOTE[self._base_note] + str(newscale.to_octave(self._octave) - 2)) self.current_scale_to_display() def update_transpose(self): self.assign_transpose(SCALES[self.current_scale_index]) self._set_suppress_rebuild_requests(True) self.request_rebuild_midi_map() self._set_suppress_rebuild_requests(False) def set_scale(self, scale): raise isinstance(scale, PadScale) or AssertionError scale_len = len(scale.notevalues) octave = scale.to_octave(self._octave) def assign_transpose(self, scale): raise isinstance(scale, PadScale) or AssertionError scale_len = len(scale.notevalues) octave = scale.to_octave(self._octave) last_note_val = None for note_index in range(16): button = self._button_sequence[note_index] scale_index = note_index % scale_len octave_offset = note_index / scale_len note_value = scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12 if note_value < 128: last_note_val = note_value elif last_note_val != None: note_value = last_note_val button.set_send_note(note_value) if self._mode == PAD_MODE: button.send_color_direct(self.get_color_by_note_mode(note_value, False)) def do_reset(self, value): if value == 0: return for row in range(4): for column in range(4): button = self._matrix[row][column] data_byte1 = button._original_identifier button.send_midi((MIDI_CC_STATUS + 2, data_byte1, 0)) def do_test(self, value): color = self.togglecolor[self.toggleindex] self.toggleindex = (self.toggleindex + 1) % len(self.togglecolor) if value == 0: return for row in range(4): for column in range(4): button = self._matrix[row][column] self.schedule_message(1, self.dosend, (color, 127, 127, row, column)) def dosend(self, parm = None): button = self._matrix[parm[3]][parm[4]] data_byte1 = button._original_identifier button.send_midi((MIDI_CC_STATUS + 0, data_byte1, parm[0])) button.send_midi((MIDI_CC_STATUS + 1, data_byte1, parm[1])) button.send_midi((MIDI_CC_STATUS + 2, data_byte1, parm[2])) def do_note_repeat(self, value): nrvalue = 0 if value != 0: nrvalue = 1 self._c_ref.set_note_repeat_state(nrvalue) def _do_toggle_send(self, value): nr_of_tracks = len(self.song().return_tracks) if value == 0 or nr_of_tracks < 1: return prev = self.send_slider_index self.send_slider_index += 1 if self.send_slider_index >= nr_of_tracks: self.send_slider_index = 0 self.show_message(' Set Send ' + str(SENDS[self.send_slider_index])) if prev != self.send_slider_index: for track in range(8): strip = self._mixer.channel_strip(track) slider_list = [] for index in range(self.send_slider_index + 1): if index < self.send_slider_index - 1: slider_list.append(None) else: slider_list.append(self.send_sliders[track]) strip.set_send_controls(tuple(slider_list)) def _do_armsolo_mode(self, value): if not self._armsolomode_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self._scenematrix.set_armsolo_exclusive(self._armsolomode_button) def _do_fire_button(self, value): if not self._fire_button != None: raise AssertionError if not value in range(128): raise AssertionError clip_slot = (value != 0 or not self._mute_button.is_momentary()) and self.song().view.highlighted_clip_slot clip_slot and clip_slot.fire() def _do_undo(self, value): if not self._undo_button != None: raise AssertionError if not value in range(128): raise AssertionError (value != 0 or not self._undo_button.is_momentary()) and self.song().can_undo == 1 and self.song().undo() self.show_message(str('UNDO')) def _do_redo(self, value): if not self._redo_button != None: raise AssertionError if not value in range(128): raise AssertionError (value != 0 or not self._redo_button.is_momentary()) and self.song().can_redo == 1 and self.song().redo() self.show_message(str('REDO')) def _a_trk_left(self, value): if not value in range(128): raise AssertionError if value != 0: direction = self.application().view.is_view_visible('Session') and Live.Application.Application.View.NavDirection.left self.application().view.scroll_view(direction, 'Session', True) def _a_trk_right(self, value): if not value in range(128): raise AssertionError if value != 0: direction = self.application().view.is_view_visible('Session') and Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Session', True) def _nav_value_left(self, value): if not self._device_nav_button_left != None: raise AssertionError if not value in range(128): raise AssertionError modifier_pressed = True value > 0 and (not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain')) and self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') else: direction = Live.Application.Application.View.NavDirection.left self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed) def _nav_value_right(self, value): if not self._device_nav_button_right != None: raise AssertionError if not value in range(128): raise AssertionError modifier_pressed = value > 0 and True (not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain')) and self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') else: direction = Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed) def _do_tap_tempo(self, value): if not value in range(128): raise AssertionError value > 0 and self.song().tap_tempo() def _do_toggle_cue(self, value): if not value in range(128): raise AssertionError value > 0 and self.song().set_or_delete_cue() def _do_toggle_prev_cue(self, value): if not value in range(128): raise AssertionError value > 0 and self.song().jump_to_prev_cue() def _do_toggle_next_cue(self, value): if not value in range(128): raise AssertionError value > 0 and self.song().jump_to_next_cue() def focus_changed(self): pass def _handle_device_changed(self, device): pass def _hande_device_parm_changed(self): pass def _do_focus_navigate(self, value): if not self._navigate_button != None: raise AssertionError raise value in range(128) or AssertionError self.nav_index = value != 0 and (self.nav_index + 1) % len(VIEWS_ALL) self.application().view.focus_view(VIEWS_ALL[self.nav_index]) self.show_message('Focus on : ' + str(VIEWS_ALL[self.nav_index])) def scroll_focus(self, delta): if delta == 1: self.nav_index = (self.nav_index + 1) % len(VIEWS_ALL) elif self.nav_index == 0: self.nav_index = len(VIEWS_ALL) - 1 else: self.nav_index -= 1 self.show_message('Focus on : ' + str(VIEWS_ALL[self.nav_index])) self.application().view.focus_view(VIEWS_ALL[self.nav_index]) def scroll_device(self, delta): if not (delta == 1 or delta == -1): raise AssertionError direction = delta == 1 and Live.Application.Application.View.NavDirection.right else: direction = Live.Application.Application.View.NavDirection.left self.application().view.scroll_view(direction, 'Detail/DeviceChain', True) def scroll_scene(self, delta): if not self.track_left_button != None: raise AssertionError raise delta == 1 or delta == -1 or AssertionError direction = delta == 1 and Live.Application.Application.View.NavDirection.down else: direction = Live.Application.Application.View.NavDirection.up self.application().view.scroll_view(direction, 'Session', True) def index_in_strip(self, track): for ind in range(len(self._mixer._channel_strips)): strack = self._mixer._channel_strips[ind]._track if strack == track: return ind return -1 def notify_track_scroll(self): self._scenematrix.update_control_selection() if self._mode == CONTROL_MODE: self._scenematrix.eval_matrix() self._scenematrix.fire_values() def send_to_display(self, text, grid = 0): if USE_DISPLAY == False: return if len(text) > 28: text = text[:27] msgsysex = [240, 0, 0, 102, 23, 18, min(grid, 3) * 28] filled = text.ljust(28) for c in filled: msgsysex.append(ord(c)) msgsysex.append(247) self._send_midi(tuple(msgsysex)) def send_color(self, button, hue, sat, bright): raise isinstance(button, ButtonElement) or AssertionError raise hue in range(128) or AssertionError raise sat in range(128) or AssertionError raise bright in range(128) or AssertionError data_byte1 = button._original_identifier button.send_midi((MIDI_CC_STATUS + 2, data_byte1, bright)) button.send_midi((MIDI_CC_STATUS + 1, data_byte1, sat)) button.send_midi((MIDI_CC_STATUS + 0, data_byte1, hue)) def turn_off_matrix(self): for row in range(4): for column in range(4): button = self._matrix[row][column] self.send_color(button, 2, 0, 0) button.set_to_notemode(False) def remove_listener(self, control, callback): if control != None and control.value_has_listener(callback): control.remove_value_listener(callback) control.disconnect() def disconnect(self): self.turn_off_matrix() self.scene_mode_button.send_value(0, True) self.clip_mode_button.send_value(0, True) self.pad_mode_button.send_value(0, True) self.control_mode_button.send_value(0, True) time.sleep(0.2) self._active = False self._suppress_send_midi = True self.remove_listener(self.scene_mode_button, self._a_mode_scene) self.remove_listener(self.clip_mode_button, self._a_mode_clip) self.remove_listener(self.pad_mode_button, self._a_mode_pad) self.remove_listener(self.control_mode_button, self._a_mode_control) self.remove_listener(self._undo_button, self._do_undo) self.remove_listener(self._redo_button, self._do_redo) self.remove_listener(self._armsolomode_button, self._do_armsolo_mode) self.remove_listener(self.xfade_assign_button, self._do_xfade_assign) self.remove_listener(self._fire_button, self._do_fire_button) self._session.remove_offset_listener(self.notify_track_scroll) self._mixer.disconnect() ControlSurface.disconnect(self)
class Novation_Impulse(ControlSurface): """ Script for Novation's Impulse keyboards """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = 'Impulse' self._suggested_output_port = 'Impulse' self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39) self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8) self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._preview_button.add_value_listener(self._preview_value) self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_name_display() device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10) mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9) device_button.name = 'Encoder_Device_Mode' mixer_button.name = 'Encoder_Mixer_Mode' self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders) self._encoder_modes.set_device_mixer_buttons(device_button, mixer_button) self._string_to_display = None for component in self.components: component.set_enabled(False) def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(3, self._send_midi, SYSEX_START + (6, 1, 1, 1, 247)) def handle_sysex(self, midi_bytes): if midi_bytes[0:-2] == SYSEX_START + (7,) and midi_bytes[-2] != 0: self._has_sliders = midi_bytes[-2] != 25 self.schedule_message(1, self._show_startup_message) for control in self.controls: if isinstance(control, InputControlElement): control.clear_send_cache() for component in self.components: component.set_enabled(True) if self._has_sliders: self._mixer.master_strip().set_volume_control(self._master_slider) self._mixer.update() else: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control(self._master_slider) for index in range(len(self._sliders)): self._mixer.channel_strip(index).set_volume_control(None) slider = self._sliders[index] slider.release_parameter() if slider.value_has_listener(self._slider_value): slider.remove_value_listener(self._slider_value) self._encoder_modes.set_provide_volume_mode(not self._has_sliders) self.request_rebuild_midi_map() def disconnect(self): self._name_display_data_source.set_display_string(' ') for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) self._master_slider.remove_value_listener(self._slider_value) if self._has_sliders: for slider in tuple(self._sliders): slider.remove_value_listener(self._slider_value) for button in self._strip_buttons: button.remove_value_listener(self._mixer_button_value) self._preview_button.remove_value_listener(self._preview_value) ControlSurface.disconnect(self) self._encoders = None self._sliders = None self._strip_buttons = None self._master_slider = None self._current_midi_map = None self._shift_button = None self._name_display = None self._prev_bank_button = None self._next_bank_button = None self._encoder_modes = None self._transport_view_modes = None self._send_midi(SYSEX_START + (6, 0, 0, 0, 247)) def build_midi_map(self, midi_map_handle): self._current_midi_map = midi_map_handle ControlSurface.build_midi_map(self, midi_map_handle) def update_display(self): ControlSurface.update_display(self) if self._string_to_display != None: self._name_display_data_source.set_display_string(self._string_to_display) self._string_to_display = None if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._show_current_track_name() def _setup_mixer(self): mute_solo_flip_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 34) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 37) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 38) self._strip_buttons = [] mute_solo_flip_button.name = 'Mute_Solo_Flip_Button' self._next_nav_button.name = 'Next_Track_Button' self._prev_nav_button.name = 'Prev_Track_Button' self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_volume_control(self._master_slider) self._sliders = [] for index in range(8): strip = self._mixer.channel_strip(index) strip.name = 'Channel_Strip_' + str(index) strip.set_invert_mute_feedback(True) self._sliders.append(SliderElement(MIDI_CC_TYPE, 0, index)) self._sliders[-1].name = str(index) + '_Volume_Control' self._sliders[-1].set_feedback_delay(-1) self._sliders[-1].add_value_listener(self._slider_value, identify_sender=True) strip.set_volume_control(self._sliders[-1]) self._strip_buttons.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + index)) self._strip_buttons[-1].name = str(index) + '_Mute_Button' self._strip_buttons[-1].add_value_listener(self._mixer_button_value, identify_sender=True) self._mixer.master_strip().set_mute_button(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 17)) self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button) def _setup_session(self): num_pads = len(PAD_TRANSLATIONS) self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36) self._track_right_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35) self._session = SessionComponent(8, 0) self._session.name = 'Session_Control' self._session.selected_scene().name = 'Selected_Scene' self._session.set_mixer(self._mixer) self._session.set_page_left_button(self._track_left_button) self._session.set_page_right_button(self._track_right_button) pads = [] for index in range(num_pads): pads.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index)) pads[-1].name = 'Pad_' + str(index) clip_slot = self._session.selected_scene().clip_slot(index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.set_launch_button(pads[-1]) clip_slot.name = str(index) + '_Selected_Clip_Slot' def _setup_transport(self): rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 27) ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 28) stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 29) play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 30) loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 31) rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 32) ffwd_button.name = 'FFwd_Button' rwd_button.name = 'Rwd_Button' loop_button.name = 'Loop_Button' play_button.name = 'Play_Button' stop_button.name = 'Stop_Button' rec_button.name = 'Record_Button' transport = ShiftableTransportComponent() transport.name = 'Transport' transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_record_button(rec_button) transport.set_shift_button(self._shift_button) self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button, loop_button) self._transport_view_modes.name = 'Transport_View_Modes' def _setup_device(self): encoders = [] for index in range(8): encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 1, index, Live.MidiMap.MapMode.relative_binary_offset)) encoders[-1].set_feedback_delay(-1) encoders[-1].add_value_listener(self._encoder_value, identify_sender=True) encoders[-1].name = 'Device_Control_' + str(index) self._encoders = tuple(encoders) self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 12) self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 11) self._prev_bank_button.name = 'Device_Bank_Down_Button' self._next_bank_button.name = 'Device_Bank_Up_Button' device = DeviceComponent() device.name = 'Device_Component' self.set_device_component(device) device.set_parameter_controls(self._encoders) device.set_bank_nav_buttons(self._prev_bank_button, self._next_bank_button) def _setup_name_display(self): self._name_display = PhysicalDisplayElement(16, 1) self._name_display.name = 'Display' self._name_display.set_message_parts(SYSEX_START + (8,), (247,)) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source(self._name_display_data_source) def _encoder_value(self, value, sender): if not sender in self._encoders: raise AssertionError if not value in range(128): raise AssertionError display_string = self._device_component.is_enabled() and ' - ' display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name self._set_string_to_display(display_string) def _slider_value(self, value, sender): if not sender in tuple(self._sliders) + (self._master_slider,): raise AssertionError if not value in range(128): raise AssertionError if self._mixer.is_enabled(): display_string = ' - ' if sender.mapped_parameter() != None: master = self.song().master_track tracks = self.song().tracks returns = self.song().return_tracks track = None if sender == self._master_slider: track = self._has_sliders and master else: track = self.song().view.selected_track else: track = self._mixer.channel_strip(self._sliders.index(sender))._track display_string = track == master and 'Master' elif track in tracks: display_string = str(list(tracks).index(track) + 1) elif track in returns: display_string = str(chr(ord('A') + list(returns).index(track))) else: raise False or AssertionError display_string += ' Volume' self._set_string_to_display(display_string) def _mixer_button_value(self, value, sender): if not value in range(128): raise AssertionError if self._mixer.is_enabled() and value > 0: strip = self._mixer.channel_strip(self._strip_buttons.index(sender)) self._string_to_display = strip != None and None self._name_display.segment(0).set_data_source(strip.track_name_data_source()) self._name_display.update() self._display_reset_delay = STANDARD_DISPLAY_DELAY else: self._set_string_to_display(' - ') def _preview_value(self, value): raise value in range(128) or AssertionError for encoder in self._encoders: encoder.set_peek_mode(value > 0) def _show_current_track_name(self): if self._name_display != None and self._mixer != None: self._string_to_display = None self._name_display.segment(0).set_data_source(self._mixer.selected_strip().track_name_data_source()) self._name_display.update() def _show_startup_message(self): self._name_display.display_message('LIVE') self._display_reset_delay = INITIAL_DISPLAY_DELAY def _set_string_to_display(self, string_to_display): raise isinstance(string_to_display, (str, unicode)) or AssertionError self._name_display.segment(0).set_data_source(self._name_display_data_source) self._string_to_display = string_to_display self._display_reset_delay = STANDARD_DISPLAY_DELAY def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._show_current_track_name() all_tracks = self._has_sliders or self._session.tracks_to_use() selected_track = self.song().view.selected_track num_strips = self._session.width() if selected_track in all_tracks: track_index = list(all_tracks).index(selected_track) new_offset = track_index - track_index % num_strips if not new_offset / num_strips == int(new_offset / num_strips): raise AssertionError self._session.set_offsets(new_offset, self._session.scene_offset())
class Axiom_DirectLink(ControlSurface): """ Script for the M-Audio Axiom DirectLink """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = "DirectLink" self._suggested_output_port = "DirectLink" self._waiting_for_first_response = True self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_pressed = False self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 13) self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 111) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 110) self._device_bank_buttons = None self._device_navigation = None self._shift_button.name = "Shift_Button" self._master_slider.name = "Master_Volume_Control" self._next_nav_button.name = "Next_Track_Button" self._prev_nav_button.name = "Prev_Track_Button" self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._shift_button.add_value_listener(self._shift_value) self._setup_mixer() self._setup_transport_and_session() self._setup_device() self._setup_display() for component in self.components: component.set_enabled(False) return def refresh_state(self): ControlSurface.refresh_state(self) self._waiting_for_first_response = True self.schedule_message(3, self._send_midi, SYSEX_START + (32, 46, 247)) def handle_sysex(self, midi_bytes): if midi_bytes[0:-2] == SYSEX_START + (32,) and midi_bytes[-2] != 0: self._has_sliders = midi_bytes[-2] & 8 != 0 if self._waiting_for_first_response: self._waiting_for_first_response = False self.schedule_message(1, self._show_startup_message) for component in self.components: component.set_enabled(True) if self._has_sliders: self._mixer.master_strip().set_volume_control(self._master_slider) self._mixer.update() else: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control(self._master_slider) self.request_rebuild_midi_map() return def disconnect(self): self._display_data_source.set_display_string(" ") self._shift_button.remove_value_listener(self._shift_value) self._inst_button.remove_value_listener(self._inst_value) for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) for slider in tuple(self._sliders) + (self._master_slider,): slider.remove_value_listener(self._slider_value) for button in tuple(self._strip_buttons) + (self._selected_mute_solo_button,): button.remove_value_listener(self._mixer_button_value) for button in self._device_bank_buttons: button.remove_value_listener(self._device_bank_value) self._encoders = None self._sliders = None self._strip_buttons = None self._master_slider = None self._current_midi_map = None self._selected_mute_solo_button = None self._inst_button = None self._shift_button = None self._device_navigation = None self._display = None ControlSurface.disconnect(self) self._send_midi(SYSEX_START + (32, 0, 247)) return def build_midi_map(self, midi_map_handle): self._current_midi_map = midi_map_handle ControlSurface.build_midi_map(self, midi_map_handle) def update_display(self): ControlSurface.update_display(self) if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._show_current_track_name() def _setup_mixer(self): self._selected_mute_solo_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 12) mute_solo_flip_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 57) self._strip_buttons = [] self._selected_mute_solo_button.name = "Selected_Mute_Button" mute_solo_flip_button.name = "Mute_Solo_Flip_Button" self._selected_mute_solo_button.add_value_listener(self._mixer_button_value, identify_sender=True) self._mixer = ShiftableMixerComponent(8) self._mixer.name = "Mixer" self._mixer.set_shift_button(self._shift_button) self._mixer.set_selected_mute_solo_button(self._selected_mute_solo_button) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._mixer.selected_strip().name = "Selected_Channel_Strip" self._mixer.master_strip().name = "Master_Channel_Strip" self._mixer.master_strip().set_volume_control(self._master_slider) self._sliders = [] for index in range(8): strip = self._mixer.channel_strip(index) strip.name = "Channel_Strip_" + str(index) strip.set_invert_mute_feedback(True) self._sliders.append(SliderElement(MIDI_CC_TYPE, 15, 33 + index)) self._sliders[-1].name = str(index) + "_Volume_Control" self._sliders[-1].set_feedback_delay(-1) self._sliders[-1].add_value_listener(self._slider_value, identify_sender=True) strip.set_volume_control(self._sliders[-1]) self._strip_buttons.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 49 + index)) self._strip_buttons[-1].name = str(index) + "_Mute_Button" self._strip_buttons[-1].add_value_listener(self._mixer_button_value, identify_sender=True) self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button) def _setup_transport_and_session(self): ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 115) rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 114) loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 113) play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 117) stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 116) rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 118) ffwd_button.name = "FFwd_Button" rwd_button.name = "Rwd_Button" loop_button.name = "Loop_Button" play_button.name = "Play_Button" stop_button.name = "Stop_Button" rec_button.name = "Record_Button" transport = ShiftableTransportComponent() transport.name = "Transport" transport.set_shift_button(self._shift_button) transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_record_button(rec_button) pads = [] for index in range(len(PAD_TRANSLATIONS)): pads.append(ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 15, PAD_TRANSLATIONS[index][2])) pads[-1].name = "Pad_" + str(index) self._session = ShiftableSessionComponent(8, 0) self._session.name = "Session_Control" self._session.selected_scene().name = "Selected_Scene" self._session.set_mixer(self._mixer) self._session.set_shift_button(self._shift_button) self._session.set_clip_slot_buttons(tuple(pads)) transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button, loop_button) transport_view_modes.name = "Transport_View_Modes" def _setup_device(self): self._encoders = [] for offset in range(8): self._encoders.append( PeekableEncoderElement( MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment ) ) self._encoders[-1].set_feedback_delay(-1) self._encoders[-1].add_value_listener(self._encoder_value, identify_sender=True) self._encoders[-1].name = "Device_Control_" + str(offset) prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 14) next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 15) prev_bank_button.name = "Device_Bank_Down_Button" next_bank_button.name = "Device_Bank_Up_Button" device = BestBankDeviceComponent() device.name = "Device_Component" self.set_device_component(device) device.set_parameter_controls(tuple(self._encoders)) device.set_bank_nav_buttons(prev_bank_button, next_bank_button) self._device_bank_buttons = (prev_bank_button, next_bank_button) prev_bank_button.add_value_listener(self._device_bank_value) next_bank_button.add_value_listener(self._device_bank_value) self._inst_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 109) self._inst_button.name = "Inst_Button" self._inst_button.add_value_listener(self._inst_value) self._device_navigation = DetailViewCntrlComponent() self._device_navigation.name = "Device_Navigation_Component" def _setup_display(self): self._display = PhysicalDisplayElement(5, 1) self._display.name = "Display" self._display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,)) self._display_data_source = DisplayDataSource() self._display.segment(0).set_data_source(self._display_data_source) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._show_current_track_name() def _shift_value(self, value): if not value in range(128): raise AssertionError self._shift_pressed = value > 0 for encoder in self._encoders: encoder.set_peek_mode(self._shift_pressed) self._shift_pressed and self._mixer.set_select_buttons(None, None) self._session.set_track_bank_buttons(self._next_nav_button, self._prev_nav_button) self._device_component.set_bank_nav_buttons(None, None) self._device_navigation.set_device_nav_buttons(self._device_bank_buttons[0], self._device_bank_buttons[1]) else: self._session.set_track_bank_buttons(None, None) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._device_navigation.set_device_nav_buttons(None, None) self._device_component.set_bank_nav_buttons(self._device_bank_buttons[0], self._device_bank_buttons[1]) self.request_rebuild_midi_map() return def _encoder_value(self, value, sender): if not sender in self._encoders: raise AssertionError if not value in range(128): raise AssertionError display_string = self._device_component.is_enabled() and " - " display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _slider_value(self, value, sender): if not sender in tuple(self._sliders) + (self._master_slider,): raise AssertionError if not value in range(128): raise AssertionError if self._mixer.is_enabled(): display_string = " - " if sender.mapped_parameter() != None: master = self.song().master_track tracks = self.song().tracks returns = self.song().return_tracks track = None if sender == self._master_slider: track = self._has_sliders and master else: track = self.song().view.selected_track else: track = self._mixer.channel_strip(self._sliders.index(sender))._track display_string = track == master and "Ma" elif track in tracks: display_string = str(list(tracks).index(track) + 1) elif track in returns: display_string = str(chr(ord("A") + list(returns).index(track))) else: raise False or AssertionError display_string += " Vol" self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _mixer_button_value(self, value, sender): if not sender in tuple(self._strip_buttons) + (self._selected_mute_solo_button,): raise AssertionError if not value in range(128): raise AssertionError if self._mixer.is_enabled() and value > 0: strip = None strip = sender == self._selected_mute_solo_button and self._mixer.selected_strip() else: strip = self._mixer.channel_strip(self._strip_buttons.index(sender)) strip != None and self._set_display_data_source(strip.track_name_data_source()) else: self._display_data_source.set_display_string(" - ") self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _device_bank_value(self, value): if not value in range(128): raise AssertionError if self._device_component.is_enabled() and value > 0: data_source = self._device_component.bank_name_data_source() data_source = self._shift_pressed and self._device_component.device_name_data_source() self._set_display_data_source(data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _inst_value(self, value): if not value in range(128): raise AssertionError value > 0 and self._device_component.is_enabled() and self.song().view.selected_track.view.select_instrument() and self._set_display_data_source( self._device_component.device_name_data_source() ) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _show_current_track_name(self): if self._display != None and self._mixer != None: self._set_display_data_source(self._mixer.selected_strip().track_name_data_source()) return def _show_startup_message(self): self._display.display_message("LIVE") self._display_reset_delay = INITIAL_DISPLAY_DELAY def _set_display_data_source(self, data_source): raise isinstance(data_source, DisplayDataSource) or AssertionError self._display.segment(0).set_data_source(data_source) data_source.update()
class MainKnobControl: __module__ = __name__ __doc__ = 'Mk2 Module for Controlling Parameters with Master Knob' def __init__(self, parent): self._parent = parent self.master_track = parent.song().master_track self.the_slider = SliderElement(MIDI_CC_TYPE, 1, 86) self.the_slider.add_value_listener(self._do_main_slider, True) self.volume_button = None self._set_volume_button(StateButton(True, MIDI_CC_TYPE, 1, 80)) self.xfade_button = None self._set_xfade_button(StateButton(True, MIDI_CC_TYPE, 1, 99)) self.swing_button = None self._set_swing_button(StateButton(True, MIDI_CC_TYPE, 1, 81)) self.mode = KN2_MODE_VOLUME self.previous_mode = -1 self.tempo_button = None self._set_tempo_button(StateButton(True, MIDI_CC_TYPE, 1, 82)) self.push_button = None self._set_push_button(StateButton(True, MIDI_CC_TYPE, 1, 87)) self.clipn_v_button = None self.clipn_h_button = None self._set_clipn_h_button(StateButton(True, MIDI_CC_TYPE, 1, 90)) self._set_clipn_v_button(StateButton(True, MIDI_CC_TYPE, 1, 91)) self.toggle_buttons = [self.volume_button, self.xfade_button, self.swing_button, self.tempo_button, self.clipn_h_button, self.clipn_v_button] self.shift_button = None self._set_shift_button(StateButton(True, MIDI_CC_TYPE, 1, 85)) self.shift_on = False self.scroll_mod_left_button = None self.scroll_mod_right_button = None self._set_scroll_mod_left_button(ButtonElement(True, MIDI_CC_TYPE, 0, 105)) self._set_scroll_mod_right_button(ButtonElement(True, MIDI_CC_TYPE, 0, 106)) self._prev_mode = KN2_MODE_VOLUME self.lrmode = LR_CONTROL_CLIP self.loop_div_index = 0 self.loop_incdex = 4.0 self.arrow_mode_button = ColorButton(True, MIDI_CC_TYPE, 30) self.arrow_mode_button.add_value_listener(self.toggle_arrow_mode) self.arrow_mode_button.send_value(1, True) self.navflags = 0 self.octave_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 70) self.octave_mod_button.add_value_listener(self._action_octave) self.scale_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 71) self.scale_mod_button.add_value_listener(self._action_scale) self.basenote_mod_button = ButtonElement(True, MIDI_CC_TYPE, 1, 72) self.basenote_mod_button.add_value_listener(self._action_base_note) self.pad_to_mainknob_mode = 0 self.octave_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 120) self.octave_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 121) self.scale_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 118) self.scale_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 119) self.basent_dwn_button = ButtonElement(True, MIDI_CC_TYPE, 3, 124) self.basent_upp_button = ButtonElement(True, MIDI_CC_TYPE, 3, 125) self.octave_dwn_button.add_value_listener(self._action_oct_down) self.octave_upp_button.add_value_listener(self._action_oct_up) self.scale_dwn_button.add_value_listener(self._action_scale_down) self.scale_upp_button.add_value_listener(self._action_scale_up) self.basent_dwn_button.add_value_listener(self._action_base_down) self.basent_upp_button.add_value_listener(self._action_base_up) self._measure_left_click = 0 self._measure_right_click = 0 self.mode_assign_map = {KN2_MODE_VOLUME: (self.chg_volume, 0, 'Master Knob controls MASTER Volume', KN2_MODE_CUE), KN2_MODE_CUE: (self.chg_cue, 0, 'Master Knob controls Cue Level', KN2_MODE_VOLUME), KN2_MODE_TEMPO_COARSE: (self.chg_tempo, 3, 'Master Knob controls TEMPO Coarse', KN2_MODE_TEMPO_FINE), KN2_MODE_TEMPO_FINE: (self.chg_tempo_fine, 3, 'Master Knob controls TEMPO Fine', KN2_MODE_TEMPO_COARSE), KN2_MODE_XFADE: (self.chg_xfade, 1, 'Master Knob controls Crossfader', -1), KN2_MODE_QUANT: (self.chg_quant, 2, 'Master Knob controls Recording Quantize', KN2_MODE_CLIP_QUANT), KN2_MODE_CLIP_QUANT: (self.chg_clip_q, 2, 'Master Knob controls Clip Start Quantize', KN2_MODE_QUANT), KN2_MODE_CLIPN_HOR: (self.nav_c_hor, 4, 'Master Knob Clip View horizontally', -1), KN2_MODE_CLIPN_VER: (self.nav_c_ver, 5, 'Master Knob Clip View vertically', -1), KN2_MODE_GENERAL: (self.chg_general, -1, None, -1), KN2_P_SCALES: (self.modify_pad_scaling, -1, None, -1)} def start_up(self): self._set_mode(KN2_MODE_VOLUME) self.arrow_mode_button.send_value(127, True) def toggle_arrow_mode(self, value): if value > 0: self.lrmode = (self.lrmode + 1) % 4 self.arrow_mode_button.send_hue(LR_MODE_HUES[self.lrmode]) self._parent.show_message('Left/Right Buttons Control: ' + L_MODE_FUNCTION[self.lrmode] + ' / ' + R_MODE_FUNCTION[self.lrmode]) def switch_to_matrix_mode(self): if self.mode != KN2_MODE_GENERAL: self.previous_mode = self.mode self._set_mode(KN2_MODE_GENERAL) def exit_matrix_mode(self): if self.mode == KN2_MODE_GENERAL: self._set_mode(self.previous_mode) self.previous_mode = -1 def update_shift(self): if self.shift_on: self.shift_button.send_value(127, True) else: self.shift_button.send_value(0, True) def _set_mode(self, mode): if not mode in range(11): raise AssertionError self.update_shift() if mode == self.mode: return self._prev_mode = mode self.mode = mode self.switch_radio_buttons(self.mode_assign_map[self.mode][1]) message = self.mode_assign_map[self.mode][2] message != None and self._parent.show_message(message) def switch_radio_buttons(self, which): for index in range(len(self.toggle_buttons)): if index == which: self.toggle_buttons[index].send_value(127, True) else: self.toggle_buttons[index].send_value(0, True) def update(self): self.switch_radio_buttons(self.mode_assign_map[self.mode][1]) self.arrow_mode_button.send_color(LR_MODE_HUES[self.lrmode]) self.arrow_mode_button.send_value(127, True) def _do_main_slider(self, value, encoder): if not value in range(128): raise AssertionError if not isinstance(encoder, EncoderElement): raise AssertionError if value == 1: delta = 1 else: delta = -1 if self.pad_to_mainknob_mode != 0: self.mode_assign_map[KN2_P_SCALES][0](delta) elif self.navflags == 0: self.mode_assign_map[self.mode][0](delta) if self.lrmode == LR_CONTROL_CLIP: self.navflags & LEFT_DOWN != 0 and self.nav_c_hor(delta) self.navflags & RIGHT_DOWN != 0 and self.nav_c_ver(delta) elif self.lrmode == LR_CONTROL_SEL: if self.navflags & LEFT_DOWN != 0: self.nav_track(delta) if self.navflags & RIGHT_DOWN != 0: self._parent.scroll_scene(delta) elif self.lrmode == LR_CONTROL_DEV: if self.navflags & LEFT_DOWN != 0: self.nav_track(delta) if self.navflags & RIGHT_DOWN != 0: self._parent.scroll_device(delta) elif self.lrmode == LR_CONTROL_LOOP: if self.navflags & LEFT_DOWN != 0: self.adjust_loop_start(delta) if self.navflags & RIGHT_DOWN != 0: self.adjust_loop_length(delta) def modify_pad_scaling(self, delta): if self.pad_to_mainknob_mode & PAD_KNOB_OCTAVE != 0: self._parent.inc_octave(delta) if self.pad_to_mainknob_mode & PAD_KNOB_SCALE != 0: self._parent.inc_scale(delta) if self.pad_to_mainknob_mode & PAD_KNOB_BASEN != 0: self._parent.inc_base_note(delta) def adjust_loop_start(self, delta): loopval = self._parent.song().loop_start loopval += self.loop_incdex * delta if loopval < 0: loopval = 0 elif loopval > 999: loopval = 999 self._parent.song().loop_start = loopval def adjust_loop_length(self, delta): loopval = self._parent.song().loop_length loopval += self.loop_incdex * delta if loopval < self.loop_incdex: loopval = self.loop_incdex elif loopval > 999: loopval = 999 self._parent.song().loop_length = loopval def chg_general(self, delta): self._parent._scenematrix.control_handler.mod_value(delta, self.shift_on) def nav_track(self, direction): if direction == 1: self._parent._a_trk_right(1) else: self._parent._a_trk_left(1) def nav_c_hor(self, direction): self._parent.move_view_horizontal(direction) def nav_c_ver(self, direction): if direction == 1: self._parent._session.bank_up() else: self._parent._session.bank_down() def chg_volume(self, diff): if self.shift_on: self.repeat(self.master_track.mixer_device.volume, diff) else: self.master_track.mixer_device.volume.value = self.calc_new_parm(self.master_track.mixer_device.volume, diff) def chg_xfade(self, diff): if self.shift_on: self.repeat(self.master_track.mixer_device.crossfader, diff) else: self.master_track.mixer_device.crossfader.value = self.calc_new_parm(self.master_track.mixer_device.crossfader, diff) def chg_cue(self, diff): if self.shift_on: self.repeat(self.master_track.mixer_device.cue_volume, diff) else: self.master_track.mixer_device.cue_volume.value = self.calc_new_parm(self.master_track.mixer_device.cue_volume, diff) def repeat(self, parm, delta): count = 0 while count < SHIFT_INC: parm.value = self.calc_new_parm(parm, delta) count += 1 def calc_new_parm(self, parm, delta): parm_range = parm.max - parm.min int_val = int((parm.value - parm.min) / parm_range * PARM_RANGE + 0.1) inc_val = min(PARM_RANGE, max(0, int_val + delta)) return float(inc_val) / float(PARM_RANGE) * parm_range + parm.min def chg_quant(self, diff): rec_quant = self._parent.song().midi_recording_quantization index = self.get_quant_index(rec_quant) new_index = index + diff if new_index >= 0 and new_index < len(QUANT_CONST): self._parent.song().midi_recording_quantization = QUANT_CONST[new_index] self._parent.show_message(QUANT_DESCR[new_index]) def chg_clip_q(self, diff): quant = self._parent.song().clip_trigger_quantization self._parent.song().clip_trigger_quantization = max(0, min(13, quant + diff)) self._parent.show_message('Clip Quantize ' + CLIQ_DESCR[self._parent.song().clip_trigger_quantization]) def chg_tempo_fine(self, diff): if diff < 0: amount = -0.01 else: amount = 0.01 self.chg_tempo(amount) def chg_tempo(self, diff): self._parent.song().tempo = max(20, min(999, self._parent.song().tempo + diff)) def get_quant_index(self, const): for index in range(len(QUANT_CONST)): if const == QUANT_CONST[index]: return index return -1 def _action_octave(self, value): if value != 0: self.pad_to_mainknob_mode |= PAD_KNOB_OCTAVE else: self.pad_to_mainknob_mode &= ~PAD_KNOB_OCTAVE def _action_scale(self, value): if value != 0: self.pad_to_mainknob_mode |= PAD_KNOB_SCALE else: self.pad_to_mainknob_mode &= ~PAD_KNOB_SCALE def _action_base_note(self, value): if value != 0: self.pad_to_mainknob_mode |= PAD_KNOB_BASEN else: self.pad_to_mainknob_mode &= ~PAD_KNOB_BASEN def _set_volume_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.volume_button != None: self.volume_button.remove_value_listener(self._action_volume) self.volume_button = button self.volume_button != None and self.volume_button.add_value_listener(self._action_volume) def _action_volume(self, value): if not self.volume_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_VOLUME and self._set_mode(KN2_MODE_VOLUME) def _set_xfade_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.xfade_button != None: self.xfade_button.remove_value_listener(self._action_xfade) self.xfade_button = button self.xfade_button != None and self.xfade_button.add_value_listener(self._action_xfade) def _action_xfade(self, value): if not self.xfade_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_XFADE and self._set_mode(KN2_MODE_XFADE) def _set_swing_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.swing_button != None: self.swing_button.remove_value_listener(self._action_swing) self.swing_button = button self.swing_button != None and self.swing_button.add_value_listener(self._action_swing) def _action_swing(self, value): if not self.swing_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_QUANT and self._set_mode(KN2_MODE_QUANT) def _set_tempo_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.tempo_button != None: self.tempo_button.remove_value_listener(self._action_tempo) self.tempo_button = button self.tempo_button != None and self.tempo_button.add_value_listener(self._action_tempo) def _action_tempo(self, value): if not self.tempo_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_TEMPO_COARSE and self._set_mode(KN2_MODE_TEMPO_COARSE) def _set_clipn_h_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.clipn_h_button != None: self.clipn_h_button.remove_value_listener(self._action_clipnh) self.clipn_h_button = button self.clipn_h_button != None and self.clipn_h_button.add_value_listener(self._action_clipnh) def _action_clipnh(self, value): if not self.clipn_h_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_CLIPN_HOR and self._set_mode(KN2_MODE_CLIPN_HOR) def _set_clipn_v_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.clipn_v_button != None: self.clipn_v_button.remove_value_listener(self._action_clipnv) self.clipn_v_button = button self.clipn_v_button != None and self.clipn_v_button.add_value_listener(self._action_clipnv) def _action_clipnv(self, value): if not self.clipn_v_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.mode != KN2_MODE_CLIPN_VER and self._set_mode(KN2_MODE_CLIPN_VER) def _set_shift_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.shift_button != None: self.shift_button.remove_value_listener(self._action_shift) self.shift_button = button self.shift_button != None and self.shift_button.add_value_listener(self._action_shift) def _action_shift(self, value): if not self.shift_button != None: raise AssertionError raise value in range(128) or AssertionError self.shift_on = value != 0 and not self.shift_on self.update_shift() def _set_scroll_mod_left_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.scroll_mod_left_button != None: self.scroll_mod_left_button.remove_value_listener(self._action_scroll_left) self.scroll_mod_left_button = button self.scroll_mod_left_button != None and self.scroll_mod_left_button.add_value_listener(self._action_scroll_left) def _set_scroll_mod_right_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.scroll_mod_right_button != None: self.scroll_mod_right_button.remove_value_listener(self._action_scroll_right) self.scroll_mod_right_button = button self.scroll_mod_right_button != None and self.scroll_mod_right_button.add_value_listener(self._action_scroll_right) def _action_scroll_left(self, value): if not self.scroll_mod_left_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.scroll_mod_left_button.send_value(127, True) self.navflags |= LEFT_DOWN self._measure_left_click = int(round(time.time() * 1000)) else: self.scroll_mod_left_button.send_value(0, True) self.navflags &= ~LEFT_DOWN clicktime = int(round(time.time() * 1000)) - self._measure_left_click if clicktime < CLICK_TIME: if self._parent._modifier_down: self._parent.modify_track_offset(-1) elif self._parent._mode == PAD_MODE: self._do_lr_as_scale_mode(-1) elif self._parent._mode == SCENE_MODE: self._parent.modify_scene_offset(-1) elif self._parent._mode == CLIP_MODE: self._parent.move_view_horizontal(-1) elif self._parent._mode == CONTROL_MODE: self._parent.move_view_horizontal(-1) def _action_scroll_right(self, value): if not self.scroll_mod_right_button != None: raise AssertionError raise value in range(128) or AssertionError value != 0 and self.scroll_mod_right_button.send_value(1) self.navflags |= RIGHT_DOWN self._measure_right_click = int(round(time.time() * 1000)) else: self.scroll_mod_right_button.send_value(0, True) self.navflags &= ~RIGHT_DOWN clicktime = int(round(time.time() * 1000)) - self._measure_right_click if clicktime < CLICK_TIME: if self._parent._modifier_down: self._parent.modify_track_offset(1) elif self._parent._mode == PAD_MODE: self._do_lr_as_scale_mode(1) elif self._parent._mode == SCENE_MODE: self._parent.modify_scene_offset(1) elif self._parent._mode == CLIP_MODE: self._parent.move_view_horizontal(1) elif self._parent._mode == CONTROL_MODE: self._parent.move_view_horizontal(1) def _do_lr_as_scale_mode(self, delta): if self.pad_to_mainknob_mode == PAD_KNOB_SCALE: self._parent.inc_scale(delta) elif self.pad_to_mainknob_mode == PAD_KNOB_BASEN: self._parent.inc_base_note(delta) else: self._parent.inc_octave(delta) def _action_oct_down(self, value): if value != 0: self._parent.inc_octave(-1) def _action_oct_up(self, value): if value != 0: self._parent.inc_octave(1) def _action_scale_down(self, value): if value != 0: self._parent.inc_scale(-1) def _action_scale_up(self, value): if value != 0: self._parent.inc_scale(1) def _action_base_down(self, value): if value != 0: self._parent.inc_base_note(-1) def _action_base_up(self, value): if value != 0: self._parent.inc_base_note(1) def _set_push_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self.push_button != None: self.push_button.remove_value_listener(self._action_push) self.push_button = button self.push_button != None and self.push_button.add_value_listener(self._action_push) def _action_push(self, value): if not self.push_button != None: raise AssertionError if not value in range(128): raise AssertionError next_mode = self.mode_assign_map[self.mode][3] next_mode != -1 and self._set_mode(next_mode) self.loop_div_index = self.lrmode == LR_CONTROL_LOOP and self.navflags != 0 and (self.loop_div_index + 1) % len(LOOP_KNOB_DIVISION) self._parent.show_message('Loop Selection Granularity : ' + str(LOOP_KNOB_DIVISION[self.loop_div_index]) + ' beats ') self.loop_incdex = LOOP_KNOB_DIVISION[self.loop_div_index] def remove_listener(self, control, callback): if control != None and control.value_has_listener(callback): control.remove_value_listener(callback) control.disconnect() def disconnect(self): self.remove_listener(self.the_slider, self._do_main_slider) self.remove_listener(self.arrow_mode_button, self.toggle_arrow_mode) self.remove_listener(self.volume_button, self._action_volume) self.remove_listener(self.xfade_button, self._action_xfade) self.remove_listener(self.swing_button, self._action_swing) self.remove_listener(self.clipn_h_button, self._action_clipnh) self.remove_listener(self.clipn_v_button, self._action_clipnv) self.remove_listener(self.shift_button, self._action_shift) self.remove_listener(self.scroll_mod_left_button, self._action_scroll_left) self.remove_listener(self.scroll_mod_right_button, self._action_scroll_right) self.remove_listener(self.push_button, self._action_push) self.remove_listener(self.octave_mod_button, self._action_octave) self.remove_listener(self.scale_mod_button, self._action_scale) self.remove_listener(self.basenote_mod_button, self._action_base_note) self.remove_listener(self.octave_dwn_button, self._action_oct_down) self.remove_listener(self.octave_upp_button, self._action_oct_up) self.remove_listener(self.scale_dwn_button, self._action_scale_down) self.remove_listener(self.scale_upp_button, self._action_scale_up) self.remove_listener(self.basent_dwn_button, self._action_base_down) self.remove_listener(self.basent_upp_button, self._action_base_up) self._parent = None self.master_track = None self.the_slider = None self.mode_assign_map = None