class NoteSetting(SlotManager, Subject): __subject_events__ = ('setting_changed',) attribute_index = -1 def __init__(self, grid_resolution = None, *a, **k): super(NoteSetting, self).__init__(*a, **k) self._encoder = None self._grid_resolution = grid_resolution self.value_source = DisplayDataSource() self.label_source = DisplayDataSource() self.label_source.set_display_string(self.get_label()) def get_label(self): raise NotImplementedError def encoder_value_to_attribute(self, value): raise NotImplementedError def attribute_min_max_to_string(self, min_value, max_value): raise NotImplementedError @property def step_length(self): return self._grid_resolution.step_length if self._grid_resolution else 1.0 def set_encoder(self, encoder): self._encoder = encoder self._on_value.subject = encoder def set_min_max(self, min_max_value): self.value_source.set_display_string(self.attribute_min_max_to_string(min_max_value[0], min_max_value[1]) if min_max_value else '-') @subject_slot('normalized_value') def _on_value(self, value): self.notify_setting_changed(self.attribute_index, self.encoder_value_to_attribute(value))
def __init__(self, mixer_modes, device, encoders, page_buttons): raise isinstance(mixer_modes, EncoderMixerModeSelector) or AssertionError raise isinstance(device, PageableDeviceComponent) or AssertionError raise isinstance(encoders, tuple) or AssertionError raise isinstance(page_buttons, tuple) or AssertionError ModeSelectorComponent.__init__(self) self._mixer_modes = mixer_modes self._device = device self._encoders = encoders self._page_buttons = page_buttons self._peek_button = None self._encoders_display = None self._value_display = None self._device_display = None self._page_displays = None self._device_dummy_source = DisplayDataSource() self._parameter_source = DisplayDataSource() self._device_dummy_source.set_display_string('Mixer') self._clean_value_display_in = -1 self._must_update_encoder_display = False self._register_timer_callback(self._on_timer) identify_sender = True for encoder in self._encoders: encoder.add_value_listener(self._parameter_value, identify_sender) self.set_mode(0)
def __init__(self, grid_resolution = None, *a, **k): super(NoteSetting, self).__init__(*a, **k) self._encoder = None self._grid_resolution = grid_resolution self.value_source = DisplayDataSource() self.label_source = DisplayDataSource() self.label_source.set_display_string(self.get_label())
def __init__(self, num_options=8, num_labels=4, *a, **k): super(OptionsComponent, self).__init__(*a, **k) self._data_sources = [DisplayDataSource() for _ in xrange(num_options)] self._label_data_sources = [ DisplayDataSource() for _ in xrange(num_labels) ] self._select_buttons = None
def __init__(self, display_label = ' ', display_seg_start = 0, *a, **k): super(ValueDisplayComponentBase, self).__init__(*a, **k) self._label_data_source = DisplayDataSource(display_label) self._value_data_source = DisplayDataSource() self._graphic_data_source = DisplayDataSource() self._display_label = display_label self._display_seg_start = display_seg_start
def __init__(self, *a, **k): super(ClipControlComponent, self).__init__(*a, **k) self._clip_param_sources = [DisplayDataSource() for _ in xrange(8)] self._clip_value_sources = [DisplayDataSource() for _ in xrange(8)] self._clip_name_data_sources = [ DisplayDataSource() for _ in xrange(self.num_label_segments) ] self._clip_name_data_sources[0].set_display_string('Clip Selection:') self._no_settings = NoClipSettingsComponent(self._clip_param_sources, self._clip_value_sources) self._midi_clip_settings = MidiClipSettingsComponent( self._clip_param_sources[4:], self._clip_value_sources[4:]) self._midi_clip_settings.set_enabled(False) self._audio_clip_settings = AudioClipSettingsComponent( self._clip_param_sources[4:], self._clip_value_sources[4:]) self._audio_clip_settings.set_enabled(False) self._loop_settings = LoopSettingsComponent( self._clip_param_sources[:4], self._clip_value_sources[:4]) self._loop_settings.set_enabled(False) self._clip_name = ClipNameComponent(self._clip_name_data_sources[1]) self._clip_name.set_enabled(False) self.register_components(self._no_settings, self._loop_settings, self._midi_clip_settings, self._audio_clip_settings, self._clip_name) self.add_mode('no_clip', (self._no_settings, self._clip_name)) self.add_mode( 'midi', (self._loop_settings, self._midi_clip_settings, self._clip_name)) self.add_mode( 'audio', (self._loop_settings, self._audio_clip_settings, self._clip_name)) self.selected_mode = 'no_clip' self._update_clip() self._on_detail_clip_changed.subject = self.song().view
def __init__(self, mixer_modes, device, encoders, page_buttons): raise isinstance(mixer_modes, EncoderMixerModeSelector) or AssertionError raise isinstance(device, PageableDeviceComponent) or AssertionError raise isinstance(encoders, tuple) or AssertionError raise isinstance(page_buttons, tuple) or AssertionError ModeSelectorComponent.__init__(self) self._mixer_modes = mixer_modes self._device = device self._encoders = encoders self._page_buttons = page_buttons self._peek_button = None self._encoders_display = None self._value_display = None self._device_display = None self._page_displays = None self._device_dummy_source = DisplayDataSource() self._parameter_source = DisplayDataSource() self._device_dummy_source.set_display_string('Mixer') self._clean_value_display_in = -1 self._must_update_encoder_display = False self._register_timer_callback(self._on_timer) identify_sender = True for encoder in self._encoders: encoder.add_value_listener(self._parameter_value, identify_sender) self.set_mode(0) return
def __init__(self, *a, **k): super(UserSettingsComponent, self).__init__(*a, **k) self._name_sources = [DisplayDataSource() for _ in xrange(4)] self._value_sources = [DisplayDataSource() for _ in xrange(4)] self._info_source = DisplayDataSource() self._settings = [] self._encoders = []
def _setup_displays(self): self._name_display = PhysicalDisplayElement(12, 1) self._name_display.name = "Name_Display" self._name_display.set_message_parts(SYSEX_START + (21,), (0, 247)) self._name_display.set_clear_all_message(CLEAR_NAME) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source(self._name_display_data_source) self._value_display = NumericalDisplayElement(3, 1) self._value_display.name = "Value_Display" self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247)) self._value_display.set_clear_all_message(CLEAR_VALUE) self._value_display_data_source = DisplayDataSource() self._value_display.segment(0).set_data_source(self._value_display_data_source) self._bank_display = NumericalDisplayElement(3, 1) self._bank_display.name = "Bank_Display" self._bank_display.set_message_parts(SYSEX_START + (19,), (0, 247)) self._bank_display.set_clear_all_message(CLEAR_BANK) self._bank_display_data_source = DisplayDataSource() self._bank_display.segment(0).set_data_source(self._bank_display_data_source) self._pad_display = NumericalDisplayElement(2, 1) self._pad_display.name = "Pad_Display" self._pad_display.set_message_parts(SYSEX_START + (18,), (0, 247)) self._pad_display.set_clear_all_message(CLEAR_PAD) self._pad_display_data_source = DisplayDataSource() self._pad_display.segment(0).set_data_source(self._pad_display_data_source)
def __init__(self, num_options = 8, num_labels = 4, num_display_segments = None, *a, **k): super(OptionsComponent, self).__init__(*a, **k) num_display_segments = num_display_segments or num_options self._label_data_sources = [ DisplayDataSource() for _ in xrange(num_labels) ] self._data_sources = [ DisplayDataSource() for _ in xrange(num_display_segments) ] self._select_buttons = None self._option_names = []
def _add_setting(self, setting): raise len(self._settings) < 8 or AssertionError, 'Cannot show more than 8 settings' self._settings.append(setting) self._update_encoders() self._top_data_sources = [ DisplayDataSource() for _ in xrange(8 - len(self._settings)) ] + [ s.label_source for s in self._settings ] self._bottom_data_sources = [ DisplayDataSource() for _ in xrange(8 - len(self._settings)) ] + [ s.value_source for s in self._settings ] self.register_disconnectable(setting) self.register_slot(setting, self.notify_setting_changed, 'setting_changed')
def __init__(self, parent, *a, **k): super(MonoScaleDisplayComponent, self).__init__(*a, **k) self.num_segments = 4 self._parent = parent self._name_display_line = None self._value_display_line = None self._name_data_sources = [ DisplayDataSource(DISPLAY_NAMES[index]) for index in xrange(4) ] self._value_data_sources = [ DisplayDataSource() for _ in range(self.num_segments) ]
class UserSettingsComponent(ControlSurfaceComponent): """ Component for changing a list of settings """ def __init__(self, *a, **k): super(UserSettingsComponent, self).__init__(*a, **k) self._name_sources = [DisplayDataSource() for _ in xrange(4)] self._value_sources = [DisplayDataSource() for _ in xrange(4)] self._info_source = DisplayDataSource() self._settings = [] self._encoders = [] def set_display_line1(self, display): if display: display.set_data_sources(self._value_sources) def set_display_line2(self, display): if display: display.set_data_sources(self._name_sources) def set_display_line3(self, display): if display: display.reset() def set_display_line4(self, display): if display: display.set_data_sources([self._info_source]) def set_encoders(self, encoders): self._encoders = encoders or [] self._on_encoder_value.replace_subjects(self._encoders[::2], count()) def _set_settings(self, settings): self._settings = settings.values() self._update_display() def _get_settings(self): return self._settings settings = property(_get_settings, _set_settings) def set_info_text(self, info_text): self._info_source.set_display_string(info_text) @subject_slot_group('normalized_value') def _on_encoder_value(self, value, index): if index >= 0 and index < len( self._settings) and self._settings[index].change_relative( value): self._update_display() def _update_display(self): for index, setting in enumerate(self._settings): self._name_sources[index].set_display_string(setting.name) self._value_sources[index].set_display_string(str(setting)) def update(self): super(UserSettingsComponent, self).update() if self.is_enabled(): self._update_display()
class UserSettingsComponent(ControlSurfaceComponent): """ Component for changing a list of settings """ def __init__(self, *a, **k): super(UserSettingsComponent, self).__init__(*a, **k) self._name_sources = [ DisplayDataSource() for _ in xrange(4) ] self._value_sources = [ DisplayDataSource() for _ in xrange(4) ] self._info_source = DisplayDataSource() self._settings = [] self._encoders = [] def set_display_line1(self, display): if display: display.set_data_sources(self._value_sources) def set_display_line2(self, display): if display: display.set_data_sources(self._name_sources) def set_display_line3(self, display): if display: display.reset() def set_display_line4(self, display): if display: display.set_data_sources([self._info_source]) def set_encoders(self, encoders): self._encoders = encoders or [] self._on_encoder_value.replace_subjects(self._encoders[::2], count()) def _set_settings(self, settings): self._settings = settings.values() self._update_display() def _get_settings(self): return self._settings settings = property(_get_settings, _set_settings) def set_info_text(self, info_text): self._info_source.set_display_string(info_text) @subject_slot_group('normalized_value') def _on_encoder_value(self, value, index): if index >= 0 and index < len(self._settings) and self._settings[index].change_relative(value): self._update_display() def _update_display(self): for index, setting in enumerate(self._settings): self._name_sources[index].set_display_string(setting.name) self._value_sources[index].set_display_string(str(setting)) def update(self): super(UserSettingsComponent, self).update() if self.is_enabled(): self._update_display()
def __init__(self, parent, display_strings, value_strings, *a, **k): assert len(display_strings) == len(value_strings) super(MonomodDisplayComponent, self).__init__(*a, **k) self.num_segments = len(display_strings) self._parent = parent self._name_display_line = None self._value_display_line = None self._name_data_sources = [ DisplayDataSource(string) for string in display_strings ] self._value_data_sources = [ DisplayDataSource(string) for string in value_strings ]
def __init__(self, *a, **k): super(PageableDeviceComponent, self).__init__(*a, **k) self._parameter_value_data_source = DisplayDataSource() self._parameter_name_data_sources = [] self._page_name_data_sources = [] self._page_index = [0, 0, 0, 0] for new_index in range(8): self._parameter_name_data_sources.append(DisplayDataSource()) self._page_name_data_sources.append(DisplayDataSource()) self._parameter_name_data_sources[-1].set_display_string(' - ') self._page_name_data_sources[-1].set_display_string(' - ')
def __init__(self, mixer): raise isinstance(mixer, NotifyingMixerComponent) or AssertionError ModeSelectorComponent.__init__(self) self._mixer = mixer self._controls = None self._page_names = ('Vol', 'Pan', 'SendA', 'SendB', 'SendC') self._page_name_sources = None self._current_page_data_source = DisplayDataSource() self._parameter_sources = [DisplayDataSource() for index in range(8)] self._show_volume_page = False self._mixer.set_update_callback(self._mixer_assignments_changed)
class ValueDisplayComponentBase(ControlSurfaceComponent): def __init__(self, display_label = ' ', display_seg_start = 0, *a, **k): super(ValueDisplayComponentBase, self).__init__(*a, **k) self._label_data_source = DisplayDataSource(display_label) self._value_data_source = DisplayDataSource() self._graphic_data_source = DisplayDataSource() self._display_label = display_label self._display_seg_start = display_seg_start def get_value_string(self): raise NotImplementedError def get_graphic_string(self): raise NotImplementedError def set_label_display(self, display): self._set_display(display, self._label_data_source) def set_value_display(self, display): self._set_display(display, self._value_data_source) def set_graphic_display(self, display): self._set_display(display, self._graphic_data_source) def set_clear_display1(self, display): self._clear_display(display) def set_clear_display2(self, display): self._clear_display(display) def set_clear_display3(self, display): self._clear_display(display) def set_clear_display4(self, display): self._clear_display(display) def _set_display(self, display, source): if display: display.set_data_sources((None,) * NUM_SEGMENTS) display.segment(self._display_seg_start).set_data_source(source) return None def _clear_display(self, display): if display: display.set_data_sources((None,)) display.reset() return None def update(self): super(ValueDisplayComponentBase, self).update() if self.is_enabled(): self._value_data_source.set_display_string(self.get_value_string()) self._graphic_data_source.set_display_string(self.get_graphic_string())
def __init__(self, grid_resolution = None, *a, **k): super(NoteSettingsComponent, self).__init__(*a, **k) self._top_data_sources = [ DisplayDataSource() for _ in xrange(8) ] self._bottom_data_sources = [ DisplayDataSource() for _ in xrange(8) ] self._info_data_source = DisplayDataSource() self._settings = [] self._encoders = [] self._add_setting(NoteNudgeSetting(grid_resolution=grid_resolution)) self._add_setting(NoteLengthCoarseSetting(grid_resolution=grid_resolution)) self._add_setting(NoteLengthFineSetting(grid_resolution=grid_resolution)) self._add_setting(NoteVelocitySetting(grid_resolution=grid_resolution))
class InfoComponent(BackgroundComponent): """ Component that will show an info text and grab all components that should be unusable. """ def __init__(self, info_text='', *a, **k): super(InfoComponent, self).__init__(*a, **k) self._data_source = DisplayDataSource() self._data_source.set_display_string(info_text) def set_display(self, display): if display: display.set_data_sources([self._data_source])
def __init__(self, *a, **k): super(LoopSettingsComponent, self).__init__(*a, **k) self._clip = None self._name_sources = [DisplayDataSource() for _ in xrange(4)] self._value_sources = [DisplayDataSource() for _ in xrange(4)] self._clip_is_looping = False self._clip_loop_start = None self._clip_loop_end = None self._clip_loop_length = None self._lowest_note_time = 0.0 self._encoder_factor = 4.0 self._shift_button = None
class InfoComponent(BackgroundComponent): """ Component that will show an info text and grab all components that should be unusable. """ def __init__(self, info_text = '', *a, **k): super(InfoComponent, self).__init__(*a, **k) self._data_source = DisplayDataSource() self._data_source.set_display_string(info_text) def set_display(self, display): if display: display.set_data_sources([self._data_source])
def __init__(self): ShiftableDeviceComponent.__init__(self) self._main_lcds = None self._parameter_data_sources = [] for index in range(8): self._parameter_data_sources.append(DisplayDataSource()) self._parameter_data_sources[-1].set_display_string('---') self._device_name_lcd = None # Explicitly NAME the device_name_data_source # This is provided and controlled by DeviceComponent # I only need to assign it to a display self._device_name_data_source = DisplayDataSource() self._param_name_value_toggle = False
def _create_display(self): self._display_line1, self._display_line2 = DisplayElement(16, 1), DisplayElement(16, 1) for index, display_line in enumerate((self._display_line1, self._display_line2)): display_line.set_message_parts(SETUP_MSG_PREFIX + (4, 0, 96), SETUP_MSG_SUFFIX) display_line.segment(0).set_position_identifier((index + 1,)) def adjust_null_terminated_string(string, width): return string.ljust(width, ' ') + '\x00' self._display_line1_data_source, self._display_line2_data_source = DisplayDataSource(adjust_string_fn=adjust_null_terminated_string), DisplayDataSource(adjust_string_fn=adjust_null_terminated_string) self._display_line1.segment(0).set_data_source(self._display_line1_data_source) self._display_line2.segment(0).set_data_source(self._display_line2_data_source) self._display_line1_data_source.set_display_string('KeyLab') self._display_line2_data_source.set_display_string('Ableton Live')
def __init__(self, *a, **k): super(DisplayingDeviceComponent, self).__init__(*a, **k) self._parameter_name_data_sources = [ DisplayDataSource(' ') for _ in xrange(8) ] self._parameter_value_data_sources = [ DisplayDataSource(' ') for _ in xrange(8) ] self._parameter_graphic_data_sources = [ DisplayDataSource(' ') for _ in xrange(8) ] self._blank_data_sources = [DisplayDataSource(' ') for _ in xrange(8)] self._mapped_parameters = [] self._alternating_display = None self._encoder_touch_buttons = []
def __init__(self, *a, **k): super(UserSettingsComponent, self).__init__(*a, **k) self._name_sources = [ DisplayDataSource() for _ in xrange(4) ] self._value_sources = [ DisplayDataSource() for _ in xrange(4) ] self._info_source = DisplayDataSource() self._settings = [] self._encoders = []
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 __init__(self, *a, **k): super(ClipNameComponent, self).__init__(*a, **k) self._clip = None self._name_data_sources = [ DisplayDataSource() for _ in xrange(self.num_label_segments) ] self._name_data_sources[0].set_display_string('Clip Selection:')
def __init__(self, *a, **k): super(SpecialChanStripComponent, self).__init__(*a, **k) self.empty_color = 'Option.Unused' self._invert_mute_feedback = True self._delete_button = None self._duplicate_button = None self._selector_button = None self._track_parameter_name_sources = [ DisplayDataSource(' ') for _ in xrange(14) ] self._track_parameter_data_sources = [ DisplayDataSource(' ') for _ in xrange(14) ] self._track_parameter_graphic_sources = [ DisplayDataSource(' ') for _ in xrange(14) ] self._on_return_tracks_changed.subject = self.song() self._on_selected_track_changed.subject = self.song().view self._fold_task = self._tasks.add(Task.sequence(Task.wait(TRACK_FOLD_DELAY), Task.run(self._do_fold_track))).kill() self._cue_volume_slot = self.register_disconnectable(ParameterSlot()) self._track_state = self.register_disconnectable(TrackArmState()) self._on_arm_state_changed.subject = self._track_state
def _setup_displays(self): self._name_display = PhysicalDisplayElement(12, 1) self._name_display.name = 'Name_Display' self._name_display.set_message_parts(SYSEX_START + (21, ), (0, 247)) self._name_display.set_clear_all_message(CLEAR_NAME) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source( self._name_display_data_source) self._value_display = NumericalDisplayElement(3, 1) self._value_display.name = 'Value_Display' self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247)) self._value_display.set_clear_all_message(CLEAR_VALUE) self._value_display_data_source = DisplayDataSource() self._value_display.segment(0).set_data_source( self._value_display_data_source) self._bank_display = NumericalDisplayElement(3, 1) self._bank_display.name = 'Bank_Display' self._bank_display.set_message_parts(SYSEX_START + (19, ), (0, 247)) self._bank_display.set_clear_all_message(CLEAR_BANK) self._bank_display_data_source = DisplayDataSource() self._bank_display.segment(0).set_data_source( self._bank_display_data_source) self._pad_display = NumericalDisplayElement(2, 1) self._pad_display.name = 'Pad_Display' self._pad_display.set_message_parts(SYSEX_START + (18, ), (0, 247)) self._pad_display.set_clear_all_message(CLEAR_PAD) self._pad_display_data_source = DisplayDataSource() self._pad_display.segment(0).set_data_source( self._pad_display_data_source)
def __init__(self, *a, **k): super(BestBankDeviceComponent, self).__init__(*a, **k) new_banks = {} new_bank_names = {} self._device_banks = DEVICE_DICT self._device_bank_names = BANK_NAME_DICT self._device_best_banks = DEVICE_BOB_DICT for device_name, current_banks in self._device_banks.iteritems(): if len(current_banks) > 1: assert device_name in self._device_best_banks.keys(), b"Could not find best-of-banks for '%s'" % device_name assert device_name in self._device_bank_names.keys(), b"Could not find bank names for '%s'" % device_name current_banks = self._device_best_banks[device_name] + current_banks new_bank_names[device_name] = (BOP_BANK_NAME,) + self._device_bank_names[device_name] new_banks[device_name] = current_banks self._device_banks = new_banks self._device_bank_names = new_bank_names self._bank_name_data_source = DisplayDataSource()
def __init__(self, *a, **k): super(ScrollableListComponent, self).__init__(*a, **k) self._data_sources = [ DisplayDataSource() for _ in range(self.num_segments) ] self._selected_option = None self._offset_index = 0 self._option_names = [] self._select_buttons = [] self._select_button_slots = self.register_slot_manager() self.register_slot(self, self._set_selected_option, 'press_option')
def __init__(self, clip_creator=None, playhead=None, *a, **k): super(NoteEditorComponent, self).__init__(*a, **k) self.loop_steps = False self._selected_page_point = 0 self._page_index = 0 self._clip_creator = clip_creator self._matrix = None self._sequencer_clip = None self._step_colors = ['NoteEditor.StepEmpty'] * STEP_SEQ_SIZE self._note_settings_layer = None self._top_data_sources = map(DisplayDataSource, STEP_PARAM_NAMES) self._bottom_data_sources = [DisplayDataSource() for _ in xrange(8)] self._show_settings_task = self._tasks.add( Task.sequence(Task.wait(Defaults.MOMENTARY_DELAY), Task.run(self._show_settings))) self._show_settings_task.kill() self._mute_button = None self._velocity_offset = 0 self._length_offset = 0 self._nudge_offset = 0 self._attribute_deltas = [None for _ in xrange(3)] self._full_velocity = False self._pressed_steps = [] self._modified_steps = [] self._pressed_step_callback = None self._quantization_buttons = [] self._quantization_button_slots = self.register_slot_manager() self._modify_task = self._tasks.add(Task.run(self._do_modification)) self._modify_task.kill() self._modify_all_notes_enabled = False self._step_tap_tasks = dict([ ((x, y), self._tasks.add( Task.sequence( Task.wait(Defaults.MOMENTARY_DELAY), Task.run( partial(self._trigger_modification, (x, y), done=True))))) for x, y in product(xrange(STEP_SEQ_WIDTH), xrange( STEP_SEQ_HEIGHT)) ]) for task in self._step_tap_tasks.itervalues(): task.kill() self._clip_notes = [] self._note_index = 36 self._triplet_factor = 1.0 self._set_quantization_index(3) self._playhead = playhead self._playhead_notes = range(92, 100) + range(84, 92) + range( 76, 84) + range(68, 76) self._playhead_triplet_notes = range(92, 98) + range(84, 90) + range( 76, 82) + range(68, 74) with self._playhead_update_guard(): self._update_full_playhead()
def __init__(self, mixer): raise isinstance(mixer, NotifyingMixerComponent) or AssertionError ModeSelectorComponent.__init__(self) self._mixer = mixer self._controls = None self._page_names = ('Vol', 'Pan', 'SendA', 'SendB', 'SendC') self._page_name_sources = None self._current_page_data_source = DisplayDataSource() self._parameter_sources = [ DisplayDataSource() for index in range(8) ] self._show_volume_page = False self._mixer.set_update_callback(self._mixer_assignments_changed)
def page_name_data_source(self, index): assert index in range(4) if self._page_name_sources == None: self._page_name_sources = [] offset = 0 if not self._show_volume_page: offset = 1 for idx in range(4): self._page_name_sources.append(DisplayDataSource()) self._page_name_sources[idx].set_display_string(self._page_names[idx + offset]) return self._page_name_sources[index]
def page_name_data_source(self, index): if not index in range(4): raise AssertionError if self._page_name_sources == None: self._page_name_sources = [] offset = 0 offset = self._show_volume_page or 1 for idx in range(4): self._page_name_sources.append(DisplayDataSource()) self._page_name_sources[idx].set_display_string(self._page_names[(idx + offset)]) return self._page_name_sources[index]
def __init__(self): DeviceComponent.__init__(self) self._parameter_value_data_source = DisplayDataSource() self._parameter_name_data_sources = [] self._page_name_data_sources = [] self._page_index = [0, 0, 0, 0] for new_index in range(8): self._parameter_name_data_sources.append(DisplayDataSource()) self._page_name_data_sources.append(DisplayDataSource()) self._parameter_name_data_sources[-1].set_display_string(' - ') self._page_name_data_sources[-1].set_display_string(' - ')
def __init__(self, *a, **k): super(BestBankDeviceComponent, self).__init__(*a, **k) new_banks = {} new_bank_names = {} self._device_banks = DEVICE_DICT self._device_bank_names = BANK_NAME_DICT self._device_best_banks = DEVICE_BOB_DICT for device_name, current_banks in self._device_banks.iteritems(): if len(current_banks) > 1: raise device_name in self._device_best_banks.keys() or AssertionError("Could not find best-of-banks for '%s'" % device_name) raise device_name in self._device_bank_names.keys() or AssertionError("Could not find bank names for '%s'" % device_name) current_banks = self._device_best_banks[device_name] + current_banks new_bank_names[device_name] = (BOP_BANK_NAME,) + self._device_bank_names[device_name] new_banks[device_name] = current_banks self._device_banks = new_banks self._device_bank_names = new_bank_names self._bank_name_data_source = DisplayDataSource()
def __init__(self): DeviceComponent.__init__(self) new_banks = {} new_bank_names = {} self._device_banks = DEVICE_DICT self._device_bank_names = BANK_NAME_DICT self._device_best_banks = DEVICE_BOB_DICT for device_name, current_banks in self._device_banks.iteritems(): raise len(current_banks) > 1 and (device_name in self._device_best_banks.keys() or AssertionError), "Could not find best-of-banks for '%s'" % device_name if not device_name in self._device_bank_names.keys(): raise AssertionError, "Could not find bank names for '%s'" % device_name current_banks = self._device_best_banks[device_name] + current_banks new_bank_names[device_name] = (BOP_BANK_NAME,) + self._device_bank_names[device_name] new_banks[device_name] = current_banks self._device_banks = new_banks self._device_bank_names = new_bank_names self._bank_name_data_source = DisplayDataSource()
class KeyLab(ArturiaControlSurface): def __init__(self, *a, **k): super(KeyLab, self).__init__(*a, **k) with self.component_guard(): self._create_controls() self._create_display() self._create_device() self._create_drums() self._create_transport() self._create_session() self._create_session_recording() self._create_mixer() def _create_controls(self): self._device_encoders = ButtonMatrixElement(rows=[ [ EncoderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier, Live.MidiMap.MapMode.relative_smooth_binary_offset, name='Device_Encoder_%d_%d' % (col_index, row_index)) for col_index, identifier in enumerate(row) ] for row_index, row in enumerate((ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[4:8])) ]) self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, ENCODER_MSG_IDS[-2], Live.MidiMap.MapMode.relative_smooth_binary_offset, name='Horizontal_Scroll_Encoder') self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, ENCODER_MSG_IDS[-1], Live.MidiMap.MapMode.relative_smooth_binary_offset, name='Vertical_Scroll_Encoder') self._volume_sliders = ButtonMatrixElement(rows=[[ SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier) for identifier in SLIDER_MSG_IDS[:-1] ]]) self._master_slider = SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, SLIDER_MSG_IDS[-1]) def make_keylab_button(name): button = ButtonElement(True, MIDI_CC_TYPE, 0, get_button_identifier_by_name(name), name=name.title()) return button for button_name in BUTTON_HARDWARE_AND_MESSAGE_IDS.keys(): setattr(self, '_' + button_name, make_keylab_button(button_name)) self._pads = ButtonMatrixElement(rows=[ [ ButtonElement(True, MIDI_CC_TYPE, PAD_CHANNEL, col_index + row_offset, name='Pad_%d_%d' % (col_index, row_index)) for col_index in xrange(4) ] for row_index, row_offset in enumerate(xrange(48, 35, -4)) ]) def _create_display(self): self._display_line1, self._display_line2 = DisplayElement(16, 1), DisplayElement(16, 1) for index, display_line in enumerate((self._display_line1, self._display_line2)): display_line.set_message_parts(SETUP_MSG_PREFIX + (4, 0, 96), SETUP_MSG_SUFFIX) display_line.segment(0).set_position_identifier((index + 1,)) def adjust_null_terminated_string(string, width): return string.ljust(width, ' ') + '\x00' self._display_line1_data_source, self._display_line2_data_source = DisplayDataSource(adjust_string_fn=adjust_null_terminated_string), DisplayDataSource(adjust_string_fn=adjust_null_terminated_string) self._display_line1.segment(0).set_data_source(self._display_line1_data_source) self._display_line2.segment(0).set_data_source(self._display_line2_data_source) self._display_line1_data_source.set_display_string('KeyLab') self._display_line2_data_source.set_display_string('Ableton Live') def _create_device(self): self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=self._device_encoders)) self._device.set_enabled(True) self.set_device_component(self._device) self._device_selection_follows_track_selection = True self._device_navigation = DeviceNavigationComponent(name='Device_Navigation', is_enabled=False, layer=Layer(device_nav_left_button=self._device_left_button, device_nav_right_button=self._device_right_button)) self._device_navigation.set_enabled(True) def _create_drums(self): self._drums = DrumRackComponent(name='Drums', is_enabled=False, layer=Layer(pads=self._pads)) self._drums.set_enabled(True) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button, loop_button=self._loop_button)) self._transport.set_enabled(True) def _create_session(self): self._session = SessionComponent(num_tracks=8, num_scenes=1, name='Session', is_enabled=False, layer=Layer(select_next_button=self._scene_down_button, select_prev_button=self._scene_up_button, selected_scene_launch_button=self._scene_launch_button, stop_all_clips_button=self._stop_all_clips_button, scene_select_encoder=self._vertical_scroll_encoder)) self._session.set_enabled(True) def _create_session_recording(self): self._session_recording = SessionRecordingComponent(ClipCreator(), ViewControlComponent(), name='Session_Recording', is_enabled=False, layer=Layer(record_button=self._session_record_button)) self._session_recording.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent(num_tracks=self._volume_sliders.width(), name='Mixer', is_enabled=False, layer=Layer(volume_controls=self._volume_sliders, track_select_encoder=self._horizontal_scroll_encoder)) self._mixer.master_strip().layer = Layer(volume_control=self._master_slider) self._mixer.set_enabled(True) def _collect_setup_messages(self): for hardware_id, identifier in izip(ENCODER_HARDWARE_IDS, ENCODER_MSG_IDS): self._setup_hardware_encoder(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in izip(SLIDER_HARDWARE_IDS, SLIDER_MSG_IDS): self._setup_hardware_slider(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in BUTTON_HARDWARE_AND_MESSAGE_IDS.itervalues(): self._setup_hardware_button(hardware_id, identifier) for hardware_id, identifier in izip(PAD_HARDWARE_IDS, PAD_MSG_IDS): self._setup_hardware_pad(hardware_id, identifier) def _setup_hardware_encoder(self, hardware_id, identifier, channel = 0): self._set_encoder_cc_msg_type(hardware_id, is_relative=True) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) def _setup_hardware_button(self, hardware_id, identifier, channel = 0, **k): self._set_encoder_cc_msg_type(hardware_id) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) self._set_value_minimum(hardware_id) self._set_value_maximum(hardware_id) def _setup_hardware_pad(self, hardware_id, identifier, channel = PAD_CHANNEL): self._set_pad_note_msg_type(hardware_id) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) def _set_pad_note_msg_type(self, hardware_id): self._collect_setup_message(MODE_PROPERTY, hardware_id, PAD_NOTE_MODE)
class EncoderMixerModeSelector(ModeSelectorComponent): """ Class that reassigns encoders on the AxiomPro to different mixer functions """ def __init__(self, mixer): raise isinstance(mixer, NotifyingMixerComponent) or AssertionError ModeSelectorComponent.__init__(self) self._mixer = mixer self._controls = None self._page_names = ("Vol", "Pan", "SendA", "SendB", "SendC") self._page_name_sources = None self._current_page_data_source = DisplayDataSource() self._parameter_sources = [DisplayDataSource() for index in range(8)] self._show_volume_page = False self._mixer.set_update_callback(self._mixer_assignments_changed) return def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._mixer = None self._controls = None self._page_names = None self._page_name_sources = None self._current_page_data_source = None self._parameter_sources = None ModeSelectorComponent.disconnect(self) return def set_modes_buttons(self, buttons): raise buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: raise isinstance(button, ButtonElement) or AssertionError self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) self.update() return def set_controls(self, controls): raise controls == None or isinstance(controls, tuple) and len(controls) == 8 or AssertionError self._controls = controls self.set_mode(0) self.update() return def set_show_volume_page(self, show): if not isinstance(show, type(False)): raise AssertionError if show != self._show_volume_page: self._show_volume_page = show if self._page_name_sources != None: offset = 0 offset = self._show_volume_page or 1 for idx in range(4): self._page_name_sources[idx].set_display_string(self._page_names[idx + offset]) self.update() return def page_name_data_source(self, index): if not index in range(4): raise AssertionError if self._page_name_sources == None: self._page_name_sources = [] offset = 0 offset = self._show_volume_page or 1 for idx in range(4): self._page_name_sources.append(DisplayDataSource()) self._page_name_sources[idx].set_display_string(self._page_names[idx + offset]) return self._page_name_sources[index] def parameter_data_source(self, index): raise self._controls != None or AssertionError raise index in range(len(self._controls)) or AssertionError return self._mixer.channel_strip(index).track_name_data_source() def current_page_data_source(self): return self._current_page_data_source def number_of_modes(self): return 4 def update(self): super(EncoderMixerModeSelector, self).update() if not self._modes_buttons != None: raise AssertionError if self.is_enabled() and self._controls != None: mode = self._mode_index self._show_volume_page or mode += 1 self._current_page_data_source.set_display_string(self._page_names[mode]) for index in range(len(self._controls)): self._controls[index].release_parameter() self._mixer.channel_strip(index).track_name_data_source().update() self._mixer.channel_strip(index).set_pan_control(None) self._mixer.channel_strip(index).set_send_controls((None, None, None)) if self._show_volume_page: self._mixer.channel_strip(index).set_volume_control(None) if not (mode == 0 and self._show_volume_page): raise AssertionError self._mixer.channel_strip(index).set_volume_control(self._controls[index]) elif mode == 1: self._mixer.channel_strip(index).set_pan_control(self._controls[index]) elif mode == 2: self._mixer.channel_strip(index).set_send_controls((self._controls[index], None, None)) elif mode == 3: self._mixer.channel_strip(index).set_send_controls((None, self._controls[index], None)) elif not (mode == 4 and not self._show_volume_page): raise AssertionError self._mixer.channel_strip(index).set_send_controls((None, None, self._controls[index])) else: print "Invalid mode index" raise False or AssertionError return def _mixer_assignments_changed(self): self.update()
class PageableDeviceComponent(DeviceComponent): """ Class representing a device on the AxiomPro """ def __init__(self): DeviceComponent.__init__(self) self._parameter_value_data_source = DisplayDataSource() self._parameter_name_data_sources = [] self._page_name_data_sources = [] self._page_index = [0, 0, 0, 0] for new_index in range(8): self._parameter_name_data_sources.append(DisplayDataSource()) self._page_name_data_sources.append(DisplayDataSource()) self._parameter_name_data_sources[-1].set_display_string(' - ') self._page_name_data_sources[-1].set_display_string(' - ') def disconnect(self): self._parameter_value_data_source = None self._parameter_name_data_sources = None self._page_name_data_sources = None DeviceComponent.disconnect(self) def set_device(self, device): DeviceComponent.set_device(self, device) if self._device == None: for source in self._parameter_name_data_sources: source.set_display_string(' - ') for source in self._page_name_data_sources: source.set_display_string(' - ') def set_bank_buttons(self, buttons): raise buttons == None or isinstance(buttons, tuple) and len(buttons) == 4 or AssertionError DeviceComponent.set_bank_buttons(self, buttons) def set_parameter_controls(self, controls): raise controls == None or isinstance(controls, tuple) and len(controls) == 8 or AssertionError if self._parameter_controls != None: for control in self._parameter_controls: if self._device != None: control.release_parameter() self._parameter_controls = controls if self._parameter_controls != None: for control in self._parameter_controls: raise control != None or AssertionError raise isinstance(control, EncoderElement) or AssertionError self.update() def parameter_value_data_source(self): return self._parameter_value_data_source def parameter_name_data_source(self, index): raise index in range(8) or AssertionError return self._parameter_name_data_sources[index] def page_name_data_source(self, index): raise index in range(8) or AssertionError return self._page_name_data_sources[index] def _bank_value(self, value, button): if not self._bank_buttons != None: raise AssertionError raise value != None or AssertionError raise button != None or AssertionError raise isinstance(value, int) or AssertionError raise isinstance(button, ButtonElement) or AssertionError if not list(self._bank_buttons).count(button) == 1: raise AssertionError if self.is_enabled(): if not button.is_momentary() or value is not 0: bank = list(self._bank_buttons).index(button) self._bank_index = self._device != None and bank != self._bank_index and bank else: self._page_index[bank] += 1 self.update() def _assign_parameters(self): if not self.is_enabled(): raise AssertionError raise self._device != None or AssertionError raise self._parameter_controls != None or AssertionError self._device.class_name in SPECIAL_DEVICE_DICT.keys() and self.__assign_parameters_special() elif self._device.class_name in DEVICE_DICT.keys(): self.__assign_parameters_normal() else: self.__assign_parameters_plugin() self._parameter_value_data_source.set_display_string('') for index in range(len(self._parameter_controls)): if self._parameter_controls[index].mapped_parameter() != None: self._parameter_name_data_sources[index].set_display_string(self._parameter_controls[index].mapped_parameter().name) else: self._parameter_name_data_sources[index].set_display_string(' - ') def __assign_parameters_special(self): """ Assign the controls to the parameters of a device with more than 4 pages """ banks = SPECIAL_DEVICE_DICT[self._device.class_name] bank_names = SPECIAL_NAME_DICT[self._device.class_name] pages = banks[self._bank_index] self._page_index[self._bank_index] %= len(pages) self._bank_name = bank_names[self._bank_index][self._page_index[self._bank_index]] page = pages[self._page_index[self._bank_index]] raise len(page) >= len(self._parameter_controls) or AssertionError for index in range(len(self._parameter_controls)): parameter = get_parameter_by_name(self._device, page[index]) if parameter != None: self._parameter_controls[index].connect_to(parameter) else: self._parameter_controls[index].release_parameter() for index in range(len(self._page_name_data_sources)): if index < len(bank_names): page_names = bank_names[index] if index == self._bank_index: self._page_name_data_sources[index].set_display_string(page_names[(self._page_index[index] + 1) % len(page_names)]) else: self._page_name_data_sources[index].set_display_string(page_names[self._page_index[index] % len(page_names)]) else: self._page_name_data_sources[index].set_display_string(' - ') def __assign_parameters_normal(self): """ Assign the controls to the parameters of a device with 4 pages or less """ if not self._device.class_name in DEVICE_BOB_DICT.keys(): raise AssertionError self._page_index[self._bank_index] = 0 banks = DEVICE_DICT[self._device.class_name] bank_names = [] if len(banks) > self._bank_index: if self._device.class_name in BANK_NAME_DICT.keys() and len(BANK_NAME_DICT[self._device.class_name]) > 1: bank_names = BANK_NAME_DICT[self._device.class_name] bank = banks[self._bank_index] self._bank_name = self._bank_index in range(len(bank_names)) and bank_names[self._bank_index] else: self._bank_name = 'Bank ' + str(self._bank_index + 1) raise len(bank) >= len(self._parameter_controls) or AssertionError for index in range(len(self._parameter_controls)): parameter = get_parameter_by_name(self._device, bank[index]) if parameter != None: self._parameter_controls[index].connect_to(parameter) else: self._parameter_controls[index].release_parameter() for index in range(len(self._page_name_data_sources)): if index < len(bank_names): self._page_name_data_sources[index].set_display_string(bank_names[index]) else: self._page_name_data_sources[index].set_display_string(' - ') def __assign_parameters_plugin(self): """ Assign the controls to the parameters of a plugin """ num_controls = len(self._parameter_controls) num_banks = min(8, number_of_parameter_banks(self._device)) num_double_pages = 0 num_double_pages_before = 0 parameters_to_use = self._device.parameters[1:] self._bank_name = 'Bank ' + str(self._bank_index + 1) if num_banks > 4: num_double_pages = num_banks - 4 if self._bank_index < num_double_pages: self._page_index[self._bank_index] %= 2 num_double_pages_before = self._bank_index else: self._page_index[self._bank_index] = 0 num_double_pages_before = num_double_pages if self._bank_index + num_double_pages_before < num_banks: bank_offset = (self._bank_index + num_double_pages_before) * num_controls page_offset = bank_offset + self._page_index[self._bank_index] * num_controls for control in self._parameter_controls: if page_offset < len(parameters_to_use): control.connect_to(parameters_to_use[page_offset]) else: control.release_parameter() page_offset += 1 bank_names = [] parameter_offset = 0 for index in range(4): display_string = ' - ' if index < num_banks: if index < num_double_pages: if not (index == self._bank_index and self._page_index[index] == 0): if index != self._bank_index: add_offset_before = self._page_index[index] != 0 add_offset_before and parameter_offset += num_controls display_string = str(parameter_offset + 1).rjust(2) + '-' + str(parameter_offset + num_controls).rjust(2) add_offset_before or parameter_offset += num_controls else: display_string = str(parameter_offset + 1).rjust(2) + '-' + str(parameter_offset + num_controls).rjust(2) self._page_name_data_sources[index].set_display_string(display_string) parameter_offset += num_controls
def _setup_display(self): self._display = PhysicalDisplayElement(5, 1) self._display.name = "Display" self._display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,)) self._display_data_source = DisplayDataSource() self._display.segment(0).set_data_source(self._display_data_source)
class Axiom_AIR_25_49_61(ControlSurface): """ Script for the M-Audio Axiom A.I.R. 25, 49 and 61 """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._alt_device_component = None with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = "HyperControl" self._suggested_output_port = "HyperControl" self._single_fader_button_modes = None self._has_faders = True self._display_reset_delay = -1 self._hc_byte = HC_BYTE self._waiting_for_first_response = True self._setup_controls() self._setup_displays() self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_modes() self._drum_group_midi_button = None self._drum_group_hyper_button = None for component in self.components: component.set_enabled(False) def disconnect(self): self._scheduled_messages = [] for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) for fader in self._faders: fader.remove_value_listener(self._fader_value) for fader_button in self._fader_buttons: fader_button.remove_value_listener(self._fader_button_value) self._master_fader.remove_value_listener(self._fader_value) self._master_fader_button.remove_value_listener(self._fader_button_value) self._select_button.remove_value_listener(self._select_button_value) self._identify_button.remove_value_listener(self._identify_value) self._fader_group_midi_button.remove_value_listener(self._midi_button_value) self._fader_group_mix_button.remove_value_listener(self._hyper_button_value) self._fader_group_fx_button.remove_value_listener(self._hyper_button_value) self._encoder_group_midi_button.remove_value_listener(self._midi_button_value) self._encoder_group_mix_button.remove_value_listener(self._hyper_button_value) self._encoder_group_fx_button.remove_value_listener(self._hyper_button_value) if self._drum_group_midi_button != None: self._drum_group_midi_button.remove_value_listener(self._midi_button_value) if self._drum_group_hyper_button != None: self._drum_group_hyper_button.remove_value_listener(self._hyper_button_value) self._alt_device_component = None self._name_display = None self._value_display = None self._bank_display = None self._pad_display = None self._name_display_data_source = None self._value_display_data_source = None self._bank_display_data_source = None self._pad_display_data_source = None self._select_button = None self._left_button = None self._right_button = None self._up_button = None self._down_button = None self._loop_button = None self._ffwd_button = None self._rwd_button = None self._play_button = None self._stop_button = None self._rec_button = None self._master_fader_button = None self._fader_buttons = None self._faders = None self._encoders = None self._drum_pads = None self._identify_button = None self._main_group_hyper_button = None self._main_group_track_button = None self._main_group_fx_button = None self._encoder_group_midi_button = None self._encoder_group_mix_button = None self._encoder_group_fx_button = None self._fader_group_mode_button = None self._fader_group_midi_button = None self._fader_group_mix_button = None self._fader_group_fx_button = None self._drum_group_midi_button = None self._drum_group_roll_button = None self._drum_group_hyper_button = None self._mixer_for_encoders = None self._mixer_for_faders = None self._device_for_encoders = None self._device_for_faders = None self._transport = None self._session = None ControlSurface.disconnect(self) self._send_midi(SYSEX_START + DISABLE_HYPERCONTROL) def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._send_midi, IDENTITY_REQUEST) def handle_sysex(self, midi_bytes): if midi_bytes[0:10] == AXIOM_AIR_RESPONSE: if midi_bytes[12:15] < AXIOM_REV4_RESPONSE: self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL) self.schedule_message(2, self._send_midi, SYSEX_START + CLEAR_ALL) self.schedule_message(3, self._name_display.display_message, "Firmware") self.schedule_message(13, self._name_display.display_message, "Update") self.schedule_message(23, self._name_display.display_message, "Required") self.schedule_message(33, self._send_midi, SYSEX_START + DISABLE_HYPERCONTROL) elif midi_bytes[12:15] >= AXIOM_REV4_RESPONSE: if self._waiting_for_first_response == True: self._waiting_for_first_response = False self._has_faders = midi_bytes[10] != 50 self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL) self.schedule_message(2, self._send_midi, SYSEX_START + SPECIAL_HYPERCONTROL) self.schedule_message(3, self._complete_setup) else: self._display_reset_delay = 0 elif midi_bytes[0:8] == REQUEST_HYPERCONTROL: self.schedule_message(5, self._send_midi, IDENTITY_REQUEST) def update_display(self): ControlSurface.update_display(self) if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._set_displays_to_default() def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._display_reset_delay = 0 def restore_bank(self, bank_index): ControlSurface.restore_bank(self, bank_index) if self._alt_device_component != None: self._alt_device_component.restore_bank(bank_index) def set_appointed_device(self, device): ControlSurface.set_appointed_device(self, device) with self.component_guard(): if self._alt_device_component != None: self._alt_device_component.set_device(device) def set_alt_device_component(self, device_component): self._alt_device_component = device_component def _update_device_selection(self): track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) if self._alt_device_component != None: self._alt_device_component.set_device(device_to_select) def _setup_controls(self): self._left_button = create_button(99, "Left_Button") self._right_button = create_button(100, "Right_Button") self._up_button = create_button(101, "Up_Button") self._down_button = create_button(102, "Down_Button") self._loop_button = create_button(113, "Loop_Button") self._rwd_button = create_button(114, "Rwd_Button") self._ffwd_button = create_button(115, "FFwd_Button") self._stop_button = create_button(116, "Stop_Button") self._play_button = create_button(117, "Play_Button") self._rec_button = create_button(118, "Record_Button") self._select_button = ConfigurableButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, GLOBAL_CHANNEL, 98) self._select_button.name = "Select_Button" self._select_button.add_value_listener(self._select_button_value) self._main_group_hyper_button = create_configurable_button(104, "Fader_Group_HyperControl_Button", 2, 14) self._main_group_track_button = create_configurable_button(105, "Main_Group_Track_Button", 2, 11) self._main_group_fx_button = create_configurable_button(106, "Main_Group_Inst_FX_Button", 2, 11) self._identify_button = create_configurable_button(97, "Identify_Button", 2, 16) self._identify_button.add_value_listener(self._identify_value) self._fader_buttons = [] for index in range(8): self._fader_buttons.append(create_configurable_button(49 + index, "Fader_Button_%d" % index)) self._fader_buttons[-1].add_value_listener(self._fader_button_value, identify_sender=True) self._faders = [] for index in range(8): self._faders.append(create_slider(33 + index, "Fader_%d" % index)) self._faders[-1].add_value_listener(self._fader_value, identify_sender=True) self._master_fader_button = create_configurable_button(57, "Master_Fader_Button") self._master_fader_button.add_value_listener(self._fader_button_value, identify_sender=True) self._master_fader = create_slider(41, "Master_Fader") self._master_fader.add_value_listener(self._fader_value, identify_sender=True) self._fader_group_mode_button = create_configurable_button(61, "Fader_Group_Mode_Button") self._fader_group_midi_button = create_configurable_button(60, "Fader_Group_MIDI_Button") self._fader_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True) self._fader_group_mix_button = create_configurable_button(58, "Fader_Group_Mix_Button", 0, 1) self._fader_group_mix_button.add_value_listener(self._hyper_button_value, identify_sender=True) self._fader_group_fx_button = create_configurable_button(59, "Fader_Group_Inst_FX_Button", 0, -1) self._fader_group_fx_button.add_value_listener(self._hyper_button_value, identify_sender=True) self._encoders = [] for index in range(8): self._encoders.append(create_encoder(17 + index, "Encoder_%d" % index)) self._encoders[-1].add_value_listener(self._encoder_value, identify_sender=True) self._encoder_group_midi_button = create_configurable_button(27, "Encoder_Group_MIDI_Button", 0, 72) self._encoder_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True) self._encoder_group_mix_button = create_configurable_button(25, "Encoder_Group_Mix_Button", 0, 72) self._encoder_group_mix_button.add_value_listener(self._hyper_button_value, identify_sender=True) self._encoder_group_fx_button = create_configurable_button(26, "Encoder_Group_Inst_FX_Button", 0, 72) self._encoder_group_fx_button.add_value_listener(self._hyper_button_value, identify_sender=True) def _setup_drum_pads(self): self._drum_pads = [] num_pads = 12 if self._has_faders else 16 for index in range(8): self._drum_pads.append(create_configurable_button(81 + index, "Pad_%d" % index, 0, 0, MIDI_CC_TYPE)) for index in range(num_pads - 8): self._drum_pads.append( ConfigurableButtonElement( IS_MOMENTARY, MIDI_NOTE_TYPE, GLOBAL_CHANNEL - 1, 81 + index, GLOBAL_SEND_CHANNEL, 8, MIDI_CC_TYPE ) ) self._drum_pads[-1].name = "Pad_" + str(index + 8) self._drum_group_midi_button = create_configurable_button(91, "Drum_Group_MIDI_Button", 2, -2) self._drum_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True) self._drum_group_roll_button = create_configurable_button(90, "Drum_Group_Roll_Button", -1) self._drum_group_hyper_button = create_configurable_button(89, "Drum_Group_HyperControl_Button", 2, 2) self._drum_group_hyper_button.add_value_listener(self._hyper_button_value, identify_sender=True) def _setup_displays(self): self._name_display = PhysicalDisplayElement(12, 1) self._name_display.name = "Name_Display" self._name_display.set_message_parts(SYSEX_START + (21,), (0, 247)) self._name_display.set_clear_all_message(CLEAR_NAME) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source(self._name_display_data_source) self._value_display = NumericalDisplayElement(3, 1) self._value_display.name = "Value_Display" self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247)) self._value_display.set_clear_all_message(CLEAR_VALUE) self._value_display_data_source = DisplayDataSource() self._value_display.segment(0).set_data_source(self._value_display_data_source) self._bank_display = NumericalDisplayElement(3, 1) self._bank_display.name = "Bank_Display" self._bank_display.set_message_parts(SYSEX_START + (19,), (0, 247)) self._bank_display.set_clear_all_message(CLEAR_BANK) self._bank_display_data_source = DisplayDataSource() self._bank_display.segment(0).set_data_source(self._bank_display_data_source) self._pad_display = NumericalDisplayElement(2, 1) self._pad_display.name = "Pad_Display" self._pad_display.set_message_parts(SYSEX_START + (18,), (0, 247)) self._pad_display.set_clear_all_message(CLEAR_PAD) self._pad_display_data_source = DisplayDataSource() self._pad_display.segment(0).set_data_source(self._pad_display_data_source) def _setup_mixer(self): self._mixer_for_encoders = SpecialMixerComponent(self._name_display, self._value_display, 8) self._mixer_for_encoders.name = "Mixer_for_encoders" self._mixer_for_faders = SpecialMixerComponent(self._name_display, self._value_display, 8) self._mixer_for_faders.name = "Mixer_for_faders" def _setup_session(self): self._session = SpecialSessionComponent(8, 0) self._session.name = "Session_Control" self._session.selected_scene().name = "Selected_Scene" self._session.set_mixer(self._mixer_for_encoders) self._session.set_alt_mixer(self._mixer_for_faders) self._session.add_offset_listener(self._update_bank_value) def _setup_transport(self): self._transport = TransportComponent() self._transport.name = "Transport" self._transport.set_stop_button(self._stop_button) self._transport.set_play_button(self._play_button) self._transport.set_record_button(self._rec_button) transport_view_modes = TransportViewModeSelector( self._transport, self._session, self._ffwd_button, self._rwd_button, self._loop_button ) transport_view_modes.name = "Transport_View_Modes" def _setup_device(self): self._device_for_encoders = BestBankDeviceComponent() self._device_for_encoders.name = "Device_Component_for_encoders" self._device_for_faders = BestBankDeviceComponent() self._device_for_faders.name = "Device_Component_for_faders" self.set_device_component(self._device_for_encoders) self.set_alt_device_component(self._device_for_faders) self._device_nav = DeviceNavComponent() self._device_nav.name = "Device_Nav_Component" def _setup_modes(self): self._fader_button_modes = FaderButtonModeSelector(self._mixer_for_faders, tuple(self._fader_buttons)) self._fader_button_modes.name = "Fader_Button_Modes" self._fader_button_modes.set_mode_toggle(self._fader_group_mode_button) self._fader_modes = FaderModeSelector( self._mixer_for_faders, self._device_for_faders, tuple(self._faders), self._fader_button_modes, self._master_fader_button, ) self._fader_modes.name = "Fader_Modes" self._fader_modes.set_mode_buttons((self._fader_group_mix_button, self._fader_group_fx_button)) self._encoder_modes = EncoderModeSelector( self._mixer_for_encoders, self._device_for_encoders, tuple(self._encoders) ) self._encoder_modes.name = "Encoder_Modes" self._encoder_modes.set_mode_buttons((self._encoder_group_mix_button, self._encoder_group_fx_button)) main_modes = MainModeSelector( self._device_for_encoders, self._device_for_faders, self._session, self._mixer_for_faders, self._device_nav, self._up_button, self._down_button, self._left_button, self._right_button, self._select_button, ) main_modes.name = "Main_Modes" main_modes.set_mode_buttons((self._main_group_track_button, self._main_group_fx_button)) def _setup_master_fader(self): if self._has_faders: self._mixer_for_encoders.master_strip().set_volume_control(self._master_fader) else: self._mixer_for_encoders.selected_strip().set_volume_control(self._master_fader) def _setup_single_fader_button_modes(self): self._single_fader_button_modes = SingleFaderButtonModeSelector( self._mixer_for_encoders, self._fader_group_midi_button ) self._single_fader_button_modes.name = "Single_Fader_Button_Modes" self._single_fader_button_modes.set_mode_toggle(self._fader_group_mode_button) def _complete_setup(self): self._setup_drum_pads() self._set_drum_pads_to_hc() self._setup_master_fader() if not self._has_faders: self._setup_single_fader_button_modes() for control in self.controls: if isinstance(control, InputControlElement): control.clear_send_cache() for component in self.components: component.set_enabled(True) self._fader_group_midi_button.send_value(LED_OFF, True) self._encoder_group_midi_button.send_value(LED_OFF, True) self._main_group_hyper_button.send_value(AMB_FULL, True) self.request_rebuild_midi_map() self._on_selected_track_changed() self.schedule_message(1, self._show_startup_message) def _show_startup_message(self): self._send_midi(SYSEX_START + CLEAR_ALL) self._name_display.display_message("Ableton Live") self._display_reset_delay = INITIAL_DISPLAY_DELAY def _select_button_value(self, value): self._display_reset_delay = STANDARD_DISPLAY_DELAY def _identify_value(self, value): for encoder in self._encoders: encoder.set_identify_mode(value > 0) for fader in self._faders: fader.set_identify_mode(value > 0) self._master_fader.set_identify_mode(value > 0) self._display_reset_delay = 0 self._identify_button.turn_on() if value > 0 else self._identify_button.turn_off() def _midi_button_value(self, value, sender): if value > 0: if sender is self._drum_group_midi_button: hc_byte = self._hc_byte ^ PADS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._drum_group_hyper_button.send_value(LED_OFF, True) self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) elif sender is self._encoder_group_midi_button: hc_byte = self._hc_byte ^ ENCODERS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._encoder_group_mix_button.send_value(LED_OFF, True) self._encoder_group_fx_button.send_value(LED_OFF, True) if self._encoder_modes.mode_index < 3: self._encoder_modes.set_enabled(False) self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) elif sender is self._fader_group_midi_button: if self._has_faders: hc_byte = self._hc_byte ^ FADERS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._fader_group_mix_button.send_value(LED_OFF, True) self._fader_group_fx_button.send_value(LED_OFF, True) self._fader_group_mode_button.send_value(LED_OFF, True) if self._fader_modes.mode_index < 2: self._fader_modes.set_enabled(False) self._fader_button_modes.set_enabled(False) self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) else: self._display_reset_delay = STANDARD_DISPLAY_DELAY def _hyper_button_value(self, value, sender): if value > 0: if sender is self._drum_group_hyper_button: if self._hc_byte | PADS != self._hc_byte: self._hc_byte = self._hc_byte | PADS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self.schedule_message(1, self._set_drum_pads_to_hc) elif sender is self._encoder_group_fx_button or sender is self._encoder_group_mix_button: if self._hc_byte | ENCODERS != self._hc_byte: self._hc_byte = self._hc_byte | ENCODERS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self._encoder_group_midi_button.turn_off() if sender is self._encoder_group_fx_button: self._encoder_modes.set_enabled(True) self._display_reset_delay = 0 return else: self.schedule_message(1, self._encoder_modes.set_enabled, True) self.schedule_message(1, self._encoder_modes.update) self._display_reset_delay = 2 return elif sender is self._fader_group_fx_button or sender is self._fader_group_mix_button: if self._hc_byte | FADERS != self._hc_byte: self._hc_byte = self._hc_byte | FADERS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self._fader_group_midi_button.turn_off() self._fader_button_modes.set_enabled(True) if sender is self._fader_group_fx_button: self._fader_modes.set_enabled(True) self._fader_button_modes.set_enabled(True) self._display_reset_delay = 0 return else: self.schedule_message(1, self._fader_modes.set_enabled, True) self.schedule_message(1, self._fader_modes.update) self.schedule_message(1, self._fader_button_modes.set_enabled, True) self.schedule_message(1, self._fader_button_modes.update) self._display_reset_delay = 2 return self._display_reset_delay = 0 def _set_drum_pads_to_hc(self): self._drum_group_midi_button.send_value(LED_OFF, True) self._drum_group_hyper_button.send_value(RED_FULL, True) for index in range(len(self._drum_pads)): self._drum_pads[index].send_value(RED_LOW, True) def _fader_button_value(self, value, sender): self._display_reset_delay = STANDARD_DISPLAY_DELAY def _fader_value(self, value, sender): param = sender.mapped_parameter() if param != None: param_range = param.max - param.min if param.name == "Track Volume": if sender == self._master_fader: if self._has_faders: name_string = "Master Vol" else: name_string = ( self._mixer_for_faders.selected_strip().track_name_data_source().display_string() + " Vol" ) else: name_string = ( self._mixer_for_faders.channel_strip(self._faders.index(sender)) .track_name_data_source() .display_string() + " Vol" ) else: name_string = param.name value = int((param.value - param.min) / param_range * 127) value_string = str(value) else: name_string = "<unmapped>" value_string = None self.schedule_message(1, self._set_value_string) self._set_name_string(name_string) self._set_value_string(value_string) def _encoder_value(self, value, sender): param = sender.mapped_parameter() if param != None: param_range = param.max - param.min if param.name == "Track Volume": name_string = ( self._mixer_for_encoders.channel_strip(self._encoders.index(sender)) .track_name_data_source() .display_string() + " Vol" ) value = int((param.value - param.min) / param_range * 127) elif param.name == "Track Panning": name_string = ( self._mixer_for_encoders.channel_strip(self._encoders.index(sender)) .track_name_data_source() .display_string() + " Pan" ) value = int(param.value / param_range * 127) if value < 0: name_string += " L" elif value > 0: name_string += " R" else: name_string += " C" else: name_string = param.name value = int((param.value - param.min) / param_range * 127) value_string = str(value) else: name_string = "<unmapped>" value_string = None self.schedule_message(1, self._set_value_string) self._set_name_string(name_string) self._set_value_string(value_string) def _set_displays_to_default(self): self._name_display.segment(0).set_data_source( self._mixer_for_encoders.selected_strip().track_name_data_source() ) self._name_display.update() self._update_bank_value() self._set_value_string(None) self._send_midi(SYSEX_START + LCD_HC_DEFAULT) def _set_name_string(self, name_string): self._name_display.segment(0).set_data_source(self._name_display_data_source) self._name_display_data_source.set_display_string(name_string) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _set_value_string(self, value_string=None): if value_string != None: self._value_display_data_source.set_display_string(value_string) else: self._value_display.reset() def _set_bank_string(self, bank_string=None): if bank_string != None: self._bank_display_data_source.set_display_string(bank_string) else: self._bank_display.reset() def _update_bank_value(self): bank = (self._session.track_offset() + 1) / self._session.width() + 1 self._set_bank_string(str(bank)) def _install_mapping(self, midi_map_handle, control, parameter, feedback_delay, feedback_map): if not self._in_build_midi_map: raise AssertionError raise midi_map_handle != None or AssertionError raise control != None and parameter != None or AssertionError raise isinstance(parameter, Live.DeviceParameter.DeviceParameter) or AssertionError raise isinstance(control, InputControlElement) or AssertionError raise isinstance(feedback_delay, int) or AssertionError if not isinstance(feedback_map, tuple): raise AssertionError success = False feedback_rule = None feedback_rule = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.NoteFeedbackRule() feedback_rule.note_no = 0 feedback_rule.vel_map = (0,) elif control.message_type() is MIDI_CC_TYPE: feedback_rule = Live.MidiMap.CCFeedbackRule() feedback_rule.cc_no = 0 feedback_rule.cc_value_map = (0,) elif control.message_type() is MIDI_PB_TYPE: feedback_rule = Live.MidiMap.PitchBendFeedbackRule() feedback_rule.value_pair_map = feedback_map raise feedback_rule != None or AssertionError feedback_rule.channel = control.message_channel() feedback_rule.delay_in_ms = feedback_delay success = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.map_midi_note_with_feedback_map( midi_map_handle, parameter, control.message_channel(), control.message_identifier(), feedback_rule ) elif control.message_type() is MIDI_CC_TYPE: success = Live.MidiMap.map_midi_cc_with_feedback_map( midi_map_handle, parameter, control.message_channel(), control.message_identifier(), control.message_map_mode(), feedback_rule, not control.needs_takeover(), ) elif control.message_type() is MIDI_PB_TYPE: success = Live.MidiMap.map_midi_pitchbend_with_feedback_map( midi_map_handle, parameter, control.message_channel(), feedback_rule, not control.needs_takeover() ) return success
def __init__(self, info_text = '', *a, **k): super(InfoComponent, self).__init__(*a, **k) self._data_source = DisplayDataSource() self._data_source.set_display_string(info_text)
def device_name_data_source(self): if self._device_name_data_source == None: self._device_name_data_source = DisplayDataSource() self._on_device_name_changed() return self._device_name_data_source
class NoteSettingsComponent(ControlSurfaceComponent): __subject_events__ = ('setting_changed',) def __init__(self, grid_resolution = None, *a, **k): super(NoteSettingsComponent, self).__init__(*a, **k) self._top_data_sources = [ DisplayDataSource() for _ in xrange(8) ] self._bottom_data_sources = [ DisplayDataSource() for _ in xrange(8) ] self._info_data_source = DisplayDataSource() self._settings = [] self._encoders = [] self._add_setting(NoteNudgeSetting(grid_resolution=grid_resolution)) self._add_setting(NoteLengthCoarseSetting(grid_resolution=grid_resolution)) self._add_setting(NoteLengthFineSetting(grid_resolution=grid_resolution)) self._add_setting(NoteVelocitySetting(grid_resolution=grid_resolution)) def _add_setting(self, setting): raise len(self._settings) < 8 or AssertionError, 'Cannot show more than 8 settings' self._settings.append(setting) self._update_encoders() self._top_data_sources = [ DisplayDataSource() for _ in xrange(8 - len(self._settings)) ] + [ s.label_source for s in self._settings ] self._bottom_data_sources = [ DisplayDataSource() for _ in xrange(8 - len(self._settings)) ] + [ s.value_source for s in self._settings ] self.register_disconnectable(setting) self.register_slot(setting, self.notify_setting_changed, 'setting_changed') def set_encoder_controls(self, encoders): self._encoders = encoders or [] self._update_encoders() def set_top_display_line(self, display): if self.is_enabled() and display: display.set_data_sources(self._top_data_sources) def set_bottom_display_line(self, display): if self.is_enabled() and display: display.set_data_sources(self._bottom_data_sources) def set_info_display_line(self, display): if self.is_enabled() and display: display.set_data_sources([self._info_data_source]) def set_clear_display_line(self, display): if self.is_enabled() and display: display.reset() def set_full_velocity_button(self, button): self._on_full_velocity.subject = button @subject_slot('value') def _on_full_velocity(self, value): if self.is_enabled(): self.notify_setting_changed(3, 127) def set_min_max(self, index, min_max_value): setting_for_index = [ i for i in self._settings if i.attribute_index == index ] for setting in setting_for_index: setting.set_min_max(min_max_value) def set_info_message(self, message): self._info_data_source.set_display_string(message.rjust(62)) def _update_encoders(self): if self.is_enabled() and self._encoders: for encoder, setting in map(None, self._encoders[-len(self._settings):], self._settings): setting.set_encoder(encoder) else: map(lambda setting: setting.set_encoder(None), self._settings) def update(self): super(NoteSettingsComponent, self).update() self._update_encoders()
class Axiom_DirectLink(ControlSurface): """ Script for the M-Audio Axiom DirectLink """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._device_selection_follows_track_selection = True self._suggested_input_port = "DirectLink" self._suggested_output_port = "DirectLink" self._waiting_for_first_response = True self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_pressed = False self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 13) self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 111) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 110) self._device_bank_buttons = None self._device_navigation = None self._shift_button.name = "Shift_Button" self._master_slider.name = "Master_Volume_Control" self._next_nav_button.name = "Next_Track_Button" self._prev_nav_button.name = "Prev_Track_Button" self._master_slider.add_value_listener(self._slider_value, identify_sender=True) self._shift_button.add_value_listener(self._shift_value) self._setup_mixer() self._setup_transport_and_session() self._setup_device() self._setup_display() for component in self.components: component.set_enabled(False) return def refresh_state(self): ControlSurface.refresh_state(self) self._waiting_for_first_response = True self.schedule_message(3, self._send_midi, SYSEX_START + (32, 46, 247)) def handle_sysex(self, midi_bytes): if midi_bytes[0:-2] == SYSEX_START + (32,) and midi_bytes[-2] != 0: self._has_sliders = midi_bytes[-2] & 8 != 0 if self._waiting_for_first_response: self._waiting_for_first_response = False self.schedule_message(1, self._show_startup_message) for component in self.components: component.set_enabled(True) if self._has_sliders: self._mixer.master_strip().set_volume_control(self._master_slider) self._mixer.update() else: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control(self._master_slider) self.request_rebuild_midi_map() return def disconnect(self): self._display_data_source.set_display_string(" ") self._shift_button.remove_value_listener(self._shift_value) self._inst_button.remove_value_listener(self._inst_value) for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) for slider in tuple(self._sliders) + (self._master_slider,): slider.remove_value_listener(self._slider_value) for button in tuple(self._strip_buttons) + (self._selected_mute_solo_button,): button.remove_value_listener(self._mixer_button_value) for button in self._device_bank_buttons: button.remove_value_listener(self._device_bank_value) self._encoders = None self._sliders = None self._strip_buttons = None self._master_slider = None self._current_midi_map = None self._selected_mute_solo_button = None self._inst_button = None self._shift_button = None self._device_navigation = None self._display = None ControlSurface.disconnect(self) self._send_midi(SYSEX_START + (32, 0, 247)) return def build_midi_map(self, midi_map_handle): self._current_midi_map = midi_map_handle ControlSurface.build_midi_map(self, midi_map_handle) def update_display(self): ControlSurface.update_display(self) if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._show_current_track_name() def _setup_mixer(self): self._selected_mute_solo_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 12) mute_solo_flip_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 57) self._strip_buttons = [] self._selected_mute_solo_button.name = "Selected_Mute_Button" mute_solo_flip_button.name = "Mute_Solo_Flip_Button" self._selected_mute_solo_button.add_value_listener(self._mixer_button_value, identify_sender=True) self._mixer = ShiftableMixerComponent(8) self._mixer.name = "Mixer" self._mixer.set_shift_button(self._shift_button) self._mixer.set_selected_mute_solo_button(self._selected_mute_solo_button) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._mixer.selected_strip().name = "Selected_Channel_Strip" self._mixer.master_strip().name = "Master_Channel_Strip" self._mixer.master_strip().set_volume_control(self._master_slider) self._sliders = [] for index in range(8): strip = self._mixer.channel_strip(index) strip.name = "Channel_Strip_" + str(index) strip.set_invert_mute_feedback(True) self._sliders.append(SliderElement(MIDI_CC_TYPE, 15, 33 + index)) self._sliders[-1].name = str(index) + "_Volume_Control" self._sliders[-1].set_feedback_delay(-1) self._sliders[-1].add_value_listener(self._slider_value, identify_sender=True) strip.set_volume_control(self._sliders[-1]) self._strip_buttons.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 49 + index)) self._strip_buttons[-1].name = str(index) + "_Mute_Button" self._strip_buttons[-1].add_value_listener(self._mixer_button_value, identify_sender=True) self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button) def _setup_transport_and_session(self): ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 115) rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 114) loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 113) play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 117) stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 116) rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 118) ffwd_button.name = "FFwd_Button" rwd_button.name = "Rwd_Button" loop_button.name = "Loop_Button" play_button.name = "Play_Button" stop_button.name = "Stop_Button" rec_button.name = "Record_Button" transport = ShiftableTransportComponent() transport.name = "Transport" transport.set_shift_button(self._shift_button) transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_record_button(rec_button) pads = [] for index in range(len(PAD_TRANSLATIONS)): pads.append(ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 15, PAD_TRANSLATIONS[index][2])) pads[-1].name = "Pad_" + str(index) self._session = ShiftableSessionComponent(8, 0) self._session.name = "Session_Control" self._session.selected_scene().name = "Selected_Scene" self._session.set_mixer(self._mixer) self._session.set_shift_button(self._shift_button) self._session.set_clip_slot_buttons(tuple(pads)) transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button, loop_button) transport_view_modes.name = "Transport_View_Modes" def _setup_device(self): self._encoders = [] for offset in range(8): self._encoders.append( PeekableEncoderElement( MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment ) ) self._encoders[-1].set_feedback_delay(-1) self._encoders[-1].add_value_listener(self._encoder_value, identify_sender=True) self._encoders[-1].name = "Device_Control_" + str(offset) prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 14) next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 15) prev_bank_button.name = "Device_Bank_Down_Button" next_bank_button.name = "Device_Bank_Up_Button" device = BestBankDeviceComponent() device.name = "Device_Component" self.set_device_component(device) device.set_parameter_controls(tuple(self._encoders)) device.set_bank_nav_buttons(prev_bank_button, next_bank_button) self._device_bank_buttons = (prev_bank_button, next_bank_button) prev_bank_button.add_value_listener(self._device_bank_value) next_bank_button.add_value_listener(self._device_bank_value) self._inst_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 109) self._inst_button.name = "Inst_Button" self._inst_button.add_value_listener(self._inst_value) self._device_navigation = DetailViewCntrlComponent() self._device_navigation.name = "Device_Navigation_Component" def _setup_display(self): self._display = PhysicalDisplayElement(5, 1) self._display.name = "Display" self._display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,)) self._display_data_source = DisplayDataSource() self._display.segment(0).set_data_source(self._display_data_source) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._show_current_track_name() def _shift_value(self, value): if not value in range(128): raise AssertionError self._shift_pressed = value > 0 for encoder in self._encoders: encoder.set_peek_mode(self._shift_pressed) self._shift_pressed and self._mixer.set_select_buttons(None, None) self._session.set_track_bank_buttons(self._next_nav_button, self._prev_nav_button) self._device_component.set_bank_nav_buttons(None, None) self._device_navigation.set_device_nav_buttons(self._device_bank_buttons[0], self._device_bank_buttons[1]) else: self._session.set_track_bank_buttons(None, None) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._device_navigation.set_device_nav_buttons(None, None) self._device_component.set_bank_nav_buttons(self._device_bank_buttons[0], self._device_bank_buttons[1]) self.request_rebuild_midi_map() return def _encoder_value(self, value, sender): if not sender in self._encoders: raise AssertionError if not value in range(128): raise AssertionError display_string = self._device_component.is_enabled() and " - " display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _slider_value(self, value, sender): if not sender in tuple(self._sliders) + (self._master_slider,): raise AssertionError if not value in range(128): raise AssertionError if self._mixer.is_enabled(): display_string = " - " if sender.mapped_parameter() != None: master = self.song().master_track tracks = self.song().tracks returns = self.song().return_tracks track = None if sender == self._master_slider: track = self._has_sliders and master else: track = self.song().view.selected_track else: track = self._mixer.channel_strip(self._sliders.index(sender))._track display_string = track == master and "Ma" elif track in tracks: display_string = str(list(tracks).index(track) + 1) elif track in returns: display_string = str(chr(ord("A") + list(returns).index(track))) else: raise False or AssertionError display_string += " Vol" self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _mixer_button_value(self, value, sender): if not sender in tuple(self._strip_buttons) + (self._selected_mute_solo_button,): raise AssertionError if not value in range(128): raise AssertionError if self._mixer.is_enabled() and value > 0: strip = None strip = sender == self._selected_mute_solo_button and self._mixer.selected_strip() else: strip = self._mixer.channel_strip(self._strip_buttons.index(sender)) strip != None and self._set_display_data_source(strip.track_name_data_source()) else: self._display_data_source.set_display_string(" - ") self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY return def _device_bank_value(self, value): if not value in range(128): raise AssertionError if self._device_component.is_enabled() and value > 0: data_source = self._device_component.bank_name_data_source() data_source = self._shift_pressed and self._device_component.device_name_data_source() self._set_display_data_source(data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _inst_value(self, value): if not value in range(128): raise AssertionError value > 0 and self._device_component.is_enabled() and self.song().view.selected_track.view.select_instrument() and self._set_display_data_source( self._device_component.device_name_data_source() ) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _show_current_track_name(self): if self._display != None and self._mixer != None: self._set_display_data_source(self._mixer.selected_strip().track_name_data_source()) return def _show_startup_message(self): self._display.display_message("LIVE") self._display_reset_delay = INITIAL_DISPLAY_DELAY def _set_display_data_source(self, data_source): raise isinstance(data_source, DisplayDataSource) or AssertionError self._display.segment(0).set_data_source(data_source) data_source.update()
class MixerOrDeviceModeSelector(ModeSelectorComponent): """ Class that toggles between mixer and device modes """ def __init__(self, mixer_modes, device, encoders, page_buttons): raise isinstance(mixer_modes, EncoderMixerModeSelector) or AssertionError raise isinstance(device, PageableDeviceComponent) or AssertionError raise isinstance(encoders, tuple) or AssertionError raise isinstance(page_buttons, tuple) or AssertionError ModeSelectorComponent.__init__(self) self._mixer_modes = mixer_modes self._device = device self._encoders = encoders self._page_buttons = page_buttons self._peek_button = None self._encoders_display = None self._value_display = None self._device_display = None self._page_displays = None self._device_dummy_source = DisplayDataSource() self._parameter_source = DisplayDataSource() self._device_dummy_source.set_display_string('Mixer') self._clean_value_display_in = -1 self._must_update_encoder_display = False self._register_timer_callback(self._on_timer) identify_sender = True for encoder in self._encoders: encoder.add_value_listener(self._parameter_value, identify_sender) self.set_mode(0) return def disconnect(self): self._unregister_timer_callback(self._on_timer) self._mixer_modes = None self._device = None self._encoders = None self._page_buttons = None self._encoders_display = None self._value_display = None self._device_display = None self._page_displays = None self._device_dummy_source = None self._parameter_source = None ModeSelectorComponent.disconnect(self) return def set_displays(self, encoders_display, value_display, device_display, page_displays): if not isinstance(encoders_display, PhysicalDisplayElement): raise AssertionError raise isinstance(value_display, PhysicalDisplayElement) or AssertionError raise isinstance(device_display, PhysicalDisplayElement) or AssertionError raise isinstance(page_displays, tuple) or AssertionError self._encoders_display = encoders_display self._value_display = value_display self._device_display = device_display self._page_displays = page_displays self._value_display != None and self._value_display.segment(0).set_data_source(self._parameter_source) self.update() return def set_peek_button(self, button): if not (button == None or isinstance(button, ButtonElement)): raise AssertionError if self._peek_button != button: if self._peek_button != None: self._peek_button.remove_value_listener(self._peek_value) self._peek_button = button self._peek_button != None and self._peek_button.add_value_listener(self._peek_value) self.update() return def number_of_modes(self): return 2 def update(self): super(MixerOrDeviceModeSelector, self).update() if self.is_enabled(): if self._mode_index == 0: self._device.set_parameter_controls(None) self._device.set_bank_buttons(None) self._mixer_modes.set_controls(self._encoders) self._mixer_modes.set_modes_buttons(self._page_buttons) if self._device_display != None: self._device_display.segment(0).set_data_source(self._mixer_modes.current_page_data_source()) self._device_display.update() if self._encoders_display != None: for index in range(len(self._encoders)): self._encoders_display.segment(index).set_data_source(self._mixer_modes.parameter_data_source(index)) self._encoders_display.update() if self._page_displays != None: for index in range(len(self._page_displays)): self._page_displays[index].segment(0).set_data_source(self._mixer_modes.page_name_data_source(index)) self._page_displays[index].update() elif self._mode_index == 1: self._mixer_modes.set_controls(None) self._mixer_modes.set_modes_buttons(None) self._device.set_parameter_controls(self._encoders) self._device.set_bank_buttons(self._page_buttons) if self._device_display != None: self._device_display.segment(0).set_data_source(self._device.device_name_data_source()) self._device_display.update() if self._encoders_display != None: for index in range(len(self._encoders)): self._encoders_display.segment(index).set_data_source(self._device.parameter_name_data_source(index)) self._encoders_display.update() if self._page_displays != None: for index in range(len(self._page_displays)): self._page_displays[index].segment(0).set_data_source(self._device.page_name_data_source(index)) self._page_displays[index].update() else: print 'Invalid mode index' raise False or AssertionError return def _parameter_value(self, value, control): if not control in self._encoders: raise AssertionError if self.is_enabled(): parameter = control.mapped_parameter() parameter != None and self._parameter_source.set_display_string(parameter.name + ': ' + parameter.__str__()) else: self._parameter_source.set_display_string('<unmapped>') self._clean_value_display_in = 20 return def _on_timer(self): if self._clean_value_display_in > 0: self._clean_value_display_in -= 1 if self._clean_value_display_in == 0: self._parameter_source.set_display_string('') self._clean_value_display_in = -1 if self._must_update_encoder_display: self._encoders_display.update() self._must_update_encoder_display = False def _peek_value(self, value): if not self._peek_button != None: raise AssertionError raise value in range(128) or AssertionError new_peek_mode = value != 0 peek_changed = False for encoder in self._encoders: if new_peek_mode != encoder.get_peek_mode(): encoder.set_peek_mode(new_peek_mode) peek_changed = True self._must_update_encoder_display = peek_changed and self._encoders_display != None and True return
class Live8DeviceComponent(ControlSurfaceComponent): __doc__ = ' Class representing a device in Live ' def __init__(self): ControlSurfaceComponent.__init__(self) self._device_banks = DEVICE_DICT self._device_best_banks = DEVICE_BOB_DICT self._device_bank_names = BANK_NAME_DICT self._device = None self._parameter_controls = None self._bank_up_button = None self._bank_down_button = None self._bank_buttons = None self._on_off_button = None self._lock_button = None self._lock_callback = None self._device_name_data_source = None self._device_bank_registry = {} self._bank_index = 0 self._bank_name = '<No Bank>' self._locked_to_device = False return None def disconnect(self): self._lock_callback = None self._device_bank_registry = None if self._parameter_controls != None: for control in self._parameter_controls: control.release_parameter() self._parameter_controls = None if self._bank_up_button != None: self._bank_up_button.remove_value_listener(self._bank_up_value) self._bank_up_button = None if self._bank_down_button != None: self._bank_down_button.remove_value_listener(self._bank_down_value) self._bank_down_button = None if self._bank_buttons != None: for button in self._bank_buttons: button.remove_value_listener(self._bank_value) self._bank_buttons = None if self._on_off_button != None: self._on_off_button.remove_value_listener(self._on_off_value) self._on_off_button = None if self._lock_button != None: self._lock_button.remove_value_listener(self._lock_value) self._lock_button = None if self._device != None: parameter = self._on_off_parameter() if parameter != None: parameter.remove_value_listener(self._on_on_off_changed) self._device.remove_name_listener(self._on_device_name_changed) self._device.remove_parameters_listener(self._on_parameters_changed) self._device = None return None def on_enabled_changed(self): self.update() def set_device(self, device): assert ((device == None) or isinstance(device, Live.Device.Device)) if ((not self._locked_to_device) and (device != self._device)): if (self._device != None): self._device.remove_name_listener(self._on_device_name_changed) self._device.remove_parameters_listener(self._on_parameters_changed) parameter = self._on_off_parameter() if (parameter != None): parameter.remove_value_listener(self._on_on_off_changed) if (self._parameter_controls != None): for control in self._parameter_controls: control.release_parameter() self._device = device if (self._device != None): self._bank_index = 0 self._device.add_name_listener(self._on_device_name_changed) self._device.add_parameters_listener(self._on_parameters_changed) parameter = self._on_off_parameter() if (parameter != None): parameter.add_value_listener(self._on_on_off_changed) for key in self._device_bank_registry.keys(): if (key == self._device): self._bank_index = self._device_bank_registry.get(key, 0) del self._device_bank_registry[key] break self._bank_name = '<No Bank>' #added self._on_device_name_changed() self.update() def set_bank_nav_buttons(self, down_button, up_button): assert ((down_button != None) or (up_button == None)) assert ((up_button == None) or isinstance(up_button, ButtonElement)) assert ((down_button == None) or isinstance(down_button, ButtonElement)) do_update = False if up_button != self._bank_up_button: do_update = True if self._bank_up_button != None: self._bank_up_button.remove_value_listener(self._bank_up_value) self._bank_up_button = up_button if self._bank_up_button != None: self._bank_up_button.add_value_listener(self._bank_up_value) if down_button != self._bank_down_button: do_update = True if self._bank_down_button != None: self._bank_down_button.remove_value_listener(self._bank_down_value) self._bank_down_button = down_button if self._bank_down_button != None: self._bank_down_button.add_value_listener(self._bank_down_value) if do_update: self.update() return None def set_bank_buttons(self, buttons): assert ((buttons == None) or isinstance(buttons, tuple)) if self._bank_buttons != None: for button in self._bank_buttons: button.remove_value_listener(self._bank_value) self._bank_buttons = buttons if self._bank_buttons != None: identify_sender = True for button in self._bank_buttons: button.add_value_listener(self._bank_value, identify_sender) self.update() return None def set_parameter_controls(self, controls): assert (controls != None) assert isinstance(controls, tuple) if self._device != None and self._parameter_controls != None: for control in self._parameter_controls: control.release_parameter() for control in controls: assert (control != None) assert isinstance(control, EncoderElement) self._parameter_controls = controls self.update() return None def set_lock_to_device(self, lock, device): assert isinstance(lock, type(False)) assert (lock is not self._locked_to_device) if lock: self.set_device(device) else: assert (device == self._device) self._locked_to_device = lock if self.is_enabled(): if (self._lock_button != None): if self._locked_to_device: self._lock_button.turn_on() else: self._lock_button.turn_off() def set_lock_button(self, button): assert ((button == None) or isinstance(button, ButtonElement)) if self._lock_button != None: self._lock_button.remove_value_listener(self._lock_value) self._lock_button = None self._lock_button = button if self._lock_button != None: self._lock_button.add_value_listener(self._lock_value) self.update() return None def set_on_off_button(self, button): assert ((button == None) or isinstance(button, ButtonElement)) if self._on_off_button != None: self._on_off_button.remove_value_listener(self._on_off_value) self._on_off_button = None self._on_off_button = button if self._on_off_button != None: self._on_off_button.add_value_listener(self._on_off_value) self.update() return None def set_lock_callback(self, callback): assert (self._lock_callback == None) assert (callback != None) assert (dir(callback).count('im_func') is 1) self._lock_callback = callback return None def restore_bank(self, bank_index): if self._device != None and self._is_banking_enabled() and self._locked_to_device and self._number_of_parameter_banks() > bank_index and self._bank_index != bank_index: self._bank_index = bank_index self.update() return None def device_name_data_source(self): if self._device_name_data_source == None: self._device_name_data_source = DisplayDataSource() self._on_device_name_changed() return self._device_name_data_source def update(self): if (self.is_enabled() and (self._device != None)): self._device_bank_registry[self._device] = self._bank_index if (self._parameter_controls != None): old_bank_name = self._bank_name #added self._assign_parameters() if self._bank_name != old_bank_name: #added self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name) #added if ((self._bank_up_button != None) and (self._bank_down_button != None)): if (self.number_of_parameter_banks()) > (self._bank_index + 1): self._bank_up_button.turn_on() else: self._bank_up_button.turn_off() if (self._bank_index > 0): self._bank_down_button.turn_on() else: self._bank_down_button.turn_off() if (self._bank_buttons != None): for index in range(len(self._bank_buttons)): if (index == self._bank_index): self._bank_buttons[index].turn_on() else: self._bank_buttons[index].turn_off() else: if (self._lock_button != None): self._lock_button.turn_off() if (self._bank_up_button != None): self._bank_up_button.turn_off() if (self._bank_down_button != None): self._bank_down_button.turn_off() if (self._bank_buttons != None): for button in self._bank_buttons: button.turn_off() if (self._parameter_controls != None): for control in self._parameter_controls: control.release_parameter() #self._rebuild_callback() def _bank_up_value(self, value): assert (self._bank_up_button != None) assert (value != None) assert isinstance(value, int) if self.is_enabled(): if ((not self._bank_up_button.is_momentary()) or (value is not 0)): if (self._device != None): num_banks = self._number_of_parameter_banks() if (self._bank_down_button == None): self._bank_name = '' self._bank_index = ((self._bank_index + 1) % num_banks) self.update() elif (num_banks > (self._bank_index + 1)): self._bank_name = '' self._bank_index += 1 self.update() def _bank_down_value(self, value): assert (self._bank_down_button != None) assert (value != None) assert isinstance(value, int) if self.is_enabled(): if ((not self._bank_down_button.is_momentary()) or (value is not 0)): if ((self._device != None) and (self._bank_index > 0)): self._bank_name = '' self._bank_index -= 1 self.update() def _lock_value(self, value): assert (self._lock_button != None) assert (self._lock_callback != None) assert (value != None) assert isinstance(value, int) if not self._lock_button.is_momentary() or value is not 0: self._lock_callback() return None def _on_off_value(self, value): assert (self._on_off_button != None) assert (value in range(128)) if not self._on_off_button.is_momentary() or value is not 0: parameter = self._on_off_parameter() if parameter != None and parameter.is_enabled: parameter.value = float(int(parameter.value == 0.0)) return None def _bank_value(self, value, button): assert (self._bank_buttons != None) assert (value != None) assert (button != None) assert isinstance(value, int) assert isinstance(button, ButtonElement) assert (list(self._bank_buttons).count(button) == 1) if self.is_enabled() and self._device != None: #added if ((not button.is_momentary()) or (value is not 0)): bank = list(self._bank_buttons).index(button) if (bank != self._bank_index): if (self._number_of_parameter_banks() > bank): self._bank_name = '' #added self._bank_index = bank self.update() else: self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name) def _is_banking_enabled(self): direct_banking = (self._bank_buttons != None) roundtrip_banking = (self._bank_up_button != None) increment_banking = ((self._bank_up_button != None) and (self._bank_down_button != None)) return (direct_banking or (roundtrip_banking or increment_banking)) def _assign_parameters(self): assert self.is_enabled() assert (self._device != None) assert (self._parameter_controls != None) self._bank_name = ('Bank ' + str(self._bank_index + 1)) #added if (self._device.class_name in self._device_banks.keys()): #modified assert (self._device.class_name in self._device_best_banks.keys()) banks = self._device_banks[self._device.class_name] bank = None #if (not self._is_banking_enabled()): # banks = self._device_best_banks[self._device.class_name] # self._bank_name = 'Best of Parameters' #added if (len(banks) > self._bank_index): bank = banks[self._bank_index] if self._is_banking_enabled(): #added if self._device.class_name in self._device_bank_names.keys(): #added self._bank_name[self._bank_index] = self._device_bank_names[self._device.class_name] #added *recheck assert ((bank == None) or (len(bank) >= len(self._parameter_controls))) for index in range(len(self._parameter_controls)): parameter = None if (bank != None): parameter = get_parameter_by_name(self._device, bank[index]) if (parameter != None): self._parameter_controls[index].connect_to(parameter) else: self._parameter_controls[index].release_parameter() else: parameters = self._device_parameters_to_map() num_controls = len(self._parameter_controls) index = (self._bank_index * num_controls) for control in self._parameter_controls: if (index < len(parameters)): control.connect_to(parameters[index]) else: control.release_parameter() index += 1 def _on_device_name_changed(self): if (self._device_name_data_source != None): if (self.is_enabled() and (self._device != None)): self._device_name_data_source.set_display_string(self._device.name) else: self._device_name_data_source.set_display_string('No Device') def _on_parameters_changed(self): self.update() def _on_off_parameter(self): result = None if (self._device != None): for parameter in self._device.parameters: if str(parameter.name).startswith('Device On'): result = parameter break return result def _on_on_off_changed(self): if (self.is_enabled() and (self._on_off_button != None)): turn_on = False if (self._device != None): parameter = self._on_off_parameter() turn_on = ((parameter != None) and (parameter.value > 0.0)) if turn_on: self._on_off_button.turn_on() else: self._on_off_button.turn_off() def _device_parameters_to_map(self): assert self.is_enabled() assert (self._device != None) assert (self._parameter_controls != None) return self._device.parameters[1:] #check this... def _number_of_parameter_banks(self): return number_of_parameter_banks(self._device) #added
class BestBankDeviceComponent(DeviceComponent): """ Special Device component that uses the best of bank of a device as default """ def __init__(self): DeviceComponent.__init__(self) new_banks = {} new_bank_names = {} self._device_banks = DEVICE_DICT self._device_bank_names = BANK_NAME_DICT self._device_best_banks = DEVICE_BOB_DICT for device_name, current_banks in self._device_banks.iteritems(): raise len(current_banks) > 1 and (device_name in self._device_best_banks.keys() or AssertionError), "Could not find best-of-banks for '%s'" % device_name if not device_name in self._device_bank_names.keys(): raise AssertionError, "Could not find bank names for '%s'" % device_name current_banks = self._device_best_banks[device_name] + current_banks new_bank_names[device_name] = (BOP_BANK_NAME,) + self._device_bank_names[device_name] new_banks[device_name] = current_banks self._device_banks = new_banks self._device_bank_names = new_bank_names self._bank_name_data_source = DisplayDataSource() def disconnect(self): self._bank_name_data_source = None DeviceComponent.disconnect(self) def bank_name_data_source(self): return self._bank_name_data_source def _bank_up_value(self, value): DeviceComponent._bank_up_value(self, value) self._update_bank_display() def _bank_down_value(self, value): DeviceComponent._bank_down_value(self, value) self._update_bank_display() def _update_bank_display(self): if self.is_enabled(): bank_name = '' if self._device != None and self._bank_name != '<No Bank>': bank_name = self._bank_name if bank_name in (BOP_BANK_NAME, 'Bank 1'): bank_name = 'Home' self._bank_name_data_source.set_display_string(bank_name) def _is_banking_enabled(self): return True def _number_of_parameter_banks(self): result = 0 if self._device != None: if self._device.class_name in self._device_banks.keys(): result = len(self._device_banks[self._device.class_name]) else: result = DeviceComponent._number_of_parameter_banks(self) return result def _parameter_banks(self): return parameter_banks(self._device, self._device_banks) def _parameter_bank_names(self): return parameter_bank_names(self._device, self._device_bank_names)