def check_translation(translation):
     raise len(translation) == 4 or AssertionError
     raise in_range(translation[0], 0, 4) or AssertionError
     raise in_range(translation[1], 0, 4) or AssertionError
     raise in_range(translation[2], 0, 128) or AssertionError
     raise in_range(translation[3], 0, 16) or AssertionError
     return True
 def check_translation(translation):
     raise len(translation) == 4 or AssertionError
     raise in_range(translation[0], 0, 4) or AssertionError
     raise in_range(translation[1], 0, 4) or AssertionError
     raise in_range(translation[2], 0, 128) or AssertionError
     raise in_range(translation[3], 0, 16) or AssertionError
     return True
 def set_light(self, column, row, value):
     if not in_range(column, 0, self.width()):
         raise AssertionError
         if not in_range(row, 0, self.height()):
             raise AssertionError
             button = len(self._buttons[row]) > column and self._buttons[row][column]
             button and button.set_light(value)
Пример #4
0
 def __init__(self, msg_type = None, channel = None, identifier = None, sysex_identifier = None, request_rebuild_midi_map = None, *a, **k):
     raise msg_type in MIDI_MSG_TYPES or AssertionError
     raise in_range(channel, 0, 16) or channel is None or AssertionError
     raise in_range(identifier, 0, 128) or identifier is None or AssertionError
     raise msg_type != MIDI_SYSEX_TYPE or channel == None or AssertionError
     raise msg_type != MIDI_SYSEX_TYPE or identifier == None or AssertionError
     raise msg_type == MIDI_SYSEX_TYPE or sysex_identifier == None or AssertionError
     super(InputControlElement, self).__init__(*a, **k)
     self._request_rebuild = request_rebuild_midi_map
     self._msg_type = msg_type
     self._msg_channel = channel
     self._msg_identifier = identifier
     self._msg_sysex_identifier = sysex_identifier
     self._original_channel = channel
     self._original_identifier = identifier
     self._needs_takeover = True
     self._is_mapped = True
     self._is_being_forwarded = True
     self._delayed_messages = []
     self._force_next_send = False
     self._mapping_feedback_delay = 0
     self._mapping_sensitivity = 1.0
     self._send_delayed_messages_task = self._tasks.add(Task.run(self._send_delayed_messages))
     self._send_delayed_messages_task.kill()
     self._parameter_to_map_to = None
     self._in_parameter_gesture = False
     self._last_sent_message = None
     self._report_input = False
     self._report_output = False
Пример #5
0
 def set_light(self, column, row, value):
     if not in_range(column, 0, self.width()):
         raise AssertionError
         if not in_range(row, 0, self.height()):
             raise AssertionError
             button = len(self._buttons[row]) > column and self._buttons[row][column]
             button and button.set_light(value)
 def __init__(self, msg_type = None, channel = None, identifier = None, sysex_identifier = None, request_rebuild_midi_map = None, *a, **k):
     raise msg_type in MIDI_MSG_TYPES or AssertionError
     raise in_range(channel, 0, 16) or channel is None or AssertionError
     raise in_range(identifier, 0, 128) or identifier is None or AssertionError
     raise msg_type != MIDI_SYSEX_TYPE or channel == None or AssertionError
     raise msg_type != MIDI_SYSEX_TYPE or identifier == None or AssertionError
     raise msg_type == MIDI_SYSEX_TYPE or sysex_identifier == None or AssertionError
     super(InputControlElement, self).__init__(*a, **k)
     self._request_rebuild = request_rebuild_midi_map
     self._msg_type = msg_type
     self._msg_channel = channel
     self._msg_identifier = identifier
     self._msg_sysex_identifier = sysex_identifier
     self._original_channel = channel
     self._original_identifier = identifier
     self._needs_takeover = True
     self._is_mapped = True
     self._is_being_forwarded = True
     self._delayed_messages = []
     self._force_next_send = False
     self._mapping_feedback_delay = 0
     self._mapping_sensitivity = 1.0
     self._send_delayed_messages_task = self._tasks.add(Task.run(self._send_delayed_messages))
     self._send_delayed_messages_task.kill()
     self._parameter_to_map_to = None
     self._in_parameter_gesture = False
     self._last_sent_message = None
     self._report_input = False
     self._report_output = False
Пример #7
0
 def send_value(self, column, row, value, force = False):
     if not in_range(value, 0, 128):
         raise AssertionError
         raise in_range(column, 0, self.width()) or AssertionError
         if not in_range(row, 0, self.height()):
             raise AssertionError
             button = len(self._buttons[row]) > column and self._buttons[row][column]
             button and button.send_value(value, force)
 def send_value(self, column, row, value, force = False):
     if not in_range(value, 0, 128):
         raise AssertionError
         raise in_range(column, 0, self.width()) or AssertionError
         if not in_range(row, 0, self.height()):
             raise AssertionError
             button = len(self._buttons[row]) > column and self._buttons[row][column]
             button and button.send_value(value, force=force)
    def suggest_needs_takeover(self, cc_no, channel):
        """ Live -> Script: Live can ask whether a given CC needs takeover """
        raise in_range(cc_no, 0, 128) or AssertionError
        raise in_range(channel, 0, 16) or AssertionError
        needs_takeover = True
        for control in self._controls:
            if isinstance(control, InputControlElement) and control.message_type() == MIDI_CC_TYPE and control.message_identifier() == cc_no and control.message_channel() == channel:
                needs_takeover = control.needs_takeover()
                break

        return needs_takeover
    def suggest_needs_takeover(self, cc_no, channel):
        """ Live -> Script: Live can ask whether a given CC needs takeover """
        raise in_range(cc_no, 0, 128) or AssertionError
        raise in_range(channel, 0, 16) or AssertionError
        needs_takeover = True
        for control in self._controls:
            if isinstance(control, InputControlElement) and control.message_type() == MIDI_CC_TYPE and control.message_identifier() == cc_no and control.message_channel() == channel:
                needs_takeover = control.needs_takeover()
                break

        return needs_takeover
    def suggest_map_mode(self, cc_no, channel):
        """ Live -> Script: Live can ask for a suitable mapping mode
        for a given CC"""
        raise in_range(cc_no, 0, 128) or AssertionError
        raise in_range(channel, 0, 16) or AssertionError
        suggested_map_mode = -1
        for control in self.controls:
            if isinstance(control, InputControlElement) and control.message_type() == MIDI_CC_TYPE and control.message_identifier() == cc_no and control.message_channel() == channel:
                suggested_map_mode = control.message_map_mode()
                break

        return suggested_map_mode
    def suggest_map_mode(self, cc_no, channel):
        """ Live -> Script: Live can ask for a suitable mapping mode
        for a given CC"""
        raise in_range(cc_no, 0, 128) or AssertionError
        raise in_range(channel, 0, 16) or AssertionError
        suggested_map_mode = -1
        for control in self.controls:
            if isinstance(control, InputControlElement) and control.message_type() == MIDI_CC_TYPE and control.message_identifier() == cc_no and control.message_channel() == channel:
                suggested_map_mode = control.message_map_mode()
                break

        return suggested_map_mode
 def _tempo_fine_value(self, value):
     if self.is_enabled():
         if self._fine_tempo_needs_pickup:
             if in_range(self._prior_fine_tempo_value, 0, 128):
                 range_max = max(value, self._prior_fine_tempo_value)
                 range_min = min(value, self._prior_fine_tempo_value)
                 if in_range(64, range_min, range_max + 1):
                     self._fine_tempo_needs_pickup = False
         else:
             raise in_range(self._prior_fine_tempo_value, 0, 128) or AssertionError
             difference = value - self._prior_fine_tempo_value
             ratio = 127.0 / TEMPO_FINE_RANGE
             new_tempo = clamp(self.song().tempo + difference / ratio, TEMPO_BOTTOM, TEMPO_TOP)
             self.song().tempo = new_tempo
     self._prior_fine_tempo_value = value
Пример #14
0
 def _tempo_fine_value(self, value):
     if self.is_enabled():
         if self._fine_tempo_needs_pickup:
             if in_range(self._prior_fine_tempo_value, 0, 128):
                 range_max = max(value, self._prior_fine_tempo_value)
                 range_min = min(value, self._prior_fine_tempo_value)
                 if in_range(64, range_min, range_max + 1):
                     self._fine_tempo_needs_pickup = False
         else:
             raise in_range(self._prior_fine_tempo_value, 0, 128) or AssertionError
             difference = value - self._prior_fine_tempo_value
             ratio = 127.0 / TEMPO_FINE_RANGE
             new_tempo = clamp(self.song().tempo + difference / ratio, TEMPO_BOTTOM, TEMPO_TOP)
             self.song().tempo = new_tempo
     self._prior_fine_tempo_value = value
 def _on_stop_track_value(self, value, sender):
     if self.is_enabled():
         if value is not 0 or not sender.is_momentary():
             tracks = self.tracks_to_use()
             track_index = list(self._stop_track_clip_buttons).index(sender) + self.track_offset()
             if in_range(track_index, 0, len(tracks)) and tracks[track_index] in self.song().tracks:
                 tracks[track_index].stop_all_clips()
 def _on_stop_track_value(self, value, sender):
     if self.is_enabled():
         if value is not 0 or not sender.is_momentary():
             tracks = self.tracks_to_use()
             track_index = list(self._stop_track_clip_buttons).index(sender) + self.track_offset()
             if in_range(track_index, 0, len(tracks)) and tracks[track_index] in self.song().tracks:
                 tracks[track_index].stop_all_clips()
 def set_identifier(self, identifier):
     if not self._msg_type != MIDI_SYSEX_TYPE:
         raise AssertionError
         raise in_range(identifier, 0,
                        128) or identifier == None or AssertionError
         self._msg_identifier = self._msg_identifier != identifier and identifier
         self._request_rebuild()
Пример #18
0
 def set_channel(self, channel):
     if not self._msg_type != MIDI_SYSEX_TYPE:
         raise AssertionError
         raise in_range(channel, 0, 16) or channel == None or AssertionError
         self._msg_channel = self._msg_channel != channel and channel
         self._request_rebuild()
     return
 def set_identifier(self, identifier):
     if not self._msg_type != MIDI_SYSEX_TYPE:
         raise AssertionError
         raise in_range(identifier, 0, 128) or identifier == None or AssertionError
         self._msg_identifier = self._msg_identifier != identifier and identifier
         self._request_rebuild()
     return
 def set_num_segments(self, num_segments):
     width = self._width
     if not in_range(num_segments, 1, width) or width % num_segments != 0:
         raise DisplaySegmentationError, 'Can not split display of size %d into %d segments' % (self.width, num_segments)
     if num_segments != len(self._logical_segments):
         self._disconnect_segments()
         self._width_per_segment = width / num_segments
         self._logical_segments = [ LogicalDisplaySegment(self._width_per_segment, self.update) for _ in xrange(num_segments) ]
Пример #21
0
 def set_num_segments(self, num_segments):
     width = self._width
     if not in_range(num_segments, 1, width) or width % num_segments != 0:
         raise DisplaySegmentationError, 'Can not split display of size %d into %d segments' % (self.width, num_segments)
     if num_segments != len(self._logical_segments):
         self._disconnect_segments()
         self._width_per_segment = width / num_segments
         self._logical_segments = [ LogicalDisplaySegment(self._width_per_segment, self.update) for _ in xrange(num_segments) ]
    def update(self):
        super(SessionZoomingComponent, self).update()
        if self._allow_updates:
            self._session_set_enabled(not self._is_zoomed_out)
            if self.is_enabled():
                if self._is_zoomed_out and self._buttons != None:
                    tracks = self._session.tracks_to_use()
                    scenes = self.song().scenes
                    slots_registry = [None for index in range(len(scenes))]
                    width = self._session.width()
                    height = self._session.height()
                    for x in range(self._buttons.width()):
                        for y in range(self._buttons.height()):
                            value_to_send = self._empty_value
                            scene_bank_offset = self._scene_bank_index * self._buttons.height() * height
                            track_offset = x * width
                            scene_offset = y * height + scene_bank_offset
                            if track_offset in range(len(tracks)) and scene_offset in range(len(scenes)):
                                value_to_send = self._stopped_value
                                if self._session.track_offset() in range(
                                    width * (x - 1) + 1, width * (x + 1)
                                ) and self._session.scene_offset() - scene_bank_offset in range(
                                    height * (y - 1) + 1, height * (y + 1)
                                ):
                                    value_to_send = self._selected_value
                                else:
                                    playing = False
                                    for track in range(track_offset, track_offset + width):
                                        for scene in range(scene_offset, scene_offset + height):
                                            if track in range(len(tracks)) and scene in range(len(scenes)):
                                                if slots_registry[scene] == None:
                                                    slots_registry[scene] = scenes[scene].clip_slots
                                                slot = (
                                                    slots_registry[scene][track]
                                                    if len(slots_registry[scene]) > track
                                                    else None
                                                )
                                                if slot != None and slot.has_clip and slot.clip.is_playing:
                                                    value_to_send = self._playing_value
                                                    playing = True
                                                    break

                                        if playing:
                                            break

                            if in_range(value_to_send, 0, 128):
                                self._buttons.send_value(x, y, value_to_send)
                            else:
                                self._buttons.set_light(x, y, value_to_send)

                if self._scene_bank_buttons != None:
                    for index, button in enumerate(self._scene_bank_buttons):
                        if button:
                            button.set_light(self._is_zoomed_out and index == self._scene_bank_index)

        else:
            self._update_requests += 1
        return
 def set_num_segments(self, num_segments, use_delimiters = True):
     if not in_range(num_segments, 1, self._width - num_segments + 1):
         raise AssertionError
         if num_segments != len(self._logical_segments):
             self._disconnect_segments()
             width_without_delimiters = use_delimiters and self._width - num_segments + 1
         else:
             width_without_delimiters = self._width
         width_per_segment = int(width_without_delimiters / num_segments)
         self._logical_segments = [ LogicalDisplaySegment(width_per_segment, self.update) for _ in xrange(num_segments) ]
 def set_num_segments(self, num_segments, use_delimiters=True):
     if not in_range(num_segments, 1, self._width - num_segments + 1):
         raise AssertionError
         if num_segments != len(self._logical_segments):
             self._disconnect_segments()
             width_without_delimiters = use_delimiters and self._width - num_segments + 1
         else:
             width_without_delimiters = self._width
         width_per_segment = int(width_without_delimiters / num_segments)
         self._logical_segments = [
             LogicalDisplaySegment(width_per_segment, self.update)
             for _ in xrange(num_segments)
         ]
Пример #25
0
    def _update_matrix_buttons(self):
        if self._buttons != None:
            tracks = self._session.tracks_to_use()
            scenes = self.song().scenes
            slots_registry = [None for index in xrange(len(scenes))]
            width = self._session.width()
            height = self._session.height()
            for x in xrange(self._buttons.width()):
                for y in xrange(self._buttons.height()):
                    value_to_send = self._empty_value
                    scene_bank_offset = self._scene_bank_index * self._buttons.height(
                    ) * height
                    track_offset = x * width
                    scene_offset = y * height + scene_bank_offset
                    if track_offset in xrange(
                            len(tracks)) and scene_offset in xrange(
                                len(scenes)):
                        value_to_send = self._stopped_value
                        if self._session.track_offset() in xrange(
                                width * (x - 1) + 1, width *
                            (x + 1)) and self._session.scene_offset(
                            ) - scene_bank_offset in xrange(
                                height * (y - 1) + 1, height * (y + 1)):
                            value_to_send = self._selected_value
                        else:
                            playing = False
                            for track in xrange(track_offset,
                                                track_offset + width):
                                for scene in xrange(scene_offset,
                                                    scene_offset + height):
                                    if track in xrange(
                                            len(tracks)) and scene in xrange(
                                                len(scenes)):
                                        if slots_registry[scene] == None:
                                            slots_registry[scene] = scenes[
                                                scene].clip_slots
                                        slot = slots_registry[scene][
                                            track] if len(slots_registry[scene]
                                                          ) > track else None
                                        if slot != None and slot.has_clip and slot.clip.is_playing:
                                            value_to_send = self._playing_value
                                            playing = True
                                            break

                                if playing:
                                    break

                    if in_range(value_to_send, 0, 128):
                        self._buttons.send_value(x, y, value_to_send)
                    else:
                        self._buttons.set_light(x, y, value_to_send)
 def update(self):
     self._has_fired_slot = False
     button = self._launch_button_value.subject
     if self._allow_updates:
         if self.is_enabled() and button != None:
             value_to_send = self._feedback_value()
             if value_to_send in (None, -1):
                 button.turn_off()
             elif in_range(value_to_send, 0, 128):
                 button.send_value(value_to_send)
             else:
                 button.set_light(value_to_send)
     else:
         self._update_requests += 1
    def update(self):
        super(SessionZoomingComponent, self).update()
        if self._allow_updates:
            self._session_set_enabled(not self._is_zoomed_out)
            if self.is_enabled():
                if self._is_zoomed_out and self._buttons != None:
                    tracks = self._session.tracks_to_use()
                    scenes = self.song().scenes
                    slots_registry = [ None for index in range(len(scenes)) ]
                    width = self._session.width()
                    height = self._session.height()
                    for x in range(self._buttons.width()):
                        for y in range(self._buttons.height()):
                            value_to_send = self._empty_value
                            scene_bank_offset = self._scene_bank_index * self._buttons.height() * height
                            track_offset = x * width
                            scene_offset = y * height + scene_bank_offset
                            if track_offset in range(len(tracks)) and scene_offset in range(len(scenes)):
                                value_to_send = self._stopped_value
                                if self._session.track_offset() in range(width * (x - 1) + 1, width * (x + 1)) and self._session.scene_offset() - scene_bank_offset in range(height * (y - 1) + 1, height * (y + 1)):
                                    value_to_send = self._selected_value
                                else:
                                    playing = False
                                    for track in range(track_offset, track_offset + width):
                                        for scene in range(scene_offset, scene_offset + height):
                                            if track in range(len(tracks)) and scene in range(len(scenes)):
                                                if slots_registry[scene] == None:
                                                    slots_registry[scene] = scenes[scene].clip_slots
                                                slot = slots_registry[scene][track] if len(slots_registry[scene]) > track else None
                                                if slot != None and slot.has_clip and slot.clip.is_playing:
                                                    value_to_send = self._playing_value
                                                    playing = True
                                                    break

                                        if playing:
                                            break

                            if in_range(value_to_send, 0, 128):
                                self._buttons.send_value(x, y, value_to_send)
                            else:
                                self._buttons.set_light(x, y, value_to_send)

                if self._scene_bank_buttons != None:
                    for index, button in enumerate(self._scene_bank_buttons):
                        if button:
                            button.set_light(self._is_zoomed_out and index == self._scene_bank_index)

        else:
            self._update_requests += 1
        return
 def update(self):
     self._has_fired_slot = False
     button = self._launch_button_value.subject
     if self._allow_updates:
         if self.is_enabled() and button != None:
             value_to_send = self._feedback_value()
             if value_to_send in (None, -1):
                 button.turn_off()
             elif in_range(value_to_send, 0, 128):
                 button.send_value(value_to_send)
             else:
                 button.set_light(value_to_send)
     else:
         self._update_requests += 1
Пример #29
0
 def _update_launch_button(self):
     if self.is_enabled() and self._launch_button != None:
         value_to_send = self._no_scene_value
         if self._scene:
             if self._scene.is_triggered:
                 value_to_send = self._triggered_value
             elif self._scene_value is not None:
                 value_to_send = self._scene_value
             else:
                 value_to_send = self._color_value(self._scene.color)
         if value_to_send is None:
             self._launch_button.turn_off()
         elif in_range(value_to_send, 0, 128):
             self._launch_button.send_value(value_to_send)
         else:
             self._launch_button.set_light(value_to_send)
 def _update_stop_clips_led(self, index):
     tracks_to_use = self.tracks_to_use()
     track_index = index + self.track_offset()
     button = self.is_enabled() and self._stop_track_clip_buttons != None and index < len(self._stop_track_clip_buttons) and self._stop_track_clip_buttons[index]
     if button != None:
         value_to_send = None
         if track_index < len(tracks_to_use):
             if tracks_to_use[track_index].clip_slots:
                 track = tracks_to_use[track_index]
                 if track.fired_slot_index == -2:
                     value_to_send = self._stop_clip_triggered_value
                 elif track.playing_slot_index >= 0:
                     value_to_send = self._stop_clip_value
             if value_to_send == None:
                 button.turn_off()
             elif in_range(value_to_send, 0, 128):
                 button.send_value(value_to_send)
             else:
                 button.set_light(value_to_send)
 def _update_stop_clips_led(self, index):
     tracks_to_use = self.tracks_to_use()
     track_index = index + self.track_offset()
     button = self.is_enabled(
     ) and self._stop_track_clip_buttons != None and index < len(
         self._stop_track_clip_buttons
     ) and self._stop_track_clip_buttons[index]
     if button != None:
         value_to_send = None
         if track_index < len(tracks_to_use):
             if tracks_to_use[track_index].clip_slots:
                 track = tracks_to_use[track_index]
                 if track.fired_slot_index == -2:
                     value_to_send = self._stop_clip_triggered_value
                 elif track.playing_slot_index >= 0:
                     value_to_send = self._stop_clip_value
             if value_to_send == None:
                 button.turn_off()
             elif in_range(value_to_send, 0, 128):
                 button.send_value(value_to_send)
             else:
                 button.set_light(value_to_send)
    def _update_matrix_buttons(self):
        if self._buttons != None:
            tracks = self._session.tracks_to_use()
            scenes = self.song().scenes
            slots_registry = [ None for index in xrange(len(scenes)) ]
            width = self._session.width()
            height = self._session.height()
            for x in xrange(self._buttons.width()):
                for y in xrange(self._buttons.height()):
                    value_to_send = self._empty_value
                    scene_bank_offset = self._scene_bank_index * self._buttons.height() * height
                    track_offset = x * width
                    scene_offset = y * height + scene_bank_offset
                    if track_offset in xrange(len(tracks)) and scene_offset in xrange(len(scenes)):
                        value_to_send = self._stopped_value
                        if self._session.track_offset() in xrange(width * (x - 1) + 1, width * (x + 1)) and self._session.scene_offset() - scene_bank_offset in xrange(height * (y - 1) + 1, height * (y + 1)):
                            value_to_send = self._selected_value
                        else:
                            playing = False
                            for track in xrange(track_offset, track_offset + width):
                                for scene in xrange(scene_offset, scene_offset + height):
                                    if track in xrange(len(tracks)) and scene in xrange(len(scenes)):
                                        if slots_registry[scene] == None:
                                            slots_registry[scene] = scenes[scene].clip_slots
                                        slot = slots_registry[scene][track] if len(slots_registry[scene]) > track else None
                                        if slot != None and slot.has_clip and slot.clip.is_playing:
                                            value_to_send = self._playing_value
                                            playing = True
                                            break

                                if playing:
                                    break

                    if in_range(value_to_send, 0, 128):
                        self._buttons.send_value(x, y, value_to_send)
                    else:
                        self._buttons.set_light(x, y, value_to_send)
 def get_button(self, column, row):
     if not in_range(column, 0, self.width()):
         raise AssertionError
         raise in_range(row, 0, self.height()) or AssertionError
         return len(self._buttons[row]) > column and self._buttons[row][column]
Пример #34
0
 def set_stopped_value(self, value):
     raise in_range(value, -1, 128) or AssertionError
     self._stopped_value = value
     self._clip_palette = []
 def set_triggered_value(self, value):
     value = int(value)
     raise in_range(value, 0, 128) or AssertionError
     self._triggered_value = value
 def set_triggered_value(self, value):
     value = int(value)
     raise in_range(value, 0, 128) or AssertionError
     self._triggered_value = value
Пример #37
0
 def _verify_value(self, value):
     upper_bound = self._msg_type < MIDI_SYSEX_TYPE and (16384 if self._msg_type == MIDI_PB_TYPE else 128)
     if not in_range(value, 0, upper_bound):
         raise AssertionError
 def scene(self, index):
     raise in_range(index, 0, len(self._scenes)) or AssertionError
     return self._scenes[index]
Пример #39
0
 def get_button(self, column, row):
     if not in_range(column, 0, self.width()):
         raise AssertionError
         raise in_range(row, 0, self.height()) or AssertionError
         return len(self._buttons[row]) > column and self._buttons[row][column]
Пример #40
0
 def _do_get_item(self, index):
     raise in_range(index, 0, len(self)) or AssertionError, 'Index out of range'
     row, col = divmod(index, self.width())
     return self.get_button(col, row)
 def set_playing_value(self, value):
     value = int(value)
     raise in_range(value, 0, 128) or AssertionError
     self._playing_value = value
 def set_stop_track_clip_value(self, value):
     raise in_range(value, 0, 128) or AssertionError
     self._stop_track_clip_value = value
Пример #43
0
 def set_playing_value(self, value):
     value = int(value)
     raise in_range(value, 0, 128) or AssertionError
     self._playing_value = value
 def set_stop_track_clip_value(self, value):
     raise in_range(value, 0, 128) or AssertionError
     self._stop_track_clip_value = value
 def _do_get_item(self, index):
     raise in_range(index, 0, len(self)) or AssertionError, 'Index out of range'
     row, col = divmod(index, self.width())
     return self.get_button(col, row)
 def scene(self, index):
     raise in_range(index, 0, len(self._scenes)) or AssertionError
     return self._scenes[index]
 def _verify_value(self, value):
     upper_bound = self._msg_type < MIDI_SYSEX_TYPE and (16384 if self._msg_type == MIDI_PB_TYPE else 128)
     if not in_range(value, 0, upper_bound):
         raise AssertionError