Ejemplo n.º 1
0
 def _fuse_tuplets(self):
     from abjad.tools import scoretools
     assert self._all_are_contiguous_components_in_same_parent(
         self, prototype=(scoretools.Tuplet, ))
     if len(self) == 0:
         return None
     first = self[0]
     first_multiplier = first.multiplier
     first_type = type(first)
     for tuplet in self[1:]:
         if tuplet.multiplier != first_multiplier:
             message = 'tuplets must carry same multiplier.'
             raise ValueError(message)
         if type(tuplet) != first_type:
             message = 'tuplets must be same type.'
             raise TypeError(message)
     if isinstance(first, scoretools.FixedDurationTuplet):
         total_contents_duration = sum([x._contents_duration for x in self])
         new_target_duration = first_multiplier * total_contents_duration
         new_tuplet = scoretools.FixedDurationTuplet(
             new_target_duration, [])
     elif isinstance(first, scoretools.Tuplet):
         new_tuplet = scoretools.Tuplet(first_multiplier, [])
     else:
         message = 'unknown tuplet type.'
         raise TypeError(message)
     wrapped = False
     if self[0]._get_parentage().root is not \
         self[-1]._get_parentage().root:
         dummy_container = scoretools.Container(self)
         wrapped = True
     mutate(self).swap(new_tuplet)
     if wrapped:
         del (dummy_container[:])
     return new_tuplet
Ejemplo n.º 2
0
 def _make_tuplets(self, divisions, leaf_lists):
     assert len(divisions) == len(leaf_lists)
     tuplets = []
     for division, leaf_list in zip(divisions, leaf_lists):
         tuplet = scoretools.FixedDurationTuplet(division, leaf_list)
         tuplets.append(tuplet)
     return tuplets
Ejemplo n.º 3
0
 def _remove_and_shrink_durated_parent_containers(self):
     from abjad.tools import indicatortools
     from abjad.tools import scoretools
     prolated_leaf_duration = self._get_duration()
     parentage = self._get_parentage(include_self=False)
     prolations = parentage._prolations
     current_prolation, i = durationtools.Duration(1), 0
     parent = self._parent
     while parent is not None and not parent.is_simultaneous:
         current_prolation *= prolations[i]
         if isinstance(parent, scoretools.FixedDurationTuplet):
             candidate_new_parent_dur = (
                 parent.target_duration -
                 current_prolation * self.written_duration)
             if durationtools.Duration(0) < candidate_new_parent_dur:
                 parent.target_duration = candidate_new_parent_dur
         elif isinstance(parent, scoretools.Measure):
             indicator = parent._get_indicator(indicatortools.TimeSignature)
             parent_time_signature = indicator
             old_prolation = parent_time_signature.implied_prolation
             naive_time_signature = (parent_time_signature.duration -
                                     prolated_leaf_duration)
             better_time_signature = mathtools.NonreducedFraction(
                 naive_time_signature)
             better_time_signature = better_time_signature.with_denominator(
                 parent_time_signature.denominator)
             better_time_signature = indicatortools.TimeSignature(
                 better_time_signature)
             detach(indicatortools.TimeSignature, parent)
             attach(better_time_signature, parent)
             indicator = parent._get_indicator(indicatortools.TimeSignature)
             parent_time_signature = indicator
             new_prolation = parent_time_signature.implied_prolation
             adjusted_prolation = old_prolation / new_prolation
             for x in parent:
                 if isinstance(x, scoretools.FixedDurationTuplet):
                     x.target_duration *= adjusted_prolation
                 else:
                     if adjusted_prolation != 1:
                         new_target = \
                             x._preprolated_duration * adjusted_prolation
                         scoretools.FixedDurationTuplet(new_target, [x])
         parent = parent._parent
         i += 1
     parentage = self._get_parentage(include_self=False)
     parent = self._parent
     if parent:
         index = parent.index(self)
         del (parent[index])
     for x in parentage:
         if not len(x):
             x._extract()
         else:
             break
Ejemplo n.º 4
0
 def _make_music(self, divisions, seeds):
     #assert not seeds, repr(seeds)
     if seeds is None:
         seeds = 0
     selections = []
     divisions = [durationtools.Division(_) for _ in divisions]
     denominators = datastructuretools.CyclicTuple(self.denominators)
     extra_counts_per_division = self.extra_counts_per_division or (0,)
     extra_counts_per_division = datastructuretools.CyclicTuple(
         extra_counts_per_division
         )
     for i, division in enumerate(divisions, seeds):
         # not yet extended to work with non-power-of-two divisions
         assert mathtools.is_positive_integer_power_of_two(
             division.denominator), repr(division)
         denominator = denominators[i]
         extra_count = extra_counts_per_division[i]
         basic_duration = durationtools.Duration(1, denominator)
         unprolated_note_count = None
         if division < 2 * basic_duration:
             notes = scoretools.make_notes([0], [division])
         else:
             unprolated_note_count = division / basic_duration
             unprolated_note_count = int(unprolated_note_count)
             unprolated_note_count = unprolated_note_count or 1
             if 0 < extra_count:
                 modulus = unprolated_note_count
                 extra_count = extra_count % modulus
             elif extra_count < 0:
                 modulus = int(math.ceil(unprolated_note_count / 2.0))
                 extra_count = abs(extra_count) % modulus
                 extra_count *= -1
             note_count = unprolated_note_count + extra_count
             durations = note_count * [basic_duration]
             notes = scoretools.make_notes([0], durations)
             assert all(
                 _.written_duration.denominator == denominator
                 for _ in notes
                 )
         tuplet_duration = durationtools.Duration(division)
         tuplet = scoretools.FixedDurationTuplet(
             duration=tuplet_duration,
             music=notes,
             )
         if unprolated_note_count is not None:
             preferred_denominator = unprolated_note_count
             tuplet.preferred_denominator = preferred_denominator
         selection = selectiontools.Selection(tuplet)
         selections.append(selection)
     self._apply_beam_specifier(selections)
     return selections
Ejemplo n.º 5
0
 def recurse(node, tuplet_duration):
     basic_prolated_duration = tuplet_duration / node._contents_duration
     basic_written_duration = \
         basic_prolated_duration.equal_or_greater_power_of_two
     tuplet = scoretools.FixedDurationTuplet(tuplet_duration, [])
     for child in node.children:
         if isinstance(child, type(self)):
             tuplet.extend(recurse(
                 child,
                 child.preprolated_duration * basic_written_duration))
         else:
             leaves = child(basic_written_duration)
             tuplet.extend(leaves)
             if 1 < len(leaves):
                 tie = spannertools.Tie()
                 attach(tie, leaves)
     if tuplet.multiplier == 1:
         return tuplet[:]
     return [tuplet]
Ejemplo n.º 6
0
def move_measure_prolation_to_full_measure_tuplet(expr):
    '''Move measure prolation to full-measure tuplet.

    Turn non-power-of-two measures into power-of-two measures containing
    a single fixed-duration tuplet.

    Note that not all non-power-of-two measures can be made power-of-two.

    Returns None because processes potentially many measures.
    '''
    from abjad.tools import indicatortools
    from abjad.tools import scoretools

    for measure in iterate(expr).by_class(scoretools.Measure):
        effective_time_signature = measure.time_signature
        if effective_time_signature.has_non_power_of_two_denominator:

            # find time signature and contents multipliers
            time_signature_multiplier = effective_time_signature.implied_prolation
            contents_multiplier = \
                measure._get_likely_multiplier_of_components(measure[:])

            # update non-power-of-two time signature to power-of-two
            power_of_two_time_signature = effective_time_signature.with_power_of_two_denominator(
                contents_multiplier)
            detach(indicatortools.TimeSignature, measure)
            attach(power_of_two_time_signature, measure)

            # find target duration and create tuplet
            target_duration = time_signature_multiplier * measure._contents_duration
            tuplet = scoretools.FixedDurationTuplet(target_duration,
                                                    measure[:])

            # scale tuplet contents, if helpful
            if contents_multiplier is not None:
                numerator = contents_multiplier.numerator
                denominator = contents_multiplier.denominator
                pair = (denominator, numerator)
                inverse_multiplier = durationtools.Multiplier(*pair)
                tuplet._scale_contents(inverse_multiplier)
Ejemplo n.º 7
0
 def _to_tuplet_with_ratio(self, proportions, is_diminution=True):
     from abjad.tools import scoretools
     # check input
     proportions = mathtools.Ratio(proportions)
     # find target duration of fixed-duration tuplet
     target_duration = self.written_duration
     # find basic duration of note in tuplet
     basic_prolated_duration = target_duration / sum(proportions.numbers)
     # find basic written duration of note in tuplet
     basic_written_duration = \
         basic_prolated_duration.equal_or_greater_assignable
     # find written duration of each note in tuplet
     written_durations = [
         _ * basic_written_duration for _ in proportions.numbers
     ]
     # make tuplet notes
     try:
         notes = [scoretools.Note(0, x) for x in written_durations]
     except AssignabilityError:
         denominator = target_duration._denominator
         note_durations = [
             durationtools.Duration(_, denominator)
             for _ in proportions.numbers
         ]
         notes = scoretools.make_notes(0, note_durations)
     # make tuplet
     tuplet = scoretools.FixedDurationTuplet(target_duration, notes)
     # fix tuplet contents if necessary
     tuplet._fix()
     # change prolation if necessary
     if not tuplet.multiplier == 1:
         if is_diminution:
             if not tuplet.is_diminution:
                 tuplet.toggle_prolation()
         else:
             if tuplet.is_diminution:
                 tuplet.toggle_prolation()
     # return tuplet
     return tuplet
Ejemplo n.º 8
0
    def to_tuplet(
        self,
        proportions,
        dotted=False,
        is_diminution=True,
        ):
        r'''Change logical tie to tuplet.

        ..  container:: example

            **Example 1.** Change logical tie to diminished tuplet:

            ::

                >>> staff = Staff(r"c'8 ~ c'16 cqs''4")
                >>> crescendo = spannertools.Hairpin(descriptor='p < f')
                >>> attach(crescendo, staff[:])
                >>> override(staff).dynamic_line_spanner.staff_padding = 3
                >>> time_signature = TimeSignature((7, 16))
                >>> attach(time_signature, staff)

            ..  doctest::

                >>> print(format(staff))
                \new Staff \with {
                    \override DynamicLineSpanner #'staff-padding = #3
                } {
                    \time 7/16
                    c'8 ~ \< \p
                    c'16
                    cqs''4 \f
                }

            ::

                >>> show(staff) # doctest: +SKIP

            ::

                >>> logical_tie = inspect_(staff[0]).get_logical_tie()
                >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=True)
                FixedDurationTuplet(Duration(3, 16), "c'8 c'16 c'16 c'16")

            ..  doctest::

                >>> print(format(staff))
                \new Staff \with {
                    \override DynamicLineSpanner #'staff-padding = #3
                } {
                    \time 7/16
                    \tweak #'text #tuplet-number::calc-fraction-text
                    \times 3/5 {
                        c'8 \< \p
                        c'16
                        c'16
                        c'16
                    }
                    cqs''4 \f
                }

            ::

                >>> show(staff) # doctest: +SKIP

        ..  container:: example

            **Example 2.** Change logical tie to augmented tuplet:

            ::

                >>> staff = Staff(r"c'8 ~ c'16 cqs''4")
                >>> crescendo = spannertools.Hairpin(descriptor='p < f')
                >>> attach(crescendo, staff[:])
                >>> override(staff).dynamic_line_spanner.staff_padding = 3
                >>> time_signature = TimeSignature((7, 16))
                >>> attach(time_signature, staff)

            ..  doctest::

                >>> print(format(staff))
                \new Staff \with {
                    \override DynamicLineSpanner #'staff-padding = #3
                } {
                    \time 7/16
                    c'8 ~ \< \p
                    c'16
                    cqs''4 \f
                }

            ::

                >>> show(staff) # doctest: +SKIP

            ::

                >>> logical_tie = inspect_(staff[0]).get_logical_tie()
                >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=False)
                FixedDurationTuplet(Duration(3, 16), "c'16 c'32 c'32 c'32")

            ..  doctest::

                >>> print(format(staff))
                \new Staff \with {
                    \override DynamicLineSpanner #'staff-padding = #3
                } {
                    \time 7/16
                    \tweak #'text #tuplet-number::calc-fraction-text
                    \times 6/5 {
                        c'16 \< \p
                        c'32
                        c'32
                        c'32
                    }
                    cqs''4 \f
                }

            ::

                >>> show(staff) # doctest: +SKIP

        Returns tuplet.
        '''
        from abjad.tools import scoretools
        from abjad.tools import mathtools
        from abjad.tools import agenttools
        from abjad.tools import scoretools
        from abjad.tools import spannertools
        from abjad.tools import scoretools

        # coerce input
        proportions = mathtools.Ratio(proportions)

        # find target duration of fixed-duration tuplet
        target_duration = self._preprolated_duration

        # find duration of each note in tuplet
        prolated_duration = target_duration / sum(proportions)

        # find written duration of each notes in tuplet
        if is_diminution:
            if dotted:
                basic_written_duration = \
                    prolated_duration.equal_or_greater_assignable
            else:
                basic_written_duration = \
                    prolated_duration.equal_or_greater_power_of_two
        else:
            if dotted:
                basic_written_duration = \
                    prolated_duration.equal_or_lesser_assignable
            else:
                basic_written_duration = \
                    prolated_duration.equal_or_lesser_power_of_two

        # find written duration of each note in tuplet
        written_durations = [x * basic_written_duration for x in proportions]

        # make tuplet notes
        try:
            notes = [scoretools.Note(0, x) for x in written_durations]
        except AssignabilityError:
            denominator = target_duration._denominator
            note_durations = [durationtools.Duration(x, denominator)
                for x in proportions]
            notes = scoretools.make_notes(0, note_durations)

        # make tuplet
        tuplet = scoretools.FixedDurationTuplet(target_duration, notes)

        # replace logical tie with tuplet
        mutate(self).replace(tuplet)

        # untie tuplet
        for spanner in tuplet._get_spanners(spannertools.Tie):
            spanner._sever_all_components()
        #detach(spannertools.Tie, tuplet)

        # return tuplet
        return tuplet
def apply_full_measure_tuplets_to_contents_of_measures_in_expr(
        expr, supplement=None):
    r'''Applies full-measure tuplets to contents of measures in `expr`:

    ::

        >>> staff = Staff([
        ...     Measure((2, 8), "c'8 d'8"),
        ...     Measure((3, 8), "e'8 f'8 g'8")])
        >>> show(staff) # doctest: +SKIP

    ..  doctest::

        >>> print(format(staff))
        \new Staff {
            {
                \time 2/8
                c'8
                d'8
            }
            {
                \time 3/8
                e'8
                f'8
                g'8
            }
        }

    ::

        >>> scoretools.apply_full_measure_tuplets_to_contents_of_measures_in_expr(staff)
        >>> show(staff) # doctest: +SKIP

    ..  doctest::

        >>> print(format(staff))
        \new Staff {
            {
                \time 2/8
                {
                    c'8
                    d'8
                }
            }
            {
                \time 3/8
                {
                    e'8
                    f'8
                    g'8
                }
            }
        }

    Returns none.
    '''
    from abjad.tools import selectiontools
    from abjad.tools import scoretools

    supplement = selectiontools.Selection(supplement)
    assert isinstance(supplement, selectiontools.Selection)

    for measure in iterate(expr).by_class(scoretools.Measure):
        target_duration = measure._preprolated_duration
        tuplet = scoretools.FixedDurationTuplet(target_duration, measure[:])
        if supplement:
            new_supplement = mutate(supplement).copy()
            tuplet.extend(new_supplement)