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)
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
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)
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
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
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)
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, )
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)
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)
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)
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
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
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
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
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)
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)
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)
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
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
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
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()
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])
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)
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()
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)
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
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)
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
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
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
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
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
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)
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
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