Пример #1
0
 def _set_duration(self, new_duration, use_messiaen_style_ties=False):
     from abjad.tools import scoretools
     from abjad.tools import spannertools
     new_duration = durationtools.Duration(new_duration)
     # change LilyPond multiplier if leaf already has LilyPond multiplier
     if self._get_indicators(durationtools.Multiplier):
         detach(durationtools.Multiplier, self)
         multiplier = new_duration.__div__(self.written_duration)
         attach(multiplier, self)
         return [self]
     # change written duration if new duration is assignable
     try:
         self.written_duration = new_duration
         return [self]
     except AssignabilityError:
         pass
     # make new notes or tuplets if new duration is nonassignable
     components = scoretools.make_notes(
         0,
         new_duration,
         use_messiaen_style_ties=use_messiaen_style_ties,
     )
     if isinstance(components[0], scoretools.Leaf):
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for x, component in zip(all_leaves, components):
             x.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         parentage = self._get_parentage()
         if not parentage._get_spanners(spannertools.Tie):
             #if spannertools.Tie._attachment_test(self):
             tie = spannertools.Tie()
             if tie._attachment_test(self):
                 tie = spannertools.Tie(
                     use_messiaen_style_ties=use_messiaen_style_ties, )
                 attach(tie, all_leaves)
         return all_leaves
     else:
         assert isinstance(components[0], scoretools.Tuplet)
         tuplet = components[0]
         components = tuplet[:]
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for x, component in zip(all_leaves, components):
             x.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not self._get_spanners(spannertools.Tie):
             #if spannertools.Tie._attachment_test(self):
             tie = spannertools.Tie()
             if tie._attachment_test(self):
                 tie = spannertools.Tie(
                     use_messiaen_style_ties=use_messiaen_style_ties, )
                 attach(tie, all_leaves)
         tuplet_multiplier = tuplet.multiplier
         scoretools.Tuplet(tuplet_multiplier, all_leaves)
         return [tuplet]
Пример #2
0
 def _make_ties_across_divisions(self, music):
     if not self.tie_across_divisions:
         return
     if self.tie_across_divisions == True:
         for division_one, division_two in \
             sequencetools.iterate_sequence_nwise(music):
             leaf_one = next(
                 iterate(division_one).by_class(prototype=scoretools.Leaf,
                                                reverse=True))
             leaf_two = next(
                 iterate(division_two).by_class(prototype=scoretools.Leaf))
             leaves = [leaf_one, leaf_two]
             prototype = (scoretools.Note, scoretools.Chord)
             if not all(isinstance(x, prototype) for x in leaves):
                 continue
             logical_tie_one = inspect_(leaf_one).get_logical_tie()
             logical_tie_two = inspect_(leaf_two).get_logical_tie()
             for tie in inspect_(leaf_one).get_spanners(spannertools.Tie):
                 detach(tie, leaf_one)
             for tie in inspect_(leaf_two).get_spanners(spannertools.Tie):
                 detach(tie, leaf_two)
             combined_logical_tie = logical_tie_one + logical_tie_two
             attach(spannertools.Tie(), combined_logical_tie)
     elif isinstance(self.tie_across_divisions, (tuple, list)):
         tie_across_divisions = datastructuretools.CyclicTuple(
             self.tie_across_divisions)
         pairs = sequencetools.iterate_sequence_nwise(music)
         for i, pair in enumerate(pairs):
             indicator = tie_across_divisions[i]
             if not bool(indicator):
                 continue
             division_one, division_two = pair
             leaf_one = next(
                 iterate(division_one).by_class(
                     prototype=scoretools.Leaf,
                     reverse=True,
                 ))
             leaf_two = next(
                 iterate(division_two).by_class(
                     prototype=scoretools.Leaf, ))
             leaves = [leaf_one, leaf_two]
             prototype = (scoretools.Note, scoretools.Chord)
             if not all(isinstance(x, prototype) for x in leaves):
                 continue
             logical_tie_one = inspect_(leaf_one).get_logical_tie()
             logical_tie_two = inspect_(leaf_two).get_logical_tie()
             for tie in inspect_(leaf_one).get_spanners(spannertools.Tie):
                 detach(tie, leaf_one)
             for tie in inspect_(leaf_two).get_spanners(spannertools.Tie):
                 detach(tie, leaf_two)
             combined_logical_tie = logical_tie_one + logical_tie_two
             attach(spannertools.Tie(), combined_logical_tie)
     else:
         raise TypeError(self.tie_across_divisions)
Пример #3
0
 def _attach_tie_spanner_to_leaf_pair(self, use_messiaen_style_ties=False):
     from abjad.tools import scoretools
     from abjad.tools import spannertools
     assert len(self) == 2
     left_leaf, right_leaf = self
     assert isinstance(left_leaf, scoretools.Leaf), left_leaf
     assert isinstance(right_leaf, scoretools.Leaf), right_leaf
     left_logical_tie = left_leaf._get_logical_tie()
     right_logical_tie = right_leaf._get_logical_tie()
     prototype = (spannertools.Tie, )
     if left_logical_tie == right_logical_tie:
         return
     try:
         left_tie_spanner = left_leaf._get_spanner(prototype)
     except MissingSpannerError:
         left_tie_spanner = None
     try:
         right_tie_spanner = right_leaf._get_spanner(prototype)
     except MissingSpannerError:
         right_tie_spanner = None
     if left_tie_spanner is not None and right_tie_spanner is not None:
         left_tie_spanner._fuse_by_reference(right_tie_spanner)
     elif left_tie_spanner is not None and right_tie_spanner is None:
         left_tie_spanner._append(right_leaf)
     elif left_tie_spanner is None and right_tie_spanner is not None:
         right_tie_spanner._append_left(left_leaf)
     elif left_tie_spanner is None and right_tie_spanner is None:
         tie = spannertools.Tie(
             use_messiaen_style_ties=use_messiaen_style_ties, )
         attach(tie, [left_leaf, right_leaf])
Пример #4
0
    def _do_tie_consecutive_notes(self, divisions):
        if not self.tie_consecutive_notes:
            return
        leaves = select(divisions).by_leaf()
        for leaf in leaves:
            detach(spannertools.Tie, leaf)
        pairs = itertools.groupby(leaves, lambda _: _.__class__)

        def _get_pitches(component):
            if isinstance(component, scoretools.Note):
                return component.written_pitch
            elif isinstance(component, scoretools.Chord):
                return component.written_pitches
            else:
                raise TypeError(component)

        for class_, group in pairs:
            group = list(group)
            if not isinstance(group[0], (scoretools.Note, scoretools.Chord)):
                continue
            subpairs = itertools.groupby(group, lambda _: _get_pitches(_))
            for pitches, subgroup in subpairs:
                subgroup = list(subgroup)
                if len(subgroup) == 1:
                    continue
                tie = spannertools.Tie()
                assert tie._attachment_test_all(subgroup)
                attach(tie, subgroup)
Пример #5
0
def edit_second_violin_voice(score, durated_reservoir):
    r'''Edits second violin voice.
    '''

    voice = score['Second Violin Voice']
    descents = durated_reservoir['Second Violin']

    last_descent = select(descents[-1])
    copied_descent = mutate(last_descent).copy()
    copied_descent = list(copied_descent)
    copied_descent[-1].written_duration = durationtools.Duration(1, 1)
    copied_descent.append(scoretools.Note('a2'))
    for leaf in copied_descent:
        articulation = indicatortools.Articulation('accent')
        attach(articulation, leaf)
        articulation = indicatortools.Articulation('tenuto')
        attach(articulation, leaf)
    voice.extend(copied_descent)

    final_sustain = []
    for _ in range(32):
        final_sustain.append(scoretools.Note('a1.'))
    final_sustain.append(scoretools.Note('a2'))
    articulation = indicatortools.Articulation('accent')
    attach(articulation, final_sustain[0])
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, final_sustain[0])

    voice.extend(final_sustain)
    tie = spannertools.Tie()
    attach(tie, final_sustain)
    voice.extend('r4 r2.')
Пример #6
0
 def _add_or_remove_notes_to_achieve_written_duration(
     self, new_written_duration):
     from abjad.tools import scoretools
     from abjad.tools import scoretools
     from abjad.tools import spannertools
     from abjad.tools import scoretools
     new_written_duration = durationtools.Duration(new_written_duration)
     if new_written_duration.is_assignable:
         self[0].written_duration = new_written_duration
         for leaf in self[1:]:
             parent = leaf._parent
             if parent:
                 index = parent.index(leaf)
                 del(parent[index])
         first = self[0]
         for spanner in first._get_spanners(spannertools.Tie):
             spanner._sever_all_components()
         #detach(spannertools.Tie, first)
     elif new_written_duration.has_power_of_two_denominator:
         durations = scoretools.make_notes(0, [new_written_duration])
         for leaf, token in zip(self, durations):
             leaf.written_duration = token.written_duration
         if len(self) == len(durations):
             pass
         elif len(durations) < len(self):
             for leaf in self[len(durations):]:
                 parent = leaf._parent
                 if parent:
                     index = parent.index(leaf)
                     del(parent[index])
         elif len(self) < len(durations):
             for spanner in self[0]._get_spanners(spannertools.Tie):
                 spanner._sever_all_components()
             #detach(spannertools.Tie, self[0])
             difference = len(durations) - len(self)
             extra_leaves = self[0] * difference
             for extra_leaf in extra_leaves:
                 for spanner in extra_leaf._get_spanners():
                     spanner._remove(extra_leaf)
             extra_tokens = durations[len(self):]
             for leaf, token in zip(extra_leaves, extra_tokens):
                 leaf.written_duration = token.written_duration
             ties = self[-1]._get_spanners(spannertools.Tie)
             if not ties:
                 tie = spannertools.Tie()
                 attach(tie, list(self))
             self[-1]._splice(extra_leaves, grow_spanners=True)
     else:
         durations = scoretools.make_notes(0, new_written_duration)
         assert isinstance(durations[0], scoretools.Tuplet)
         fmtuplet = durations[0]
         new_logical_tie_written = \
             fmtuplet[0]._get_logical_tie()._preprolated_duration
         self._add_or_remove_notes_to_achieve_written_duration(
             new_logical_tie_written)
         multiplier = fmtuplet.multiplier
         scoretools.Tuplet(multiplier, self.leaves)
     return self[0]._get_logical_tie()
Пример #7
0
 def _do_tie_consecutive_notes(self, divisions):
     if not self.tie_consecutive_notes:
         return
     leaves = list(iterate(divisions).by_leaf())
     for leaf in leaves:
         detach(spannertools.Tie, leaf)
     pairs = itertools.groupby(leaves, lambda _: _.__class__)
     for class_, group in pairs:
         group = list(group)
         if isinstance(group[0], scoretools.Note):
             if 1 < len(group):
                 attach(spannertools.Tie(), group)
Пример #8
0
 def _do_tie_across_divisions(self, divisions):
     if not self.tie_across_divisions:
         return
     if self.strip_ties:
         return
     if self.tie_consecutive_notes:
         return
     length = len(divisions)
     tie_across_divisions = self.tie_across_divisions
     if isinstance(tie_across_divisions, bool):
         tie_across_divisions = [tie_across_divisions]
     if not isinstance(tie_across_divisions, patterntools.Pattern):
         tie_across_divisions = patterntools.Pattern.from_vector(
             tie_across_divisions)
     pairs = sequencetools.iterate_sequence_nwise(divisions)
     rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest)
     for i, pair in enumerate(pairs):
         if not tie_across_divisions.matches_index(i, length):
             continue
         division_one, division_two = pair
         leaf_one = next(
             iterate(division_one).by_class(
                 prototype=scoretools.Leaf,
                 reverse=True,
             ))
         leaf_two = next(
             iterate(division_two).by_class(prototype=scoretools.Leaf, ))
         leaves = [leaf_one, leaf_two]
         if isinstance(leaf_one, rest_prototype):
             continue
         if isinstance(leaf_two, rest_prototype):
             continue
         prototype = (scoretools.Note, scoretools.Chord)
         if not all(isinstance(x, prototype) for x in leaves):
             continue
         logical_tie_one = inspect_(leaf_one).get_logical_tie()
         logical_tie_two = inspect_(leaf_two).get_logical_tie()
         for tie in inspect_(leaf_one).get_spanners(spannertools.Tie):
             detach(tie, leaf_one)
         for tie in inspect_(leaf_two).get_spanners(spannertools.Tie):
             detach(tie, leaf_two)
         combined_logical_tie = logical_tie_one + logical_tie_two
         tie_spanner = spannertools.Tie(
             use_messiaen_style_ties=self.use_messiaen_style_ties, )
         tie_spanner._unconstrain_contiguity()
         if tie_spanner._attachment_test_all(combined_logical_tie):
             attach(tie_spanner, combined_logical_tie)
         tie_spanner._constrain_contiguity()
Пример #9
0
 def _notate_leaves(
     self,
     grace_handler=None,
     voice=None,
     ):
     for leaf in iterate(voice).by_leaf():
         if leaf._has_indicator(indicatortools.Annotation):
             annotation = leaf._get_indicator(indicatortools.Annotation)
             pitches, grace_container = grace_handler(annotation.value)
             if not pitches:
                 new_leaf = scoretools.Rest(leaf)
             elif 1 < len(pitches):
                 new_leaf = scoretools.Chord(leaf)
                 new_leaf.written_pitches = pitches
             else:
                 new_leaf = scoretools.Note(leaf)
                 new_leaf.written_pitch = pitches[0]
             if grace_container:
                 attach(grace_container, new_leaf)
             tie = spannertools.Tie()
             if tie._attachment_test(new_leaf):
                 attach(tie, new_leaf)
             mutate(leaf).replace(new_leaf)
         else:
             previous_leaf = leaf._get_leaf(-1)
             if isinstance(previous_leaf, scoretools.Rest):
                 new_leaf = type(previous_leaf)(
                     leaf.written_duration,
                     )
             elif isinstance(previous_leaf, scoretools.Note):
                 new_leaf = type(previous_leaf)(
                     previous_leaf.written_pitch,
                     leaf.written_duration,
                     )
             else:
                 new_leaf = type(previous_leaf)(
                     previous_leaf.written_pitch,
                     leaf.written_duration,
                     )
             mutate(leaf).replace(new_leaf)
             tie = inspect_(previous_leaf).get_spanner(spannertools.Tie)
             if tie is not None:
                 tie._append(new_leaf)
         if leaf._has_indicator(indicatortools.Tempo):
             tempo = leaf._get_indicator(indicatortools.Tempo)
             detach(indicatortools.Tempo, leaf)
             attach(tempo, new_leaf)
Пример #10
0
 def _make_music(self, divisions, rotation):
     from abjad.tools import rhythmmakertools
     selections = []
     duration_specifier = self._get_duration_spelling_specifier()
     tie_specifier = self._get_tie_specifier()
     tuplet_specifier = self._get_tuplet_spelling_specifier()
     for division in divisions:
         if (duration_specifier.spell_metrically == True or
             (duration_specifier.spell_metrically == 'unassignable'
              and not mathtools.is_assignable_integer(division.numerator))):
             meter = metertools.Meter(division)
             rhythm_tree_container = meter.root_node
             durations = [_.duration for _ in rhythm_tree_container]
         elif isinstance(duration_specifier.spell_metrically,
                         rhythmmakertools.PartitionTable):
             partition_table = duration_specifier.spell_metrically
             durations = partition_table.respell_division(division)
         else:
             durations = [division]
         selection = scoretools.make_leaves(
             pitches=0,
             durations=durations,
             decrease_durations_monotonically=\
                 duration_specifier.decrease_durations_monotonically,
             forbidden_written_duration=\
                 duration_specifier.forbidden_written_duration,
             is_diminution=tuplet_specifier.is_diminution,
             use_messiaen_style_ties=tie_specifier.use_messiaen_style_ties,
             )
         if (1 < len(selection)
                 and not selection[0]._has_spanner(spannertools.Tie)):
             tie = spannertools.Tie(use_messiaen_style_ties=tie_specifier.
                                    use_messiaen_style_ties, )
             attach(tie, selection[:])
         selections.append(selection)
     selections = self._apply_burnish_specifier(selections)
     beam_specifier = self._get_beam_specifier()
     beam_specifier(selections)
     selections = self._apply_division_masks(selections, rotation)
     if duration_specifier.rewrite_meter:
         selections = duration_specifier._rewrite_meter_(
             selections,
             divisions,
             use_messiaen_style_ties=tie_specifier.use_messiaen_style_ties,
         )
     return selections
Пример #11
0
def edit_first_violin_voice(score, durated_reservoir):
    r'''Edits first violin voice.
    '''

    voice = score['First Violin Voice']
    descents = durated_reservoir['First Violin']
    descents = selectiontools.Selection(descents)

    last_descent = select(descents[-1])
    copied_descent = mutate(last_descent).copy()
    voice.extend(copied_descent)

    final_sustain_rhythm = [(6, 4)] * 43 + [(1, 2)]
    final_sustain_notes = scoretools.make_notes(["c'"], final_sustain_rhythm)
    voice.extend(final_sustain_notes)
    tie = spannertools.Tie()
    attach(tie, final_sustain_notes)
    voice.extend('r4 r2.')
Пример #12
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]
Пример #13
0
 def _make_ties_across_divisions(self, divisions):
     from abjad.tools import rhythmmakertools
     if not self.tie_across_divisions:
         return
     length = len(divisions)
     tie_across_divisions = self.tie_across_divisions
     if isinstance(tie_across_divisions, bool):
         tie_across_divisions = [tie_across_divisions]
     if not isinstance(tie_across_divisions,
         rhythmmakertools.BooleanPattern):
         tie_across_divisions = \
             rhythmmakertools.BooleanPattern.from_sequence(
                 tie_across_divisions)
     pairs = sequencetools.iterate_sequence_nwise(divisions)
     for i, pair in enumerate(pairs):
         if not tie_across_divisions.matches_index(i, length):
             continue
         division_one, division_two = pair
         leaf_one = next(iterate(division_one).by_class(
             prototype=scoretools.Leaf,
             reverse=True,
             ))
         leaf_two = next(iterate(division_two).by_class(
             prototype=scoretools.Leaf,
             ))
         leaves = [leaf_one, leaf_two]
         prototype = (scoretools.Note, scoretools.Chord)
         if not all(isinstance(x, prototype) for x in leaves):
             continue
         logical_tie_one = inspect_(leaf_one).get_logical_tie()
         logical_tie_two = inspect_(leaf_two).get_logical_tie()
         for tie in inspect_(leaf_one).get_spanners(spannertools.Tie):
             detach(tie, leaf_one)
         for tie in inspect_(leaf_two).get_spanners(spannertools.Tie):
             detach(tie, leaf_two)
         combined_logical_tie = logical_tie_one + logical_tie_two
         tie_spanner = spannertools.Tie(
             use_messiaen_style_ties=self.use_messiaen_style_ties,
             )
         tie_spanner._unconstrain_contiguity()
         attach(tie_spanner, combined_logical_tie)
         tie_spanner._constrain_contiguity()
Пример #14
0
def edit_viola_voice(score, durated_reservoir):
    r'''Edits viola voice.
    '''

    voice = score['Viola Voice']
    descents = durated_reservoir['Viola']

    for leaf in descents[-1]:
        articulation = indicatortools.Articulation('accent')
        attach(articulation, leaf)
        articulation = indicatortools.Articulation('tenuto')
        attach(articulation, leaf)
    last_descent = select(descents[-1])
    copied_descent = mutate(last_descent).copy()
    for leaf in copied_descent:
        if leaf.written_duration == durationtools.Duration(4, 4):
            leaf.written_duration = durationtools.Duration(8, 4)
        else:
            leaf.written_duration = durationtools.Duration(4, 4)
    voice.extend(copied_descent)

    bridge = scoretools.Note('e1')
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, bridge)
    articulation = indicatortools.Articulation('accent')
    attach(articulation, bridge)
    voice.append(bridge)

    final_sustain_rhythm = [(6, 4)] * 21 + [(1, 2)]
    final_sustain_notes = scoretools.make_notes(['e'], final_sustain_rhythm)
    articulation = indicatortools.Articulation('accent')
    attach(articulation, final_sustain_notes[0])
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, final_sustain_notes[0])
    voice.extend(final_sustain_notes)
    tie = spannertools.Tie()
    attach(tie, final_sustain_notes)
    voice.extend('r4 r2.')
Пример #15
0
    def _apply_spanners(self, leaves):

        spanner_references = {
            spannertools.Beam: None,
            spannertools.Slur: None,
        }

        first_leaf = leaves[0]
        for leaf, next_leaf in \
            sequencetools.iterate_sequence_nwise(leaves, wrapped=True):

            span_events = self._get_span_events(leaf)
            for current_class, directions in span_events.items():

                starting, stopping = [], []
                for direction in directions:
                    if direction == Left:
                        starting.append(Left)
                    else:
                        stopping.append(Right)

                # apply undirected events immediately,
                # and do not maintain a reference to them
                if current_class is spannertools.Tie:
                    if next_leaf is first_leaf:
                        message = 'unterminated {} at {}.'
                        message = message.format(current_class.__name__, leaf)
                        raise Exception(message)
                    previous_tie = [
                        x for x in leaf._get_spanners()
                        if isinstance(x, spannertools.Tie)
                    ]
                    if previous_tie:
                        previous_tie[0]._append(next_leaf)
                    else:
                        tie = spannertools.Tie()
                        attach(tie, (leaf, next_leaf))

                elif current_class is spannertools.Beam:
                    # A beam may begin and end on the same leaf
                    # but only one beam spanner may cover any given leaf,
                    # and starting events are processed before ending ones
                    for _ in starting:
                        if spanner_references[current_class] is not None:
                            message = 'already have beam.'
                            raise Exception(message)
                        else:
                            spanner_references[current_class] = current_class()
                    for _ in stopping:
                        if spanner_references[current_class] is not None:
                            spanner_references[current_class]._append(leaf)
                            spanner_references[current_class] = None

                elif current_class is spannertools.Slur:
                    # Slurs process stop events before start events,
                    # they must contain more than one leaf,
                    # but they can stop on a leaf and start on the same leaf.
                    for _ in stopping:
                        if spanner_references[current_class] is not None:
                            spanner_references[current_class]._append(leaf)
                            spanner_references[current_class] = None
                        else:
                            message = 'can not end: {}.'
                            message = message.format(current_class.__name)
                            raise Exception(message)
                    for _ in starting:
                        if spanner_references[current_class] is None:
                            spanner_references[current_class] = current_class()
                        else:
                            message = 'already have: {}.'
                            message = message.format(current_class.__name)
                            raise Exception(message)

            # append leaf to all tracked spanners,
            for current_class, instance in spanner_references.items():
                if instance is not None:
                    instance._append(leaf)

        # check for unterminated spanners
        for current_class, instance in spanner_references.items():
            if instance is not None:
                message = 'unterminated {}.'
                message = message.format(current_class.__name__)
                raise Exception(message)
Пример #16
0
def make_tied_leaf(
    kind,
    duration,
    decrease_durations_monotonically=True,
    forbidden_written_duration=None,
    pitches=None,
    tie_parts=True,
):
    r'''Make tied `kind` with `duration`.

    ..  container:: example

        **Example 1.** Make note:

        ::

            >>> leaves = scoretools.make_tied_leaf(
            ...     Note,
            ...     Duration(1, 2),
            ...     pitches='C#5',
            ...     )
            >>> staff = Staff(leaves)
            >>> time_signature = TimeSignature((2, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new Staff {
                \time 2/4
                cs''2
            }

    ..  container:: example

        **Example 2.** Make note and forbid half notes:

        ::

            >>> leaves = scoretools.make_tied_leaf(
            ...     Note,
            ...     Duration(1, 2),
            ...     pitches='C#5',
            ...     forbidden_written_duration=Duration(1, 2),
            ...     )
            >>> staff = Staff(leaves)
            >>> time_signature = TimeSignature((2, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new Staff {
                \time 2/4
                cs''4 ~
                cs''4
            }

    ..  container:: example

        **Example 3.** Make tied note with half notes forbidden and
        durations decreasing monotonically:

        ::

            >>> leaves = scoretools.make_tied_leaf(
            ...     Note,
            ...     Duration(9, 8),
            ...     pitches='C#5',
            ...     forbidden_written_duration=Duration(1, 2),
            ...     decrease_durations_monotonically=True,
            ...     )
            >>> staff = Staff(leaves)
            >>> time_signature = TimeSignature((9, 8))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new Staff {
                \time 9/8
                cs''4 ~
                cs''4 ~
                cs''4 ~
                cs''4 ~
                cs''8
            }

    ..  container:: example

        **Example 4.** Make tied note with half notes forbidden and
        durations increasing monotonically:

        ::

            >>> leaves = scoretools.make_tied_leaf(
            ...     Note,
            ...     Duration(9, 8),
            ...     pitches='C#5',
            ...     forbidden_written_duration=Duration(1, 2),
            ...     decrease_durations_monotonically=False,
            ...     )
            >>> staff = Staff(leaves)
            >>> time_signature = TimeSignature((9, 8))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new Staff {
                \time 9/8
                cs''8 ~
                cs''4 ~
                cs''4 ~
                cs''4 ~
                cs''4
            }

    Returns selection of unincorporated leaves.
    '''
    from abjad.tools import scoretools
    from abjad.tools import spannertools

    # check input
    duration = durationtools.Duration(duration)
    if forbidden_written_duration is not None:
        forbidden_written_duration = \
            durationtools.Duration(forbidden_written_duration)
        assert forbidden_written_duration.is_assignable
        assert forbidden_written_duration.numerator == 1

    # find preferred numerator of written durations if necessary
    if forbidden_written_duration is not None and \
        forbidden_written_duration <= duration:
        denominators = [
            2 * forbidden_written_duration.denominator,
            duration.denominator,
        ]
        denominator = mathtools.least_common_multiple(*denominators)
        forbidden_written_duration = \
            mathtools.NonreducedFraction(forbidden_written_duration)
        forbidden_written_duration = \
            forbidden_written_duration.with_denominator(denominator)
        duration = mathtools.NonreducedFraction(duration)
        duration = duration.with_denominator(denominator)
        forbidden_numerator = forbidden_written_duration.numerator
        assert forbidden_numerator % 2 == 0
        preferred_numerator = forbidden_numerator / 2

    # make written duration numerators
    numerators = []
    parts = mathtools.partition_integer_into_canonic_parts(duration.numerator)
    if forbidden_written_duration is not None and \
        forbidden_written_duration <= duration:
        for part in parts:
            if forbidden_numerator <= part:
                better_parts = \
                    mathtools.partition_integer_into_parts_less_than_double(
                    part, preferred_numerator)
                numerators.extend(better_parts)
            else:
                numerators.append(part)
    else:
        numerators = parts

    # reverse numerators if necessary
    if not decrease_durations_monotonically:
        numerators = list(reversed(numerators))

    # make one leaf per written duration
    result = []
    for numerator in numerators:
        written_duration = \
            durationtools.Duration(numerator, duration.denominator)
        if not pitches is None:
            args = (pitches, written_duration)
        else:
            args = (written_duration, )
        result.append(kind(*args))

    # apply tie spanner if required
    if tie_parts and 1 < len(result):
        if not issubclass(kind, (scoretools.Rest, scoretools.Skip)):
            tie = spannertools.Tie()
            attach(tie, result)

    # return result
    result = selectiontools.Selection(result)
    return result
Пример #17
0
def make_leaves_from_talea(
    talea,
    talea_denominator,
    decrease_durations_monotonically=True,
    forbidden_written_duration=None,
    spell_metrically=None,
    use_messiaen_style_ties=False,
):
    r'''Makes leaves from `talea`.

    Interprets positive elements in `talea` as notes numerators.

    Interprets negative elements in `talea` as rests numerators.

    Sets the pitch of all notes to middle C.

    ..  container:: example

        **Example 1.** Makes leaves from talea:

        ::

            >>> leaves = scoretools.make_leaves_from_talea([3, -3, 5, -5], 16)
            >>> staff = Staff(leaves)
            >>> staff.context_name = 'RhythmicStaff'
            >>> time_signature = TimeSignature((4, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new RhythmicStaff {
                \time 4/4
                c'8.
                r8.
                c'4 ~
                c'16
                r4
                r16
            }

    ..  container:: example

        **Example 2.** Increases durations monotonically:

        ::

            >>> leaves = scoretools.make_leaves_from_talea(
            ...     [3, -3, 5, -5], 16,
            ...     decrease_durations_monotonically=False,
            ...     )
            >>> staff = Staff(leaves)
            >>> staff.context_name = 'RhythmicStaff'
            >>> time_signature = TimeSignature((4, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new RhythmicStaff {
                \time 4/4
                c'8.
                r8.
                c'16 ~
                c'4
                r16
                r4
            }

    ..  container:: example

        **Example 3.** Forbids written durations greater than or equal
        to a half note:

        ::

            >>> leaves = scoretools.make_leaves_from_talea(
            ...     [3, -3, 5, -5], 16,
            ...     forbidden_written_duration=Duration(1, 4),
            ...     )
            >>> staff = Staff(leaves)
            >>> staff.context_name = 'RhythmicStaff'
            >>> time_signature = TimeSignature((4, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new RhythmicStaff {
                \time 4/4
                c'8.
                r8.
                c'8 ~
                c'8 ~
                c'16
                r8
                r8
                r16
            }

    ..  container:: example

        **Example 4.** Spells unassignable durations metrically:

        ::

            >>> leaves = scoretools.make_leaves_from_talea(
            ...     [3, -3, 5, -5], 16,
            ...     spell_metrically='unassignable',
            ...     )
            >>> staff = Staff(leaves)
            >>> staff.context_name = 'RhythmicStaff'
            >>> time_signature = TimeSignature((4, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new RhythmicStaff {
                \time 4/4
                c'8.
                r8.
                c'8. ~
                c'8
                r8.
                r8
            }

    ..  container:: example

        **Example 5.** Uses Messiaen-style ties:

        ::

            >>> leaves = scoretools.make_leaves_from_talea(
            ...     [5, 9], 8,
            ...     spell_metrically='unassignable',
            ...     use_messiaen_style_ties=True,
            ...     )
            >>> staff = Staff(leaves)
            >>> staff.context_name = 'RhythmicStaff'
            >>> time_signature = TimeSignature((4, 4))
            >>> attach(time_signature, staff)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> print(format(staff))
            \new RhythmicStaff {
                \time 4/4
                c'4.
                c'4 \repeatTie
                c'4.
                c'4. \repeatTie
                c'4. \repeatTie
            }

    Returns selection.
    '''
    from abjad.tools import metertools
    from abjad.tools import scoretools
    from abjad.tools import spannertools

    assert all(x != 0 for x in talea), repr(talea)

    result = []
    for note_value in talea:
        if 0 < note_value:
            pitches = [0]
        else:
            pitches = [None]
        division = durationtools.Duration(
            abs(note_value),
            talea_denominator,
        )
        if (spell_metrically is True or
            (spell_metrically == 'unassignable'
             and not mathtools.is_assignable_integer(division.numerator))):
            meter = metertools.Meter(division)
            rhythm_tree_container = meter.root_node
            durations = [_.duration for _ in rhythm_tree_container]
        else:
            durations = [division]
        leaves = scoretools.make_leaves(
            pitches,
            durations,
            decrease_durations_monotonically=decrease_durations_monotonically,
            forbidden_written_duration=forbidden_written_duration,
            use_messiaen_style_ties=use_messiaen_style_ties,
        )
        if (1 < len(leaves) and not leaves[0]._has_spanner(spannertools.Tie)
                and not isinstance(leaves[0], scoretools.Rest)):
            tie = spannertools.Tie(
                use_messiaen_style_ties=use_messiaen_style_ties, )
            attach(tie, leaves[:])
        result.extend(leaves)
    result = selectiontools.Selection(result)
    return result