예제 #1
0
    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
예제 #2
0
 def supply_missing_set_expressions(self, attribute, score_specification,
                                    voice_name):
     r'''Operates in place and returns inventory.
     '''
     assert self.is_sorted
     if not self and not score_specification.time_signatures:
         return self
     elif not self and score_specification.time_signatures:
         timespan = score_specification.timespan
         set_expression = \
             score_specification.make_default_timespan_delimited_single_context_set_expression(
             attribute, timespan, voice_name)
         self[:] = [set_expression]
         return self
     timespans = timespantools.TimespanInventory(
         [expr.target_timespan for expr in self])
     timespans.append(score_specification.timespan)
     missing_region_timespans = timespans.compute_logical_xor()
     for missing_region_timespan in missing_region_timespans:
         missing_set_expression = \
             score_specification.make_default_timespan_delimited_single_context_set_expression(
             attribute, missing_region_timespan, voice_name)
         self.append(missing_set_expression)
     self.sort()
     return self
예제 #3
0
    def __or__(self, expr):
        r'''Logical OR of two payload expressions.

        Payload expression must be able to fuse.

        Returns timespan inventory.
        '''
        assert self._can_fuse(expr)
        if isinstance(self.payload, scoretools.Container):
            selection = select(self.payload[0], contiguous=True)
            left = mutate(selection).copy()[0]
            selection = select(expr.payload[0], contiguous=True)
            right = mutate(selection).copy()[0]
            payload = scoretools.Container([left, right])
            for component in payload[:]:
                component._extract()
            payload = scoretools.Container([payload])
        else:
            payload = self.payload + expr.payload
        result = type(self)(
            [],
            start_offset=self.timespan.start_offset,
            voice_name=self.voice_name,
        )
        result._payload = payload
        return timespantools.TimespanInventory([result])
예제 #4
0
 def __init__(self):
     from experimental.tools import musicexpressiontools
     self._leaf_start_offsets = []
     self._leaf_stop_offsets = []
     self._leaves = []
     self._payload_expressions_by_attribute = \
         musicexpressiontools.AttributeDictionary()
     for attribute in self._payload_expressions_by_attribute:
         self._payload_expressions_by_attribute[attribute] = \
             timespantools.TimespanInventory()
     self._voice_division_list = None
예제 #5
0
    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
예제 #6
0
 def _get_timespan_delimited_single_context_set_expressions(
         self, attribute):
     result = timespantools.TimespanInventory()
     for context_proxy in \
         self.score_specification.single_context_set_expressions_by_context.values():
         expressions = \
             context_proxy.timespan_delimited_single_context_set_expressions_by_attribute[attribute]
         for timespan_delimited_single_context_set_expression in expressions:
             if not timespan_delimited_single_context_set_expression.source_expression == self:
                 result.append(
                     timespan_delimited_single_context_set_expression)
     return result
예제 #7
0
    def __or__(self, set_expression):
        r'''Logical OR of timespan-delimited single-context set expression
        and `set_expression`.

        Raises exception when timespan-delimited single-context set expression
        can not fuse with `set_expression`.

        Returns timespan inventory.
        '''
        assert self._can_fuse(set_expression)
        stop_offset = self.target_timespan.stop_offset + \
            set_expression.target_timespan.duration
        target_timespan = new(self.target_timespan, stop_offset=stop_offset)
        result = new(self, target_timespan=target_timespan)
        return timespantools.TimespanInventory([result])
예제 #8
0
    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(
            timespantools.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
예제 #9
0
 def get_offset_indices(
     self,
     timespan_1,
     timespan_2_start_offsets,
     timespan_2_stop_offsets,
 ):
     r'''Gets offset indices of compound inequality.
     '''
     from abjad.tools import timespantools
     from abjad.tools import timespantools
     timespans = timespantools.TimespanInventory()
     for element in self:
         # TODO: compress the following two branches
         if isinstance(element, type(self)):
             result = element.get_offset_indices(timespan_1,
                                                 timespan_2_start_offsets,
                                                 timespan_2_stop_offsets)
             timespans.extend(result)
         elif isinstance(element, timespantools.Inequality):
             offset_indices = element.get_offset_indices(
                 timespan_1, timespan_2_start_offsets,
                 timespan_2_stop_offsets)
             timespan = timespantools.Timespan(*offset_indices)
             timespans.append(timespan)
         else:
             message = 'unknown inequality: {!r}.'
             message = message(element)
             raise TypeError(message)
     if self.logical_operator == 'and':
         result = timespans.compute_logical_and()
     elif self.logical_operator == 'or':
         timespans.sort()
         result = timespans.compute_logical_or()
     elif self.logical_operator == 'xor':
         result = timespans.compute_logical_xor()
     else:
         message = 'unknown logical operator: {!r}.'
         message = mesage.format(self.logical_operator)
         raise ValueError(message)
     return result
예제 #10
0
 def __init__(self):
     #collections.OrderedDict.__init__(self)
     datastructuretools.TypedOrderedDict.__init__(self)
     for attribute in self.attributes:
         self[attribute] = timespantools.TimespanInventory()
     assert 'time_signatures' in self
예제 #11
0
    def __illustrate__(self, denominator=16, range_=None, scale=None):
        r'''Illustrates meter inventory.

        ..  container:: example

            ::

                >>> meter_inventory = metertools.MeterInventory([
                ...     (3, 4), (5, 16), (7, 8),
                ...     ])
                >>> show(meter_inventory, scale=0.5) # doctest: +SKIP

            ..  doctest

                >>> illustration = meter_inventory.__illustrate__()
                >>> print(format(illustration))
                % ...
                <BLANKLINE>
                \version "..."
                \language "english"
                <BLANKLINE>
                \header {
                    tagline = \markup {}
                }
                <BLANKLINE>
                \layout {}
                <BLANKLINE>
                \paper {}
                <BLANKLINE>
                \markup {
                    \column
                        {
                            \combine
                                \combine
                                    \translate
                                        #'(1.0 . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        3
                                                        4
                                    \translate
                                        #'(49.387... . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        5
                                                        16
                                \translate
                                    #'(69.548... . 1)
                                    \sans
                                        \fontsize
                                            #-3
                                            \center-align
                                                \fraction
                                                    7
                                                    8
                            \combine
                                \postscript
                                    #"
                                    0.2 setlinewidth
                                    1 0.5 moveto
                                    49.387... 0.5 lineto
                                    stroke
                                    1 1.25 moveto
                                    1 -0.25 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    49.387... 0.5 moveto
                                    69.548... 0.5 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    69.548... 0.5 moveto
                                    126 0.5 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    126 1.25 moveto
                                    126 -0.25 lineto
                                    stroke
                                    "
                                \postscript
                                    #"
                                    1 -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    5.032... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    9.064... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    13.096... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    17.129... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    21.161... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    25.193... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    29.225... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    33.258... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    37.290... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    41.322... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    45.354... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    53.419... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    57.451... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    61.483... -2 moveto
                                    0 -7.272... rlineto
                                    stroke
                                    65.516... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    73.580... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    77.612... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    81.645... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    85.677... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    89.709... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    93.741... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    97.774... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    101.806... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    105.838... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    109.870... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    113.903... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    117.935... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    121.967... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    126 -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    "
                        }
                    }


        Returns LilyPond file.
        '''
        from abjad.tools import metertools
        durations = [_.duration for _ in self]
        total_duration = sum(durations)
        offsets = mathtools.cumulative_sums(durations, start=0)
        timespan_inventory = timespantools.TimespanInventory()
        for one, two in sequencetools.iterate_sequence_nwise(offsets):
            timespan = timespantools.Timespan(
                start_offset=one,
                stop_offset=two,
                )
            timespan_inventory.append(timespan)

        if range_ is not None:
            minimum, maximum = range_
        else:
            minimum, maximum = 0, total_duration
        minimum = float(durationtools.Offset(minimum))
        maximum = float(durationtools.Offset(maximum))
        if scale is None:
            scale = 1.
        assert 0 < scale
        postscript_scale = 125. / (maximum - minimum)
        postscript_scale *= float(scale)
        postscript_x_offset = (minimum * postscript_scale) - 1
        timespan_markup = timespan_inventory._make_timespan_inventory_markup(
            timespan_inventory,
            postscript_x_offset,
            postscript_scale,
            draw_offsets=False,
            )
        ps = markuptools.Postscript()
        rational_x_offset = durationtools.Offset(0)
        for meter in self:
            kernel_denominator = denominator or meter.denominator
            kernel = metertools.MetricAccentKernel.from_meter(
                meter, kernel_denominator)
            for offset, weight in sorted(kernel.kernel.items()):
                weight = float(weight) * -40
                ps_x_offset = float(rational_x_offset + offset)
                ps_x_offset *= postscript_scale
                ps_x_offset += 1
                ps = ps.moveto(ps_x_offset, -2)
                ps = ps.rlineto(0, weight)
                ps = ps.stroke()
            rational_x_offset += meter.duration
        ps = markuptools.Markup.postscript(ps)
        lines_markup = markuptools.Markup.combine(timespan_markup, ps)
        fraction_markups = []
        for meter, offset in zip(self, offsets):
            numerator, denominator = meter.numerator, meter.denominator
            fraction = markuptools.Markup.fraction(numerator, denominator)
            fraction = fraction.center_align().fontsize(-3).sans()
            x_translation = (float(offset) * postscript_scale)
            x_translation -= postscript_x_offset
            fraction = fraction.translate((x_translation, 1))
            fraction_markups.append(fraction)
        fraction_markup = fraction_markups[0]
        for markup in fraction_markups[1:]:
            fraction_markup = markuptools.Markup.combine(
                fraction_markup, markup)
        markup = markuptools.Markup.column([fraction_markup, lines_markup])
        return markup.__illustrate__()