Exemple #1
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)
Exemple #2
0
 def _get_measure_start_offsets(self, component):
     wrappers = []
     prototype = TimeSignature
     root = inspect(component).parentage().root
     for component_ in self._iterate_entire_score(root):
         wrappers_ = inspect(component_).wrappers(prototype)
         wrappers.extend(wrappers_)
     pairs = []
     for wrapper in wrappers:
         component = wrapper.component
         start_offset = inspect(component).timespan().start_offset
         time_signature = wrapper.indicator
         pair = start_offset, time_signature
         pairs.append(pair)
     offset_zero = Offset(0)
     default_time_signature = TimeSignature((4, 4))
     default_pair = (offset_zero, default_time_signature)
     if pairs and not pairs[0] == offset_zero:
         pairs.insert(0, default_pair)
     elif not pairs:
         pairs = [default_pair]
     pairs.sort(key=lambda x: x[0])
     score_stop_offset = inspect(root).timespan().stop_offset
     dummy_last_pair = (score_stop_offset, None)
     pairs.append(dummy_last_pair)
     measure_start_offsets = []
     for current_pair, next_pair in Sequence(pairs).nwise():
         current_start_offset, current_time_signature = current_pair
         next_start_offset, next_time_signature = next_pair
         measure_start_offset = current_start_offset
         while measure_start_offset < next_start_offset:
             measure_start_offsets.append(measure_start_offset)
             measure_start_offset += current_time_signature.duration
     return measure_start_offsets
Exemple #3
0
 def _to_measure_number(self, component, measure_number_start_offsets):
     inspector = inspect(component)
     component_start_offset = inspector.timespan().start_offset
     measure_number_start_offsets = measure_number_start_offsets[:]
     measure_number_start_offsets.append(mathtools.Infinity())
     pairs = Sequence(measure_number_start_offsets)
     pairs = pairs.nwise()
     for measure_index, pair in enumerate(pairs):
         if pair[0] <= component_start_offset < pair[-1]:
             measure_number = measure_index + 1
             return measure_number
     message = "can not find measure number: {!r}, {!r}."
     message = message.format(component, measure_number_start_offsets)
     raise ValueError(message)
Exemple #4
0
 def check_duplicate_ids(self,
                         argument=None) -> typing.Tuple[typing.List, int]:
     """
     Checks duplicate IDs.
     """
     violators = []
     components = iterate(argument).components()
     total_ids = [id(_) for _ in components]
     unique_ids = Sequence(total_ids).remove_repeats()
     if len(unique_ids) < len(total_ids):
         for current_id in unique_ids:
             if 1 < total_ids.count(current_id):
                 violators.extend(
                     [_ for _ in components if id(_) == current_id])
     return violators, len(total_ids)
Exemple #5
0
 def _make_metronome_mark_map(self, score_root):
     from abjad.utilities.Multiplier import Multiplier
     from abjad.utilities.Offset import Offset
     from abjad.utilities.Sequence import Sequence
     from abjad.indicators.MetronomeMark import MetronomeMark
     from abjad.timespans.AnnotatedTimespan import AnnotatedTimespan
     from abjad.timespans.TimespanList import TimespanList
     pairs = []
     all_stop_offsets = set()
     for component in self._iterate_entire_score(score_root):
         indicators = component._get_indicators(MetronomeMark)
         if len(indicators) == 1:
             metronome_mark = indicators[0]
             if not metronome_mark.is_imprecise:
                 pair = (component._start_offset, metronome_mark)
                 pairs.append(pair)
         if component._stop_offset is not None:
             all_stop_offsets.add(component._stop_offset)
     pairs.sort(key=lambda _: _[0])
     if not pairs:
         return
     if pairs[0][0] != 0:
         return
     score_stop_offset = max(all_stop_offsets)
     timespans = TimespanList()
     clocktime_rate = MetronomeMark((1, 4), 60)
     clocktime_start_offset = Offset(0)
     for left, right in Sequence(pairs).nwise(wrapped=True):
         metronome_mark = left[-1]
         start_offset = left[0]
         stop_offset = right[0]
         # last timespan
         if stop_offset == 0:
             stop_offset = score_stop_offset
         duration = stop_offset - start_offset
         multiplier = Multiplier(60, metronome_mark.units_per_minute)
         clocktime_duration = duration / metronome_mark.reference_duration
         clocktime_duration *= multiplier
         timespan = AnnotatedTimespan(
             start_offset=start_offset,
             stop_offset=stop_offset,
             annotation=(clocktime_start_offset, clocktime_duration),
         )
         timespans.append(timespan)
         clocktime_start_offset += clocktime_duration
     return timespans
Exemple #6
0
 def _to_measure_number(self, component, measure_start_offsets):
     component_start_offset = inspect(component).timespan().start_offset
     displacement = component_start_offset.displacement
     if displacement is not None:
         component_start_offset = Offset(
             component_start_offset, displacement=None
         )
         # score-initial grace music only:
         if displacement < 0 and component_start_offset == 0:
             measure_number = 0
             return measure_number
     measure_start_offsets = measure_start_offsets[:]
     measure_start_offsets.append(mathtools.Infinity())
     pairs = Sequence(measure_start_offsets)
     pairs = pairs.nwise()
     for measure_index, pair in enumerate(pairs):
         if pair[0] <= component_start_offset < pair[-1]:
             measure_number = measure_index + 1
             return measure_number
     message = f"can not find measure number for {repr(component)}:\n"
     message += f"   {repr(measure_start_offsets)}"
     raise ValueError(message)
Exemple #7
0
    def _split_by_durations(
        self,
        durations,
        cyclic=False,
        tie_split_notes=True,
        repeat_ties=False,
        ):
        from .AfterGraceContainer import AfterGraceContainer
        from .Chord import Chord
        from .GraceContainer import GraceContainer
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet
        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).duration()
        if cyclic:
            durations = durations.repeat_to_weight(leaf_duration)
        if sum(durations) < leaf_duration:
            last_duration = leaf_duration - sum(durations)
            durations = list(durations)
            durations.append(last_duration)
            durations = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(TieIndicator)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        grace_container = self._detach_grace_container()
        after_grace_container = self._detach_after_grace_container()
        leaf_prolation = inspect(self).parentage().prolation
        for duration in durations:
            new_leaf = copy.copy(self)
            preprolated_duration = duration / leaf_prolation
            selection = new_leaf._set_duration(
                preprolated_duration,
                repeat_ties=repeat_ties,
                )
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace_notes=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
#        for leaf in result_leaves:
#            detach(Tie, leaf)
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if self._parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, '_time_orientation', enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.Right:
                attach(indicator, last_result_leaf)
            else:
                raise ValueError(direction)
        # move grace containers
        if grace_container is not None:
            container = grace_container[0]
            assert isinstance(container, GraceContainer), repr(container)
            attach(container, first_result_leaf)
        if after_grace_container is not None:
            container = after_grace_container[0]
            prototype = AfterGraceContainer
            assert isinstance(container, prototype), repr(container)
            attach(container, last_result_leaf)
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if (tie_split_notes and
            isinstance(self, (Note, Chord)) and
            1 < len(result_leaves)):
            result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties)
        #assert not inspect(result_leaves[0]).has_indicator(RepeatTie)
        detach(RepeatTie, result_leaves[0])
        #assert not inspect(result_leaves[-1]).has_indicator(TieIndicator)
        detach(TieIndicator, result_leaves[-1])
        if originally_repeat_tied:
            tie = RepeatTie()
            attach(tie, result_leaves[0])
        if originally_tied:
            tie = TieIndicator()
            attach(tie, result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Exemple #8
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.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)
Exemple #9
0
    def _split_by_durations(self, durations, cyclic=False):
        from .Chord import Chord
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet

        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).duration()
        if cyclic:
            durations = durations.repeat_to_weight(leaf_duration)
        if sum(durations) < leaf_duration:
            last_duration = leaf_duration - sum(durations)
            durations = list(durations)
            durations.append(last_duration)
            durations = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(Tie)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        # detach grace containers
        before_grace_container = self._before_grace_container
        if before_grace_container is not None:
            detach(before_grace_container, self)
        after_grace_container = self._after_grace_container
        if after_grace_container is not None:
            detach(after_grace_container, self)
        # do other things
        leaf_prolation = inspect(self).parentage().prolation
        for duration in durations:
            new_leaf = copy.copy(self)
            preprolated_duration = duration / leaf_prolation
            selection = new_leaf._set_duration(preprolated_duration)
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if inspect(self).parentage().parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, "_time_orientation", enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.Right:
                attach(indicator, last_result_leaf)
            else:
                raise ValueError(direction)
        # reattach grace containers
        if before_grace_container is not None:
            attach(before_grace_container, first_result_leaf)
        if after_grace_container is not None:
            attach(after_grace_container, last_result_leaf)
        # fuse tuplets
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if isinstance(self, (Note, Chord)) and 1 < len(result_leaves):
            result_leaves._attach_tie_to_leaves()
        if originally_repeat_tied and not inspect(
                result_leaves[0]).has_indicator(RepeatTie):
            attach(RepeatTie(), result_leaves[0])
        if originally_tied and not inspect(
                result_leaves[-1]).has_indicator(Tie):
            attach(Tie(), result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves