Пример #1
0
    def _add_or_remove_notes_to_achieve_written_duration(self, new_written_duration):
        from abjad.tools import scoretools
        from abjad.tools import notetools
        from abjad.tools import spannertools
        from abjad.tools import tuplettools
        from abjad.tools.scoretools import attach

        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.TieSpanner):
                spanner.detach()
        elif new_written_duration.has_power_of_two_denominator:
            durations = notetools.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.TieSpanner):
                    spanner.detach()
                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.TieSpanner)
                if not ties:
                    tie = spannertools.TieSpanner()
                    attach(tie, list(self))
                self[-1]._splice(extra_leaves, grow_spanners=True)
        else:
            durations = notetools.make_notes(0, new_written_duration)
            assert isinstance(durations[0], tuplettools.Tuplet)
            fmtuplet = durations[0]
            new_chain_written = fmtuplet[0]._get_tie_chain()._preprolated_duration
            self._add_or_remove_notes_to_achieve_written_duration(new_chain_written)
            multiplier = fmtuplet.multiplier
            tuplettools.Tuplet(multiplier, self.leaves)
        return self[0]._get_tie_chain()
def fill_measures_in_expr_with_minimal_number_of_notes(expr, decrease_durations_monotonically=True, iterctrl=None):
    '''Fill measures in `expr` with minimal number of notes that decrease durations monotonically:

    ::

        >>> measure = Measure((5, 18), [])

    ::

        >>> measuretools.fill_measures_in_expr_with_minimal_number_of_notes(
        ...     measure, decrease_durations_monotonically=True)

    ..  doctest::

        >>> f(measure)
        {
            \time 5/18
            \scaleDurations #'(8 . 9) {
                c'4 ~
                c'16
            }
        }

    Fill measures in `expr` with minimal number of notes that increase durations monotonically:

    ::

        >>> measure = Measure((5, 18), [])

    ::

        >>> measuretools.fill_measures_in_expr_with_minimal_number_of_notes(
        ...     measure, decrease_durations_monotonically=False)

    ..  doctest::

        >>> f(measure)
        {
            \time 5/18
            \scaleDurations #'(8 . 9) {
                c'16 ~
                c'4
            }
        }

    Returns none.
    '''
    from abjad.tools import contexttools
    from abjad.tools import iterationtools

    if iterctrl is None:
        iterctrl = lambda measure, i: True
    for i, measure in enumerate(iterationtools.iterate_measures_in_expr(expr)):
        if iterctrl(measure, i):
            time_signature = measure.time_signature
            written_duration = time_signature.duration / time_signature.implied_prolation
            notes = notetools.make_notes(0, written_duration, decrease_durations_monotonically=decrease_durations_monotonically)
            measure[:] = notes
Пример #3
0
 def _make_container(self, division):
     numerator, denominator = division
     # eventually allow for non-power-of-two divisions
     assert mathtools.is_positive_integer_power_of_two(denominator)
     denominator_multiplier = 2 ** self.denominator_multiplier_exponent
     denominator *= denominator_multiplier
     unit_duration = durationtools.Duration(1, denominator)
     numerator *= denominator_multiplier
     notes = notetools.make_notes(numerator * [0], [unit_duration])
     container = containertools.Container(notes)
     if self.beam_each_cell:
         beam = spannertools.BeamSpanner()
         attach(beam, container)
     return container
Пример #4
0
 def _set_duration(self, new_duration):
     from abjad.tools import leaftools
     from abjad.tools import notetools
     from abjad.tools import spannertools
     from abjad.tools import tuplettools
     from abjad.tools.scoretools import attach
     new_duration = durationtools.Duration(new_duration)
     # change LilyPond multiplier if leaf already has LilyPond multiplier
     if self.lilypond_duration_multiplier is not None:
         multiplier = new_duration / self.written_duration
         self.lilypond_duration_multiplier = multiplier
         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 = notetools.make_notes(0, new_duration)
     if isinstance(components[0], leaftools.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.TieSpanner):
             tie = spannertools.TieSpanner()
             attach(tie, all_leaves)
         return all_leaves
     else:
         assert isinstance(components[0], tuplettools.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.TieSpanner):
             tie = spannertools.TieSpanner()
             attach(tie, all_leaves)
         tuplet_multiplier = tuplet.multiplier
         tuplettools.Tuplet(tuplet_multiplier, all_leaves)
         return [tuplet]
Пример #5
0
    def __call__(self, pulse_duration):
        r'''Generate Abjad score components:

        ::

            >>> leaf = rhythmtreetools.RhythmTreeLeaf(5)
            >>> leaf((1, 4))
            Selection(Note("c'1"), Note("c'4"))

        Returns sequence of components.
        '''
        pulse_duration = durationtools.Duration(pulse_duration)
        total_duration = pulse_duration * self.preprolated_duration
        if self.is_pitched:
            return notetools.make_notes(0, total_duration)
        return resttools.make_rests(total_duration)
Пример #6
0
def make_repeated_notes(count, duration=durationtools.Duration(1, 8)):
    r'''Make `count` repeated notes with note head-assignable `duration`:

    ::

        >>> notetools.make_repeated_notes(4)
        Selection(Note("c'8"), Note("c'8"), Note("c'8"), Note("c'8"))

    Make `count` repeated tie chains with tied `duration`:

    ::

        >>> notes = notetools.make_repeated_notes(2, (5, 16))
        >>> voice = Voice(notes)

    ..  doctest::

        >>> f(voice)
        \new Voice {
            c'4 ~
            c'16
            c'4 ~
            c'16
        }

    Make ad hoc tuplet holding `count` repeated notes with non-power-of-two `duration`:

    ::

        >>> notetools.make_repeated_notes(3, (1, 12))
        Selection(Tuplet(2/3, [c'8, c'8, c'8]),)

    Set pitch of all notes created to middle C.

    Returns list of zero or more newly constructed notes or list of one newly constructed tuplet.
    '''
    from abjad.tools import notetools

    return notetools.make_notes([0] * count, [duration])
Пример #7
0
 def _to_tuplet_with_ratio(self, proportions, is_diminution=True):
     from abjad.tools import notetools
     from abjad.tools import tuplettools
     # check input
     proportions = mathtools.Ratio(proportions)
     # find target duration of fixed-duration tuplet
     target_duration = self.written_duration
     # find basic prolated duration of note in tuplet
     basic_prolated_duration = target_duration / sum(proportions)
     # 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 = [x * basic_written_duration for x in proportions]
     # make tuplet notes
     try:
         notes = [notetools.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 = notetools.make_notes(0, note_durations)
     # make tuplet
     tuplet = tuplettools.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
Пример #8
0
    def make_notes(self, n=None, written_duration=None):
        r'''Make first `n` notes in pitch class segment.

        Set `n` equal to `n` or length of segment.

        Set `written_duration` equal to `written_duration` or ``1/8``:

        ::

            >>> notes = named_pitch_segment.make_notes()
            >>> staff = Staff(notes)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> f(staff)
            \new Staff {
                bf,8
                aqs8
                fs'8
                g'8
                bqf8
                g'8
            }

        Allow nonassignable `written_duration`:

        ::

            >>> notes = named_pitch_segment.make_notes(4, Duration(5, 16))
            >>> staff = Staff(notes)
            >>> time_signature = contexttools.TimeSignatureMark((5, 4))
            >>> attach(time_signature, staff)
            TimeSignatureMark((5, 4))(Staff{8})
            >>> show(staff) # doctest: +SKIP

        ..  doctest:: 

            >>> f(staff)
            \new Staff {
                \time 5/4
                bf,4 ~
                bf,16
                aqs4 ~
                aqs16
                fs'4 ~
                fs'16
                g'4 ~
                g'16
            }

        Returns list of notes.
        '''
        from abjad.tools import durationtools
        from abjad.tools import iterationtools
        from abjad.tools import notetools
        from abjad.tools import pitchtools
        n = n or len(self)
        written_duration = written_duration or durationtools.Duration(1, 8)
        result = notetools.make_notes([0] * n, [written_duration])
        for i, tie_chain in enumerate(
            iterationtools.iterate_tie_chains_in_expr(result)):
            pitch = self[i % len(self)]
            for note in tie_chain:
                note.written_pitch = pitch
        return result
Пример #9
0
    def to_tuplet(self, proportions, dotted=False, is_diminution=True):
        r"""Change tie chain to tuplet.

        ..  container:: example

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

            ::

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

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

            ::

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

            ::

                >>> tie_chain = inspect(staff[0]).get_tie_chain()
                >>> tie_chain.to_tuplet([2, 1, 1, 1], is_diminution=True)
                FixedDurationTuplet(3/16, [c'8, c'16, c'16, c'16])

            ..  doctest::

                >>> f(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 tie chain to augmented tuplet:

            ::

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

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

            ::

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

            ::

                >>> tie_chain = inspect(staff[0]).get_tie_chain()
                >>> tie_chain.to_tuplet([2, 1, 1, 1], is_diminution=False)
                FixedDurationTuplet(3/16, [c'16, c'32, c'32, c'32])

            ..  doctest::

                >>> f(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 mutationtools
        from abjad.tools import notetools
        from abjad.tools import spannertools
        from abjad.tools import tuplettools

        # coerce input
        proportions = mathtools.Ratio(proportions)

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

        # find prolated 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 = [notetools.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 = notetools.make_notes(0, note_durations)

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

        # replace tie chain with tuplet
        mutationtools.mutate(self).replace(tuplet)

        # untie tuplet
        for spanner in tuplet._get_spanners(spannertools.TieSpanner):
            spanner.detach()

        # return tuplet
        return tuplet
Пример #10
0
def make_gridded_test_rhythm(grid_length, rhythm_number, denominator=16):
    r'''Make test rhythm number `rhythm_number` that fits `grid_length`.

    Returns selection of one or more possibly tied notes.

    ..  container:: example

        **Example 1.** The eight test rhythms that fit a length-``4`` grid:

        ::

            >>> for rhythm_number in range(8):
            ...     notes = timesignaturetools.make_gridded_test_rhythm(
            ...         4, rhythm_number, denominator=4)
            ...     measure = Measure((4, 4), notes)
            ...     print '{}\t{}'.format(rhythm_number, measure)
            ...
            0   |4/4 c'1|
            1   |4/4 c'2. c'4|
            2   |4/4 c'2 c'4 c'4|
            3   |4/4 c'2 c'2|
            4   |4/4 c'4 c'4 c'2|
            5   |4/4 c'4 c'4 c'4 c'4|
            6   |4/4 c'4 c'2 c'4|
            7   |4/4 c'4 c'2.|

    ..  container:: example

        **Example 2.** The sixteenth test rhythms for that a length-``5`` grid:

        ::

            >>> for rhythm_number in range(16):
            ...     notes = timesignaturetools.make_gridded_test_rhythm(
            ...         5, rhythm_number, denominator=4)
            ...     measure = Measure((5, 4), notes)
            ...     print '{}\t{}'.format(rhythm_number, measure)
            ...
            0   |5/4 c'1 ~ c'4|
            1   |5/4 c'1 c'4|
            2   |5/4 c'2. c'4 c'4|
            3   |5/4 c'2. c'2|
            4   |5/4 c'2 c'4 c'2|
            5   |5/4 c'2 c'4 c'4 c'4|
            6   |5/4 c'2 c'2 c'4|
            7   |5/4 c'2 c'2.|
            8   |5/4 c'4 c'4 c'2.|
            9   |5/4 c'4 c'4 c'2 c'4|
            10  |5/4 c'4 c'4 c'4 c'4 c'4|
            11  |5/4 c'4 c'4 c'4 c'2|
            12  |5/4 c'4 c'2 c'2|
            13  |5/4 c'4 c'2 c'4 c'4|
            14  |5/4 c'4 c'2. c'4|
            15  |5/4 c'4 c'1|

    Use for testing metrical hierarchy establishment.
    '''
    from abjad.tools import notetools

    # check input
    assert mathtools.is_positive_integer(grid_length)
    assert isinstance(rhythm_number, int)
    assert mathtools.is_positive_integer_power_of_two(denominator)

    # find count of all rhythms that fit grid length
    rhythm_count = 2 ** (grid_length - 1)

    # read rhythm number cyclically to allow large and negative rhythm numbers
    rhythm_number = rhythm_number % rhythm_count

    # find binary representation of rhythm
    binary_representation = mathtools.integer_to_binary_string(rhythm_number)
    binary_representation = binary_representation.zfill(grid_length)

    # partition binary representation of rhythm
    parts = sequencetools.partition_sequence_by_value_of_elements(binary_representation)

    # find durations
    durations = [durationtools.Duration(len(part), denominator) for part in parts]

    # make notes
    notes = notetools.make_notes([0], durations)

    # return notes
    return notes
def make_repeated_notes_with_shorter_notes_at_end(
    pitch, written_duration, total_duration, prolation=1):
    r'''Make repeated notes with `pitch` and `written_duration` summing to
    `total_duration` under `prolation`:

    ::

        >>> args = [0, Duration(1, 16), Duration(1, 4)]
        >>> notes = notetools.make_repeated_notes_with_shorter_notes_at_end(*args)
        >>> voice = Voice(notes)

    ..  doctest::

        >>> f(voice)
        \new Voice {
            c'16
            c'16
            c'16
            c'16
        }

    Fill power-of-two remaining duration with power-of-two notes of lesser written duration:

    ::

        >>> args = [0, Duration(1, 16), Duration(9, 32)]
        >>> notes = notetools.make_repeated_notes_with_shorter_notes_at_end(*args)
        >>> voice = Voice(notes)

    ..  doctest::

        >>> f(voice)
        \new Voice {
            c'16
            c'16
            c'16
            c'16
            c'32
        }

    Fill non-power-of-two remaining duration with ad hoc tuplet:

    ::

        >>> args = [0, Duration(1, 16), Duration(4, 10)]
        >>> notes = notetools.make_repeated_notes_with_shorter_notes_at_end(*args)
        >>> voice = Voice(notes)

    ..  doctest::

        >>> f(voice)
        \new Voice {
            c'16
            c'16
            c'16
            c'16
            c'16
            c'16
            \times 4/5 {
                c'32
            }
        }

    Set `prolation` when making notes in a measure with a non-power-of-two denominator.

    Returns list of components.
    '''
    from abjad.tools import notetools

    written_duration = durationtools.Duration(written_duration)
    total_duration = durationtools.Duration(total_duration)
    prolation = durationtools.Duration(prolation)
    prolation = fractions.Fraction(prolation)

    duration = prolation * written_duration
    current_duration = durationtools.Duration(0)
    result = []
    while current_duration + duration <= total_duration:
        result.append(notetools.Note(pitch, written_duration))
        current_duration += duration
    remainder_duration = total_duration - current_duration
    if durationtools.Duration(0) < remainder_duration:
        multiplied_remainder = remainder_duration / prolation
        result.extend(notetools.make_notes(pitch, [multiplied_remainder]))

    result = selectiontools.Selection(result)
    return result
Пример #12
0
 def __call__(self, pulse_duration):
     pulse_duration = durationtools.Duration(pulse_duration)
     total_duration = pulse_duration * self.preprolated_duration
     return notetools.make_notes(0, total_duration)
Пример #13
0
    def make_notes(self, n=None, written_duration=None):
        r'''Make first `n` notes in pitch class segment.

        Set `n` equal to `n` or length of segment.

        Set `written_duration` equal to `written_duration` or ``1/8``:

        ::

            >>> pitch_class_segment = pitchtools.PitchClassSegment(
            ...     [2, 4.5, 6, 11, 4.5, 10])

        ::

            >>> notes = pitch_class_segment.make_notes()
            >>> staff = Staff(notes)
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> f(staff)
            \new Staff {
                d'8
                eqs'8
                fs'8
                b'8
                eqs'8
                bf'8
            }

        Allow nonassignable `written_duration`:

        ::

            >>> notes = pitch_class_segment.make_notes(4, Duration(5, 16))
            >>> staff = Staff(notes)
            >>> time_signature = contexttools.TimeSignatureMark((5, 4))
            >>> attach(time_signature, staff)
            TimeSignatureMark((5, 4))(Staff{8})
            >>> show(staff) # doctest: +SKIP

        ..  doctest::

            >>> f(staff)
            \new Staff {
                \time 5/4
                d'4 ~
                d'16
                eqs'4 ~
                eqs'16
                fs'4 ~
                fs'16
                b'4 ~
                b'16
            }

        Returns list of notes.
        '''
        from abjad.tools import iterationtools
        from abjad.tools import notetools
        from abjad.tools import pitchtools
        n = n or len(self)
        written_duration = written_duration or durationtools.Duration(1, 8)
        result = notetools.make_notes([0] * n, [written_duration])
        for i, tie_chain in enumerate(
            iterationtools.iterate_tie_chains_in_expr(result)):
            pitch_class = pitchtools.NamedPitchClass(self[i % len(self)])
            pitch = pitchtools.NamedPitch(pitch_class, 4)
            for note in tie_chain:
                note.written_pitch = pitch
        return result