Esempio n. 1
0
    def _setup_mixer_control(self):
        is_momentary = True
        num_tracks = 8
        num_returns = 7
        mixer = MixerComponent(num_tracks, num_returns)
        for track in range(num_tracks):
            strip = mixer.channel_strip(track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 15, 54 - track))
            strip.set_pan_control(SliderElement(MIDI_CC_TYPE, 15, 80 - track))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117 - track))
            strip.set_invert_mute_feedback(True)

        for track in range(num_returns):
            strip = mixer.return_strip(track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 15, 10 + track))

        mixer.set_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 108),
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109))
        mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 15, 9))
        mixer.master_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, 15, 46))
        session = SessionComponent(0, 0)
        session.set_select_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 95),
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 92))
        session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 91))
 def _setup_session_control(self):
     is_momentary = True
     num_tracks = 1  #single column
     num_scenes = 7  #seven rows, which will be mapped to seven "white" notes
     global session  #We want to instantiate the global session as a SessionComponent object (it was a global "None" type up until now...)
     session = SessionComponent(
         num_tracks, num_scenes
     )  #(num_tracks, num_scenes) A session highlight ("red box") will appear with any two non-zero values
     session.set_offsets(
         0, 0
     )  #(track_offset, scene_offset) Sets the initial offset of the "red box" from top left
     """set up the session navigation buttons"""
     session.set_select_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 25),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 27)
     )  # (next_button, prev_button) Scene select buttons - up & down - we'll also use a second ControlComponent for this (yellow box)
     session.set_scene_bank_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 51),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 49)
     )  # (up_button, down_button) This is to move the "red box" up or down (increment track up or down, not screen up or down, so they are inversed)
     #session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 56), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 54)) # (right_button, left_button) This moves the "red box" selection set left & right. We'll put our track selection in Part B of the script, rather than here...
     session.set_stop_all_clips_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))
     session.selected_scene().set_launch_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 30))
     """Here we set up the scene launch assignments for the session"""
     launch_notes = [
         60, 62, 64, 65, 67, 69, 71
     ]  #this is our set of seven "white" notes, starting at C4
     for index in range(
             num_scenes
     ):  #launch_button assignment must match number of scenes
         session.scene(index).set_launch_button(
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                           launch_notes[index])
         )  #step through the scenes (in the session) and assign corresponding note from the launch_notes array
     """Here we set up the track stop launch assignment(s) for the session"""  #The following code is set up for a longer array (we only have one track, so it's over-complicated, but good for future adaptation)..
     stop_track_buttons = []
     for index in range(num_tracks):
         stop_track_buttons.append(
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                           58 + index)
         )  #this would need to be adjusted for a longer array (because we've already used the next note numbers elsewhere)
     session.set_stop_track_clip_buttons(
         tuple(stop_track_buttons))  #array size needs to match num_tracks
     """Here we set up the clip launch assignments for the session"""
     clip_launch_notes = [
         48, 50, 52, 53, 55, 57, 59
     ]  #this is a set of seven "white" notes, starting at C3
     for index in range(num_scenes):
         session.scene(index).clip_slot(0).set_launch_button(
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                           clip_launch_notes[index])
         )  #step through scenes and assign a note to first slot of each
     """Here we set up a mixer and channel strip(s) which move with the session"""
     session.set_mixer(
         mixer)  #Bind the mixer to the session so that they move together
Esempio n. 3
0
 def _setup_session_control(self):
     is_momentary = True
     down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 89)
     up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 90)
     session = SessionComponent(NUM_TRACKS, 0)
     session.set_select_buttons(down_button, up_button)
     session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 87))
     track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 68) for index in range(NUM_TRACKS) ]
     session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
     for index in range(NUM_TRACKS):
         session.selected_scene().clip_slot(index).set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 69))
Esempio n. 4
0
 def _setup_session_control(self):
     is_momentary = True
     down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 89)
     up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 90)
     session = SessionComponent(NUM_TRACKS, 0)
     session.set_select_buttons(down_button, up_button)
     session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 87))
     track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 68) for index in range(NUM_TRACKS) ]
     session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
     for index in range(NUM_TRACKS):
         session.selected_scene().clip_slot(index).set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 69))
Esempio n. 5
0
    def _create_session_control(self):
        is_momentary = True
        num_tracks = 1
        num_scenes = 7
        global session
        session = SessionComponent(num_tracks, num_scenes)
        session.set_offsets(0, 0)
        """set up the session navigation buttons"""
        session.set_select_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 25),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 27))
        session.set_scene_bank_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 51),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 49))
        session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))
        session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 30))
        """Here we set up the scene launch assignments for the session"""
        launch_notes = [60, 62, 64, 65, 67, 69, 71]
        for index in range(num_scenes):
            session.scene(index).set_launch_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              launch_notes[index]))
        """Here we set up the track stop launch assignment(s) for the session"""
        stop_track_buttons = []
        for index in range(num_tracks):
            stop_track_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              58 + index))
        session.set_stop_track_clip_buttons(tuple(stop_track_buttons))
        """Here we set up the clip launch assignments for the session"""
        clip_launch_notes = [48, 50, 52, 53, 55, 57, 59]
        for index in range(num_scenes):
            session.scene(index).clip_slot(0).set_launch_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              clip_launch_notes[index]))
        """Here we set up a mixer and channel strip(s) which move with the session"""

        self.log_message("Captain's log stardate 3")
    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))
Esempio n. 7
0
    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87)
        right_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 107)  #78
        left_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 106)  #77
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        global session
        session = SessionComponent(8, 40)
        session.name = 'Session_Control'
        session.set_track_bank_buttons(right_button, left_button)
        matrix = ButtonMatrixElement()
        matrix.name = 'Button_Matrix'
        scene_launch_notes = [56, 57, 58, 59, 60, 61, 62, 63]
        scene_launch_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                          scene_launch_notes[index]) for index in range(8)
        ]
        track_stop_buttons = [
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, (index + 28))
            for index in range(8)
        ]
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'
        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(
                index) + '_Stop_Button'
        session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        for scene_index in range(8):
            scene = session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            #scene.set_triggered_value(2)
            for track_index in range(7):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                                       (track_index * 8) + scene_index)
                button.name = str(track_index) + '_Clip_' + str(
                    scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_stopped_value(0)
                clip_slot.set_started_value(64)
                clip_slot.set_launch_button(button)

            matrix.add_row(tuple(button_row))

        #self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        session.selected_scene().name = 'Selected_Scene'
        #session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        #session_zoom = SessionZoomingComponent(session)
        #session_zoom.name = 'Session_Overview'
        #session_zoom.set_button_matrix(matrix)
        #session_zoom.set_zoom_button(self._shift_button)
        #session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        #session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        #session_zoom.set_stopped_value(0)
        #session_zoom.set_selected_value(127)
        session.set_mixer(mixer)
        return None  #return session
Esempio n. 8
0
class Launchkey(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """

    def __init__(self, c_instance, control_factory = LaunchkeyControlFactory(), identity_response = SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._control_factory = control_factory
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'Launchkey InControl'
            self._suggested_output_port = 'Launchkey InControl'
            self._has_sliders = True
            self._current_midi_map = None
            self._master_slider = make_slider(7, 'Master_Volume_Control')
            self._modes_buttons = []
            for index in range(3):
                button = ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0, 13 + index)
                self._modes_buttons.append(button)
                self._modes_buttons[-1].add_value_listener(self._dummy_listener)

            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_navigation()
            for component in self.components:
                component.set_enabled(False)

        return

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(2, self._send_midi, LIVE_MODE_ON)
        self.schedule_message(3, self._send_midi, SIZE_QUERY)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:11] == self._identity_response:
            self._has_sliders = midi_bytes[11] != 48
            self._send_midi(LED_FLASHING_ON)
            self._update_mixer_offset()
            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)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    self._mixer.channel_strip(index).set_mute_button(None)
                    slider = self._sliders[index]
                    slider.release_parameter()

                self._mixer.selected_strip().set_volume_control(self._master_slider)
            self.request_rebuild_midi_map()
        return

    def disconnect(self):
        ControlSurface.disconnect(self)
        for button in self._modes_buttons:
            if button.value_has_listener(self._dummy_listener):
                button.remove_value_listener(self._dummy_listener)

        self._modes_buttons = None
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)
        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 _setup_mixer(self):
        mute_solo_flip_button = make_button(59, 'Master_Button')
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        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 = []
        self._strip_buttons = []
        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(make_slider(41 + index, 'Volume_Control_%d' % index))
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(make_button(51 + index, 'Mute_Button_%d' % index))

        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button)

    def _setup_session(self):
        scene_launch_button = self._control_factory.create_scene_launch_button()
        scene_stop_button = self._control_factory.create_scene_stop_button()
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(scene_launch_button)
        self._session.selected_scene().set_triggered_value(GREEN_BLINK)
        self._session.set_stop_all_clips_button(scene_stop_button)
        scene_stop_button.set_on_off_values(AMBER_FULL, LED_OFF)
        self._session.set_mixer(self._mixer)
        self._session.set_stop_clip_value(AMBER_HALF)
        self._session.set_stop_clip_triggered_value(GREEN_BLINK)
        clip_launch_buttons = []
        clip_stop_buttons = []
        for index in range(8):
            clip_launch_buttons.append(self._control_factory.create_clip_launch_button(index))
            clip_stop_buttons.append(self._control_factory.create_clip_stop_button(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(clip_launch_buttons[-1])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(tuple(clip_stop_buttons))

    def _setup_transport(self):
        rwd_button = make_button(112, 'Rwd_Button')
        ffwd_button = make_button(113, 'FFwd_Button')
        stop_button = make_button(114, 'Stop_Button')
        play_button = make_button(115, 'Play_Button')
        loop_button = make_button(116, 'Loop_Button')
        rec_button = make_button(117, 'Record_Button')
        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_record_button(rec_button)
        transport.set_loop_button(loop_button)
        self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = [ make_encoder(21 + index, 'Device_Control_%d' % index) for index in xrange(8) ]
        self._encoders = tuple(encoders)
        device = DeviceComponent()
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)

    def _setup_navigation(self):
        self._next_track_button = self._control_factory.create_next_track_button()
        self._prev_track_button = self._control_factory.create_prev_track_button()
        self._session_navigation = SessionNavigationComponent(name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = 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
            self._session.set_offsets(new_offset, self._session.scene_offset())
Esempio n. 9
0
class KeyPad(ControlSurface):
    """
    Reloop KeyPad controller script.
    """
    _encoder_range = range(73, 81)
    _product_model_id = 101

    def __init__(self, c_instance):
        super(KeyPad, self).__init__(c_instance)
        with self.component_guard():
            self._create_controls()
            self._setup_mixer()
            self._setup_transport()
            self._setup_session()
            self._setup_cue_control()
            self.set_pad_translations(PAD_TRANSLATIONS)

    def _preset_message(self, send_byte):
        """ Sysex message for setting the preset to #2. """
        return (240, 38, self._product_model_id, send_byte, 17, 2, 247)

    def refresh_state(self):
        super(KeyPad, self).refresh_state()
        self.schedule_message(2, self._send_midi, self._preset_message(1))

    def handle_sysex(self, midi_bytes):
        if midi_bytes != self._preset_message(2):
            super(KeyPad, self).handle_sysex(midi_bytes)
        else:
            map(lambda x: x.set_enabled(True),
                (self._mixer, self._session, self._transport,
                 self._cue_control))

    def _create_controls(self):
        def make_controls_range(maker, label, cc_range):
            ccs = [(index + 1, cc) for index, cc in enumerate(cc_range)]
            return [maker(1, cc, label % index) for index, cc in ccs] + [
                maker(2, cc, label % (index + len(ccs))) for index, cc in ccs
            ]

        def make_controls(maker, label, cc_offset):
            return make_controls_range(maker, label,
                                       xrange(cc_offset, cc_offset + 8))

        make_non_momentary_button = partial(make_button, is_momentary=False)
        self._encoders = make_controls(make_encoder, 'Encoder_%d', 57)
        self._rotaries_a = make_controls(make_slider, 'Rotary_A%d', 89)
        self._rotaries_b = make_controls(make_slider, 'Rotary_B%d', 97)
        self._faders = make_controls(make_slider, 'Fader_%d', 0)
        self._mute_buttons = make_controls(make_non_momentary_button,
                                           'Mute_%d_Button', 8)
        self._solo_buttons = make_controls(make_button, 'Solo_%d_Button', 24)
        self._arm_buttons = make_controls(make_button, 'Arm_%d_Button', 40)
        self._play_button = make_button(1, 105, 'Play_Button')
        self._stop_button = make_button(1, 106, 'Stop_Button')
        self._record_button = make_button(1, 107, 'Record_Button')
        self._encoder_pushes = make_controls_range(
            partial(make_button, is_momentary=False), 'Encoder_%d_Button',
            self._encoder_range)
        self._shifted_mute_buttons = make_controls(make_non_momentary_button,
                                                   'Shifted_Mute_%d_Button',
                                                   16)
        self._shifted_solo_buttons = make_controls(make_button,
                                                   'Shifted_Solo_%d_Button',
                                                   32)
        self._all_shifted_arm_buttons = make_controls(make_button,
                                                      'Shifted_Arm_%d_Button',
                                                      49)
        self._shifted_arm_buttons = [
            CombinedButtonsElement(
                buttons=(self._all_shifted_arm_buttons[index],
                         self._all_shifted_arm_buttons[index + 8]))
            for index in xrange(8)
        ]
        self._shifted_play_button = make_button(1, 108, 'Shifted_Play_Button')
        self._shifted_stop_button = make_button(1, 109, 'Shifted_Stop_Button')
        self._shifted_record_button = make_button(1, 110,
                                                  'Shifted_Record_Button')
        self._shifted_octave_down_button = make_button(
            1, 111, 'Shifted_Octave_Down_Button')
        self._shifted_octave_up_button = make_button(
            1, 112, 'Shifted_Octave_Up_Button')

    def _setup_mixer(self):
        self._mixer = MixerComponent(NUM_CHANNEL_STRIPS)
        self._mixer.name = 'Mixer'
        self._mixer.set_enabled(False)
        for index in xrange(NUM_CHANNEL_STRIPS):
            strip = self._mixer.channel_strip(index)
            strip.set_invert_mute_feedback(True)
            sends = ButtonMatrixElement(name='%d_Send_Controls' % (index + 1),
                                        rows=[(self._rotaries_a[index],
                                               self._rotaries_b[index])])
            strip.layer = Layer(volume_control=self._faders[index],
                                pan_control=self._encoders[index],
                                send_controls=sends,
                                mute_button=self._mute_buttons[index],
                                solo_button=self._solo_buttons[index],
                                arm_button=self._arm_buttons[index],
                                select_button=self._encoder_pushes[index])

    def _setup_transport(self):
        self._transport = TransportComponent(name='Transport')
        self._transport.set_enabled(False)
        self._transport.layer = Layer(
            play_button=self._play_button,
            stop_button=self._stop_button,
            record_button=self._record_button,
            overdub_button=self._shifted_record_button,
            loop_button=self._shifted_arm_buttons[3],
            tap_tempo_button=self._shifted_arm_buttons[4],
            metronome_button=self._shifted_arm_buttons[5],
            nudge_down_button=self._shifted_arm_buttons[6],
            nudge_up_button=self._shifted_arm_buttons[7])

    def _setup_session(self):
        self._session = SessionComponent(NUM_CHANNEL_STRIPS,
                                         name='Session_Control')
        self._session.set_enabled(False)
        stop_buttons = ButtonMatrixElement(name='Track_Stop_Buttons',
                                           rows=[self._shifted_solo_buttons])
        self._session.layer = Layer(
            stop_all_clips_button=self._shifted_stop_button,
            stop_track_clip_buttons=stop_buttons,
            select_prev_button=self._shifted_octave_down_button,
            select_next_button=self._shifted_octave_up_button)
        self._session.selected_scene().name = 'Selected_Scene_Control'
        self._session.selected_scene().layer = Layer(
            launch_button=self._shifted_play_button)
        for index in xrange(NUM_CHANNEL_STRIPS):
            slot = self._session.selected_scene().clip_slot(index)
            slot.layer = Layer(launch_button=self._shifted_mute_buttons[index])

    def _setup_cue_control(self):
        self._cue_control = CuePointControlComponent(name='Cue_Point_Control')
        self._cue_control.set_enabled(False)
        self._cue_control.layer = Layer(
            toggle_cue_button=self._shifted_arm_buttons[0],
            prev_cue_button=self._shifted_arm_buttons[1],
            next_cue_button=self._shifted_arm_buttons[2])
class Novation_Impulse2(ControlSurface):
    """ Script for Novation's Impulse keyboards """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.c_instance = 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._string_to_display = None
            self.shift_pressed = False
            # special alternative buttons mode. for now only mixer buttons become record buttons. later we will add something more
            self.alternative_buttons_mode = False
            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._shift_button.add_value_listener(self._shift_button_handler)

            for component in self.components:
                component.set_enabled(False)

    # attributes
    def alternative_buttons_mode(self):
        return self.alternative_buttons_mode

    def alternative_buttons_mode(self,value):
        self.log ('alternative_buttons_mode_value ' + str(value))
        self.alternative_buttons_mode = value

    def shift_pressed(self):
        return self.shift_pressed

    def shift_pressed(self,value):
        self.log ('shift_pressed value ' + str(value))
        self.shift_pressed = value

    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.log('starting disconnect 1')
        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)
        self.log('starting disconnect 3')
        ControlSurface.disconnect(self)
        self.log('starting disconnect 3')
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = 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.log('starting disconnect 4')
        self._send_midi(SYSEX_START + (6, 0, 0, 0, 247))
        self.log('starting disconnect 5')

        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_button_handler)
            self._shift_button = None
        self.log('starting disconnect 6')

    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):
        self.log('setup mixer')
        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(self, 8, self.c_instance)
        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)
        #self._mixer.set_shift_button(self._shift_button)
        self._mixer.updateMixerButtons()

        self._button9 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + 8)

    def _setup_session(self):
        num_pads = len(PAD_TRANSLATIONS)
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer)
        # for ableton 9.1.1 and lower
        #self._session.set_track_banking_increment(num_pads)
        #self._session.set_track_bank_buttons(ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35), ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36))
        # for ableton 9.1.1 and higher
        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.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'
        self._transport = ShiftableTransportComponent(self.c_instance,self._session, self, ffwd_button, rwd_button)
        self._transport.name = 'Transport'
        self._transport.set_stop_buttonOnInit(stop_button)
        self._transport.set_play_button(play_button)
        self._transport.set_record_buttonOnInit(rec_button)
#        self._transport.set_shift_button(self._shift_button)
        self._transport.set_mixer9_button(self._button9)
        self._transport_view_modes = TransportViewModeSelector(self,self.c_instance,self._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
        display_string = ''
        if self._device_component.is_enabled():
#            display_string = sender.name
#            track = self.song().view.selected_track
#            display_string = str(list(tracks).index(track) + 1)
            pass
        if (sender.mapped_parameter() != None):
#            display_string = display_string + '-'
            display_string =  display_string + sender.mapped_parameter().name
        self._set_string_to_display(display_string)

    def _slider_value(self, value, sender):
        self.log ('_slider_value ' + str(value) + ' ' +str(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 = ' - '
            master = self.song().master_track
            tracks = self.song().tracks
            returns = self.song().return_tracks
            track = None
            if sender.mapped_parameter() != None:
                self.log ('1')
                if sender == self._master_slider:
                    self.log ('2')
#                    track = self._has_sliders and master
                    if self._has_sliders:
                        track = master
                    else:
                        self.log ('2.1')
                        track = self.song().view.selected_track
                else:
                    self.log ('3')
                    track = self._mixer.channel_strip(self._sliders.index(sender))._track
            else:
                self.log ('4')
                track = self.song().view.selected_track
            self.log('track='+str(track))
            if track == master:
                display_string  = '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
                raise AssertionError
            display_string += ' Volume'
            self._set_string_to_display(display_string)

    def _mixer_button_value(self, value, sender):
        self.log ('__mixer_button_value ' + str(value) + ' ' +str(sender))
        if not value in range(128):
            raise AssertionError
        #if self._mixer.is_enabled() and value > 0:
        if self._mixer.is_enabled():
            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(' - ')
        # if shift_pressed XOR alternative_mode
        if self.shift_pressed <> self.alternative_buttons_mode:
            self.log("_mixer_button_value")
            self.log(str(value))
            if (value == 0):
                self.select_armed_track_if_only_one()

    def select_armed_track_if_only_one(self):
        self.log("select_armed_track_if_only_one")
        song = self.song()
        armed_tracks = []
        tracks = song.tracks
        self.log("select_armed_track_if_only_one 2")
        for track in tracks:
            if track.can_be_armed and track.arm:
                armed_tracks.append(track)
        self.log(str(len(armed_tracks)))
        if (len(armed_tracks) == 1):
            self.log("selecting the track")
            sel_track = armed_tracks[0]
            self.song().view.selected_track = sel_track
            self._mixer._selected_tracks = []
            self._mixer._selected_tracks.append(sel_track)
            self._mixer.on_selected_track_changed()

    def _preview_value(self, value):
        if not value in range(128):
            raise 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):
        if not isinstance(string_to_display, (str, unicode)):
            raise 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):
        self.log('_on_selected_track_changed')
        ControlSurface._on_selected_track_changed(self)
        self._show_current_track_name()
        #all_tracks = self._has_sliders or self._session.tracks_to_use()
        all_tracks2 = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks2:
            track_index = list(all_tracks2).index(selected_track)
            self.log('track_index '+ str(track_index))
            new_offset = track_index - track_index % num_strips
            self.log('new_offset '+ str(new_offset))
            if not new_offset / num_strips == int(new_offset / num_strips):
                raise AssertionError
            self._session.set_offsets(new_offset, self._session.scene_offset())


    def _shift_button_handler(self, value):
        self.log("root shift handler : "+ str(value))
        if not self._shift_button != None:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        self.log("root shift handler 2")
        self.shift_pressed = value > 0
# calling other handlers
        self._mixer._shift_button_handler(value)
        self._transport._shift_button_handler(value)
        self._transport_view_modes._shift_button_handler(value)

#clip stop
        self.log("root shift handler 3")
        num_pads = len(PAD_TRANSLATIONS)
        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)
            if self.shift_pressed:
                clip_slot.set_launch_button(None)
            else:
                clip_slot.set_launch_button(pads[index])
        if self.shift_pressed:
            self._session.set_stop_track_clip_buttons(tuple(pads))
        else:
            self._session.set_stop_track_clip_buttons(None)

        self.log("root shift handler 4")

    def flipAlternativeButtonMode(self):
        self.alternative_buttons_mode = not self.alternative_buttons_mode
        self.updateAlternativeButtonMode()

    def updateAlternativeButtonMode(self):
        self._mixer.updateMixerButtons()
        self._transport_view_modes.update()

    def log(self, message):
        pass
Esempio n. 11
0
class MPK_mini_hero(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """

    def __init__(self, c_instance, identity_response = SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'MPK mini'
            self._suggested_output_port = 'MPK mini'

            self._setup_buttons()
            self._setup_components()

            for component in self.components:
                component.set_enabled(True) # Puvodne False

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        
        # for val in range(127):
        #     self.schedule_message(2, self._send_midi, (144, val, 0))
            
        # self.schedule_message(3, self._send_midi, (144, 9, 127))

    def handle_sysex(self, midi_bytes):
        self._send_midi(LED_FLASHING_ON)
        self._update_mixer_offset()
        for control in self.controls:
            if isinstance(control, InputControlElement):
                control.clear_send_cache()

        for component in self.components:
            component.set_enabled(True)

        self.request_rebuild_midi_map()

    def disconnect(self):
        ControlSurface.disconnect(self)

        self._encoders = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)

    def _setup_buttons(self):
        # Pads CC Mode
        self._scene_launch_button = make_pad_button(PAD_MODE_CC, 1, 'Scene_Launch_Button')
        self._overdub_button = make_pad_button(PAD_MODE_CC, 2, 'Session_Overdub_Button')
        self._ffwd_button = make_pad_button(PAD_MODE_CC, 3, 'FFwd_Button')
        self._clip_undo_button = make_pad_button(PAD_MODE_CC, 4, 'Clip_Undo_Button')
        self._prev_track_button = make_pad_button(PAD_MODE_CC, 5, 'Prev_Track_Button')
        self._next_track_button = make_pad_button(PAD_MODE_CC, 6, 'Next_Track_Button')
        self._rwd_button = make_pad_button(PAD_MODE_CC, 7, 'Rwd_Button')
        self._scene_stop_button = make_pad_button(PAD_MODE_CC, 9, 'Scene_Stop_Button')
        self._stop_button = make_pad_button(PAD_MODE_CC, 10, 'Stop_Button')
        self._play_button = make_pad_button(PAD_MODE_CC, 11, 'Play_Button')
        self._loop_button = make_pad_button(PAD_MODE_CC, 12, 'Loop_Button')
        self._rec_button = make_pad_button(PAD_MODE_CC, 13, 'Record_Button')

        # Pads Notes Mode
        self._clip_launch_buttons = [ make_pad_button(PAD_MODE_NOTES, index, 'Clip_Launch_%d' % index) for index in xrange(8) ]
        self._clip_stop_buttons = [ make_pad_button(PAD_MODE_NOTES, 8 + index, 'Clip_Stop_%d' % index) for index in xrange(8) ]

        # Encoders

        self._encoders = tuple([ make_encoder(21 + index, 'Device_Control_%d' % index) for index in xrange(8) ])

        # Scenes

        self._scene_launch_buttons = []
        for key_no in [0,2,4,5,7,9,11,  12,14,16,17,19,21,23,  24]:
            self._scene_launch_buttons.append(make_scene_button(key_no, 'Scene_Launch_%d' % key_no))

    def _setup_components(self):
        
        # Session

        self._session = SessionComponent(8, len(self._scene_launch_buttons))
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._scene_launch_button)
        self._session.set_stop_all_clips_button(self._scene_stop_button)

        for index in range(8):
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_launch_button(self._clip_launch_buttons[index])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(tuple(self._clip_stop_buttons))

        # Undo

        self._do_undo.subject = self._clip_undo_button;

        # Transport

        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(self._stop_button)
        transport.set_play_button(self._play_button)
        transport.set_record_button(self._rec_button)
        transport.set_loop_button(self._loop_button)

        self._transport_view_modes = TransportViewModeSelector(transport, self._session, self._ffwd_button, self._rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

        session_recording = SessionRecordingComponent(ClipCreator(), ViewControlComponent(), name='Session_Recording', is_enabled=False, layer=Layer(record_button=self._overdub_button))

        # Device

        # device = DeviceComponent()
        # device.name = 'Device_Component'
        # self.set_device_component(device)
        # device.set_parameter_controls(self._encoders)

        # Navigation

        self._session_navigation = SessionNavigationComponent(name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

        # Playing
        # self._session.set_scene_launch_buttons(tuple(self._scene_launch_buttons))
        for index in range(len(self._scene_launch_buttons)):
            scene = self._session.scene(index)
            scene.set_launch_button(self._scene_launch_buttons[index])

    @subject_slot('value')
    def _do_undo(self, value):
        if value:
            if self.song().can_undo == 1:
                self.song().undo()
                self.show_message(str('UNDO'))

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = 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
            self._session.set_offsets(new_offset, self._session.scene_offset())
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())
Esempio n. 13
0
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._suggested_input_port = b'Impulse'
            self._suggested_output_port = b'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 = b'Shift_Button'
            self._master_slider.name = b'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 = b'Encoder_Device_Mode'
            mixer_button.name = b'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 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()
        return

    def disconnect(self):
        self._name_display_data_source.set_display_string(b'  ')
        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))
        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._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()
        return

    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 = b'Mute_Solo_Flip_Button'
        self._next_nav_button.name = b'Next_Track_Button'
        self._prev_nav_button.name = b'Prev_Track_Button'
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = b'Mixer'
        self._mixer.set_select_buttons(self._next_nav_button,
                                       self._prev_nav_button)
        self._mixer.selected_strip().name = b'Selected_Channel_Strip'
        self._mixer.master_strip().name = b'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 = b'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) + b'_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) + b'_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 = b'Session_Control'
        self._session.selected_scene().name = b'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 = b'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) + b'_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 = b'FFwd_Button'
        rwd_button.name = b'Rwd_Button'
        loop_button.name = b'Loop_Button'
        play_button.name = b'Play_Button'
        stop_button.name = b'Stop_Button'
        rec_button.name = b'Record_Button'
        transport = ShiftableTransportComponent()
        transport.name = b'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 = b'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 = b'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 = b'Device_Bank_Down_Button'
        self._next_bank_button.name = b'Device_Bank_Up_Button'
        device = DeviceComponent(device_selection_follows_track_selection=True)
        device.name = b'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 = b'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):
        assert sender in self._encoders
        assert value in range(128)
        if self._device_component.is_enabled():
            display_string = b' - '
            if sender.mapped_parameter() != None:
                display_string = sender.mapped_parameter().name
            self._set_string_to_display(display_string)
        return

    def _slider_value(self, value, sender):
        assert sender in tuple(self._sliders) + (self._master_slider, )
        assert value in range(128)
        if self._mixer.is_enabled():
            display_string = b' - '
            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:
                    if self._has_sliders:
                        track = master
                    else:
                        track = self.song().view.selected_track
                else:
                    track = self._mixer.channel_strip(
                        self._sliders.index(sender))._track
                if track == master:
                    display_string = b'Master'
                elif track in tracks:
                    display_string = str(list(tracks).index(track) + 1)
                elif track in returns:
                    display_string = str(
                        chr(ord(b'A') + list(returns).index(track)))
                else:
                    assert False
                display_string += b' Volume'
            self._set_string_to_display(display_string)
        return

    def _mixer_button_value(self, value, sender):
        assert value in range(128)
        if self._mixer.is_enabled() and value > 0:
            strip = self._mixer.channel_strip(
                self._strip_buttons.index(sender))
            if strip != None:
                self._string_to_display = 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(b' - ')
        return

    def _preview_value(self, value):
        assert value in range(128)
        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()
        return

    def _show_startup_message(self):
        self._name_display.display_message(b'LIVE')
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _set_string_to_display(self, string_to_display):
        assert isinstance(string_to_display, (str, unicode))
        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())
Esempio n. 14
0
class FancyScript(ControlSurface):
    ''' A generic script class with predefined behaviour.
      It can be customised to use/not use certain controls on instantiation.
  '''
    
    def __init__(self, c_instance, macro_map_mode, volume_map_mode, device_controls, transport_controls, volume_controls, trackarm_controls, bank_controls, descriptions = None, mixer_options = None):
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(True)
        global_channel = 0
        if descriptions:
            if list(descriptions.keys()).count('INPUTPORT') > 0:
                self._suggested_input_port = descriptions['INPUTPORT']
            
            if list(descriptions.keys()).count('OUTPUTPORT') > 0:
                self._suggested_output_port = descriptions['OUTPUTPORT']
            
            if list(descriptions.keys()).count('CHANNEL') > 0:
                global_channel = descriptions['CHANNEL']
                if global_channel not in range(16):
                    global_channel = 0
                
            
            if list(descriptions.keys()).count('PAD_TRANSLATION') > 0:
                self.set_pad_translations(descriptions['PAD_TRANSLATION'])
        #delete this print
        self.log_message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"+str(type(macro_map_mode)))
        self._init_mixer_component(volume_controls, trackarm_controls, mixer_options, global_channel, volume_map_mode)
        self._init_device_component(device_controls, bank_controls, global_channel, macro_map_mode)
        self._init_transport_component(transport_controls, global_channel, macro_map_mode) #that last arg is new and shold be deleted
        #this is a new method call
        self._init_clip_slot_component(volume_controls)#this should take some args)
        #this is too
        self._init_session_component(global_channel, 3, 1)
        self.set_suppress_rebuild_requests(False)

    def _init_session_component(self, global_channel, num_tracks, num_scenes):
        self._session_component = SessionComponent(num_tracks, num_scenes)
        self._session_selected_scene = self._session_component.selected_scene()
        stop_buttons = []
        for i in range(num_tracks):
            stopper = ButtonElement(True, MIDI_CC_TYPE, global_channel, (3, 6, 9)[i])
            stopper.name = 'Clip_Stop_Button'
            stop_buttons = stop_buttons + [stopper]
            clip_start_button = ButtonElement(True, MIDI_CC_TYPE, global_channel, (2, 5, 8)[i])
            clip_start_button.name = 'Clip_Start_Button'
            self._session_selected_scene.clip_slot(i).set_launch_button(clip_start_button)
        #self._session_component.set_stop_track_clip_buttons(stop_buttons)

    def _init_clip_slot_component(self, volume_controls):
        num_strips = len(volume_controls)
        num_scenes = 1 # this is not always true, just in our case
        
        b1 = ButtonElement(False, MIDI_CC_TYPE, 1, 3)
        b2 = ButtonElement(False, MIDI_CC_TYPE, 1, 6)
        b3 = ButtonElement(False, MIDI_CC_TYPE, 1, 9)


    
    def handle_sysex(self, midi_bytes):
        pass

    
    def _init_mixer_component(self, volume_controls, trackarm_controls, mixer_options, global_channel, volume_map_mode):
        if volume_controls != None and trackarm_controls != None:
            num_strips = max(len(volume_controls), len(trackarm_controls))
            send_info = []
            momentary_buttons = False
            mixer = SpecialMixerComponent(num_strips)
            mixer.name = 'Mixer'
            mixer.master_strip().name = 'Master_Channel_Strip'
            mixer.selected_strip().name = 'Selected_Channel_Strip'
            if mixer_options != None:
                if 'MASTERVOLUME' in mixer_options.keys() and mixer_options['MASTERVOLUME'] in range(128):
                    encoder = EncoderElement(MIDI_CC_TYPE, global_channel, mixer_options['MASTERVOLUME'], volume_map_mode)
                    encoder.name = 'Master_Volume_Control'
                    mixer.master_strip().set_volume_control(encoder)
                
                if 'NUMSENDS' in mixer_options.keys() and mixer_options['NUMSENDS'] > 0:
                    for send in range(mixer_options['NUMSENDS']):
                        key = 'SEND' + str(send + 1)
                        if not key in mixer_options.keys():
                            raise AssertionError
                        send_info.append(mixer_options[key])
                    
                
                momentary_buttons = 'NOTOGGLE' in mixer_options.keys()
                next_bank_button = None
                prev_bank_button = None
                if 'NEXTBANK' in mixer_options.keys() and mixer_options['NEXTBANK'] in range(128):
                    next_bank_button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, mixer_options['NEXTBANK'])
                    next_bank_button.name = 'Mixer_Next_Bank_Button'
                
                if 'PREVBANK' in mixer_options.keys() and mixer_options['PREVBANK'] in range(128):
                    prev_bank_button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, mixer_options['PREVBANK'])
                    prev_bank_button.name = 'Mixer_Previous_Bank_Button'
                
                mixer.set_bank_buttons(next_bank_button, prev_bank_button)
            
            for track in range(num_strips):
                strip = mixer.channel_strip(track)
                strip.name = 'Channel_Strip_' + str(track)
                if track in range(len(volume_controls)):
                    channel = global_channel
                    cc = volume_controls[track]
                    if isinstance(volume_controls[track], (tuple, list)):
                        cc = volume_controls[track][0]
                        if volume_controls[track][1] in range(16):
                            channel = volume_controls[track][1]
                        
                    
                    if cc in range(128) and channel in range(16):
                        encoder = EncoderElement(MIDI_CC_TYPE, channel, cc, volume_map_mode)
                        encoder.name = str(track) + '_Volume_Control'
                        strip.set_volume_control(encoder)
                    
                
                if track in range(len(trackarm_controls)) and trackarm_controls[track] in range(128):
                    button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, trackarm_controls[track])
                    button.name = str(track) + '_Arm_Button'
                    strip.set_arm_button(button)
                
                send_controls = []
                for send in send_info:
                    encoder = None
                    if track in range(len(send)):
                        channel = global_channel
                        cc = send[track]
                        if isinstance(send[track], (tuple, list)):
                            cc = send[track][0]
                            if send[track][1] in range(16):
                                channel = send[track][1]
                            
                        
                        if cc in range(128) and channel in range(16):
                            encoder = EncoderElement(MIDI_CC_TYPE, channel, cc, volume_map_mode)
                            encoder.name = str(track) + '_Send_' + str(list(send_info).index(send)) + '_Control'
                        
                    
                    send_controls.append(encoder)
                strip.set_send_controls(tuple(send_controls))
            
        

    
    def _init_device_component(self, device_controls, bank_controls, global_channel, macro_map_mode):
        is_momentary = True
        if device_controls:
            device = DeviceComponent()
            device.name = 'Device_Component'
            if bank_controls:
                next_button = None
                prev_button = None
                if 'NEXTBANK' in bank_controls.keys() and bank_controls['NEXTBANK'] in range(128):
                    next_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, bank_controls['NEXTBANK'])
                    next_button.name = 'Device_Next_Bank_Button'
                
                if 'PREVBANK' in bank_controls.keys() and bank_controls['PREVBANK'] in range(128):
                    prev_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, bank_controls['PREVBANK'])
                    prev_button.name = 'Device_Previous_Bank_Button'
                
                device.set_bank_nav_buttons(prev_button, next_button)
                if 'TOGGLELOCK' in bank_controls.keys() and bank_controls['TOGGLELOCK'] in range(128):
                    lock_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, bank_controls['TOGGLELOCK'])
                    lock_button.name = 'Device_Lock_Button'
                    device.set_lock_button(lock_button)
                
                bank_buttons = []
                for index in range(8):
                    key = 'BANK' + str(index + 1)
                    if key in bank_controls.keys():
                        control_info = bank_controls[key]
                        channel = global_channel
                        cc = -1
                        if isinstance(control_info, (tuple, list)):
                            cc = control_info[0]
                            if control_info[1] in range(16):
                                channel = control_info[1]
                            
                        else:
                            cc = control_info
                        if cc in range(128) and channel in range(16):
                            button = ButtonElement(is_momentary, MIDI_CC_TYPE, channel, cc)
                            button.name = 'Device_Bank_' + str(index) + '_Button'
                            bank_buttons.append(button)
                        
                    channel in range(16)
                if len(bank_buttons) > 0:
                    device.set_bank_buttons(tuple(bank_buttons))
                
            
            parameter_encoders = []
            for control_info in device_controls:
                channel = global_channel
                cc = -1
                if isinstance(control_info, (tuple, list)):
                    cc = control_info[0]
                    if control_info[1] in range(16):
                        channel = control_info[1]
                    
                else:
                    cc = control_info
                if cc in range(128) and channel in range(16):
                    encoder = EncoderElement(MIDI_CC_TYPE, channel, cc, macro_map_mode)
                    encoder.name = 'Device_Parameter_' + str(list(device_controls).index(control_info)) + '_Control'
                    parameter_encoders.append(encoder)
                    continue
            if len(parameter_encoders) > 0:
                device.set_parameter_controls(tuple(parameter_encoders))
            
            self.set_device_component(device)
        

    
    def _init_transport_component(self, transport_controls, global_channel, macro_map_mode):
        is_momentary = True
        if transport_controls:
            transport = TransportComponent()
            transport.name = 'Transport'
            #THIS IS NEW STUFF
            #if 'TEMPO' in transport_control.keys() and transport_controls['TEMPO'] in range(128):
            tempo_slider = EncoderElement(MIDI_CC_TYPE, global_channel, 1, macro_map_mode)
            tempo_slider.name = 'Tempo_Slider'
            transport.set_tempo_control(tempo_slider)
            #END NEW STUFF
            if 'STOP' in transport_controls.keys() and transport_controls['STOP'] in range(128):
                stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['STOP'])
                stop_button.name = 'Stop_Button'
                transport.set_stop_button(stop_button)
            
            if 'PLAY' in transport_controls.keys() and transport_controls['PLAY'] in range(128):
                play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['PLAY'])
                play_button.name = 'Play_Button'
                transport.set_play_button(play_button)
            
            if 'REC' in transport_controls.keys() and transport_controls['REC'] in range(128):
                rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['REC'])
                rec_button.name = 'Record_Button'
                transport.set_record_button(rec_button)
            
            if 'LOOP' in transport_controls.keys() and transport_controls['LOOP'] in range(128):
                loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['LOOP'])
                loop_button.name = 'Loop_Button'
                transport.set_loop_button(loop_button)
            
            ffwd_button = None
            rwd_button = None
            momentary_seek = 'NORELEASE' not in transport_controls.keys()
            if 'FFWD' in transport_controls.keys() and transport_controls['FFWD'] in range(128):
                ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['FFWD'])
                ffwd_button.name = 'FFwd_Button'
            
            if 'RWD' in transport_controls.keys() and transport_controls['RWD'] in range(128):
                rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['RWD'])
                rwd_button.name = 'Rwd_Button'
            
            transport.set_seek_buttons(ffwd_button, rwd_button)
Esempio n. 15
0
class MPK_SessionControl(ControlSurface):
    __module__ = __name__
    __doc__ = "MPK Session Control Script"

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._setup_mixer_control()
            self._setup_transport_control()
            self._setup_session_control()
            self._setup_channel_strip_control()
            self.set_highlighting_session_component(self.session)

    # Sets up the control surface ('colored box')
    def _setup_session_control(self):
        num_tracks = 3  # 3 columns (tracks)
        num_scenes = 1  # 1 row (scenes)

        # a session highlight ("red box") will appear with any two non-zero values
        self.session = SessionComponent(num_tracks, num_scenes)
        # (track_offset, scene_offset) Sets the initial offset of the "red box" from top left
        self.session.set_offsets(0, 0)

        self.session.set_select_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                          KEYBOARD_HIGH_C - 7),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                          KEYBOARD_HIGH_C - 6))

        # These calls control the actual movement of the box; however, we're just
        # using scene and track select to move around
        # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 86), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 85))
        # self.session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 15), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 14))

        # Launch current scene with top right pad
        self.session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, BANK_B[3]))
        # Stop all clips with bottom right pad
        self.session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, BANK_B[7]))

        # First three pads launch clips in box
        clip_launch_notes = [BANK_B[0], BANK_B[1], BANK_B[2]]
        clip_select_notes = [
            KEYBOARD_MID_C - 6, KEYBOARD_MID_C - 4, KEYBOARD_MID_C - 2
        ]

        for tracks in range(num_tracks):
            self.session.scene(0).clip_slot(tracks).set_launch_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              clip_launch_notes[tracks]))
            self.session.scene(0).clip_slot(tracks).set_select_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              clip_select_notes[tracks]))
            self.session.scene(0).clip_slot(tracks).set_started_value(1)
            self.session.scene(0).clip_slot(tracks).set_stopped_value(0)

        # Bottom three pads stop current tracks in box
        track_stop_notes = [BANK_B[4], BANK_B[5], BANK_B[6]]
        # This looks unnecessary but I don't know the actual API call to to set the stop track button for the selected track
        stop_track_buttons = []
        for tracks in range(num_tracks):
            stop_track_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              track_stop_notes[tracks]))

        self.session.set_stop_track_clip_buttons(tuple(stop_track_buttons))

        #here we set up a mixer and channel strip(s) which move with the session
        self.session.set_mixer(
            self.mixer
        )  #bind the mixer to the session so that they move together
        selected_scene = self.song(
        ).view.selected_scene  #this is from the Live API
        all_scenes = self.song().scenes
        index = list(all_scenes).index(selected_scene)
        self.session.set_offsets(0, index)  #(track_offset, scene_offset)

    def _setup_transport_control(self):
        self.transport = TransportComponent()
        self.transport.set_stop_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                          KEYBOARD_LOW_C))
        self.transport.set_play_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 113))
        self.transport.set_metronome_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 114))
        self.transport.set_tap_tempo_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 81))

    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]))
            #self.mixer.channel_strip(currentTrackIndex + 2).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[6]))

    def _setup_channel_strip_control(self):
        self.channelstrip = ChannelStripComponent()
        self.channelstrip.set_track(self.mixer.channel_strip(0)._track)

    def _on_selected_track_changed(self):
        """This is an override, to add special functionality (we want to move the session to the selected track, when it changes)
    Note that it is sometimes necessary to reload Live (not just the script) when making changes to this function"""
        ControlSurface._on_selected_track_changed(
            self
        )  # This will run component.on_selected_track_changed() for all components
        """here we set the mixer and session to the selected track, when the selected track changes"""
        selected_track = self.song(
        ).view.selected_track  #this is how to get the currently selected track, using the Live API
        self.mixer.channel_strip(0).set_track(selected_track)
        all_tracks = (
            (self.song().tracks + self.song().return_tracks) +
            (self.song().master_track, )
        )  #this is from the MixerComponent's _next_track_value method
        index = list(all_tracks).index(selected_track)  #and so is this

        self.session.set_offsets(
            index, self.session._scene_offset
        )  #(track_offset, scene_offset); we leave scene_offset unchanged, but set track_offset to the selected track. This allows us to jump the red box to the selected track.

    def _on_selected_scene_changed(self):
        """This is an override, to add special functionality (we want to move the session to the selected scene, when it changes)"""
        """When making changes to this function on the fly, it is sometimes necessary to reload Live (not just the script)..."""
        ControlSurface._on_selected_scene_changed(
            self
        )  # This will run component.on_selected_scene_changed() for all components
        """Here we set the mixer and session to the selected track, when the selected track changes"""
        selected_scene = self.song(
        ).view.selected_scene  #this is how we get the currently selected scene, using the Live API
        all_scenes = self.song().scenes  #then get all of the scenes
        index = list(all_scenes).index(
            selected_scene
        )  #then identify where the selected scene sits in relation to the full list
        self.session.set_offsets(
            self.session._track_offset, index
        )  #(track_offset, scene_offset) Set the session's scene offset to match the selected track (but make no change to the track offset)

    def disconnect(self):
        #clean things up on disconnect

        #create entry in log file
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "----------MPK SessionControl log closed----------")

        ControlSurface.disconnect(self)
        return None
Esempio n. 16
0
class KeyPad(ControlSurface):
    """
    Reloop KeyPad controller script.
    """
    _encoder_range = range(73, 81)
    _product_model_id = 101

    def __init__(self, c_instance):
        super(KeyPad, self).__init__(c_instance)
        with self.component_guard():
            self._create_controls()
            self._setup_mixer()
            self._setup_transport()
            self._setup_session()
            self._setup_cue_control()
            self.set_pad_translations(PAD_TRANSLATIONS)

    def _preset_message(self, send_byte):
        """ Sysex message for setting the preset to #2. """
        return (240,
         38,
         self._product_model_id,
         send_byte,
         17,
         2,
         247)

    def refresh_state(self):
        super(KeyPad, self).refresh_state()
        self.schedule_message(2, self._send_midi, self._preset_message(1))

    def handle_sysex(self, midi_bytes):
        if midi_bytes != self._preset_message(2):
            super(KeyPad, self).handle_sysex(midi_bytes)
        else:
            map(lambda x: x.set_enabled(True), (self._mixer,
             self._session,
             self._transport,
             self._cue_control))

    def _create_controls(self):

        def make_controls_range(maker, label, cc_range):
            ccs = [ (index + 1, cc) for index, cc in enumerate(cc_range) ]
            return [ maker(1, cc, label % index) for index, cc in ccs ] + [ maker(2, cc, label % (index + len(ccs))) for index, cc in ccs ]

        def make_controls(maker, label, cc_offset):
            return make_controls_range(maker, label, xrange(cc_offset, cc_offset + 8))

        make_non_momentary_button = partial(make_button, is_momentary=False)
        self._encoders = make_controls(make_encoder, 'Encoder_%d', 57)
        self._rotaries_a = make_controls(make_slider, 'Rotary_A%d', 89)
        self._rotaries_b = make_controls(make_slider, 'Rotary_B%d', 97)
        self._faders = make_controls(make_slider, 'Fader_%d', 0)
        self._mute_buttons = make_controls(make_non_momentary_button, 'Mute_%d_Button', 8)
        self._solo_buttons = make_controls(make_button, 'Solo_%d_Button', 24)
        self._arm_buttons = make_controls(make_button, 'Arm_%d_Button', 40)
        self._play_button = make_button(1, 105, 'Play_Button')
        self._stop_button = make_button(1, 106, 'Stop_Button')
        self._record_button = make_button(1, 107, 'Record_Button')
        self._encoder_pushes = make_controls_range(partial(make_button, is_momentary=False), 'Encoder_%d_Button', self._encoder_range)
        self._shifted_mute_buttons = make_controls(make_non_momentary_button, 'Shifted_Mute_%d_Button', 16)
        self._shifted_solo_buttons = make_controls(make_button, 'Shifted_Solo_%d_Button', 32)
        self._all_shifted_arm_buttons = make_controls(make_button, 'Shifted_Arm_%d_Button', 49)
        self._shifted_arm_buttons = [ CombinedButtonsElement(buttons=(self._all_shifted_arm_buttons[index], self._all_shifted_arm_buttons[index + 8])) for index in xrange(8) ]
        self._shifted_play_button = make_button(1, 108, 'Shifted_Play_Button')
        self._shifted_stop_button = make_button(1, 109, 'Shifted_Stop_Button')
        self._shifted_record_button = make_button(1, 110, 'Shifted_Record_Button')
        self._shifted_octave_down_button = make_button(1, 111, 'Shifted_Octave_Down_Button')
        self._shifted_octave_up_button = make_button(1, 112, 'Shifted_Octave_Up_Button')

    def _setup_mixer(self):
        self._mixer = MixerComponent(NUM_CHANNEL_STRIPS)
        self._mixer.name = 'Mixer'
        self._mixer.set_enabled(False)
        for index in xrange(NUM_CHANNEL_STRIPS):
            strip = self._mixer.channel_strip(index)
            strip.set_invert_mute_feedback(True)
            sends = ButtonMatrixElement(name='%d_Send_Controls' % (index + 1), rows=[(self._rotaries_a[index], self._rotaries_b[index])])
            strip.layer = Layer(volume_control=self._faders[index], pan_control=self._encoders[index], send_controls=sends, mute_button=self._mute_buttons[index], solo_button=self._solo_buttons[index], arm_button=self._arm_buttons[index], select_button=self._encoder_pushes[index])

    def _setup_transport(self):
        self._transport = TransportComponent(name='Transport')
        self._transport.set_enabled(False)
        self._transport.layer = Layer(play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button, overdub_button=self._shifted_record_button, loop_button=self._shifted_arm_buttons[3], tap_tempo_button=self._shifted_arm_buttons[4], metronome_button=self._shifted_arm_buttons[5], nudge_down_button=self._shifted_arm_buttons[6], nudge_up_button=self._shifted_arm_buttons[7])

    def _setup_session(self):
        self._session = SessionComponent(NUM_CHANNEL_STRIPS, name='Session_Control')
        self._session.set_enabled(False)
        stop_buttons = ButtonMatrixElement(name='Track_Stop_Buttons', rows=[self._shifted_solo_buttons])
        self._session.layer = Layer(stop_all_clips_button=self._shifted_stop_button, stop_track_clip_buttons=stop_buttons, select_prev_button=self._shifted_octave_down_button, select_next_button=self._shifted_octave_up_button)
        self._session.selected_scene().name = 'Selected_Scene_Control'
        self._session.selected_scene().layer = Layer(launch_button=self._shifted_play_button)
        for index in xrange(NUM_CHANNEL_STRIPS):
            slot = self._session.selected_scene().clip_slot(index)
            slot.layer = Layer(launch_button=self._shifted_mute_buttons[index])

    def _setup_cue_control(self):
        self._cue_control = CuePointControlComponent(name='Cue_Point_Control')
        self._cue_control.set_enabled(False)
        self._cue_control.layer = Layer(toggle_cue_button=self._shifted_arm_buttons[0], prev_cue_button=self._shifted_arm_buttons[1], next_cue_button=self._shifted_arm_buttons[2])
Esempio n. 17
0
class MPK_mini_hero(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """
    def __init__(self, c_instance, identity_response=SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'MPK mini'
            self._suggested_output_port = 'MPK mini'

            self._setup_buttons()
            self._setup_components()

            for component in self.components:
                component.set_enabled(True)  # Puvodne False

    def refresh_state(self):
        ControlSurface.refresh_state(self)

        # for val in range(127):
        #     self.schedule_message(2, self._send_midi, (144, val, 0))

        # self.schedule_message(3, self._send_midi, (144, 9, 127))

    def handle_sysex(self, midi_bytes):
        self._send_midi(LED_FLASHING_ON)
        self._update_mixer_offset()
        for control in self.controls:
            if isinstance(control, InputControlElement):
                control.clear_send_cache()

        for component in self.components:
            component.set_enabled(True)

        self.request_rebuild_midi_map()

    def disconnect(self):
        ControlSurface.disconnect(self)

        self._encoders = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)

    def _setup_buttons(self):
        # Pads CC Mode
        self._scene_launch_button = make_pad_button(PAD_MODE_CC, 1,
                                                    'Scene_Launch_Button')
        self._overdub_button = make_pad_button(PAD_MODE_CC, 2,
                                               'Session_Overdub_Button')
        self._ffwd_button = make_pad_button(PAD_MODE_CC, 3, 'FFwd_Button')
        self._clip_undo_button = make_pad_button(PAD_MODE_CC, 4,
                                                 'Clip_Undo_Button')
        self._prev_track_button = make_pad_button(PAD_MODE_CC, 5,
                                                  'Prev_Track_Button')
        self._next_track_button = make_pad_button(PAD_MODE_CC, 6,
                                                  'Next_Track_Button')
        self._rwd_button = make_pad_button(PAD_MODE_CC, 7, 'Rwd_Button')
        self._scene_stop_button = make_pad_button(PAD_MODE_CC, 9,
                                                  'Scene_Stop_Button')
        self._stop_button = make_pad_button(PAD_MODE_CC, 10, 'Stop_Button')
        self._play_button = make_pad_button(PAD_MODE_CC, 11, 'Play_Button')
        self._loop_button = make_pad_button(PAD_MODE_CC, 12, 'Loop_Button')
        self._rec_button = make_pad_button(PAD_MODE_CC, 13, 'Record_Button')

        # Pads Notes Mode
        self._clip_launch_buttons = [
            make_pad_button(PAD_MODE_NOTES, index, 'Clip_Launch_%d' % index)
            for index in xrange(8)
        ]
        self._clip_stop_buttons = [
            make_pad_button(PAD_MODE_NOTES, 8 + index, 'Clip_Stop_%d' % index)
            for index in xrange(8)
        ]

        # Encoders

        self._encoders = tuple([
            make_encoder(21 + index, 'Device_Control_%d' % index)
            for index in xrange(8)
        ])

        # Scenes

        self._scene_launch_buttons = []
        for key_no in [0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24]:
            self._scene_launch_buttons.append(
                make_scene_button(key_no, 'Scene_Launch_%d' % key_no))

    def _setup_components(self):

        # Session

        self._session = SessionComponent(8, len(self._scene_launch_buttons))
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._scene_launch_button)
        self._session.set_stop_all_clips_button(self._scene_stop_button)

        for index in range(8):
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_launch_button(self._clip_launch_buttons[index])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(
            tuple(self._clip_stop_buttons))

        # Undo

        self._do_undo.subject = self._clip_undo_button

        # Transport

        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(self._stop_button)
        transport.set_play_button(self._play_button)
        transport.set_record_button(self._rec_button)
        transport.set_loop_button(self._loop_button)

        self._transport_view_modes = TransportViewModeSelector(
            transport, self._session, self._ffwd_button, self._rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

        session_recording = SessionRecordingComponent(
            ClipCreator(),
            ViewControlComponent(),
            name='Session_Recording',
            is_enabled=False,
            layer=Layer(record_button=self._overdub_button))

        # Device

        # device = DeviceComponent()
        # device.name = 'Device_Component'
        # self.set_device_component(device)
        # device.set_parameter_controls(self._encoders)

        # Navigation

        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

        # Playing
        # self._session.set_scene_launch_buttons(tuple(self._scene_launch_buttons))
        for index in range(len(self._scene_launch_buttons)):
            scene = self._session.scene(index)
            scene.set_launch_button(self._scene_launch_buttons[index])

    @subject_slot('value')
    def _do_undo(self, value):
        if value:
            if self.song().can_undo == 1:
                self.song().undo()
                self.show_message(str('UNDO'))

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = 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
            self._session.set_offsets(new_offset, self._session.scene_offset())
Esempio n. 18
0
	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87)		   
		right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 67)
		left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 66)
		up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 71)
		down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 68)
		right_button.name = 'Bank_Select_Right_Button'
		left_button.name = 'Bank_Select_Left_Button'
		up_button.name = 'Bank_Select_Up_Button'
		down_button.name = 'Bank_Select_Down_Button'
		global session
		session = SessionComponent(7, 8)
		session.name = 'Session_Control'
		session.set_track_bank_buttons(right_button, left_button)
		session.set_scene_bank_buttons(down_button, up_button)
		matrix = ButtonMatrixElement()
		matrix.name = 'Button_Matrix'
		scene_launch_notes = [56,57,58,59,60,61,62,63]
		scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, scene_launch_notes[index]) for index in range(8) ]
		#track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
		#for index in range(len(track_stop_buttons)):
		#	 track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
		#stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
		#stop_all_button.name = 'Stop_All_Clips_Button'
		#self._session.set_stop_all_clips_button(stop_all_button)
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_track_clip_value(2)
		#button_notes = [0,8,16,24,32,40,48,56,1,9,17,25,33,41,49,57,2,10,18,26,34,42,50,58,3,11,19,27,35,43,51,59,4,12,20,28,36,44,52,60,5,13,21,29,37,45,53,61,6,14,22,30,38,46,54,62]
		for scene_index in range(8):
			scene = session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			#scene.set_triggered_value(2)
			for track_index in range(7):
				button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (track_index * 8) + scene_index)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				#clip_slot.set_triggered_to_play_value(2)
				#clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(0)
				clip_slot.set_started_value(64)
				#clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)

			matrix.add_row(tuple(button_row))

		#self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
		session.selected_scene().name = 'Selected_Scene'
		#session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		#session_zoom = SessionZoomingComponent(session)
		#session_zoom.name = 'Session_Overview'
		#session_zoom.set_button_matrix(matrix)
		#session_zoom.set_zoom_button(self._shift_button)
		#session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
		#session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		#session_zoom.set_stopped_value(0)
		#session_zoom.set_selected_value(127)
		session.set_mixer(mixer)
		self.set_highlighting_session_component(session)
		return None #return session
Esempio n. 19
0
class Novation_Impulse2(ControlSurface):
    """ Script for Novation's Impulse keyboards """
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.c_instance = 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._string_to_display = None
            self.shift_pressed = False
            # special alternative buttons mode. for now only mixer buttons become record buttons. later we will add something more
            self.alternative_buttons_mode = False
            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._shift_button.add_value_listener(self._shift_button_handler)

            for component in self.components:
                component.set_enabled(False)

    # attributes
    def alternative_buttons_mode(self):
        return self.alternative_buttons_mode

    def alternative_buttons_mode(self, value):
        self.log('alternative_buttons_mode_value ' + str(value))
        self.alternative_buttons_mode = value

    def shift_pressed(self):
        return self.shift_pressed

    def shift_pressed(self, value):
        self.log('shift_pressed value ' + str(value))
        self.shift_pressed = value

    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.log('starting disconnect 1')
        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)
        self.log('starting disconnect 3')
        ControlSurface.disconnect(self)
        self.log('starting disconnect 3')
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = 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.log('starting disconnect 4')
        self._send_midi(SYSEX_START + (6, 0, 0, 0, 247))
        self.log('starting disconnect 5')

        if self._shift_button != None:
            self._shift_button.remove_value_listener(
                self._shift_button_handler)
            self._shift_button = None
        self.log('starting disconnect 6')

    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):
        self.log('setup mixer')
        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(self, 8, self.c_instance)
        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)
        #self._mixer.set_shift_button(self._shift_button)
        self._mixer.updateMixerButtons()

        self._button9 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + 8)

    def _setup_session(self):
        num_pads = len(PAD_TRANSLATIONS)
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer)
        # for ableton 9.1.1 and lower
        #self._session.set_track_banking_increment(num_pads)
        #self._session.set_track_bank_buttons(ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35), ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36))
        # for ableton 9.1.1 and higher
        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.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'
        self._transport = ShiftableTransportComponent(self.c_instance,
                                                      self._session, self,
                                                      ffwd_button, rwd_button)
        self._transport.name = 'Transport'
        self._transport.set_stop_buttonOnInit(stop_button)
        self._transport.set_play_button(play_button)
        self._transport.set_record_buttonOnInit(rec_button)
        #        self._transport.set_shift_button(self._shift_button)
        self._transport.set_mixer9_button(self._button9)
        self._transport_view_modes = TransportViewModeSelector(
            self, self.c_instance, self._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
        display_string = ''
        if self._device_component.is_enabled():
            #            display_string = sender.name
            #            track = self.song().view.selected_track
            #            display_string = str(list(tracks).index(track) + 1)
            pass
        if (sender.mapped_parameter() != None):
            #            display_string = display_string + '-'
            display_string = display_string + sender.mapped_parameter().name
        self._set_string_to_display(display_string)

    def _slider_value(self, value, sender):
        self.log('_slider_value ' + str(value) + ' ' + str(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 = ' - '
            master = self.song().master_track
            tracks = self.song().tracks
            returns = self.song().return_tracks
            track = None
            if sender.mapped_parameter() != None:
                self.log('1')
                if sender == self._master_slider:
                    self.log('2')
                    #                    track = self._has_sliders and master
                    if self._has_sliders:
                        track = master
                    else:
                        self.log('2.1')
                        track = self.song().view.selected_track
                else:
                    self.log('3')
                    track = self._mixer.channel_strip(
                        self._sliders.index(sender))._track
            else:
                self.log('4')
                track = self.song().view.selected_track
            self.log('track=' + str(track))
            if track == master:
                display_string = '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
                raise AssertionError
            display_string += ' Volume'
            self._set_string_to_display(display_string)

    def _mixer_button_value(self, value, sender):
        self.log('__mixer_button_value ' + str(value) + ' ' + str(sender))
        if not value in range(128):
            raise AssertionError
        #if self._mixer.is_enabled() and value > 0:
        if self._mixer.is_enabled():
            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(' - ')
        # if shift_pressed XOR alternative_mode
        if self.shift_pressed <> self.alternative_buttons_mode:
            self.log("_mixer_button_value")
            self.log(str(value))
            if (value == 0):
                self.select_armed_track_if_only_one()

    def select_armed_track_if_only_one(self):
        self.log("select_armed_track_if_only_one")
        song = self.song()
        armed_tracks = []
        tracks = song.tracks
        self.log("select_armed_track_if_only_one 2")
        for track in tracks:
            if track.can_be_armed and track.arm:
                armed_tracks.append(track)
        self.log(str(len(armed_tracks)))
        if (len(armed_tracks) == 1):
            self.log("selecting the track")
            sel_track = armed_tracks[0]
            self.song().view.selected_track = sel_track
            self._mixer._selected_tracks = []
            self._mixer._selected_tracks.append(sel_track)
            self._mixer.on_selected_track_changed()

    def _preview_value(self, value):
        if not value in range(128):
            raise 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):
        if not isinstance(string_to_display, (str, unicode)):
            raise 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):
        self.log('_on_selected_track_changed')
        ControlSurface._on_selected_track_changed(self)
        self._show_current_track_name()
        #all_tracks = self._has_sliders or self._session.tracks_to_use()
        all_tracks2 = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks2:
            track_index = list(all_tracks2).index(selected_track)
            self.log('track_index ' + str(track_index))
            new_offset = track_index - track_index % num_strips
            self.log('new_offset ' + str(new_offset))
            if not new_offset / num_strips == int(new_offset / num_strips):
                raise AssertionError
            self._session.set_offsets(new_offset, self._session.scene_offset())

    def _shift_button_handler(self, value):
        self.log("root shift handler : " + str(value))
        if not self._shift_button != None:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        self.log("root shift handler 2")
        self.shift_pressed = value > 0
        # calling other handlers
        self._mixer._shift_button_handler(value)
        self._transport._shift_button_handler(value)
        self._transport_view_modes._shift_button_handler(value)

        #clip stop
        self.log("root shift handler 3")
        num_pads = len(PAD_TRANSLATIONS)
        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)
            if self.shift_pressed:
                clip_slot.set_launch_button(None)
            else:
                clip_slot.set_launch_button(pads[index])
        if self.shift_pressed:
            self._session.set_stop_track_clip_buttons(tuple(pads))
        else:
            self._session.set_stop_track_clip_buttons(None)

        self.log("root shift handler 4")

    def flipAlternativeButtonMode(self):
        self.alternative_buttons_mode = not self.alternative_buttons_mode
        self.updateAlternativeButtonMode()

    def updateAlternativeButtonMode(self):
        self._mixer.updateMixerButtons()
        self._transport_view_modes.update()

    def log(self, message):
        pass
class Launchkey(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """
    def __init__(self,
                 c_instance,
                 control_factory=LaunchkeyControlFactory(),
                 identity_response=SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._control_factory = control_factory
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'Launchkey InControl'
            self._suggested_output_port = 'Launchkey InControl'
            self._has_sliders = True
            self._current_midi_map = None
            self._master_slider = make_slider(7, 'Master_Volume_Control')
            self._modes_buttons = []
            for index in range(3):
                button = ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,
                                       13 + index)
                self._modes_buttons.append(button)
                self._modes_buttons[-1].add_value_listener(
                    self._dummy_listener)

            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_navigation()
            for component in self.components:
                component.set_enabled(False)

        return

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(2, self._send_midi, LIVE_MODE_ON)
        self.schedule_message(3, self._send_midi, SIZE_QUERY)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:11] == self._identity_response:
            self._has_sliders = midi_bytes[11] != 48
            self._send_midi(LED_FLASHING_ON)
            self._update_mixer_offset()
            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)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    self._mixer.channel_strip(index).set_mute_button(None)
                    slider = self._sliders[index]
                    slider.release_parameter()

                self._mixer.selected_strip().set_volume_control(
                    self._master_slider)
            self.request_rebuild_midi_map()
        return

    def disconnect(self):
        ControlSurface.disconnect(self)
        for button in self._modes_buttons:
            if button.value_has_listener(self._dummy_listener):
                button.remove_value_listener(self._dummy_listener)

        self._modes_buttons = None
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)
        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 _setup_mixer(self):
        mute_solo_flip_button = make_button(59, 'Master_Button')
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        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 = []
        self._strip_buttons = []
        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(
                make_slider(41 + index, 'Volume_Control_%d' % index))
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(
                make_button(51 + index, 'Mute_Button_%d' % index))

        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons),
                                                mute_solo_flip_button)

    def _setup_session(self):
        scene_launch_button = self._control_factory.create_scene_launch_button(
        )
        scene_stop_button = self._control_factory.create_scene_stop_button()
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(scene_launch_button)
        self._session.selected_scene().set_triggered_value(GREEN_BLINK)
        self._session.set_stop_all_clips_button(scene_stop_button)
        scene_stop_button.set_on_off_values(AMBER_FULL, LED_OFF)
        self._session.set_mixer(self._mixer)
        self._session.set_stop_clip_value(AMBER_HALF)
        self._session.set_stop_clip_triggered_value(GREEN_BLINK)
        clip_launch_buttons = []
        clip_stop_buttons = []
        for index in range(8):
            clip_launch_buttons.append(
                self._control_factory.create_clip_launch_button(index))
            clip_stop_buttons.append(
                self._control_factory.create_clip_stop_button(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(clip_launch_buttons[-1])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(tuple(clip_stop_buttons))

    def _setup_transport(self):
        rwd_button = make_button(112, 'Rwd_Button')
        ffwd_button = make_button(113, 'FFwd_Button')
        stop_button = make_button(114, 'Stop_Button')
        play_button = make_button(115, 'Play_Button')
        loop_button = make_button(116, 'Loop_Button')
        rec_button = make_button(117, 'Record_Button')
        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_record_button(rec_button)
        transport.set_loop_button(loop_button)
        self._transport_view_modes = TransportViewModeSelector(
            transport, self._session, ffwd_button, rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = [
            make_encoder(21 + index, 'Device_Control_%d' % index)
            for index in xrange(8)
        ]
        self._encoders = tuple(encoders)
        device = DeviceComponent(device_selection_follows_track_selection=True)
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)

    def _setup_navigation(self):
        self._next_track_button = self._control_factory.create_next_track_button(
        )
        self._prev_track_button = self._control_factory.create_prev_track_button(
        )
        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = 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
            self._session.set_offsets(new_offset, self._session.scene_offset())
Esempio n. 21
0
	def _setup_session_control(self):
		is_momentary = True		  
		right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 43)
		left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 42)
		up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 44)
		down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 45)
		right_button.name = 'Bank_Select_Right_Button'
		left_button.name = 'Bank_Select_Left_Button'
		up_button.name = 'Bank_Select_Up_Button'
		down_button.name = 'Bank_Select_Down_Button'
		global session
		session = SessionComponent(4, 4)
		session.name = 'Session_Control'
		session.set_track_bank_buttons(right_button, left_button)
		session.set_scene_bank_buttons(down_button, up_button)
		self._session = session
		matrix = ButtonMatrixElement()
		matrix.name = 'Button_Matrix'
		scene_launch_notes = [33,34,35,36]
		scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, scene_launch_notes[index]) for index in range(4) ]
		#track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(4) ]
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
		#for index in range(len(track_stop_buttons)):
		#	 track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
		#stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
		#stop_all_button.name = 'Stop_All_Clips_Button'
		#self._session.set_stop_all_clips_button(stop_all_button)
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_clip_value(2)
		button_notes = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]
		for scene_index in range(4):
			scene = session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			#scene.set_triggered_value(2)
			for track_index in range(4):
				button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, (track_index * 4) + scene_index + 1)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				#clip_slot.set_triggered_to_play_value(2)
				#clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(0)
				clip_slot.set_started_value(64)
				#clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)
			matrix.add_row(tuple(button_row))
		#self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
		session.selected_scene().name = 'Selected_Scene'
		#session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		#session_zoom = SessionZoomingComponent(session)
		#session_zoom.name = 'Session_Overview'
		#session_zoom.set_button_matrix(matrix)
		#session_zoom.set_zoom_button(self._shift_button)
		#session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
		#session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		#session_zoom.set_stopped_value(0)
		#session_zoom.set_selected_value(127)
		self.set_highlighting_session_component(session)
		session.set_mixer(mixer)
		return None #return session
Esempio n. 22
0
    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87)        
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 78)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 77)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 71)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 79)
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        global session
        session = SessionComponent(7, 8)
        session.name = 'Session_Control'
        session.set_track_bank_buttons(right_button, left_button)
        session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        matrix.name = 'Button_Matrix'
        scene_launch_notes = [56,57,58,59,60,61,62,63]
        scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, scene_launch_notes[index]) for index in range(8) ]
        #track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
        #for index in range(len(track_stop_buttons)):
        #    track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
        #stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        #stop_all_button.name = 'Stop_All_Clips_Button'
        #self._session.set_stop_all_clips_button(stop_all_button)
        #self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        #self._session.set_stop_track_clip_value(2)
        #button_notes = [0,8,16,24,32,40,48,56,1,9,17,25,33,41,49,57,2,10,18,26,34,42,50,58,3,11,19,27,35,43,51,59,4,12,20,28,36,44,52,60,5,13,21,29,37,45,53,61,6,14,22,30,38,46,54,62]
        for scene_index in range(8):
            scene = session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            #scene.set_triggered_value(2)
            for track_index in range(7):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (track_index * 8) + scene_index)
                button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                #clip_slot.set_triggered_to_play_value(2)
                #clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(0)
                clip_slot.set_started_value(64)
                #clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)

            matrix.add_row(tuple(button_row))

        #self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        session.selected_scene().name = 'Selected_Scene'
        #session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        #session_zoom = SessionZoomingComponent(session)
        #session_zoom.name = 'Session_Overview'
        #session_zoom.set_button_matrix(matrix)
        #session_zoom.set_zoom_button(self._shift_button)
        #session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        #session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        #session_zoom.set_stopped_value(0)
        #session_zoom.set_selected_value(127)
        session.set_mixer(mixer)
        return None #return session
Esempio n. 23
0
class FancyScript(ControlSurface):
    ''' A generic script class with predefined behaviour.
      It can be customised to use/not use certain controls on instantiation.
  '''
    def __init__(self,
                 c_instance,
                 macro_map_mode,
                 volume_map_mode,
                 device_controls,
                 transport_controls,
                 volume_controls,
                 trackarm_controls,
                 bank_controls,
                 descriptions=None,
                 mixer_options=None):
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(True)
        global_channel = 0
        if descriptions:
            if list(descriptions.keys()).count('INPUTPORT') > 0:
                self._suggested_input_port = descriptions['INPUTPORT']

            if list(descriptions.keys()).count('OUTPUTPORT') > 0:
                self._suggested_output_port = descriptions['OUTPUTPORT']

            if list(descriptions.keys()).count('CHANNEL') > 0:
                global_channel = descriptions['CHANNEL']
                if global_channel not in range(16):
                    global_channel = 0

            if list(descriptions.keys()).count('PAD_TRANSLATION') > 0:
                self.set_pad_translations(descriptions['PAD_TRANSLATION'])
        #delete this print
        self.log_message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" +
                         str(type(macro_map_mode)))
        self._init_mixer_component(volume_controls, trackarm_controls,
                                   mixer_options, global_channel,
                                   volume_map_mode)
        self._init_device_component(device_controls, bank_controls,
                                    global_channel, macro_map_mode)
        self._init_transport_component(
            transport_controls, global_channel,
            macro_map_mode)  #that last arg is new and shold be deleted
        #this is a new method call
        self._init_clip_slot_component(
            volume_controls)  #this should take some args)
        #this is too
        self._init_session_component(global_channel, 3, 1)
        self.set_suppress_rebuild_requests(False)

    def _init_session_component(self, global_channel, num_tracks, num_scenes):
        self._session_component = SessionComponent(num_tracks, num_scenes)
        self._session_selected_scene = self._session_component.selected_scene()
        stop_buttons = []
        for i in range(num_tracks):
            stopper = ButtonElement(True, MIDI_CC_TYPE, global_channel,
                                    (3, 6, 9)[i])
            stopper.name = 'Clip_Stop_Button'
            stop_buttons = stop_buttons + [stopper]
            clip_start_button = ButtonElement(True, MIDI_CC_TYPE,
                                              global_channel, (2, 5, 8)[i])
            clip_start_button.name = 'Clip_Start_Button'
            self._session_selected_scene.clip_slot(i).set_launch_button(
                clip_start_button)
        #self._session_component.set_stop_track_clip_buttons(stop_buttons)

    def _init_clip_slot_component(self, volume_controls):
        num_strips = len(volume_controls)
        num_scenes = 1  # this is not always true, just in our case

        b1 = ButtonElement(False, MIDI_CC_TYPE, 1, 3)
        b2 = ButtonElement(False, MIDI_CC_TYPE, 1, 6)
        b3 = ButtonElement(False, MIDI_CC_TYPE, 1, 9)

    def handle_sysex(self, midi_bytes):
        pass

    def _init_mixer_component(self, volume_controls, trackarm_controls,
                              mixer_options, global_channel, volume_map_mode):
        if volume_controls != None and trackarm_controls != None:
            num_strips = max(len(volume_controls), len(trackarm_controls))
            send_info = []
            momentary_buttons = False
            mixer = SpecialMixerComponent(num_strips)
            mixer.name = 'Mixer'
            mixer.master_strip().name = 'Master_Channel_Strip'
            mixer.selected_strip().name = 'Selected_Channel_Strip'
            if mixer_options != None:
                if 'MASTERVOLUME' in mixer_options.keys(
                ) and mixer_options['MASTERVOLUME'] in range(128):
                    encoder = EncoderElement(MIDI_CC_TYPE, global_channel,
                                             mixer_options['MASTERVOLUME'],
                                             volume_map_mode)
                    encoder.name = 'Master_Volume_Control'
                    mixer.master_strip().set_volume_control(encoder)

                if 'NUMSENDS' in mixer_options.keys(
                ) and mixer_options['NUMSENDS'] > 0:
                    for send in range(mixer_options['NUMSENDS']):
                        key = 'SEND' + str(send + 1)
                        if not key in mixer_options.keys():
                            raise AssertionError
                        send_info.append(mixer_options[key])

                momentary_buttons = 'NOTOGGLE' in mixer_options.keys()
                next_bank_button = None
                prev_bank_button = None
                if 'NEXTBANK' in mixer_options.keys(
                ) and mixer_options['NEXTBANK'] in range(128):
                    next_bank_button = ButtonElement(momentary_buttons,
                                                     MIDI_CC_TYPE,
                                                     global_channel,
                                                     mixer_options['NEXTBANK'])
                    next_bank_button.name = 'Mixer_Next_Bank_Button'

                if 'PREVBANK' in mixer_options.keys(
                ) and mixer_options['PREVBANK'] in range(128):
                    prev_bank_button = ButtonElement(momentary_buttons,
                                                     MIDI_CC_TYPE,
                                                     global_channel,
                                                     mixer_options['PREVBANK'])
                    prev_bank_button.name = 'Mixer_Previous_Bank_Button'

                mixer.set_bank_buttons(next_bank_button, prev_bank_button)

            for track in range(num_strips):
                strip = mixer.channel_strip(track)
                strip.name = 'Channel_Strip_' + str(track)
                if track in range(len(volume_controls)):
                    channel = global_channel
                    cc = volume_controls[track]
                    if isinstance(volume_controls[track], (tuple, list)):
                        cc = volume_controls[track][0]
                        if volume_controls[track][1] in range(16):
                            channel = volume_controls[track][1]

                    if cc in range(128) and channel in range(16):
                        encoder = EncoderElement(MIDI_CC_TYPE, channel, cc,
                                                 volume_map_mode)
                        encoder.name = str(track) + '_Volume_Control'
                        strip.set_volume_control(encoder)

                if track in range(len(trackarm_controls)
                                  ) and trackarm_controls[track] in range(128):
                    button = ButtonElement(momentary_buttons, MIDI_CC_TYPE,
                                           global_channel,
                                           trackarm_controls[track])
                    button.name = str(track) + '_Arm_Button'
                    strip.set_arm_button(button)

                send_controls = []
                for send in send_info:
                    encoder = None
                    if track in range(len(send)):
                        channel = global_channel
                        cc = send[track]
                        if isinstance(send[track], (tuple, list)):
                            cc = send[track][0]
                            if send[track][1] in range(16):
                                channel = send[track][1]

                        if cc in range(128) and channel in range(16):
                            encoder = EncoderElement(MIDI_CC_TYPE, channel, cc,
                                                     volume_map_mode)
                            encoder.name = str(track) + '_Send_' + str(
                                list(send_info).index(send)) + '_Control'

                    send_controls.append(encoder)
                strip.set_send_controls(tuple(send_controls))

    def _init_device_component(self, device_controls, bank_controls,
                               global_channel, macro_map_mode):
        is_momentary = True
        if device_controls:
            device = DeviceComponent()
            device.name = 'Device_Component'
            if bank_controls:
                next_button = None
                prev_button = None
                if 'NEXTBANK' in bank_controls.keys(
                ) and bank_controls['NEXTBANK'] in range(128):
                    next_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                global_channel,
                                                bank_controls['NEXTBANK'])
                    next_button.name = 'Device_Next_Bank_Button'

                if 'PREVBANK' in bank_controls.keys(
                ) and bank_controls['PREVBANK'] in range(128):
                    prev_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                global_channel,
                                                bank_controls['PREVBANK'])
                    prev_button.name = 'Device_Previous_Bank_Button'

                device.set_bank_nav_buttons(prev_button, next_button)
                if 'TOGGLELOCK' in bank_controls.keys(
                ) and bank_controls['TOGGLELOCK'] in range(128):
                    lock_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                global_channel,
                                                bank_controls['TOGGLELOCK'])
                    lock_button.name = 'Device_Lock_Button'
                    device.set_lock_button(lock_button)

                bank_buttons = []
                for index in range(8):
                    key = 'BANK' + str(index + 1)
                    if key in bank_controls.keys():
                        control_info = bank_controls[key]
                        channel = global_channel
                        cc = -1
                        if isinstance(control_info, (tuple, list)):
                            cc = control_info[0]
                            if control_info[1] in range(16):
                                channel = control_info[1]

                        else:
                            cc = control_info
                        if cc in range(128) and channel in range(16):
                            button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                   channel, cc)
                            button.name = 'Device_Bank_' + str(
                                index) + '_Button'
                            bank_buttons.append(button)

                    channel in range(16)
                if len(bank_buttons) > 0:
                    device.set_bank_buttons(tuple(bank_buttons))

            parameter_encoders = []
            for control_info in device_controls:
                channel = global_channel
                cc = -1
                if isinstance(control_info, (tuple, list)):
                    cc = control_info[0]
                    if control_info[1] in range(16):
                        channel = control_info[1]

                else:
                    cc = control_info
                if cc in range(128) and channel in range(16):
                    encoder = EncoderElement(MIDI_CC_TYPE, channel, cc,
                                             macro_map_mode)
                    encoder.name = 'Device_Parameter_' + str(
                        list(device_controls).index(control_info)) + '_Control'
                    parameter_encoders.append(encoder)
                    continue
            if len(parameter_encoders) > 0:
                device.set_parameter_controls(tuple(parameter_encoders))

            self.set_device_component(device)

    def _init_transport_component(self, transport_controls, global_channel,
                                  macro_map_mode):
        is_momentary = True
        if transport_controls:
            transport = TransportComponent()
            transport.name = 'Transport'
            #THIS IS NEW STUFF
            #if 'TEMPO' in transport_control.keys() and transport_controls['TEMPO'] in range(128):
            tempo_slider = EncoderElement(MIDI_CC_TYPE, global_channel, 1,
                                          macro_map_mode)
            tempo_slider.name = 'Tempo_Slider'
            transport.set_tempo_control(tempo_slider)
            #END NEW STUFF
            if 'STOP' in transport_controls.keys(
            ) and transport_controls['STOP'] in range(128):
                stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                            global_channel,
                                            transport_controls['STOP'])
                stop_button.name = 'Stop_Button'
                transport.set_stop_button(stop_button)

            if 'PLAY' in transport_controls.keys(
            ) and transport_controls['PLAY'] in range(128):
                play_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                            global_channel,
                                            transport_controls['PLAY'])
                play_button.name = 'Play_Button'
                transport.set_play_button(play_button)

            if 'REC' in transport_controls.keys(
            ) and transport_controls['REC'] in range(128):
                rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                           global_channel,
                                           transport_controls['REC'])
                rec_button.name = 'Record_Button'
                transport.set_record_button(rec_button)

            if 'LOOP' in transport_controls.keys(
            ) and transport_controls['LOOP'] in range(128):
                loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                            global_channel,
                                            transport_controls['LOOP'])
                loop_button.name = 'Loop_Button'
                transport.set_loop_button(loop_button)

            ffwd_button = None
            rwd_button = None
            momentary_seek = 'NORELEASE' not in transport_controls.keys()
            if 'FFWD' in transport_controls.keys(
            ) and transport_controls['FFWD'] in range(128):
                ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE,
                                            global_channel,
                                            transport_controls['FFWD'])
                ffwd_button.name = 'FFwd_Button'

            if 'RWD' in transport_controls.keys(
            ) and transport_controls['RWD'] in range(128):
                rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE,
                                           global_channel,
                                           transport_controls['RWD'])
                rwd_button.name = 'Rwd_Button'

            transport.set_seek_buttons(ffwd_button, rwd_button)