Example #1
0
    def quarters_per_minute(self) -> typing.Union[tuple, None, Fraction]:
        """
        Gets metronome mark quarters per minute.

        ..  container:: example

            >>> mark = abjad.MetronomeMark((1, 8), 52)
            >>> mark.quarters_per_minute
            Fraction(104, 1)

        Gives tuple when metronome mark ``units_per_minute`` is a range.

        Gives none when metronome mark is imprecise.

        Gives fraction otherwise.
        """
        if self.is_imprecise:
            return None
        if isinstance(self.units_per_minute, tuple):
            low = (Duration(1, 4) / self.reference_duration *
                   self.units_per_minute[0])
            high = (Duration(1, 4) / self.reference_duration *
                    self.units_per_minute[1])
            return (low, high)
        result = (Duration(1, 4) / self.reference_duration *
                  self.units_per_minute)
        return Fraction(result)
Example #2
0
 def __init__(
     self,
     *,
     increase_monotonic: bool = None,
     forbidden_note_duration: typings.DurationTyping = None,
     forbidden_rest_duration: typings.DurationTyping = None,
     skips_instead_of_rests: bool = None,
     tag: Tag = None,
     use_multimeasure_rests: bool = None,
 ) -> None:
     if increase_monotonic is not None:
         increase_monotonic = bool(increase_monotonic)
     self._increase_monotonic = increase_monotonic
     if forbidden_note_duration is None:
         forbidden_note_duration_ = None
     else:
         forbidden_note_duration_ = Duration(forbidden_note_duration)
     self._forbidden_note_duration = forbidden_note_duration_
     if forbidden_rest_duration is None:
         forbidden_rest_duration_ = None
     else:
         forbidden_rest_duration_ = Duration(forbidden_rest_duration)
     self._forbidden_rest_duration = forbidden_rest_duration_
     if skips_instead_of_rests is not None:
         skips_instead_of_rests = bool(skips_instead_of_rests)
     self._skips_instead_of_rests = skips_instead_of_rests
     if tag is not None:
         assert isinstance(tag, Tag), repr(tag)
     self._tag = tag
     if use_multimeasure_rests is not None:
         use_multimeasure_rests = bool(use_multimeasure_rests)
     self._use_multimeasure_rests = use_multimeasure_rests
Example #3
0
 def __init__(
     self,
     written_duration=None,
     *,
     multiplier: typings.DurationTyping = None,
     tag: str = None,
 ) -> None:
     original_input = written_duration
     if isinstance(written_duration, Leaf):
         multiplier = written_duration.multiplier
     if isinstance(written_duration, str):
         string = f'{{ {written_duration} }}'
         parsed = parse(string)
         assert len(parsed) == 1 and isinstance(parsed[0], Leaf)
         written_duration = parsed[0]
     if isinstance(written_duration, Leaf):
         written_duration = written_duration.written_duration
     elif written_duration is None:
         written_duration = Duration(1, 4)
     else:
         written_duration = Duration(written_duration)
     Leaf.__init__(
         self,
         written_duration,
         multiplier=multiplier,
         tag=tag,
     )
     if isinstance(original_input, Leaf):
         self._copy_override_and_set_from_leaf(original_input)
Example #4
0
 def _get_contents_duration(self):
     if self.simultaneous:
         return max([Duration(0)] + [x._get_preprolated_duration() for x in self])
     else:
         duration = Duration(0)
         for x in self:
             duration += x._get_preprolated_duration()
         return duration
Example #5
0
 def _get_duration_in_seconds(self):
     if self.simultaneous:
         return max([Duration(0)] + [x._get_duration(in_seconds=True) for x in self])
     else:
         duration = Duration(0)
         for leaf in iterate(self).leaves():
             duration += leaf._get_duration(in_seconds=True)
         return duration
Example #6
0
    def __call__(self, pitches, durations) -> Selection:
        """
        Calls note-maker on ``pitches`` and ``durations``.
        """
        from .Tuplet import Tuplet

        if isinstance(pitches, str):
            pitches = pitches.split()
        if not isinstance(pitches, collections.abc.Iterable):
            pitches = [pitches]
        if isinstance(durations, (numbers.Number, tuple)):
            durations = [durations]
        nonreduced_fractions = Sequence(
            [NonreducedFraction(_) for _ in durations]
        )
        size = max(len(nonreduced_fractions), len(pitches))
        nonreduced_fractions = nonreduced_fractions.repeat_to_length(size)
        pitches = Sequence(pitches).repeat_to_length(size)
        durations = Duration._group_by_implied_prolation(nonreduced_fractions)
        result: typing.List[typing.Union[Note, Tuplet]] = []
        for duration in durations:
            # get factors in denominator of duration group duration not 1 or 2
            factors = set(mathtools.factors(duration[0].denominator))
            factors.discard(1)
            factors.discard(2)
            ps = pitches[0 : len(duration)]
            pitches = pitches[len(duration) :]
            if len(factors) == 0:
                result.extend(
                    self._make_unprolated_notes(
                        ps,
                        duration,
                        increase_monotonic=self.increase_monotonic,
                        tag=self.tag,
                    )
                )
            else:
                # compute prolation
                denominator = duration[0].denominator
                numerator = mathtools.greatest_power_of_two_less_equal(
                    denominator
                )
                multiplier = Multiplier(numerator, denominator)
                ratio = multiplier.reciprocal
                duration = [ratio * Duration(d) for d in duration]
                ns = self._make_unprolated_notes(
                    ps,
                    duration,
                    increase_monotonic=self.increase_monotonic,
                    tag=self.tag,
                )
                tuplet = Tuplet(multiplier, ns)
                result.append(tuplet)
        return Selection(result)
Example #7
0
 def _get_timespan(self, in_seconds=False):
     if len(self):
         timespan_ = self[0]._get_timespan(in_seconds=in_seconds)
         start_offset = timespan_.start_offset
         timespan_ = self[-1]._get_timespan(in_seconds=in_seconds)
         stop_offset = timespan_.stop_offset
     else:
         start_offset = Duration(0)
         stop_offset = Duration(0)
     return Timespan(
         start_offset=start_offset,
         stop_offset=stop_offset,
         )
Example #8
0
 def _set_duration(self, new_duration, repeat_ties=False):
     import abjad
     new_duration = Duration(new_duration)
     # change LilyPond multiplier if leaf already has LilyPond multiplier
     if self._get_indicators(Multiplier):
         detach(Multiplier, self)
         multiplier = new_duration.__div__(self.written_duration)
         attach(multiplier, self)
         return select(self)
     # change written duration if new duration is assignable
     try:
         self.written_duration = new_duration
         return select(self)
     except exceptions.AssignabilityError:
         pass
     # make new notes or tuplets if new duration is nonassignable
     maker = abjad.NoteMaker(repeat_ties=repeat_ties, )
     components = maker(0, new_duration)
     if isinstance(components[0], Leaf):
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not inspect(self).has_spanner(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         return select(all_leaves)
     else:
         assert isinstance(components[0], abjad.Tuplet)
         tuplet = components[0]
         components = tuplet[:]
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not inspect(self).has_spanner(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         multiplier = tuplet.multiplier
         tuplet = abjad.Tuplet(multiplier, [])
         abjad.mutate(all_leaves).wrap(tuplet)
         return select(tuplet)
Example #9
0
    def _set_duration(self, new_duration):
        from .Chord import Chord
        from .Note import Note
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet
        from abjad.spanners import tie as abjad_tie

        new_duration = Duration(new_duration)
        if self.multiplier is not None:
            multiplier = new_duration.__div__(self.written_duration)
            self.multiplier = multiplier
            return select(self)
        try:
            self.written_duration = new_duration
            return select(self)
        except exceptions.AssignabilityError:
            pass
        maker = NoteMaker()
        components = maker(0, new_duration)
        new_leaves = select(components).leaves()
        following_leaf_count = len(new_leaves) - 1
        following_leaves = following_leaf_count * self
        all_leaves = [self] + following_leaves
        for leaf, new_leaf in zip(all_leaves, new_leaves):
            leaf.written_duration = new_leaf.written_duration
        logical_tie = self._get_logical_tie()
        logical_tie_leaves = list(logical_tie.leaves)
        for leaf in logical_tie:
            detach(Tie, leaf)
            detach(RepeatTie, leaf)
        if self._parent is not None:
            index = self._parent.index(self)
            next_ = index + 1
            self._parent[next_:next_] = following_leaves
        index = logical_tie_leaves.index(self)
        next_ = index + 1
        logical_tie_leaves[next_:next_] = following_leaves
        if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)):
            abjad_tie(logical_tie_leaves)
        if isinstance(components[0], Leaf):
            return select(all_leaves)
        else:
            assert isinstance(components[0], Tuplet)
            assert len(components) == 1
            tuplet = components[0]
            multiplier = tuplet.multiplier
            tuplet = Tuplet(multiplier, [])
            mutate(all_leaves).wrap(tuplet)
            return select(tuplet)
Example #10
0
File: Leaf.py Project: Abjad/abjad
    def _set_duration(self, new_duration, repeat_ties=False):
        from .Chord import Chord
        from .Note import Note
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet
        from abjad.spanners import tie as abjad_tie

        new_duration = Duration(new_duration)
        if self.multiplier is not None:
            multiplier = new_duration.__div__(self.written_duration)
            self.multiplier = multiplier
            return select(self)
        try:
            self.written_duration = new_duration
            return select(self)
        except exceptions.AssignabilityError:
            pass
        maker = NoteMaker(repeat_ties=repeat_ties)
        components = maker(0, new_duration)
        new_leaves = select(components).leaves()
        following_leaf_count = len(new_leaves) - 1
        following_leaves = following_leaf_count * self
        all_leaves = [self] + following_leaves
        for leaf, new_leaf in zip(all_leaves, new_leaves):
            leaf.written_duration = new_leaf.written_duration
        logical_tie = self._get_logical_tie()
        logical_tie_leaves = list(logical_tie.leaves)
        for leaf in logical_tie:
            detach(TieIndicator, leaf)
            detach(RepeatTie, leaf)
        if self._parent is not None:
            index = self._parent.index(self)
            next_ = index + 1
            self._parent[next_:next_] = following_leaves
        index = logical_tie_leaves.index(self)
        next_ = index + 1
        logical_tie_leaves[next_:next_] = following_leaves
        if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)):
            abjad_tie(logical_tie_leaves)
        if isinstance(components[0], Leaf):
            return select(all_leaves)
        else:
            assert isinstance(components[0], Tuplet)
            assert len(components) == 1
            tuplet = components[0]
            multiplier = tuplet.multiplier
            tuplet = Tuplet(multiplier, [])
            mutate(all_leaves).wrap(tuplet)
            return select(tuplet)
Example #11
0
    def __sub__(self, argument) -> "MetronomeMark":
        """
        Subtracts ``argument`` from metronome mark.

        ..  container:: example

            Same reference reference durations:

            >>> mark_1 = abjad.MetronomeMark((1, 4), 90)
            >>> mark_2 = abjad.MetronomeMark((1, 4), 60)
            >>> mark_1 - mark_2
            MetronomeMark(reference_duration=Duration(1, 4), units_per_minute=30)

        ..  container:: example

            Different reference durations:

            >>> mark_1 = abjad.MetronomeMark((1, 4), 90)
            >>> mark_2 = abjad.MetronomeMark((1, 2), 90)
            >>> mark_1 - mark_2
            MetronomeMark(reference_duration=Duration(1, 4), units_per_minute=45)

        ..  container:: example exception

            Raises imprecise metronome mark error with textual indication:

            >>> mark_1 = abjad.MetronomeMark(textual_indication='Langsam')
            >>> mark_2 = abjad.MetronomeMark((1, 2), 90)
            >>> mark_1 - mark_2
            Traceback (most recent call last):
                ...
            abjad.exceptions.ImpreciseMetronomeMarkError

        """
        if not isinstance(argument, type(self)):
            raise Exception("must be metronome mark: {argument!r}.")
        if self.is_imprecise or argument.is_imprecise:
            raise exceptions.ImpreciseMetronomeMarkError
        assert isinstance(self.quarters_per_minute, (int, float, Fraction))
        assert isinstance(argument.quarters_per_minute, (int, float, Fraction))
        assert isinstance(self.reference_duration, Duration)
        assert isinstance(argument.reference_duration, Duration)
        new_quarters_per_minute = (self.quarters_per_minute -
                                   argument.quarters_per_minute)
        minimum_denominator = min((
            self.reference_duration.denominator,
            argument.reference_duration.denominator,
        ))
        nonreduced_fraction = NonreducedFraction(new_quarters_per_minute / 4)
        nonreduced_fraction = nonreduced_fraction.with_denominator(
            minimum_denominator)
        new_units_per_minute, new_reference_duration_denominator = (
            nonreduced_fraction.pair)
        new_reference_duration = Duration(1,
                                          new_reference_duration_denominator)
        metronome_mark = type(self)(
            reference_duration=new_reference_duration,
            units_per_minute=new_units_per_minute,
        )
        return metronome_mark
Example #12
0
 def written_duration(self, argument):
     rational = Duration(argument)
     if not rational.is_assignable:
         message = 'not assignable duration: {!r}.'
         message = message.format(rational)
         raise exceptions.AssignabilityError(message)
     self._written_duration = rational
Example #13
0
 def _get_duration_in_seconds(self):
     mark = self._get_effective(MetronomeMark)
     if mark is not None and not mark.is_imprecise:
         result = (self._get_duration() / mark.reference_duration /
                   mark.units_per_minute * 60)
         return Duration(result)
     raise exceptions.MissingMetronomeMarkError
Example #14
0
    def __rmul__(
        self, multiplier: typing.Union[int, Fraction]
    ) -> typing.Optional["MetronomeMark"]:
        """
        Multiplies ``multiplier`` by metronome mark.

        ..  container::: example

            Doubles metronome mark:

            >>> mark = abjad.MetronomeMark((1, 4), 84)
            >>> mark * 2
            MetronomeMark(reference_duration=Duration(1, 4), units_per_minute=168)

        ..  container::: example

            Triples metronome mark:

            >>> mark = abjad.MetronomeMark((1, 4), 84)
            >>> mark * 3
            MetronomeMark(reference_duration=Duration(1, 4), units_per_minute=252)

        """
        if not isinstance(multiplier, (int, Fraction)):
            return None
        if self.is_imprecise:
            raise exceptions.ImpreciseMetronomeMarkError
        assert isinstance(self.units_per_minute, (int, Fraction))
        new_units_per_minute = multiplier * self.units_per_minute
        new_reference_duration = Duration(self.reference_duration)
        metronome_mark = type(self)(
            reference_duration=new_reference_duration,
            units_per_minute=new_units_per_minute,
        )
        return metronome_mark
Example #15
0
 def __init__(self, written_duration):
     Component.__init__(self)
     self._after_grace_container = None
     self._grace_container = None
     self._leaf_index = None
     self._spanners = []
     self.written_duration = Duration(written_duration)
Example #16
0
    def __init__(
        self,
        pair: typings.IntegerPair = (4, 4),
        *,
        partial: Duration = None,
        hide: bool = None,
    ) -> None:
        import abjad

        pair_ = getattr(pair, "pair", pair)
        assert isinstance(pair_, tuple), repr(pair_)
        assert len(pair_) == 2, repr(pair_)
        numerator, denominator = pair_
        assert isinstance(numerator, int), repr(numerator)
        assert isinstance(denominator, int), repr(denominator)
        self._numerator: int = numerator
        self._denominator: int = denominator
        if partial is not None:
            partial = Duration(partial)
        self._partial: typing.Optional[Duration] = partial
        if partial is not None:
            self._partial_repr_string = ", partial=%r" % self._partial
        else:
            self._partial_repr_string = ""
        if hide is not None:
            hide = bool(hide)
        self._hide: typing.Optional[bool] = hide
        self._multiplier = self.implied_prolation
        result = mathtools.is_nonnegative_integer_power_of_two(
            self.denominator)
        assert isinstance(result, bool)
        self._has_non_power_of_two_denominator: bool = not (result)
Example #17
0
 def __init__(
     self,
     *arguments,
     multiplier: typings.DurationTyping = None,
     tag: Tag = None,
 ) -> None:
     input_leaf = None
     written_duration = None
     if len(arguments) == 1 and isinstance(arguments[0], str):
         string = f"{{ {arguments[0]} }}"
         parsed = parse(string)
         assert len(parsed) == 1 and isinstance(parsed[0], Leaf)
         input_leaf = parsed[0]
         written_duration = input_leaf.written_duration
     elif len(arguments) == 1 and isinstance(arguments[0], Leaf):
         written_duration = arguments[0].written_duration
         input_leaf = arguments[0]
     elif len(arguments) == 1 and not isinstance(arguments[0], str):
         written_duration = arguments[0]
     elif len(arguments) == 0:
         written_duration = Duration(1, 4)
     else:
         message = f"can not initialize skip from {arguments!r}."
         raise ValueError(message)
     Leaf.__init__(self, written_duration, multiplier=multiplier, tag=tag)
     if input_leaf is not None:
         self._copy_override_and_set_from_leaf(input_leaf)
Example #18
0
 def _get_multiplied_duration(self):
     if self.written_duration:
         multiplier_prototype = (Multiplier, NonreducedFraction)
         if self._get_indicators(multiplier_prototype):
             multipliers = self._get_indicators(multiplier_prototype)
             if 1 == len(multipliers):
                 multiplier = multipliers[0]
                 multiplier = Duration(multiplier)
             elif 1 < len(multipliers):
                 message = 'more than one duration multiplier.'
                 raise ValueError(message)
             multiplied_duration = multiplier * self.written_duration
             return multiplied_duration
         else:
             return Duration(self.written_duration)
     else:
         return None
Example #19
0
    def _make_lhs_score_markup(self, reference_duration=None):
        import abjad

        reference_duration = reference_duration or self.reference_duration
        maker = abjad.NoteMaker()
        selection = maker([0], [reference_duration])
        markup = Duration._to_score_markup(selection)
        return markup
Example #20
0
 def _get_tremolo_reattack_duration(self):
     tremolos = inspect(self).indicators(Tremolo)
     if not tremolos:
         return
     tremolo = tremolos[0]
     exponent = 2 + tremolo.beam_count
     denominator = 2**exponent
     reattack_duration = Duration(1, denominator)
     return reattack_duration
Example #21
0
    def _add_or_remove_notes_to_achieve_written_duration(
            self, new_written_duration):
        from abjad.spanners import tie as abjad_tie
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet

        new_written_duration = Duration(new_written_duration)
        maker = NoteMaker()
        if new_written_duration.is_assignable:
            self[0].written_duration = new_written_duration
            for leaf in self[1:]:
                mutate(leaf).extract()
            detach(Tie, self[0])
            detach(RepeatTie, self[0])
        elif new_written_duration.has_power_of_two_denominator:
            durations = maker(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):]:
                    mutate(leaf).extract()
            elif len(self) < len(durations):
                # detach(Tie, self[0])
                detach(Tie, self[0])
                detach(RepeatTie, self[0])
                difference = len(durations) - len(self)
                extra_leaves = self[0] * difference
                for extra_leaf in extra_leaves:
                    # detach(Tie, extra_leaf)
                    detach(Tie, extra_leaf)
                    detach(RepeatTie, extra_leaf)
                extra_tokens = durations[len(self):]
                for leaf, token in zip(extra_leaves, extra_tokens):
                    leaf.written_duration = token.written_duration
                parent = inspect(self[-1]).parentage().parent
                index = parent.index(self[-1])
                next_ = index + 1
                parent[next_:next_] = extra_leaves
                leaves = self.leaves + extra_leaves
                # attach(Tie(), leaves)
                abjad_tie(leaves)
        else:
            components = maker(0, new_written_duration)
            assert isinstance(components[0], Tuplet)
            tuplet = components[0]
            logical_tie = tuplet[0]._get_logical_tie()
            duration = logical_tie._get_preprolated_duration()
            leaves_ = self._add_or_remove_notes_to_achieve_written_duration(
                duration)
            multiplier = tuplet.multiplier
            tuplet = Tuplet(multiplier, [])
            # mutate(self.leaves).wrap(tuplet)
            mutate(leaves_).wrap(tuplet)

        return self[0]._get_logical_tie()
Example #22
0
 def __init__(self, *arguments):
     import abjad
     from abjad.ly import drums
     assert len(arguments) in (0, 1, 2)
     if len(arguments) == 1 and isinstance(arguments[0], str):
         string = '{{ {} }}'.format(arguments[0])
         parsed = abjad.parse(string)
         assert len(parsed) == 1 and isinstance(parsed[0], Leaf)
         arguments = [parsed[0]]
     is_cautionary = False
     is_forced = False
     is_parenthesized = False
     if len(arguments) == 1 and isinstance(arguments[0], Leaf):
         leaf = arguments[0]
         written_pitch = None
         written_duration = leaf.written_duration
         if 'written_pitch' in dir(leaf):
             written_pitch = leaf.note_head.written_pitch
             is_cautionary = leaf.note_head.is_cautionary
             is_forced = leaf.note_head.is_forced
             is_parenthesized = leaf.note_head.is_parenthesized
         elif 'written_pitches' in dir(leaf):
             written_pitches = [x.written_pitch for x in leaf.note_heads]
             if written_pitches:
                 written_pitch = written_pitches[0]
                 is_cautionary = leaf.note_heads[0].is_cautionary
                 is_forced = leaf.note_heads[0].is_forced
                 is_parenthesized = leaf.note_heads[0].is_parenthesized
     elif len(arguments) == 2:
         written_pitch, written_duration = arguments
     elif len(arguments) == 0:
         written_pitch = 'C4'
         written_duration = Duration(1, 4)
     else:
         message = 'can not initialize note from {!r}.'
         raise ValueError(message.format(arguments))
     Leaf.__init__(self, written_duration)
     if written_pitch is not None:
         if written_pitch not in drums:
             self.note_head = NoteHead(
                 written_pitch=written_pitch,
                 is_cautionary=is_cautionary,
                 is_forced=is_forced,
                 is_parenthesized=is_parenthesized,
                 )
         else:
             self.note_head = DrumNoteHead(
                 written_pitch=written_pitch,
                 is_cautionary=is_cautionary,
                 is_forced=is_forced,
                 is_parenthesized=is_parenthesized,
                 )
     else:
         self.note_head = None
     if len(arguments) == 1 and isinstance(arguments[0], Leaf):
         self._copy_override_and_set_from_leaf(arguments[0])
Example #23
0
    def __call__(self, pitches, durations) -> Selection:
        """
        Calls note-maker on ``pitches`` and ``durations``.
        """
        from .Tuplet import Tuplet

        if isinstance(pitches, str):
            pitches = pitches.split()
        if not isinstance(pitches, collections.abc.Iterable):
            pitches = [pitches]
        if isinstance(durations, (numbers.Number, tuple)):
            durations = [durations]
        nonreduced_fractions = Sequence(
            [NonreducedFraction(_) for _ in durations]
        )
        size = max(len(nonreduced_fractions), len(pitches))
        nonreduced_fractions = nonreduced_fractions.repeat_to_length(size)
        pitches = Sequence(pitches).repeat_to_length(size)
        durations = Duration._group_by_implied_prolation(nonreduced_fractions)
        result: typing.List[typing.Union[Note, Tuplet]] = []
        for duration in durations:
            # get factors in denominator of duration group duration not 1 or 2
            factors = set(mathtools.factors(duration[0].denominator))
            factors.discard(1)
            factors.discard(2)
            ps = pitches[0 : len(duration)]
            pitches = pitches[len(duration) :]
            if len(factors) == 0:
                result.extend(
                    self._make_unprolated_notes(
                        ps,
                        duration,
                        increase_monotonic=self.increase_monotonic,
                        repeat_ties=self.repeat_ties,
                        tag=self.tag,
                    )
                )
            else:
                # compute prolation
                denominator = duration[0].denominator
                numerator = mathtools.greatest_power_of_two_less_equal(
                    denominator
                )
                multiplier = Multiplier(numerator, denominator)
                ratio = multiplier.reciprocal
                duration = [ratio * Duration(d) for d in duration]
                ns = self._make_unprolated_notes(
                    ps,
                    duration,
                    increase_monotonic=self.increase_monotonic,
                    repeat_ties=self.repeat_ties,
                    tag=self.tag,
                )
                tuplet = Tuplet(multiplier, ns)
                result.append(tuplet)
        return Selection(result)
Example #24
0
 def _add_or_remove_notes_to_achieve_written_duration(
         self, new_written_duration):
     import abjad
     new_written_duration = Duration(new_written_duration)
     maker = abjad.NoteMaker()
     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(abjad.Tie):
             spanner._sever_all_leaves()
     elif new_written_duration.has_power_of_two_denominator:
         durations = maker(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(abjad.Tie):
                 spanner._sever_all_leaves()
             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(abjad.Tie)
             if not ties:
                 tie = abjad.Tie()
                 if all(tie._attachment_test(_) for _ in self):
                     abjad.attach(tie, self.leaves)
             self[-1]._splice(extra_leaves, grow_spanners=True)
     else:
         durations = maker(0, new_written_duration)
         assert isinstance(durations[0], abjad.Tuplet)
         tuplet = durations[0]
         logical_tie = tuplet[0]._get_logical_tie()
         duration = logical_tie._get_preprolated_duration()
         self._add_or_remove_notes_to_achieve_written_duration(duration)
         multiplier = tuplet.multiplier
         tuplet = abjad.Tuplet(multiplier, [])
         abjad.mutate(self.leaves).wrap(tuplet)
     return self[0]._get_logical_tie()
Example #25
0
    def duration(self) -> Duration:
        """
        Gets duration of time signature.

        ..  container:: example

            >>> abjad.TimeSignature((3, 8)).duration
            Duration(3, 8)

        """
        return Duration(self.numerator, self.denominator)
Example #26
0
 def __init__(
     self,
     components=None,
     identifier: str = None,
     leaf_duration: typings.DurationTyping = None,
     name: str = None,
     tag: Tag = None,
 ) -> None:
     super().__init__(components, identifier=identifier, name=name, tag=tag)
     if leaf_duration is not None:
         leaf_duration = Duration(leaf_duration)
     self._leaf_duration = leaf_duration
Example #27
0
    def duration_to_milliseconds(self, duration) -> Duration:
        """
        Gets millisecond value of ``duration`` under a given metronome mark.

        ..  container:: example

            Dotted sixteenth lasts 1500 msec at quarter equals 60:

            >>> mark = abjad.MetronomeMark((1, 4), 60)
            >>> mark.duration_to_milliseconds((3, 8))
            Duration(1500, 1)

        """
        assert isinstance(self.reference_duration, Duration)
        denominator = self.reference_duration.denominator
        numerator = self.reference_duration.numerator
        whole_note_duration = 1000
        whole_note_duration *= Multiplier(denominator, numerator)
        whole_note_duration *= Multiplier(60, self.units_per_minute)
        duration = Duration(duration)
        return Duration(duration * whole_note_duration)
Example #28
0
 def __init__(
     self,
     *,
     increase_monotonic: bool = None,
     forbidden_note_duration: typings.DurationTyping = None,
     forbidden_rest_duration: typings.DurationTyping = None,
     metrical_hierarchy=None,
     skips_instead_of_rests: bool = None,
     repeat_ties: bool = None,
     tag: str = None,
     use_multimeasure_rests: bool = None,
 ) -> None:
     if increase_monotonic is not None:
         increase_monotonic = bool(increase_monotonic)
     self._increase_monotonic = increase_monotonic
     if forbidden_note_duration is None:
         forbidden_note_duration_ = None
     else:
         forbidden_note_duration_ = Duration(forbidden_note_duration)
     self._forbidden_note_duration = forbidden_note_duration_
     if forbidden_rest_duration is None:
         forbidden_rest_duration_ = None
     else:
         forbidden_rest_duration_ = Duration(forbidden_rest_duration)
     self._forbidden_rest_duration = forbidden_rest_duration_
     self._metrical_hierarchy = metrical_hierarchy
     if skips_instead_of_rests is not None:
         skips_instead_of_rests = bool(skips_instead_of_rests)
     self._skips_instead_of_rests = skips_instead_of_rests
     if repeat_ties is not None:
         repeat_ties = bool(repeat_ties)
     self._repeat_ties = repeat_ties
     if tag is not None:
         assert isinstance(tag, str), repr(tag)
     self._tag = tag
     if use_multimeasure_rests is not None:
         use_multimeasure_rests = bool(use_multimeasure_rests)
     self._use_multimeasure_rests = use_multimeasure_rests
Example #29
0
 def _should_force_repeat_tie_up(leaf):
     if not isinstance(leaf, (Note, Chord)):
         return False
     if leaf.written_duration < Duration(1):
         return False
     clef = inspect(leaf).effective(Clef, default=Clef('treble'))
     if isinstance(leaf, Note):
         written_pitches = [leaf.written_pitch]
     else:
         written_pitches = leaf.written_pitches
     for written_pitch in written_pitches:
         staff_position = written_pitch.to_staff_position(clef=clef)
         if staff_position.number == 0:
             return True
     return False
Example #30
0
 def _remove_and_shrink_durated_parent_containers(self):
     import abjad
     prolated_leaf_duration = self._get_duration()
     parentage = abjad.inspect(self).parentage(include_self=False)
     prolations = parentage._prolations
     current_prolation, i = Duration(1), 0
     parent = self._parent
     while parent is not None and not parent.is_simultaneous:
         current_prolation *= prolations[i]
         if isinstance(parent, abjad.Measure):
             indicator = parent._get_indicator(abjad.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 = abjad.NonreducedFraction(
                 naive_time_signature)
             better_time_signature = better_time_signature.with_denominator(
                 parent_time_signature.denominator)
             better_time_signature = abjad.TimeSignature(
                 better_time_signature)
             abjad.detach(abjad.TimeSignature, parent)
             abjad.attach(better_time_signature, parent)
             indicator = parent._get_indicator(abjad.TimeSignature)
             parent_time_signature = indicator
             new_prolation = parent_time_signature.implied_prolation
             adjusted_prolation = old_prolation / new_prolation
             for x in parent:
                 if adjusted_prolation != 1:
                     new_target = x._get_preprolated_duration()
                     new_target *= adjusted_prolation
                     contents_duration = abjad.inspect(x)
                     multiplier = new_target / contents_duration
                     tuplet = abjad.Tuplet(multiplier, [])
                     abjad.mutate(x).wrap(tuplet)
         parent = parent._parent
         i += 1
     parentage = abjad.inspect(self).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
Example #31
0
 def _get_on_beat_grace_leaf_offsets(leaf):
     container = leaf._parent
     anchor_leaf = container._get_on_beat_anchor_leaf()
     anchor_leaf_start_offset = anchor_leaf._start_offset
     assert anchor_leaf_start_offset is not None
     anchor_leaf_start_offset = Offset(anchor_leaf_start_offset.pair)
     start_displacement = Duration(0)
     sibling = leaf._sibling(-1)
     while sibling is not None and sibling._parent is container:
         start_displacement += abjad_inspect(sibling).duration()
         sibling = sibling._sibling(-1)
     stop_displacement = start_displacement + abjad_inspect(leaf).duration()
     if start_displacement == 0:
         start_displacement = None
     start_offset = Offset(anchor_leaf_start_offset.pair,
                           displacement=start_displacement)
     stop_offset = Offset(anchor_leaf_start_offset.pair,
                          displacement=stop_displacement)
     return start_offset, stop_offset
Example #32
0
 def __init__(
     self,
     reference_duration: typings.DurationTyping = None,
     units_per_minute: typing.Union[int, Fraction] = None,
     textual_indication: str = None,
     *,
     custom_markup: Markup = None,
     decimal: typing.Union[bool, str] = None,
     hide: bool = None,
 ) -> None:
     assert isinstance(textual_indication, (str, type(None)))
     arguments = (reference_duration, units_per_minute, textual_indication)
     if all(_ is None for _ in arguments):
         reference_duration = (1, 4)
         units_per_minute = 60
     if reference_duration:
         reference_duration = Duration(reference_duration)
     if isinstance(units_per_minute, float):
         raise Exception(
             f"do not set units-per-minute to float ({units_per_minute});"
             " use fraction with decimal override instead."
         )
     prototype = (int, Fraction, collections.abc.Sequence, type(None))
     assert isinstance(units_per_minute, prototype)
     if isinstance(units_per_minute, collections.abc.Sequence):
         assert len(units_per_minute) == 2
         item_prototype = (int, Duration)
         assert units_per_minute is not None
         assert all(isinstance(x, item_prototype) for x in units_per_minute)
         units_per_minute = tuple(sorted(units_per_minute))
     self._reference_duration = reference_duration
     self._textual_indication = textual_indication
     self._units_per_minute = units_per_minute
     if custom_markup is not None:
         assert isinstance(custom_markup, Markup), repr(custom_markup)
     self._custom_markup = custom_markup
     if decimal is not None:
         assert isinstance(decimal, (bool, str)), repr(decimal)
     self._decimal = decimal
     if hide is not None:
         hide = bool(hide)
     self._hide = hide
Example #33
0
    def __call__(self, pitches, durations) -> Selection:
        """
        Calls leaf-maker on ``pitches`` and ``durations``.

        Returns selection.
        """
        from .Tuplet import Tuplet

        if isinstance(pitches, str):
            pitches = pitches.split()
        if not isinstance(pitches, collections.abc.Iterable):
            pitches = [pitches]
        if isinstance(durations, (numbers.Number, tuple)):
            durations = [durations]
        nonreduced_fractions = Sequence(
            [NonreducedFraction(_) for _ in durations]
        )
        size = max(len(nonreduced_fractions), len(pitches))
        nonreduced_fractions = nonreduced_fractions.repeat_to_length(size)
        pitches = Sequence(pitches).repeat_to_length(size)
        duration_groups = Duration._group_by_implied_prolation(
            nonreduced_fractions
        )
        result: typing.List[typing.Union[Tuplet, Leaf]] = []
        for duration_group in duration_groups:
            # get factors in denominator of duration group other than 1, 2.
            factors = mathtools.factors(duration_group[0].denominator)
            factors = set(factors)
            factors.discard(1)
            factors.discard(2)
            current_pitches = pitches[0 : len(duration_group)]
            pitches = pitches[len(duration_group) :]
            if len(factors) == 0:
                for pitch, duration in zip(current_pitches, duration_group):
                    leaves = self._make_leaf_on_pitch(
                        pitch,
                        duration,
                        increase_monotonic=self.increase_monotonic,
                        forbidden_note_duration=self.forbidden_note_duration,
                        forbidden_rest_duration=self.forbidden_rest_duration,
                        repeat_ties=self.repeat_ties,
                        skips_instead_of_rests=self.skips_instead_of_rests,
                        tag=self.tag,
                        use_multimeasure_rests=self.use_multimeasure_rests,
                    )
                    result.extend(leaves)
            else:
                # compute tuplet prolation
                denominator = duration_group[0].denominator
                numerator = mathtools.greatest_power_of_two_less_equal(
                    denominator
                )
                multiplier = (numerator, denominator)
                ratio = 1 / Duration(*multiplier)
                duration_group = [
                    ratio * Duration(duration) for duration in duration_group
                ]
                # make tuplet leaves
                tuplet_leaves: typing.List[Leaf] = []
                for pitch, duration in zip(current_pitches, duration_group):
                    leaves = self._make_leaf_on_pitch(
                        pitch,
                        duration,
                        increase_monotonic=self.increase_monotonic,
                        repeat_ties=self.repeat_ties,
                        skips_instead_of_rests=self.skips_instead_of_rests,
                        tag=self.tag,
                        use_multimeasure_rests=self.use_multimeasure_rests,
                    )
                    tuplet_leaves.extend(leaves)
                tuplet = Tuplet(multiplier, tuplet_leaves)
                result.append(tuplet)
        return Selection(result)
Example #34
0
 def _get_right_markup(self):
     if self.right_markup is not None:
         return self.right_markup
     markup = Duration._to_score_markup(self.right_rhythm)
     return markup
Example #35
0
    def _make_tied_leaf(
        class_,
        duration,
        increase_monotonic=None,
        forbidden_duration=None,
        multiplier=None,
        pitches=None,
        tag=None,
        tie_parts=True,
        repeat_ties=False,
    ):
        from abjad.spanners import tie as abjad_tie

        duration = Duration(duration)
        if forbidden_duration is not None:
            assert forbidden_duration.is_assignable
            assert forbidden_duration.numerator == 1
        # find preferred numerator of written durations if necessary
        if forbidden_duration is not None and forbidden_duration <= duration:
            denominators = [
                2 * forbidden_duration.denominator,
                duration.denominator,
            ]
            denominator = mathtools.least_common_multiple(*denominators)
            forbidden_duration = NonreducedFraction(forbidden_duration)
            forbidden_duration = forbidden_duration.with_denominator(
                denominator
            )
            duration = NonreducedFraction(duration)
            duration = duration.with_denominator(denominator)
            forbidden_numerator = forbidden_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_duration is not None and forbidden_duration <= duration:
            for part in parts:
                if forbidden_numerator <= part:
                    better_parts = LeafMaker._partition_less_than_double(
                        part, preferred_numerator
                    )
                    numerators.extend(better_parts)
                else:
                    numerators.append(part)
        else:
            numerators = parts
        # reverse numerators if necessary
        if increase_monotonic:
            numerators = list(reversed(numerators))
        # make one leaf per written duration
        result = []
        for numerator in numerators:
            written_duration = Duration(numerator, duration.denominator)
            if pitches is not None:
                arguments = (pitches, written_duration)
            else:
                arguments = (written_duration,)
            result.append(class_(*arguments, multiplier=multiplier, tag=tag))
        result = Selection(result)
        # tie if required
        if tie_parts and 1 < len(result):
            if not issubclass(class_, (Rest, Skip)):
                abjad_tie(result, repeat=repeat_ties)
        return result