def find_instrument_meeting_requirement(requirement, track_or_chain): instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices) if liveobj_valid(instrument): if requirement(instrument): return instrument if instrument.can_have_chains: recursive_call = partial(find_instrument_meeting_requirement, requirement) return find_if(bool, imap(recursive_call, instrument.chains))
def _update_stop_all_clips_button(self): button = self._stop_all_button if button: value_to_send = self._stop_clip_disabled_value tracks = self.song.tracks if find_if(lambda x: x.playing_slot_index >= 0 and x.fired_slot_index != -2, tracks): value_to_send = self._stop_clip_value elif find_if(lambda x: x.fired_slot_index == -2, tracks): value_to_send = self._stop_clip_triggered_value button.set_light(value_to_send)
def _update_attachments(self): visible_routing_channels = set(self._visible_routing_channels()) attached_routing_channels = set(self._attached_routing_channels()) to_be_detached = attached_routing_channels - visible_routing_channels to_be_attached = visible_routing_channels - attached_routing_channels for routing_channel in to_be_detached: rt_assignment = find_if(lambda rt: rt.attached_object == routing_channel, self.real_time_channels) rt_assignment.set_data(None) for routing_channel in to_be_attached: free_channel = find_if(lambda rt: rt.attached_object is None, self.real_time_channels) free_channel.set_data(routing_channel) self._update_list_index_to_pool_index_mapping()
def _show_notes_information(self, mode = None): if self.is_enabled(): if mode is None: mode = self.selected_mode if mode == 'sequence': message = u'Sequence %s to %s' first = find_if(lambda editor: editor.editing_note is not None, self._note_editors) last = find_if(lambda editor: editor.editing_note is not None, reversed(self._note_editors)) start_note = first.editing_note if first is not None else None end_note = last.editing_note if last is not None else None else: message = u'Play %s to %s' start_note = self._instrument._pattern.note(0, 0).index end_note = self._instrument._pattern.note(7, 7).index self.show_notification(message % (pitch_index_to_string(start_note), pitch_index_to_string(end_note)))
def _find_item(self, path, items = None, browser = None): name = path[0] elem = find_if(lambda x: x.name == name, items) if elem: if len(path) == 1: return [elem] return self._find_item(path[1:], elem.children)
def possible_conversions(track, decorator_factory=None): conversions = [] if liveobj_valid(track): if is_midi_track(track) and len(track.devices) > 0: drum_rack = find_drum_rack_instrument(track) if liveobj_valid(drum_rack): drum_pad = drum_rack.view.selected_drum_pad if liveobj_valid(drum_pad) and len( drum_pad.chains) == 1 and find_instrument_devices( drum_pad.chains[0]): conversions.append( DrumPadToMidiTrack(drum_pad=drum_pad, track=track)) else: simpler = find_simpler(track) if simpler != None and simpler.playback_mode == Live.SimplerDevice.PlaybackMode.slicing: conversions.append( SlicesToDrumRack(device=simpler, track=track)) else: conversions.append( MoveDeviceChain(device=simpler, track=track, decorator_factory=decorator_factory)) elif is_audio_track(track): highlighted_clip_slot = track.canonical_parent.view.highlighted_clip_slot clip = find_if( lambda slot: slot.has_clip and highlighted_clip_slot == slot, track.clip_slots) if liveobj_valid(clip) and not clip.is_recording: conversions.append( CreateTrackWithSimpler(clip_slot=highlighted_clip_slot, track=track)) return conversions
def possible_conversions(track, decorator_factory = None): category = NullConvertCategory() if liveobj_valid(track): if is_midi_track(track) and len(track.devices) > 0: drum_rack = find_drum_rack_instrument(track) if liveobj_valid(drum_rack): drum_pad = drum_rack.view.selected_drum_pad if liveobj_valid(drum_pad) and len(drum_pad.chains) == 1 and find_instrument_devices(drum_pad.chains[0]): category = MidiTrackWithDrumRack(actions=[DrumPadToMidiTrack()], drum_pad=drum_pad, track=track) else: simpler = find_simpler(track) if simpler != None and simpler.playback_mode == Live.SimplerDevice.PlaybackMode.slicing: category = MidiTrackWithSimpler(actions=[SlicesToDrumRack()], device=simpler, track=track) else: category = MidiTrackWithoutSimpler(actions=[MoveDeviceChain()], device=simpler, track=track, decorator_factory=decorator_factory) elif is_audio_track(track): detail_clip = track.canonical_parent.view.detail_clip song = track.canonical_parent if liveobj_valid(detail_clip) and detail_clip.is_arrangement_clip: if not detail_clip.is_recording: actions = [CreateTrackWithSimpler(), CreateTrackWithClipInDrumRackPad()] if Live.Conversions.is_convertible_to_midi(song, detail_clip): actions.extend([ConvertAudioClipToHarmonyMidi(), ConvertAudioClipToMelodyMidi(), ConvertAudioClipToDrumsMidi()]) category = AudioTrackWithArrangementClip(actions=actions, song_view=track.canonical_parent.view, track=track) else: highlighted_clip_slot = track.canonical_parent.view.highlighted_clip_slot clip_slot = find_if(lambda slot: slot.has_clip and highlighted_clip_slot == slot, track.clip_slots) if liveobj_valid(clip_slot) and not clip_slot.is_recording: actions = [CreateTrackWithSimpler(), CreateTrackWithClipInDrumRackPad()] if Live.Conversions.is_convertible_to_midi(song, clip_slot.clip): actions.extend([ConvertAudioClipToHarmonyMidi(), ConvertAudioClipToMelodyMidi(), ConvertAudioClipToDrumsMidi()]) category = AudioTrackWithSessionClip(actions=actions, clip_slot=highlighted_clip_slot, track=track) return category
def get_name_for_roi(self, roi): """ Returns the name for the given roi or None, if it doesn't have one """ item = find_if(lambda i: i[1] == roi, self.regions_of_interest.iteritems()) if item is not None: return item[0]
def _find_item(self, path, items=None, browser=None): name = path[0] elem = find_if(lambda x: x.name == name, items) if elem: if len(path) == 1: return [elem] return self._find_item(path[1:], elem.children)
def _update_note_infos(self): if self.settings.is_enabled(): def min_max((l_min, l_max), (r_min, r_max)): return (min(l_min, r_min), max(l_max, r_max)) all_min_max_attributes = filter( None, imap(lambda e: e.get_min_max_note_values(), self._editors)) min_max_values = [ (99999, -99999) ] * 4 if len(all_min_max_attributes) > 0 else None for min_max_attribute in all_min_max_attributes: for i, attribute in enumerate(min_max_attribute): min_max_values[i] = min_max(min_max_values[i], attribute) for i in xrange(4): self.settings.set_min_max( i, min_max_values[i] if min_max_values else None) edit_all_notes_active = find_if( lambda e: e.modify_all_notes_enabled, self._editors) != None self.settings.set_info_message( 'Tweak to add note' if not edit_all_notes_active and not min_max_values else '')
def _collect_parameters(self): parameters = self._device.parameters bank_slots = self._current_parameter_slots() return [(find_if(lambda p: p.original_name == str(slot_definition), parameters), getattr(slot_definition, u'display_name', None)) for slot_definition in bank_slots]
def _collect_options(self): option_slots = self._current_option_slots() options = getattr(self._device, 'options', []) return [ find_if(lambda o: o.name == str(slot_definition), options) for slot_definition in option_slots ]
def _collect_parameters(self): parameters = self._device.parameters bank_slots = self._current_parameter_slots() return [ find_if(lambda p: p.original_name == str(slot_definition), parameters) for slot_definition in bank_slots ]
def _show_notes_information(self, mode = None): if self.is_enabled(): if mode is None: mode = self.selected_mode if mode == 'sequence': message = u'Sequence %s to %s' first = find_if(lambda editor: editor.editing_note is not None, self._note_editors) last = find_if(lambda editor: editor.editing_note is not None, reversed(self._note_editors)) start_note = first.editing_note if first is not None else None end_note = last.editing_note if last is not None else None else: message = u'Play %s to %s' start_note = self._instrument._pattern.note(0, 0).index end_note = self._instrument._pattern.note(7, 7).index self.show_notification(message % (pitch_index_to_string(start_note), pitch_index_to_string(end_note))) return
def set_device(self, device): self._simpler = device if is_simpler(device) else None self.__on_selected_slice_changed.subject = self._simpler with self._updating_nudge_parameter(): self._nudge_parameter = find_if( lambda p: p.name == "Nudge", self._simpler.parameters if liveobj_valid(self._simpler) else [] )
def _select_region_around_visible_region(self): region_getters = self._get_unique_region_getters() source_getter = find_if(lambda g: self._visible_region_inside(g()), region_getters[1::-1]) if source_getter is not None: self._source_region_getter = source_getter self._target_region_getter = region_getters[ region_getters.index(source_getter) + 1]
def get_name_for_roi(self, roi): u""" Returns the name for the given roi or None, if it doesn't have one """ item = find_if(lambda i: i[1] == roi, self.regions_of_interest.iteritems()) if item is not None: return item[0]
def find_decorated_object(proxied_object, decorator_factory): decorated_obj = None if liveobj_valid(proxied_object): decorated_obj = find_if( lambda obj: not liveobj_changed(obj.proxied_object, proxied_object ), decorator_factory.decorated_objects.itervalues()) return decorated_obj
def set_device(self, device): self._simpler = device if is_simpler(device) else None self.__on_selected_slice_changed.subject = self._simpler with self._updating_nudge_parameter(): self._nudge_parameter = find_if( lambda p: p.name == 'Nudge', self._simpler.parameters if liveobj_valid(self._simpler) else []) return
def _select_region_around_visible_region(self): regions_of_interest = self._get_unique_regions_of_interest() source_roi = find_if( lambda roi: self.visible_region.inside(roi.region_with_margin), reversed(regions_of_interest[:-1])) if source_roi is not None: self._set_source_and_target_roi( source_roi, regions_of_interest[regions_of_interest.index(source_roi) + 1])
def find_first_playing_grouped_track(group_track, all_tracks): def is_playing_and_grouped(track): return is_child_of_group_track( group_track, track) and not track.is_foldable and track.playing_slot_index >= 0 return find_if( is_playing_and_grouped, all_tracks[index_if(lambda t: t == group_track, all_tracks):])
def find_instrument_devices(track_or_chain): """ Returns a list with all instruments from a track or chain. """ instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices) if liveobj_valid(instrument): if not instrument.can_have_drum_pads and instrument.can_have_chains: return chain([instrument], *imap(find_instrument_devices, instrument.chains)) return [instrument] return []
def _exclusive_arm_next_track(self, index): if not self.song.exclusive_arm: return next_index = (index + 1) % len(self._tracks) self._exclusive_arm( find_if( lambda t: liveobj_valid(t) and not is_group_track(t) and not playing_or_recording_clip_slot(t), chain(self._tracks[next_index:], self._tracks[:next_index])) or self._tracks[next_index])
def _extract_path(self, path, items=None, browser=None): if isinstance(path, string_types): path = [path] if items is None: items = [getattr(browser, self.root_name)] if path: name = path[0] elem = find_if(lambda x: x.name == name, items) if elem: items = self._extract_path(path[1:], elem.children) return tuple(items)
def find_instrument_devices(track_or_chain): """ Returns a list with all instruments from a track or chain. """ if liveobj_valid(track_or_chain): instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices) if liveobj_valid(instrument): if not instrument.can_have_drum_pads and instrument.can_have_chains: return chain([instrument], *imap(find_instrument_devices, instrument.chains)) return [instrument] return []
def __init__(self, all_pads = tuple(), parameter_sender = nop, default_profile = PadParameters(), update_delay = 0, *a, **k): raise find_if(lambda pad: pad < 0 or pad > 63, all_pads or []) == None or AssertionError super(PadUpdateComponent, self).__init__(*a, **k) self.parameter_sender = parameter_sender self._all_pads = set(all_pads) self._modified_pads = set(all_pads) self._profiles = {'default': default_profile} self._profile_for = dict(zip(all_pads, repeat('default'))) self._profile_count = {'default': len(all_pads)} self._update_task = self._tasks.add(task.sequence(task.wait(update_delay), task.run(self._update_modified))) self._update_task.restart()
def _extract_path(self, path, items = None, browser = None): if isinstance(path, (str, unicode)): path = [path] if items is None: items = [getattr(browser, self.root_name)] if path: name = path[0] elem = find_if(lambda x: x.name == name, items) if elem: items = self._extract_path(path[1:], elem.children) return tuple(items)
def __init__(self, all_pads = tuple(), parameter_sender = nop, default_profile = None, update_delay = 0, *a, **k): assert find_if(lambda pad: pad < 0 or pad > 63, all_pads or []) == None super(PadUpdateComponent, self).__init__(*a, **k) self.parameter_sender = parameter_sender self._all_pads = set(all_pads) self._modified_pads = set(all_pads) self._profiles = {u'default': default_profile} self._profile_for = dict(list(zip(all_pads, repeat(u'default')))) self._profile_count = {u'default': len(all_pads)} self._update_task = self._tasks.add(task.sequence(task.wait(update_delay), task.run(self._update_modified))) self._update_task.restart()
def _show_notes_information(self, mode = None): if self.is_enabled() and self.show_notifications: if mode is None: mode = self.selected_mode if mode == u'sequence': message = u'Sequence %s to %s' start_note = self._note_editors[0].editing_notes[0] end_editor = find_if(lambda editor: len(editor.editing_notes) > 0, reversed(self._note_editors)) end_note = end_editor.editing_notes[0] self.show_notification(message % (pitch_index_to_string(start_note), pitch_index_to_string(end_note))) else: self.instrument.show_pitch_range_notification()
def get_or_create_first_empty_clip_slot(track, song=None): if liveobj_valid(track): first_empty_slot = find_if(lambda s: not s.has_clip, track.clip_slots) if first_empty_slot: if liveobj_valid(first_empty_slot): return first_empty_slot try: song.create_scene(-1) slot = track.clip_slots[(-1)] if liveobj_valid(slot): return slot except Live.Base.LimitationError: pass
def selected_target_note(self): note_and_channel = (-1, -1) if liveobj_valid(self._drum_group_device) and liveobj_valid(self._selected_drum_pad): if self._selected_drum_pad in self.assigned_drum_pads: predicate = lambda b: self._pad_for_button(b) == self._selected_drum_pad button = find_if(predicate, self.matrix) if button != None and None not in (button.identifier, button.channel): note_and_channel = ( button.identifier, button.channel) else: note_and_channel = ( self._selected_drum_pad.note, NON_FEEDBACK_CHANNEL) return NamedTuple(note=note_and_channel[0], channel=note_and_channel[1])
def _on_content_lists_changed(self): self._last_selected_item = None components = self._list_components contents = self._browser_model.content_lists[self._scroll_offset:] messages = self._browser_model.empty_list_messages scroll_depth = len(self._browser_model.content_lists) - len( self._list_components) self._max_scroll_offset = max(0, scroll_depth + 2) self._max_hierarchy = max(0, scroll_depth) for component, content, message in zip_longest(components, contents, messages): if component != None: component.scrollable_list = content component.empty_list_message = message active_lists = len(contents) num_head = clamp(active_lists - 1, 0, self.NUM_COLUMNS - 1) head = components[:num_head] last = components[num_head:] def set_data_sources_with_separator(component, sources, separator): for source in sources: source.separator = separator component.set_data_sources(sources) component.set_enabled(True) for idx, component in enumerate(head): offset = idx * self.COLUMN_SIZE sources = self._data_sources[offset:offset + self.COLUMN_SIZE] set_data_sources_with_separator(component, sources, u'|') if last: offset = num_head * self.COLUMN_SIZE scrollable_list = last[0].scrollable_list if scrollable_list and find_if(lambda item: item.content.is_folder, scrollable_list.items): sources = self._data_sources[offset:offset + self.COLUMN_SIZE] list( map(DisplayDataSource.clear, self._data_sources[offset + self.COLUMN_SIZE:])) else: sources = self._data_sources[offset:] set_data_sources_with_separator(last[0], sources, u'') for component in last[1:]: component.set_enabled(False) self.set_select_buttons(self._select_buttons) self.set_state_buttons(self._state_buttons) self.set_encoder_controls(self._encoder_controls) self._update_navigation_button_state()
def _exclusive_arm_next_track(self, index): u""" Arm the next track after `index` that's not playing or recording a clip. If all tracks are playing/recording, then we just arm the adjacent track. """ if not self.song.exclusive_arm: return next_index = (index + 1) % len(self._tracks) self._exclusive_arm( find_if( lambda t: liveobj_valid(t) and not is_group_track(t) and not playing_or_recording_clip_slot(t), chain(self._tracks[next_index:], self._tracks[:next_index])) or self._tracks[next_index])
def _on_content_lists_changed(self): self._last_selected_item = None components = self._list_components contents = self._browser_model.content_lists[self._scroll_offset:] messages = self._browser_model.empty_list_messages scroll_depth = len(self._browser_model.content_lists) - len(self._list_components) self._max_scroll_offset = max(0, scroll_depth + 2) self._max_hierarchy = max(0, scroll_depth) for component, content, message in map(None, components, contents, messages): if component != None: component.scrollable_list = content component.empty_list_message = message active_lists = len(contents) num_head = clamp(active_lists - 1, 0, self.NUM_COLUMNS - 1) head = components[:num_head] last = components[num_head:] def set_data_sources_with_separator(component, sources, separator): for source in sources: source.separator = separator component.set_data_sources(sources) component.set_enabled(True) for idx, component in enumerate(head): offset = idx * self.COLUMN_SIZE sources = self._data_sources[offset:offset + self.COLUMN_SIZE] set_data_sources_with_separator(component, sources, '|') if last: offset = num_head * self.COLUMN_SIZE scrollable_list = last[0].scrollable_list if scrollable_list and find_if(lambda item: item.content.is_folder, scrollable_list.items): sources = self._data_sources[offset:offset + self.COLUMN_SIZE] map(DisplayDataSource.clear, self._data_sources[offset + self.COLUMN_SIZE:]) else: sources = self._data_sources[offset:] set_data_sources_with_separator(last[0], sources, '') for component in last[1:]: component.set_enabled(False) self.set_select_buttons(self._select_buttons) self.set_state_buttons(self._state_buttons) self.set_encoder_controls(self._encoder_controls) self._update_navigation_button_state()
def _update_note_infos(self): if self.settings.is_enabled(): def min_max((l_min, l_max), (r_min, r_max)): return (min(l_min, r_min), max(l_max, r_max)) all_min_max_attributes = filter(None, imap(lambda e: e.get_min_max_note_values(), self._editors)) min_max_values = [(99999, -99999)] * 4 if len(all_min_max_attributes) > 0 else None for min_max_attribute in all_min_max_attributes: for i, attribute in enumerate(min_max_attribute): min_max_values[i] = min_max(min_max_values[i], attribute) for i in xrange(4): self.settings.set_min_max(i, min_max_values[i] if min_max_values else None) edit_all_notes_active = find_if(lambda e: e.modify_all_notes_enabled, self._editors) != None self.settings.set_info_message('Tweak to add note' if not edit_all_notes_active and not min_max_values else '')
def get_or_create_first_empty_clip_slot(track, song=None): u""" Return the first empty clip slot, creating a new scene if there is currently none available. Return `None` if this fails """ assert song is not None, u'A song instance must be injected to use `get_or_create_first_empty_clip_slot`' if liveobj_valid(track): first_empty_slot = find_if(lambda s: not s.has_clip, track.clip_slots) if first_empty_slot and liveobj_valid(first_empty_slot): return first_empty_slot try: song.create_scene(-1) slot = track.clip_slots[-1] if liveobj_valid(slot): return slot except Live.Base.LimitationError: pass
def _get_selected_child_from_model(self): devices = map(second, self.children) selected = self._get_track().view.selected_device if selected == None: return find_if(lambda d: isinstance(d, Live.DrumPad.DrumPad), devices) is_deeper = False while selected: if selected in devices: if isinstance(selected, Live.DrumPad.DrumPad): self._on_selected_drum_pad() self._update_child_slots() return selected if is_deeper and selected.can_have_drum_pads: self._on_selected_drum_pad() self._update_child_slots() return selected.view.selected_drum_pad return selected selected = selected.canonical_parent is_deeper = True
def possible_conversions(track, decorator_factory = None): conversions = [] if liveobj_valid(track): if is_midi_track(track) and len(track.devices) > 0: drum_rack = find_drum_rack_instrument(track) if liveobj_valid(drum_rack): drum_pad = drum_rack.view.selected_drum_pad if liveobj_valid(drum_pad) and len(drum_pad.chains) == 1 and find_instrument_devices(drum_pad.chains[0]): conversions.append(DrumPadToMidiTrack(drum_pad=drum_pad, track=track)) else: simpler = find_simpler(track) if simpler != None and simpler.playback_mode == Live.SimplerDevice.PlaybackMode.slicing: conversions.append(SlicesToDrumRack(device=simpler, track=track)) else: conversions.append(MoveDeviceChain(device=simpler, track=track, decorator_factory=decorator_factory)) elif is_audio_track(track): highlighted_clip_slot = track.canonical_parent.view.highlighted_clip_slot clip = find_if(lambda slot: slot.has_clip and highlighted_clip_slot == slot, track.clip_slots) if liveobj_valid(clip) and not clip.is_recording: conversions.append(CreateTrackWithSimpler(clip_slot=highlighted_clip_slot, track=track)) return conversions
def _color_for_pad(self, pad): has_soloed_pads = bool(find_if(lambda pad: pad.solo, self._all_drum_pads)) button_color = 'DrumGroup.PadEmpty' if pad == self._selected_drum_pad: button_color = 'DrumGroup.PadSelected' if has_soloed_pads and not pad.solo and not pad.mute: button_color = 'DrumGroup.PadSelectedNotSoloed' elif pad.mute and not pad.solo: button_color = 'DrumGroup.PadMutedSelected' elif has_soloed_pads and pad.solo: button_color = 'DrumGroup.PadSoloedSelected' elif pad.chains: register = (pad.note-4)%32 button_color = 'DrumGroup.PadFilled' if (0 <= register <16) else 'DrumGroup.PadFilledAlt' if has_soloed_pads and not pad.solo: button_color = 'DrumGroup.PadFilled' if not pad.mute else 'DrumGroup.PadMuted' elif not has_soloed_pads and pad.mute: button_color = 'DrumGroup.PadMuted' elif has_soloed_pads and pad.solo: button_color = 'DrumGroup.PadSoloed' return button_color
def _on_selected_device_changed(self): selected_device = self._selected_track.view.selected_device #if selected_device: # self._script.log_message('selected_device=' + str(selected_device.name)) if selected_device == None: self._set_current_node(self._make_exit_node()) return is_just_default_child_selection = False if self._current_node and self._current_node.children: selected = self.selected_object #self._script.log_message('selected=' + str(selected)) if isinstance(selected, Live.DrumPad.DrumPad) and find_if(lambda pad: pad.chains and pad.chains[0].devices and pad.chains[0].devices[0] == selected_device, selected.canonical_parent.drum_pads): is_just_default_child_selection = True if isinstance(selected, Live.Chain.Chain) and selected_device and selected_device.canonical_parent == selected and selected.devices[0] == selected_device: is_just_default_child_selection = True if not is_just_default_child_selection: if selected_device: target = selected_device.canonical_parent self._script.log_message('target=' + str(target)) if (not self._current_node or self._current_node.object != target): node = self._make_navigation_node(target, is_entering=False) #self._script.log_message('node=' + str(node)) self._set_current_node(node)
def is_selected(self): return find_if(lambda x: x.is_selected, self.children)
def find_drum_pad(items): elements = imap(lambda i: i.item, items) return find_if(lambda e: is_drum_pad(e), elements)
def process_firmware_response(self, data): if not self.state == 'start': raise AssertionError entry = find_if(lambda entry: entry['type'] == 'firmware', data) self.state = entry and ('success' if entry['success'] else 'failure')
def _find_top_level_instrument(self): return find_if(lambda device: device.type == Live.Device.DeviceType.instrument, self._current_track().devices)
def find_parameter(name, host): parameters = host.parameters if host != None else [] return find_if(lambda p: p.original_name == name, parameters)
def _get_parameter_by_name(device, name): parameters = device.parameters if liveobj_valid(device) else [] return find_if(lambda x: x.name == name, parameters)
def selected_slice(self): return find_if(lambda s: s.time == self.view.selected_slice, self.slices)
def scale_by_name(name): return find_if(lambda m: m.name == name, SCALES)
def is_first_device_on_pad(device, drum_pad): return find_if(lambda pad: pad.chains and pad.chains[0].devices and pad.chains[0].devices[0] == device, drum_pad.canonical_parent.drum_pads)
def find_decorated_object(proxied_object, decorator_factory): decorated_obj = None if liveobj_valid(proxied_object): decorated_obj = find_if(lambda obj: not liveobj_changed(obj.proxied_object, proxied_object), decorator_factory.decorated_objects.itervalues()) return decorated_obj
def get_parameter_by_name(self, name): return find_if(lambda p: p.name == name, self._live_object.parameters)
def get_parameter_by_name(decorator, name): return find_if(lambda p: p.name == name, decorator._live_object.parameters)
def _is_edit_all_notes_active(self): return find_if(lambda e: e.modify_all_notes_enabled, self._editors) != None
def _get_scale_from_name(self, name): return find_if(lambda scale: scale.name == name, SCALES) or DEFAULT_SCALE