def depthwise_offset_inventory(self): r'''Gets depthwise offset inventory of meter. .. container:: example :: >>> for depth, offsets in enumerate( ... meter.depthwise_offset_inventory): ... print(depth, offsets) 0 (Offset(0, 1), Offset(7, 4)) 1 (Offset(0, 1), Offset(3, 4), Offset(5, 4), Offset(7, 4)) 2 (Offset(0, 1), Offset(1, 4), Offset(1, 2), Offset(3, 4), Offset(1, 1), Offset(5, 4), Offset(3, 2), Offset(7, 4)) Returns dictionary. ''' inventory = [] for depth, nodes in sorted(self.root_node.depthwise_inventory.items()): offsets = [] for node in nodes: offsets.append(durationtools.Offset(node.start_offset)) offsets.append( durationtools.Offset(self.numerator, self.denominator)) inventory.append(tuple(offsets)) return tuple(inventory)
def set_offsets(self, start_offset=None, stop_offset=None): r'''Set timespan expression start offset to `start_offset` and stop offset to `stop_offset`: :: >>> result = timespan.set_offsets(Offset(3, 2), Offset(7, 2)) :: >>> print(format(result)) musicexpressiontools.TimespanExpression( anchor='red', callbacks=musicexpressiontools.CallbackInventory( [ 'self._scale(original_start_offset, original_stop_offset, Multiplier(4, 5))', 'self._set_offsets(original_start_offset, original_stop_offset, Offset(3, 2), Offset(7, 2))', ] ), ) Returns copy of timespan expression with callback. ''' if start_offset is not None: start_offset = durationtools.Offset(start_offset) if stop_offset is not None: stop_offset = durationtools.Offset(stop_offset) callback = \ 'self._set_offsets(original_start_offset, original_stop_offset, {!r}, {!r})' callback = callback.format(start_offset, stop_offset) return self._copy_and_append_callback(callback)
def __init__(self, payload=None, start_offset=None, voice_name=None): assert isinstance(voice_name, (str, type(None))), repr(voice_name) IterablePayloadExpression.__init__(self, payload=payload) start_offset = start_offset or durationtools.Offset(0) start_offset = durationtools.Offset(start_offset) self._start_offset = start_offset self._voice_name = voice_name
def __init__(self, divisions, start_offset=None, voice_name=None): from experimental.tools import musicexpressiontools assert isinstance(voice_name, (str, type(None))), repr(voice_name) start_offset = start_offset or durationtools.Offset(0) start_offset = durationtools.Offset(start_offset) self._start_offset = start_offset divisions = [durationtools.Division(_) for _ in divisions] self._divisions = divisions self._voice_name = voice_name
def __sub__(self, timespan): r'''Subtract `timespan` from start-positioned payload expression. Operates in place and returns timespan inventory. ''' if timespan.delays_timespan(self): split_offset = durationtools.Offset(timespan.stop_offset) duration_to_trim = split_offset - self.start_offset result = self._split_payload_at_offsets([duration_to_trim]) trimmed_payload = result[-1] self._payload = trimmed_payload self._start_offset = split_offset result = timespantools.TimespanInventory([self]) elif timespan.curtails_timespan(self): split_offset = durationtools.Offset(timespan.start_offset) duration_to_trim = self.stop_offset - split_offset if hasattr(self.payload, 'duration'): payload_duration = self.payload.duration else: payload_duration = self.payload._get_duration() duration_to_keep = payload_duration - duration_to_trim result = self._split_payload_at_offsets([duration_to_keep]) trimmed_payload = result[0] self._payload = trimmed_payload result = timespantools.TimespanInventory([self]) elif timespan.trisects_timespan(self): split_offsets = [] split_offsets.append(timespan.start_offset - self.start_offset) split_offsets.append(timespan.duration) result = self._split_payload_at_offsets(split_offsets) left_payload = result[0] right_payload = result[-1] left_timespan = timespantools.Timespan(self.start_offset) left_payload_expression = type(self)( payload=[], start_offset=left_timespan.start_offset, voice_name=self.voice_name, ) left_payload_expression._payload = left_payload right_timespan = timespantools.Timespan(timespan.stop_offset) right_payload_expression = type(self)( payload=[], start_offset=right_timespan.start_offset, voice_name=self.voice_name, ) right_payload_expression._payload = right_payload payload_expressions = \ [left_payload_expression, right_payload_expression] result = timespantools.TimespanInventory(payload_expressions) else: result = timespantools.TimespanInventory([self]) return result
def __init__( self, source_expression=None, start_offset=None, total_duration=None, voice_name=None, ): assert isinstance(voice_name, str), repr(voice_name) start_offset = start_offset or durationtools.Offset(0) start_offset = durationtools.Offset(start_offset) total_duration = durationtools.Duration(total_duration) self._source_expression = source_expression self._start_offset = start_offset self._total_duration = total_duration self._voice_name = voice_name
def previous_vertical_moment(self): r'''Reference to previous vertical moment backward in time. ''' from abjad.tools import scoretools if self.offset == 0: raise IndexError most_recent_start_offset = durationtools.Offset(0) token_leaf = None for leaf in self.leaves: #print '' #print leaf leaf_start = leaf._get_timespan().start_offset if leaf_start < self.offset: #print 'found leaf starting before this moment ...' if most_recent_start_offset <= leaf_start: most_recent_start_offset = leaf_start token_leaf = leaf else: #print 'found leaf starting on this moment ...' try: previous_leaf = leaf._get_in_my_logical_voice( -1, prototype=scoretools.Leaf) start = previous_leaf._get_timespan().start_offset #print previous_leaf, start if most_recent_start_offset <= start: most_recent_start_offset = start token_leaf = previous_leaf except IndexError: pass #print 'token_leaf is %s ...' % token_leaf if token_leaf is None: token_leaf = leaf #print 'token_leaf is %s ...' % token_leaf previous_vertical_moment = token_leaf._get_vertical_moment() return previous_vertical_moment
def __init__( self, component=None, indicator=None, is_annotation=None, name=None, scope=None, synthetic_offset=None, ): from abjad.tools import scoretools from abjad.tools import spannertools assert not isinstance(indicator, type(self)), repr(indicator) if component is not None: #assert isinstance(component, scoretools.Component) prototype = (scoretools.Component, spannertools.Spanner) assert isinstance(component, prototype) if scope is not None: if isinstance(scope, type): assert issubclass(scope, scoretools.Component) else: assert isinstance(scope, (scoretools.Component, str)) self._indicator = indicator if is_annotation is not None: is_annotation = bool(is_annotation) self._is_annotation = is_annotation self._component = component if name is not None: name = str(name) self._name = name self._scope = scope self._effective_context = None if synthetic_offset is not None: synthetic_offset = durationtools.Offset(synthetic_offset) self._synthetic_offset = synthetic_offset
def __call__(self): r'''Fits meters. ''' selected_kernels = [] current_offset = durationtools.Offset(0) while current_offset < self.ordered_offsets[-1]: kernel_scores = [] kernels = self._get_kernels(selected_kernels) offset_counter = self._get_offset_counter_at(current_offset) if not offset_counter: winning_kernel = self.longest_kernel if selected_kernels: winning_kernel = selected_kernels[-1] else: for kernel in kernels: initial_score = kernel(offset_counter) lookahead_score = self._get_lookahead_score( current_offset, kernel, kernels, ) score = initial_score + lookahead_score kernel_score = self.KernelScore( kernel=kernel, score=score, ) kernel_scores.append(kernel_score) kernel_scores.sort(key=lambda kernel_score: kernel_score.score) winning_kernel = kernel_scores[-1].kernel selected_kernels.append(winning_kernel) current_offset += winning_kernel.duration selected_meters = tuple(self.kernels[_] for _ in selected_kernels) return selected_meters
def __init__( self, beatspan=None, offset_in_ms=None, search_tree=None, tempo=None, ): from abjad.tools import quantizationtools beatspan = beatspan or durationtools.Duration(0) beatspan = durationtools.Duration(beatspan) offset_in_ms = offset_in_ms or durationtools.Duration(0) offset_in_ms = durationtools.Offset(offset_in_ms) if search_tree is None: search_tree = quantizationtools.UnweightedSearchTree() assert isinstance(search_tree, quantizationtools.SearchTree) tempo = tempo or indicatortools.Tempo(durationtools.Duration(1, 4), 60) #tempo = indicatortools.Tempo(tempo) if isinstance(tempo, tuple): tempo = indicatortools.Tempo(*tempo) assert not tempo.is_imprecise q_events = [] q_grids = [] self._beatspan = beatspan self._distances = {} self._offset_in_ms = offset_in_ms self._q_events = q_events self._q_grid = None self._q_grids = q_grids self._search_tree = search_tree self._tempo = tempo
def offsets(self): r'''The offsets between 0 and 1 of all of the leaf nodes in the QGrid. Returns tuple of ``Offset`` instances. ''' return tuple([x.start_offset for x in self.leaves[:-1]] + [durationtools.Offset(1)])
def __new__( class_, argument=None, payload=None, start_offset=None, ): from abjad.tools import durationtools argument = argument or (0, 1) if isinstance(argument, str): division = eval(argument) argument = division if payload is None: payload = argument.payload if start_offset is None: start_offset = argument.start_offset if isinstance(argument, mathtools.NonreducedFraction): if payload is None: payload = getattr(argument, 'payload', None) if start_offset is None: start_offset = getattr(argument, 'start_offset', None) self = NonreducedFraction.__new__(class_, argument) self._payload = payload if start_offset is not None: start_offset = durationtools.Offset(start_offset) self._start_offset = start_offset return self
def subdivide_leaves(self, pairs): r'''Given a sequence of leaf-index:subdivision-ratio pairs ``pairs``, subdivide the ``QGridLeaves`` described by the indices into ``QGridContainers`` containing ``QGridLeaves`` with durations equal to their respective subdivision-ratios. Returns the ``QEventProxies`` attached to thus subdivided ``QGridLeaf``. ''' pairs = sorted(dict(pairs).items()) leaf_indices = [pair[0] for pair in pairs] subdivisions = [pair[1] for pair in pairs] all_leaves = self.leaves leaves_to_subdivide = [all_leaves[idx] for idx in leaf_indices] q_event_proxies = [] for i, leaf in enumerate(leaves_to_subdivide): next_leaf = all_leaves[all_leaves.index(leaf) + 1] if next_leaf is self.next_downbeat: next_leaf_offset = durationtools.Offset(1) else: next_leaf_offset = next_leaf.start_offset q_event_proxies.extend(self.subdivide_leaf(leaf, subdivisions[i])) for q_event_proxy in tuple(next_leaf.q_event_proxies): if q_event_proxy.offset < next_leaf_offset: idx = next_leaf.q_event_proxies.index(q_event_proxy) q_event_proxies.append(next_leaf.q_event_proxies.pop(idx)) return q_event_proxies
def _from_expr_and_offset(expr, offset): from abjad.tools import scoretools from abjad.tools import selectiontools offset = durationtools.Offset(offset) governors = [] prototype = (list, tuple, selectiontools.SimultaneousSelection) message = 'must be component or of Abjad components: {!r}.' message = message.format(expr) if isinstance(expr, scoretools.Component): governors.append(expr) elif isinstance(expr, prototype): for x in expr: if isinstance(x, scoretools.Component): governors.append(x) else: raise TypeError(message) else: raise TypeError(message) governors.sort(key=lambda x: x._get_parentage().score_index) governors = tuple(governors) components = [] for governor in governors: components.extend(VerticalMoment._recurse(governor, offset)) components.sort(key=lambda x: x._get_parentage().score_index) components = tuple(components) return governors, components
def repeat_to_stop_offset(self, stop_offset): r'''Repeat start-positioned rhythm payload expression to `stop_offset`. :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.repeat_to_stop_offset(Offset(17, 16)) :: >>> print(format(expression)) musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=scoretools.Container( "{ c'8 d'8 e'8 f'8 } { c'8 d'8 e'8 f'8 } { c'16 }" ), start_offset=durationtools.Offset(0, 1), ) Operates in place and returns start-positioned rhythm payload expression. ''' stop_offset = durationtools.Offset(stop_offset) assert self.stop_offset <= stop_offset additional_duration = stop_offset - self.stop_offset needed_copies = int( math.ceil(additional_duration / self.payload._get_duration())) copies = [] for i in range(needed_copies): copies.append(copy.deepcopy(self.payload)) for element in copies: self.payload.extend(element) assert stop_offset <= self.stop_offset stop_offset = durationtools.Offset(stop_offset) assert stop_offset <= self.stop_offset assert self.start_offset < stop_offset duration_to_trim = self.stop_offset - stop_offset duration_to_keep = self.payload._get_duration() - duration_to_trim shards = self._split_payload_at_offsets([duration_to_keep]) assert len(shards) in (1, 2), repr(shards) self._payload = shards[0] return self
def __init__( self, offset_in_ms=None, search_tree=None, time_signature=None, tempo=None, use_full_measure=False, ): from abjad.tools import quantizationtools offset_in_ms = offset_in_ms or 0 offset_in_ms = durationtools.Offset(offset_in_ms) if search_tree is None: search_tree = quantizationtools.UnweightedSearchTree() assert isinstance(search_tree, quantizationtools.SearchTree) tempo = tempo or indicatortools.Tempo((1, 4), 60) #tempo = indicatortools.Tempo(tempo) if isinstance(tempo, tuple): tempo = indicatortools.Tempo(*tempo) assert not tempo.is_imprecise time_signature = time_signature or (4, 4) time_signature = indicatortools.TimeSignature(time_signature) use_full_measure = bool(use_full_measure) beats = [] if use_full_measure: beatspan = time_signature.duration beat = quantizationtools.QTargetBeat( beatspan=beatspan, offset_in_ms=offset_in_ms, search_tree=search_tree, tempo=tempo ) beats.append(beat) else: beatspan = durationtools.Duration(1, time_signature.denominator) current_offset_in_ms = offset_in_ms beatspan_duration_in_ms = \ tempo.duration_to_milliseconds(beatspan) for i in range(time_signature.numerator): beat = quantizationtools.QTargetBeat( beatspan=beatspan, offset_in_ms=current_offset_in_ms, search_tree=search_tree, tempo=tempo ) beats.append(beat) current_offset_in_ms += beatspan_duration_in_ms self._beats = tuple(beats) self._offset_in_ms = offset_in_ms self._search_tree = search_tree self._tempo = tempo self._time_signature = time_signature self._use_full_measure = use_full_measure
def _iterate_vertical_moments_forward_in_expr(expr): #if not isinstance(expr, scoretools.Component): # raise TypeError governors = (expr, ) current_offset, stop_offsets, buffer = \ durationtools.Offset(0), [], [] _buffer_components_starting_with(expr, buffer, stop_offsets) while buffer: vertical_moment = selectiontools.VerticalMoment() offset = durationtools.Offset(current_offset) components = list(buffer) components.sort(key=lambda x: x._get_parentage().score_index) vertical_moment._offset = offset vertical_moment._governors = governors vertical_moment._components = components yield vertical_moment current_offset, stop_offsets = min(stop_offsets), [] _update_buffer(current_offset, buffer, stop_offsets)
def _get_span_beam_offsets(self): offsets = [] if self.durations: offset = durationtools.Offset(self.durations[0]) offsets.append(offset) for duration in self.durations[1:]: offset = offsets[-1] + duration offsets.append(offset) offsets.pop() return offsets
def _get_grace_note_offsets(grace_note): from abjad.tools import durationtools grace_container = grace_note._parent carrier_leaf = grace_container._carrier carrier_leaf_start_offset = carrier_leaf._start_offset grace_displacement = -grace_note.written_duration sibling = grace_note._get_sibling(1) while sibling is not None: grace_displacement -= sibling.written_duration sibling = sibling._get_sibling(1) start_offset = durationtools.Offset( carrier_leaf_start_offset, grace_displacement=grace_displacement, ) grace_displacement += grace_note.written_duration stop_offset = durationtools.Offset( carrier_leaf_start_offset, grace_displacement=grace_displacement, ) return start_offset, stop_offset
def __and__(self, timespan): r'''Keep intersection of start-positioned payload expression and `timespan`. Operates in place and returns timespan inventory. ''' if timespan.contains_timespan_improperly(self): result = timespantools.TimespanInventory([self]) elif timespan.delays_timespan(self): split_offset = durationtools.Offset(timespan.stop_offset) duration_to_keep = split_offset - self.start_offset result = self._split_payload_at_offsets([duration_to_keep]) trimmed_payload = result[0] self._payload = trimmed_payload result = timespantools.TimespanInventory([self]) elif timespan.curtails_timespan(self): split_offset = durationtools.Offset(timespan.start_offset) duration_to_trim = split_offset - self.start_offset result = self._split_payload_at_offsets([duration_to_trim]) trimmed_payload = result[-1] self._payload = trimmed_payload self._start_offset = split_offset result = timespantools.TimespanInventory([self]) elif timespan.trisects_timespan(self): split_offsets = [] split_offsets.append(timespan.start_offset - self.start_offset) split_offsets.append(timespan.duration) result = self._split_payload_at_offsets(split_offsets) middle_payload = result[1] middle_timespan = timespantools.Timespan(*timespan.offsets) middle_payload_expression = type(self)( payload=[], start_offset=middle_timespan.start_offset, voice_name=self.voice_name, ) middle_payload_expression._payload = middle_payload result = timespantools.TimespanInventory( [middle_payload_expression]) else: result = timespantools.TimespanInventory() return result
def _update_component_offsets(component): from abjad.tools import durationtools previous = component._get_nth_component_in_time_order_from(-1) if previous is not None: start_offset = previous._stop_offset else: start_offset = durationtools.Offset(0) stop_offset = start_offset + component._get_duration() component._start_offset = start_offset component._stop_offset = stop_offset component._timespan._start_offset = start_offset component._timespan._stop_offset = stop_offset
def __init__(self, *args): from abjad.tools import quantizationtools if len(args) == 2: q_event, offset = args[0], durationtools.Offset(args[1]) assert isinstance(q_event, quantizationtools.QEvent) assert 0 <= offset <= 1 elif len(args) == 3: q_event, minimum, maximum = args[0], \ durationtools.Offset(args[1]), \ durationtools.Offset(args[2]) assert isinstance(q_event, quantizationtools.QEvent) assert minimum <= q_event.offset <= maximum offset = (q_event.offset - minimum) / (maximum - minimum) elif len(args) == 0: q_event = None offset = durationtools.Offset(0) else: message = 'can not initialize {}: {!r}.' message = message.format(type(self).__name__, args) raise ValueError(message) self._q_event = q_event self._offset = durationtools.Offset(offset)
def __init__(self, items=None): TypedCounter.__init__(self, item_class=durationtools.Offset) if items: for item in items: if hasattr(item, 'start_offset') and \ hasattr(item, 'stop_offset'): self[item.start_offset] += 1 self[item.stop_offset] += 1 elif hasattr(item, '_get_timespan'): self[item._get_timespan().start_offset] += 1 self[item._get_timespan().stop_offset] += 1 else: offset = durationtools.Offset(item) self[offset] += 1
def __init__(self, root_node=None, next_downbeat=None): from abjad.tools import quantizationtools if root_node is None: root_node = quantizationtools.QGridLeaf(preprolated_duration=1) assert isinstance( root_node, (quantizationtools.QGridLeaf, quantizationtools.QGridContainer)) if next_downbeat is None: next_downbeat = quantizationtools.QGridLeaf(preprolated_duration=1) assert isinstance(next_downbeat, quantizationtools.QGridLeaf) self._root_node = root_node self._next_downbeat = next_downbeat self._next_downbeat._offset = durationtools.Offset(1) self._next_downbeat._offsets_are_current = True
def __init__(self, music=None, offset=None): self._music = music if music is None: self._offset = offset self._components = () self._governors = () return governors, components = self._from_expr_and_offset(music, offset) offset = durationtools.Offset(offset) assert isinstance(governors, tuple) assert isinstance(components, tuple) self._offset = offset self._governors = tuple(governors) components = list(components) components.sort(key=lambda x: x._get_parentage().score_index) self._components = tuple(components)
def _get_logical_measure_start_offsets(self, component): from abjad.tools import durationtools from abjad.tools import indicatortools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ from abjad.tools.topleveltools import iterate expressions = [] prototype = indicatortools.TimeSignature components = self._iterate_entire_score(component) for component in components: expressions_ = component._get_indicators( prototype, unwrap=False, ) expressions.extend(expressions_) pairs = [] for expression in expressions: inspector = inspect_(expression.component) start_offset = inspector.get_timespan().start_offset time_signature = expression.indicator pair = start_offset, time_signature pairs.append(pair) offset_zero = durationtools.Offset(0) default_time_signature = indicatortools.TimeSignature((4, 4)) default_pair = (offset_zero, default_time_signature) if pairs and not pairs[0] == offset_zero: pairs.insert(0, default_pair) elif not pairs: pairs = [default_pair] pairs.sort(key=lambda x: x[0]) parentage = component._get_parentage() score_root = parentage.root inspector = inspect_(score_root) score_stop_offset = inspector.get_timespan().stop_offset dummy_last_pair = (score_stop_offset, None) pairs.append(dummy_last_pair) measure_start_offsets = [] pairs = sequencetools.iterate_sequence_nwise(pairs, n=2) for current_pair, next_pair in pairs: current_start_offset, current_time_signature = current_pair next_start_offset, next_time_signature = next_pair measure_start_offset = current_start_offset while measure_start_offset < next_start_offset: measure_start_offsets.append(measure_start_offset) measure_start_offset += current_time_signature.duration return measure_start_offsets
def evaluate(self): r'''Evaluate segment select expression. Returns none when nonevaluable. Returns start-positioned payload expression when evaluable. ''' from experimental.tools import musicexpressiontools segments = self.score_specification.segment_specifications[:] start_offset = durationtools.Offset(0) print('SEGMENTS', segments) expression = musicexpressiontools.StartPositionedPayloadExpression( payload=segments, start_offset=start_offset, ) expression = self._apply_callbacks(expression) return expression
def __call__(self): r'''Fits meters. Returns meter inventory. ''' from abjad.tools import metertools selected_kernels = [] current_offset = durationtools.Offset(0) while current_offset < self.ordered_offsets[-1]: kernel_scores = [] kernels = self._get_kernels(selected_kernels) offset_counter = self._get_offset_counter_at(current_offset) if not offset_counter: winning_kernel = self.longest_kernel if selected_kernels: winning_kernel = selected_kernels[-1] else: for kernel in kernels: if self.maximum_run_length and \ 1 < len(kernels) and \ self.maximum_run_length <= len(selected_kernels): last_n_kernels = \ selected_kernels[-self.maximum_run_length:] if len(set(last_n_kernels)) == 1: if kernel == last_n_kernels[-1]: continue initial_score = kernel(offset_counter) lookahead_score = self._get_lookahead_score( current_offset, kernel, kernels, ) score = initial_score + lookahead_score kernel_score = self.KernelScore( kernel=kernel, score=score, ) kernel_scores.append(kernel_score) kernel_scores.sort(key=lambda kernel_score: kernel_score.score) winning_kernel = kernel_scores[-1].kernel selected_kernels.append(winning_kernel) current_offset += winning_kernel.duration selected_meters = (self.kernels[_] for _ in selected_kernels) selected_meters = metertools.MeterInventory(selected_meters) return selected_meters
def _update_offsets_of_entire_tree(self): def recurse(container, current_offset): container._offset = current_offset container._offsets_are_current = True for child in container: if hasattr(child, 'children'): current_offset = recurse(child, current_offset) else: child._offset = current_offset child._offsets_are_current = True current_offset += child.duration return current_offset offset = durationtools.Offset(0) root = self.root if root is self and not hasattr(self, 'children'): self._offset = offset self._offsets_are_current = True else: recurse(root, offset)
def _update_component_offsets_in_seconds(component): from abjad.tools import durationtools try: current_duration_in_seconds = \ component._get_duration(in_seconds=True) previous = component._get_nth_component_in_time_order_from(-1) if previous is not None: component._start_offset_in_seconds = \ previous._get_timespan(in_seconds=True).stop_offset else: component._start_offset_in_seconds = durationtools.Offset(0) # this one case is possible for containers only if component._start_offset_in_seconds is None: raise MissingTempoError component._stop_offset_in_seconds = \ component._start_offset_in_seconds + \ current_duration_in_seconds except MissingTempoError: pass