def _split_payload_at_offsets(self, offsets): assert isinstance(self.payload, containertools.Container) music = self.payload self._payload = containertools.Container() shards = mutationtools.mutate([music]).split( offsets, cyclic=False, fracture_spanners=True, ) shards = [shard[0] for shard in shards] for shard in shards: if not inspect(shard).is_well_formed(): wellformednesstools.tabulate_well_formedness_violations_in_expr(shard) return shards
def evaluate(self): r'''Evaluate counttime component select expression. Returns none when nonevaluable. Returns start-positioned rhythm payload expression when evaluable. ''' from experimental.tools import musicexpressiontools anchor_timespan = self._evaluate_anchor_timespan() voice_proxy = \ self.score_specification.voice_data_structures_by_voice[ self.voice_name] rhythm_payload_expressions = \ voice_proxy.payload_expressions_by_attribute['rhythm'] # TODO: will this have to be optimized with bisect? rhythm_payload_expressions = \ rhythm_payload_expressions.get_timespans_that_satisfy_time_relation( timerelationtools.timespan_2_intersects_timespan_1( timespan_1=anchor_timespan)) if not rhythm_payload_expressions: return rhythm_payload_expressions = \ copy.deepcopy(rhythm_payload_expressions) rhythm_payload_expressions = \ timespantools.TimespanInventory(rhythm_payload_expressions) rhythm_payload_expressions.sort() assert anchor_timespan.is_well_formed, repr(anchor_timespan) rhythm_payload_expressions &= anchor_timespan expression = \ musicexpressiontools.StartPositionedRhythmPayloadExpression( start_offset=anchor_timespan.start_offset) for rhythm_payload_expression in rhythm_payload_expressions: expression.payload.extend(rhythm_payload_expression.payload) assert inspect(expression.payload).is_well_formed() # TODO: eventually make this be able to work #callback_cache = self.score_specification.interpreter.callback_cache #expression = expression.get_elements_that_satisfy_time_relation( # time_relation, callback_cache) expression = self._apply_callbacks(expression) expression._voice_name = self.voice_name return expression
def rotate(self, n, fracture_spanners=True): r'''Rotate start-positioned rhythm payload expression. Example 1. Rotate by count: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-1) :: >>> print expression.storage_format musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=containertools.Container( music=[{d'8, e'8, f'8}, {c'8}] ), start_offset=durationtools.Offset(0, 1) ) Example 2. Rotate by duration: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-Duration(3, 16)) :: >>> print expression.storage_format musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=containertools.Container( music=[{d'16, e'8, f'8}, {c'8, d'16}] ), start_offset=durationtools.Offset(0, 1) ) Operates in place and returns start-positioned rhythm payload expression. ''' from experimental.tools import musicexpressiontools if isinstance(n, int): leaves = datastructuretools.CyclicTuple(self.payload.select_leaves()) if 0 < n: split_offset = leaves[-n]._get_timespan().start_offset elif n == 0: return self else: split_offset = leaves[-(n+1)]._get_timespan().stop_offset elif isinstance(n, musicexpressiontools.RotationIndicator): rotation_indicator = n if rotation_indicator.level is None: components_at_level = self.payload.select_leaves() else: components_at_level = [] for component in \ iterationtools.iterate_components_in_expr(self.payload): score_index = component._get_parentage().score_index if len(score_index) == rotation_indicator.level: components_at_level.append(component) components_at_level = datastructuretools.CyclicTuple(components_at_level) if isinstance(rotation_indicator.index, int): if 0 < rotation_indicator.index: split_offset = components_at_level[ -rotation_indicator.index]._get_timespan().start_offset elif n == 0: return self else: split_offset = components_at_level[ -(rotation_indicator.index+1)]._get_timespan().stop_offset else: index = durationtools.Duration(rotation_indicator.index) if 0 <= index: split_offset = self.payload._get_duration() - index else: split_offset = abs(index) if rotation_indicator.fracture_spanners is not None: fracture_spanners = rotation_indicator.fracture_spanners else: n = durationtools.Duration(n) if 0 <= n: split_offset = self.payload._get_duration() - n else: split_offset = abs(n) #self._debug(split_offset, 'split offset') try: payload_duration = getattr(self, 'payload') except AttributeError: payload_duration = self.payload._get_duration() if split_offset == payload_duration: return self if fracture_spanners: result = mutationtools.mutate([self.payload]).split( [split_offset], cyclic=False, fracture_spanners=True, tie_split_notes=False, ) left_half, right_half = result[0][0], result[-1][0] payload = containertools.Container() payload.extend(right_half) payload.extend(left_half) assert inspect(payload).is_well_formed() self._payload = payload else: result = mutationtools.mutate(self.payload[:]).split( [split_offset], cyclic=False, fracture_spanners=False, tie_split_notes=False, ) left_half, right_half = result[0], result[-1] spanner_classes = (spannertools.DuratedComplexBeamSpanner, ) descendants = self.payload._get_descendants() for spanner in descendants.get_spanners(spanner_classes): if left_half[-1] in spanner and right_half[0] in spanner: leaf_right_of_split = right_half[0] split_offset_in_beam = spanner._duration_offset_in_me( leaf_right_of_split) left_durations, right_durations = \ sequencetools.split_sequence_by_weights( spanner.durations, [split_offset_in_beam], cyclic=False, overhang=True, ) new_durations = right_durations + left_durations spanner._durations = new_durations new_payload = right_half + left_half self.payload._music = new_payload for component in new_payload: component._update_later(offsets=True) for spanner in self.payload._get_descendants().get_spanners(): spanner._components.sort( lambda x, y: cmp(x._get_parentage().score_index, y._get_parentage().score_index)) assert inspect(self.payload).is_well_formed() return self