def partition_by_ratio_of_durations(self, ratio):
        r'''Partition payload expression by ratio of durations.

        ::

            >>> result = \
            ...     payload_expression.partition_by_ratio_of_durations((1, 1))

        ::

            >>> for element in result:
            ...     print element.storage_format
            musicexpressiontools.IterablePayloadExpression(
                payload=((4, 16),)
                )
            musicexpressiontools.IterablePayloadExpression(
                payload=((2, 16),)
                )

        Returns newly constructed payload expression.
        '''
        element_durations = [self._duration_helper(x) for x in self.payload]
        element_tokens = self._durations_to_integers(element_durations)
        token_parts = sequencetools.partition_sequence_by_ratio_of_weights(
                element_tokens, ratio)
        part_lengths = [len(x) for x in token_parts]
        duration_parts = sequencetools.partition_sequence_by_counts(
            element_durations, part_lengths)
        element_parts = sequencetools.partition_sequence_by_counts(
            self.payload, part_lengths)
        result = []
        for part in element_parts:
            part = self.new(payload=part)
            result.append(part)
        return result
示例#2
0
 def _beat_list_to_grouped_beat_list(self, beat_list):
     assert isinstance(beat_list, (list, tuple)), repr(beat_list)
     beat_list_ = []
     for beat in beat_list:
         if hasattr(beat, 'duration'):
             beat = durationtools.Division(beat.duration)
         else:
             beat = durationtools.Division(beat)
         beat_list_.append(beat)
     beat_list = beat_list_
     total_duration = sum(beat_list)
     total_duration = durationtools.Duration(total_duration)
     if (total_duration.is_assignable and 
         self.fuse_assignable_total_duration):
         return [[durationtools.Division(total_duration)]]
     if self.counts is None:
         beat_group = list(beat_list)
         grouped_beat_list = [beat_group]
         return grouped_beat_list
     grouped_beat_list = sequencetools.partition_sequence_by_counts(
         beat_list,
         counts=self.counts,
         cyclic=True,
         overhang=False,
         )
     beats_included = sum([len(_) for _ in grouped_beat_list])
     if beats_included == len(beat_list):
         return grouped_beat_list
     remainder_length = len(beat_list) - beats_included
     if self.remainder_direction == Left:
         grouped_beat_list = sequencetools.partition_sequence_by_counts(
             beat_list[remainder_length:],
             counts=self.counts,
             cyclic=True,
             overhang=False
             )
         remainder = beat_list[:remainder_length]
         if self.append_remainder:
             grouped_beat_list[0] = remainder + grouped_beat_list[0]
         else:
             grouped_beat_list.insert(0, remainder)
     else:
         grouped_beat_list = sequencetools.partition_sequence_by_counts(
             beat_list[:-remainder_length],
             counts=self.counts,
             cyclic=True,
             overhang=False
             )
         remainder = beat_list[-remainder_length:]
         if self.append_remainder:
             grouped_beat_list[-1] = grouped_beat_list[-1] + remainder
         else:
             grouped_beat_list.append(remainder)
     return grouped_beat_list
示例#3
0
 def _beat_list_to_grouped_beat_list(self, beat_list):
     assert isinstance(beat_list, (list, tuple)), repr(beat_list)
     beat_list_ = []
     for beat in beat_list:
         if hasattr(beat, 'duration'):
             beat = durationtools.Division(beat.duration)
         else:
             beat = durationtools.Division(beat)
         beat_list_.append(beat)
     beat_list = beat_list_
     total_duration = sum(beat_list)
     total_duration = durationtools.Duration(total_duration)
     if (total_duration.is_assignable
             and self.fuse_assignable_total_duration):
         return [[durationtools.Division(total_duration)]]
     if self.counts is None:
         beat_group = list(beat_list)
         grouped_beat_list = [beat_group]
         return grouped_beat_list
     grouped_beat_list = sequencetools.partition_sequence_by_counts(
         beat_list,
         counts=self.counts,
         cyclic=True,
         overhang=False,
     )
     beats_included = sum([len(_) for _ in grouped_beat_list])
     if beats_included == len(beat_list):
         return grouped_beat_list
     remainder_length = len(beat_list) - beats_included
     if self.remainder_direction == Left:
         grouped_beat_list = sequencetools.partition_sequence_by_counts(
             beat_list[remainder_length:],
             counts=self.counts,
             cyclic=True,
             overhang=False)
         remainder = beat_list[:remainder_length]
         if self.append_remainder:
             grouped_beat_list[0] = remainder + grouped_beat_list[0]
         else:
             grouped_beat_list.insert(0, remainder)
     else:
         grouped_beat_list = sequencetools.partition_sequence_by_counts(
             beat_list[:-remainder_length],
             counts=self.counts,
             cyclic=True,
             overhang=False)
         remainder = beat_list[-remainder_length:]
         if self.append_remainder:
             grouped_beat_list[-1] = grouped_beat_list[-1] + remainder
         else:
             grouped_beat_list.append(remainder)
     return grouped_beat_list
示例#4
0
    def make_spanner_score_02(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 20 notes.

        ::

            2.12 (r9710) initialization:        250,954 function calls
            2.12 (r9724) initialization:        248,717 function calls

            2.12 (r9703) LilyPond format:       495,768 function calls
            2.12 (r9710) LilyPond format:       496,572 function calls
            2.12 (r9724) LilyPond format:       511,471 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [20],
                cyclic=True,
        ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#5
0
    def partition_by_ratio_of_durations(self, ratio):
        r'''Partition start-positioned payload expression
        by ratio of durations.

        Operates in place and returns newly constructed inventory.
        '''
        from experimental.tools import musicexpressiontools
        element_durations = [
            self._get_duration_of_expr(leaf) for leaf in self.elements
        ]
        integers = self._durations_to_integers(element_durations)
        parts = sequencetools.partition_sequence_by_ratio_of_weights(
            integers, ratio)
        part_lengths = [len(part) for part in parts]
        parts = sequencetools.partition_sequence_by_counts(
            self.elements, part_lengths)
        durations = [self._get_duration_of_list(part) for part in parts]
        payload_parts = self._split_payload_at_offsets(durations)
        start_offsets = mathtools.cumulative_sums(durations)[:-1]
        start_offsets = [
            self.start_offset + start_offset for start_offset in start_offsets
        ]
        payload_expressions = \
            musicexpressiontools.TimespanScopedSingleContextSetExpressionInventory()
        for payload_part, start_offset in zip(payload_parts, start_offsets):
            timespan = timespantools.Timespan(start_offset)
            payload_expression = type(self)(
                [],
                start_offset=timespan.start_offset,
                voice_name=self.voice_name,
            )
            payload_expression._payload = payload_part
            payload_expressions.append(payload_expression)
        return payload_expressions
    def partition_by_ratio_of_durations(self, ratio):
        r'''Partition start-positioned payload expression
        by ratio of durations.

        Operates in place and returns newly constructed inventory.
        '''
        from experimental.tools import musicexpressiontools
        element_durations = [
            self._get_duration_of_expr(leaf) for leaf in self.elements]
        integers = self._durations_to_integers(element_durations)
        parts = sequencetools.partition_sequence_by_ratio_of_weights(
            integers, ratio)
        part_lengths = [len(part) for part in parts]
        parts = sequencetools.partition_sequence_by_counts(
            self.elements, part_lengths)
        durations = [self._get_duration_of_list(part) for part in parts]
        payload_parts = self._split_payload_at_offsets(durations)
        start_offsets = mathtools.cumulative_sums(durations)[:-1]
        start_offsets = [
            self.start_offset + start_offset
            for start_offset in start_offsets]
        payload_expressions = \
            musicexpressiontools.TimespanScopedSingleContextSetExpressionInventory()
        for payload_part, start_offset in zip(payload_parts, start_offsets):
            timespan = timespantools.Timespan(start_offset)
            payload_expression = type(self)(
                [],
                start_offset=timespan.start_offset,
                voice_name=self.voice_name,
                )
            payload_expression._payload = payload_part
            payload_expressions.append(payload_expression)
        return payload_expressions
示例#7
0
 def new(sources):
     from supriya.tools import synthdeftools
     from supriya.tools import ugentools
     flattened_sources = []
     for source in sources:
         if isinstance(source, synthdeftools.UGenArray):
             flattened_sources.extend(source)
         else:
             flattened_sources.append(source)
     sources = synthdeftools.UGenArray(flattened_sources)
     summed_sources = []
     parts = sequencetools.partition_sequence_by_counts(
         sources,
         [4],
         cyclic=True,
         overhang=True,
     )
     for part in parts:
         if len(part) == 4:
             summed_sources.append(ugentools.Sum4(*part))
         elif len(part) == 3:
             summed_sources.append(ugentools.Sum3(*part))
         elif len(part) == 2:
             summed_sources.append(part[0] + part[1])
         else:
             summed_sources.append(part[0])
     if len(summed_sources) == 1:
         return summed_sources[0]
     return Mix.new(summed_sources)
示例#8
0
 def _burnish_all_division_parts(self, divisions, quintuplet):
     lefts, middles, rights, left_lengths, right_lengths=quintuplet
     lefts_index, rights_index = 0, 0
     burnished_divisions = []
     for division_index, division in enumerate(divisions):
         left_length = left_lengths[division_index]
         left = lefts[lefts_index:lefts_index+left_length]
         lefts_index += left_length
         right_length = right_lengths[division_index]
         right = rights[rights_index:rights_index+right_length]
         rights_index += right_length
         available_left_length = len(division)
         left_length = min([left_length, available_left_length])
         available_right_length = len(division) - left_length
         right_length = min([right_length, available_right_length])
         middle_length = len(division) - left_length - right_length
         left = left[:left_length]
         middle = middle_length * [middles[division_index]]
         right = right[:right_length]
         left_part, middle_part, right_part = \
             sequencetools.partition_sequence_by_counts(
             division, 
             [left_length, middle_length, right_length], 
             cyclic=False, 
             overhang=False,
             )
         left_part = self._burnish_division_part(left_part, left)
         middle_part = self._burnish_division_part(middle_part, middle)
         right_part = self._burnish_division_part(right_part, right)
         burnished_division = left_part + middle_part + right_part
         burnished_divisions.append(burnished_division)
     unburnished_weights = [mathtools.weight(x) for x in divisions]
     burnished_weights = [mathtools.weight(x) for x in burnished_divisions]
     assert burnished_weights == unburnished_weights
     return burnished_divisions
示例#9
0
    def make_spanner_score_03(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 100 notes.

        ::

            2.12 (r9710) initialization:        251,606 function calls
            2.12 (r9724) initialization:        249,369 function calls

            2.12 (r9703) LilyPond format:       509,752 function calls
            2.12 (r9710) LilyPond format:       510,556 function calls
            2.12 (r9724) LilyPond format:       525,463 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            voice[:],
            [100],
            cyclic=True,
            ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#10
0
    def make_hairpin_score_03(self):
        r'''Make 200-note voice with crescendo spanner on every 100 notes.

        ::

            2.12 (r9726) initialization:        249,363 function calls
            2.12 (r9726) initialization:        249,363 function calls

            2.12 (r9726) LilyPond format:       133,898 function calls
            2.12 (r9728) LilyPond format:       128,948 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [100],
                cyclic=True,
        ):
            crescendo = spannertools.Crescendo()
            topleveltools.attach(crescendo, part)
        return voice
示例#11
0
    def make_spanner_score_02(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 20 notes.

        ::

            2.12 (r9710) initialization:        250,954 function calls
            2.12 (r9724) initialization:        248,717 function calls

            2.12 (r9703) LilyPond format:       495,768 function calls
            2.12 (r9710) LilyPond format:       496,572 function calls
            2.12 (r9724) LilyPond format:       511,471 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            voice[:],
            [20],
            cyclic=True,
            ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#12
0
    def make_spanner_score_01(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 4 notes.

        ::

            2.12 (r9710) initialization:        248,654 function calls
            2.12 (r9724) initialization:        248,660 function calls

            2.12 (r9703) LilyPond format:       425,848 function calls
            2.12 (r9710) LilyPond format:       426,652 function calls
            2.12 (r9724) LilyPond format:       441,884 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [4],
                cyclic=True,
        ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#13
0
    def make_bound_hairpin_score_03(self):
        r'''Make 200-note voice with p-to-f bound crescendo spanner
        on every 100 notes.

        ::

            2.12 (r9726) initialization:        267,417 function calls

            2.12 (r9726) LilyPond format:       116,534 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            voice[:],
            [100],
            cyclic=True,
            ):
            crescendo = spannertools.Crescendo()
            topleveltools.attach(crescendo, part)
            dynamic = indicatortools.Dynamic('p')
            topleveltools.attach(dynamic, part[0])
            dynamic = indicatortools.Dynamic('r')
            topleveltools.attach(dynamic, part[-1])
        return voice
示例#14
0
    def make_score_with_indicators_01(self):
        r'''Make 200-note voice with dynamic on every 20th note:

        ::

            2.12 (r9704) initialization:        630,433 function calls
            2.12 (r9710) initialization:        235,120 function calls
            2.12 r(9726) initialization:        235,126 function calls

            2.12 (r9704) LilyPond format:       136,637 function calls
            2.12 (r9710) LilyPond format:        82,730 function calls
            2.12 (r9726) LilyPond format:        88,382 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import topleveltools
        staff = scoretools.Staff(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                staff[:],
            [20],
                cyclic=True,
        ):
            dynamic = indicatortools.Dynamic('f')
            topleveltools.attach(dynamic, part[0])
        return staff
示例#15
0
    def make_score_with_indicators_02(self):
        r'''Make 200-note staff with dynamic on every 4th note.

        ::

            2.12 (r9704) initialization:      4,632,761 function calls
            2.12 (r9710) initialization:        327,280 function calls
            2.12 (r9726) initialization:        325,371 function calls

            2.12 (r9704) LilyPond format:       220,277 function calls
            2.12 (r9710) LilyPond format:        84,530 function calls
            2.12 (r9726) LilyPond format:        90,056 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import topleveltools
        staff = scoretools.Staff(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                staff[:],
            [4],
                cyclic=True,
        ):
            dynamic = indicatortools.Dynamic('f')
            topleveltools.attach(dynamic, part[0])
        return staff
示例#16
0
 def new(sources):
     from supriya.tools import synthdeftools
     from supriya.tools import ugentools
     flattened_sources = []
     for source in sources:
         if isinstance(source, synthdeftools.UGenArray):
             flattened_sources.extend(source)
         else:
             flattened_sources.append(source)
     sources = synthdeftools.UGenArray(flattened_sources)
     summed_sources = []
     parts = sequencetools.partition_sequence_by_counts(
         sources,
         [4],
         cyclic=True,
         overhang=True,
         )
     for part in parts:
         if len(part) == 4:
             summed_sources.append(ugentools.Sum4(*part))
         elif len(part) == 3:
             summed_sources.append(ugentools.Sum3(*part))
         elif len(part) == 2:
             summed_sources.append(part[0] + part[1])
         else:
             summed_sources.append(part[0])
     if len(summed_sources) == 1:
         return summed_sources[0]
     return Mix.new(summed_sources) 
示例#17
0
def partition_sequence_by_ratio_of_lengths(sequence, lengths):
    '''Partitions `sequence` by ratio of `lengths`.

    ::

        >>> sequence = tuple(range(10))

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_lengths(
        ...     sequence,
        ...     [1, 1, 2],
        ...     )
        [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)]

    Uses rounding magic to avoid fractional part lengths.

    Returns list of `sequence` objects.
    '''
    from abjad.tools import sequencetools

    lengths = mathtools.partition_integer_by_ratio(len(sequence), lengths)
    return sequencetools.partition_sequence_by_counts(
        sequence,
        lengths,
        cyclic=False,
        overhang=False,
        )
def partition_sequence_by_ratio_of_lengths(sequence, lengths):
    '''Partitions `sequence` by ratio of `lengths`.

    ::

        >>> sequence = tuple(range(10))

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_lengths(
        ...     sequence, 
        ...     [1, 1, 2],
        ...     )
        [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)]

    Uses rounding magic to avoid fractional part lengths.

    Returns list of `sequence` objects.
    '''
    from abjad.tools import sequencetools

    lengths = mathtools.partition_integer_by_ratio(len(sequence), lengths)
    return sequencetools.partition_sequence_by_counts(
        sequence, 
        lengths, 
        cyclic=False, 
        overhang=False,
        )
示例#19
0
 def format_datagram(cls, datagram):
     result = []
     result.append('size {}'.format(len(datagram)))
     index = 0
     while index < len(datagram):
         chunk = datagram[index:index + 16]
         line = '{: >4}   '.format(index)
         hex_blocks = []
         ascii_block = ''
         for chunk in sequencetools.partition_sequence_by_counts(
             chunk, [4], cyclic=True):
             hex_block = []
             for byte in chunk:
                 char = int(byte)
                 if 31 < char < 127:
                     char = chr(char)
                 else:
                     char = '.'
                 ascii_block += char
                 hexed = hex(byte)[2:].zfill(2)
                 hex_block.append(hexed)
             hex_block = ' '.join(hex_block)
             hex_blocks.append(hex_block)
         hex_blocks = '  '.join(hex_blocks)
         ascii_block = '|{}|'.format(ascii_block)
         hex_blocks = '{: <53}'.format(hex_blocks)
         line += hex_blocks
         line += ascii_block
         result.append(line)
         index += 16
     result = '\n'.join(result)
     return result
示例#20
0
    def make_score_with_indicators_02(self):
        r'''Make 200-note staff with dynamic on every 4th note.

        ::

            2.12 (r9704) initialization:      4,632,761 function calls
            2.12 (r9710) initialization:        327,280 function calls
            2.12 (r9726) initialization:        325,371 function calls

            2.12 (r9704) LilyPond format:       220,277 function calls
            2.12 (r9710) LilyPond format:        84,530 function calls
            2.12 (r9726) LilyPond format:        90,056 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import topleveltools
        staff = scoretools.Staff(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            staff[:],
            [4],
            cyclic=True,
            ):
            dynamic = indicatortools.Dynamic('f')
            topleveltools.attach(dynamic, part[0])
        return staff
示例#21
0
    def make_bound_hairpin_score_03(self):
        r'''Make 200-note voice with p-to-f bound crescendo spanner
        on every 100 notes.

        ::

            2.12 (r9726) initialization:        267,417 function calls

            2.12 (r9726) LilyPond format:       116,534 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [100],
                cyclic=True,
        ):
            crescendo = spannertools.Crescendo()
            topleveltools.attach(crescendo, part)
            dynamic = indicatortools.Dynamic('p')
            topleveltools.attach(dynamic, part[0])
            dynamic = indicatortools.Dynamic('r')
            topleveltools.attach(dynamic, part[-1])
        return voice
示例#22
0
    def make_spanner_score_01(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 4 notes.

        ::

            2.12 (r9710) initialization:        248,654 function calls
            2.12 (r9724) initialization:        248,660 function calls

            2.12 (r9703) LilyPond format:       425,848 function calls
            2.12 (r9710) LilyPond format:       426,652 function calls
            2.12 (r9724) LilyPond format:       441,884 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            voice[:],
            [4],
            cyclic=True,
            ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#23
0
    def make_score_with_indicators_01(self):
        r'''Make 200-note voice with dynamic on every 20th note:

        ::

            2.12 (r9704) initialization:        630,433 function calls
            2.12 (r9710) initialization:        235,120 function calls
            2.12 r(9726) initialization:        235,126 function calls

            2.12 (r9704) LilyPond format:       136,637 function calls
            2.12 (r9710) LilyPond format:        82,730 function calls
            2.12 (r9726) LilyPond format:        88,382 function calls

        '''
        from abjad.tools import indicatortools
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import topleveltools
        staff = scoretools.Staff(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            staff[:],
            [20],
            cyclic=True,
            ):
            dynamic = indicatortools.Dynamic('f')
            topleveltools.attach(dynamic, part[0])
        return staff
示例#24
0
    def make_hairpin_score_03(self):
        r'''Make 200-note voice with crescendo spanner on every 100 notes.

        ::

            2.12 (r9726) initialization:        249,363 function calls
            2.12 (r9726) initialization:        249,363 function calls

            2.12 (r9726) LilyPond format:       133,898 function calls
            2.12 (r9728) LilyPond format:       128,948 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
            voice[:],
            [100],
            cyclic=True,
            ):
            crescendo = spannertools.Crescendo()
            topleveltools.attach(crescendo, part)
        return voice
示例#25
0
    def make_spanner_score_03(self):
        r'''Make 200-note voice with durated complex beam spanner
        on every 100 notes.

        ::

            2.12 (r9710) initialization:        251,606 function calls
            2.12 (r9724) initialization:        249,369 function calls

            2.12 (r9703) LilyPond format:       509,752 function calls
            2.12 (r9710) LilyPond format:       510,556 function calls
            2.12 (r9724) LilyPond format:       525,463 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [100],
                cyclic=True,
        ):
            beam = spannertools.DuratedComplexBeam()
            topleveltools.attach(beam, part)
        return voice
示例#26
0
 def format_datagram(cls, datagram):
     result = []
     result.append('size {}'.format(len(datagram)))
     index = 0
     while index < len(datagram):
         chunk = datagram[index:index + 16]
         line = '{: >4}   '.format(index)
         hex_blocks = []
         ascii_block = ''
         for chunk in sequencetools.partition_sequence_by_counts(
             chunk, [4], cyclic=True):
             hex_block = []
             for byte in chunk:
                 char = int(byte)
                 if 31 < char < 127:
                     char = chr(char)
                 else:
                     char = '.'
                 ascii_block += char
                 hexed = hex(byte)[2:].zfill(2)
                 hex_block.append(hexed)
             hex_block = ' '.join(hex_block)
             hex_blocks.append(hex_block)
         hex_blocks = '  '.join(hex_blocks)
         ascii_block = '|{}|'.format(ascii_block)
         hex_blocks = '{: <53}'.format(hex_blocks)
         line += hex_blocks
         line += ascii_block
         result.append(line)
         index += 16
     result = '\n'.join(result)
     return result
示例#27
0
    def __call__(self, expr):
        r'''Calls retrogression on `expr`.

        ..  container:: example

            **Example 1.** Retrograde pitch classes.

            ::

                >>> operator_ = pitchtools.Retrogression()
                >>> pitch_classes = pitchtools.PitchClassSegment([0, 1, 4, 7])
                >>> operator_(pitch_classes)
                PitchClassSegment([7, 4, 1, 0])

        ..  container:: example

            **Example 2.** Does not retrograde single pitches or pitch-classes.

            ::

                >>> operator_ = pitchtools.Retrogression()
                >>> pitch_class = pitchtools.NumberedPitchClass(6)
                >>> operator_(pitch_class)
                NumberedPitchClass(6)

        ..  container:: example

            **Example 3.** Periodic retrogression.

            ::

                >>> operator_ = pitchtools.Retrogression(period=3)
                >>> pitches = pitchtools.PitchSegment("c' d' e' f' g' a' b' c''")
                >>> operator_(pitches)
                PitchSegment(["e'", "d'", "c'", "a'", "g'", "f'", "c''", "b'"])

        Returns new object with type equal to that of `expr`.
        '''
        from abjad.tools import pitchtools
        if isinstance(expr, (pitchtools.Pitch, pitchtools.PitchClass)):
            return expr
        if not isinstance(expr, (
            pitchtools.PitchSegment,
            pitchtools.PitchClassSegment,
            )):
            expr = pitchtools.PitchSegment(expr)
        if not self.period:
            return type(expr)(reversed(expr))
        result = new(expr, items=())
        for shard in sequencetools.partition_sequence_by_counts(
            expr,
            [self.period],
            cyclic=True,
            overhang=True,
            ):
            shard = type(expr)(shard)
            shard = type(expr)(reversed(shard))
            result = result + shard
        return result
示例#28
0
    def __call__(self, expr):
        r'''Calls retrogression on `expr`.

        ..  container:: example

            **Example 1.** Retrograde pitch classes.

            ::

                >>> operator_ = pitchtools.Retrogression()
                >>> pitch_classes = pitchtools.PitchClassSegment([0, 1, 4, 7])
                >>> operator_(pitch_classes)
                PitchClassSegment([7, 4, 1, 0])

        ..  container:: example

            **Example 2.** Does not retrograde single pitches or pitch-classes.

            ::

                >>> operator_ = pitchtools.Retrogression()
                >>> pitch_class = pitchtools.NumberedPitchClass(6)
                >>> operator_(pitch_class)
                NumberedPitchClass(6)

        ..  container:: example

            **Example 3.** Periodic retrogression.

            ::

                >>> operator_ = pitchtools.Retrogression(period=3)
                >>> pitches = pitchtools.PitchSegment("c' d' e' f' g' a' b' c''")
                >>> operator_(pitches)
                PitchSegment(["e'", "d'", "c'", "a'", "g'", "f'", "c''", "b'"])

        Returns new object with type equal to that of `expr`.
        '''
        from abjad.tools import pitchtools
        if isinstance(expr, (pitchtools.Pitch, pitchtools.PitchClass)):
            return expr
        if not isinstance(expr, (
                pitchtools.PitchSegment,
                pitchtools.PitchClassSegment,
        )):
            expr = pitchtools.PitchSegment(expr)
        if not self.period:
            return type(expr)(reversed(expr))
        result = new(expr, items=())
        for shard in sequencetools.partition_sequence_by_counts(
                expr,
            [self.period],
                cyclic=True,
                overhang=True,
        ):
            shard = type(expr)(shard)
            shard = type(expr)(reversed(shard))
            result = result + shard
        return result
    def __call__(self, logical_ties, timespan=None, offset=0):
        r'''Calls note and chord hairpin handler on `logical_ties`
        with `offset`.

        Returns none.
        '''
        if (self.span == 'contiguous notes and chords'
            or isinstance(self.span, (tuple, list))):
            groups = self._group_contiguous_logical_ties(logical_ties)
        elif self.span == 'nontrivial ties':
            groups = [[_] for _ in logical_ties]
        else:
            raise ValueError(self.span)
        if isinstance(self.span, (tuple, list)):
            new_groups = []
            for group in groups:
                leaves = iterate(group).by_class(scoretools.Leaf)
                leaves = list(leaves)
                shards = sequencetools.partition_sequence_by_counts(
                    leaves,
                    counts=self.span,
                    cyclic=True,
                    )
                new_groups.extend(shards)
            groups = new_groups
            groups = [[_] for _ in groups]
        for group_index, group in enumerate(groups):
            notes = []
            for logical_tie in group:
                for note in logical_tie:
                    notes.append(note)
            if len(notes) == 0:
                continue
            total_notes = len(notes)
            notes_to_span = []
            for note_index, note in enumerate(notes):
                if self._index_matches_patterns(note_index, total_notes):
                    notes_to_span.append(note)
            if not notes_to_span:
                continue
            if (len(notes_to_span) == 1 and
                not self.attach_start_dynamic_to_lone_notes):
                continue
            if (len(notes_to_span) == 1 and
                self.attach_start_dynamic_to_lone_notes):
                hairpin_token = self.hairpin_token[group_index]
                start_dynamic = hairpin_token[0]
                dynamic = indicatortools.Dynamic(start_dynamic)
                attach(dynamic, notes[0])
                continue
            hairpin_token = self.hairpin_token[group_index]
            descriptor = ' '.join([_ for _ in hairpin_token if _])
            hairpin = spannertools.Hairpin(
                descriptor=descriptor,
                include_rests=False,
                )
            attach(hairpin, notes_to_span)
    def __call__(self, logical_ties, timespan=None, offset=0):
        r'''Calls note and chord hairpin handler on `logical_ties`
        with `offset`.

        Returns none.
        '''
        if (self.span == 'contiguous notes and chords'
                or isinstance(self.span, (tuple, list))):
            groups = self._group_contiguous_logical_ties(logical_ties)
        elif self.span == 'nontrivial ties':
            groups = [[_] for _ in logical_ties]
        else:
            raise ValueError(self.span)
        if isinstance(self.span, (tuple, list)):
            new_groups = []
            for group in groups:
                leaves = iterate(group).by_class(scoretools.Leaf)
                leaves = list(leaves)
                shards = sequencetools.partition_sequence_by_counts(
                    leaves,
                    counts=self.span,
                    cyclic=True,
                )
                new_groups.extend(shards)
            groups = new_groups
            groups = [[_] for _ in groups]
        for group_index, group in enumerate(groups):
            notes = []
            for logical_tie in group:
                for note in logical_tie:
                    notes.append(note)
            if len(notes) == 0:
                continue
            total_notes = len(notes)
            notes_to_span = []
            for note_index, note in enumerate(notes):
                if self._index_matches_patterns(note_index, total_notes):
                    notes_to_span.append(note)
            if not notes_to_span:
                continue
            if (len(notes_to_span) == 1
                    and not self.attach_start_dynamic_to_lone_notes):
                continue
            if (len(notes_to_span) == 1
                    and self.attach_start_dynamic_to_lone_notes):
                hairpin_token = self.hairpin_token[group_index]
                start_dynamic = hairpin_token[0]
                dynamic = indicatortools.Dynamic(start_dynamic)
                attach(dynamic, notes[0])
                continue
            hairpin_token = self.hairpin_token[group_index]
            descriptor = ' '.join([_ for _ in hairpin_token if _])
            hairpin = spannertools.Hairpin(
                descriptor=descriptor,
                include_rests=False,
            )
            attach(hairpin, notes_to_span)
示例#31
0
 def _handle_input_levels(self, message):
     contents = message.contents[2:]
     peak_levels = []
     rms_levels = []
     for peak, rms in sequencetools.partition_sequence_by_counts(
         contents, counts=[2], cyclic=True):
         peak_levels.append(peak)
         rms_levels.append(rms)
     self._input_meter_peak_levels = tuple(peak_levels)
     self._input_meter_rms_levels = tuple(rms_levels)
def partition_sequence_by_ratio_of_lengths(sequence, ratio):
    '''Partitions `sequence` by `ratio` of lengths.

    ..  container:: example

        **Example 1.** Partitions sequence by ``1:1:1`` ratio:

        ::

            >>> sequence = list(range(10))
            >>> sequencetools.partition_sequence_by_ratio_of_lengths(
            ...     sequence,
            ...     [1, 1, 1],
            ...     )
            [[0, 1, 2], [3, 4, 5, 6], [7, 8, 9]]

        Returns list of lists.

    ..  container:: example

        **Example 2.** Partitions sequence by ``1:1:2`` ratio:

        ::

            >>> sequence = tuple(range(10))
            >>> sequencetools.partition_sequence_by_ratio_of_lengths(
            ...     sequence,
            ...     [1, 1, 2],
            ...     )
            [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)]

        Returns list of tuples.

    Uses the rounding magic implemented in
    ``mathtools.partition_integer_by_ratio()`` to avoid fractional part
    lengths.

    Returns list of `sequence` objects.
    '''
    from abjad.tools import sequencetools
    if sequence is None:
        callback = sequencetools.PartitionByRatioOfLengthsCallback(
            ratio=ratio,
            )
        return callback
    ratio = mathtools.Ratio(ratio)
    counts = mathtools.partition_integer_by_ratio(len(sequence), ratio)
    return sequencetools.partition_sequence_by_counts(
        sequence,
        counts,
        cyclic=False,
        overhang=Exact,
        )
示例#33
0
def partition_sequence_by_ratio_of_lengths(sequence, ratio):
    '''Partitions `sequence` by `ratio` of lengths.

    ..  container:: example

        **Example 1.** Partitions sequence by ``1:1:1`` ratio:

        ::

            >>> sequence = list(range(10))
            >>> sequencetools.partition_sequence_by_ratio_of_lengths(
            ...     sequence,
            ...     [1, 1, 1],
            ...     )
            [[0, 1, 2], [3, 4, 5, 6], [7, 8, 9]]

        Returns list of lists.

    ..  container:: example

        **Example 2.** Partitions sequence by ``1:1:2`` ratio:

        ::

            >>> sequence = tuple(range(10))
            >>> sequencetools.partition_sequence_by_ratio_of_lengths(
            ...     sequence,
            ...     [1, 1, 2],
            ...     )
            [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)]

        Returns list of tuples.

    Uses the rounding magic implemented in
    ``mathtools.partition_integer_by_ratio()`` to avoid fractional part
    lengths.

    Returns list of `sequence` objects.
    '''
    from abjad.tools import sequencetools
    if sequence is None:
        callback = sequencetools.PartitionByRatioOfLengthsCallback(
            ratio=ratio, )
        return callback
    ratio = mathtools.Ratio(ratio)
    counts = mathtools.partition_integer_by_ratio(len(sequence), ratio)
    return sequencetools.partition_sequence_by_counts(
        sequence,
        counts,
        cyclic=False,
        overhang=Exact,
    )
示例#34
0
    def partition_by_ratio_of_durations(self, ratio):
        r'''Partition payload expression by ratio of durations.

        ::

            >>> result = \
            ...     payload_expression.partition_by_ratio_of_durations((1, 1))

        ::

            >>> for element in result:
            ...     print(format(element))
            musicexpressiontools.IterablePayloadExpression(
                payload=(
                    (4, 16),
                    ),
                )
            musicexpressiontools.IterablePayloadExpression(
                payload=(
                    (2, 16),
                    ),
                )

        Returns newly constructed payload expression.
        '''
        element_durations = [self._duration_helper(x) for x in self.payload]
        element_tokens = self._durations_to_integers(element_durations)
        token_parts = sequencetools.partition_sequence_by_ratio_of_weights(
            element_tokens, ratio)
        part_lengths = [len(x) for x in token_parts]
        duration_parts = sequencetools.partition_sequence_by_counts(
            element_durations, part_lengths)
        element_parts = sequencetools.partition_sequence_by_counts(
            self.payload, part_lengths)
        result = []
        for part in element_parts:
            part = new(self, payload=part)
            result.append(part)
        return result
示例#35
0
    def __str__(self):
        r'''Gets string representation of OSC object.

        ::

            size 164
               0   2f 64 5f 72  65 63 76 00  2c 62 62 00  00 00 00 6b   |/d_recv.,bb....k|
              16   53 43 67 66  00 00 00 02  00 01 04 74  65 73 74 00   |SCgf.......test.|
              32   00 00 02 43  dc 00 00 00  00 00 00 00  00 00 00 00   |...C............|
              48   00 00 00 00  00 00 02 06  53 69 6e 4f  73 63 02 00   |........SinOsc..|
              64   00 00 02 00  00 00 01 00  00 ff ff ff  ff 00 00 00   |................|
              80   00 ff ff ff  ff 00 00 00  01 02 03 4f  75 74 02 00   |...........Out..|
              96   00 00 02 00  00 00 00 00  00 ff ff ff  ff 00 00 00   |................|
             112   01 00 00 00  00 00 00 00  00 00 00 00  00 00 00 24   |...............$|
             128   2f 73 5f 6e  65 77 00 00  2c 73 69 69  69 00 00 00   |/s_new..,siii...|
             144   74 65 73 74  00 00 00 00  00 00 03 e9  00 00 00 00   |test............|
             160   00 00 00 01                                          |....|

        '''
        datagram = bytearray(self.to_datagram())
        result = []
        result.append('size {}'.format(len(datagram)))
        index = 0
        while index < len(datagram):
            chunk = datagram[index:index + 16]
            line = '{: >4}   '.format(index)
            hex_blocks = []
            ascii_block = ''
            for chunk in sequencetools.partition_sequence_by_counts(
                chunk, [4], cyclic=True):
                hex_block = []
                for byte in chunk:
                    char = int(byte)
                    if 31 < char < 127:
                        char = chr(char)
                    else:
                        char = '.'
                    ascii_block += char
                    hexed = hex(byte)[2:].zfill(2)
                    hex_block.append(hexed)
                hex_block = ' '.join(hex_block)
                hex_blocks.append(hex_block)
            hex_blocks = '  '.join(hex_blocks)
            ascii_block = '|{}|'.format(ascii_block)
            hex_blocks = '{: <53}'.format(hex_blocks)
            line += hex_blocks
            line += ascii_block
            result.append(line)
            index += 16
        result = '\n'.join(result)
        return result
示例#36
0
 def _partition_groups(self, groups):
     new_groups = []
     for group in groups:
         leaves = iterate(group).by_class(scoretools.Leaf)
         leaves = list(leaves)
         shards = sequencetools.partition_sequence_by_counts(
             leaves,
             counts=self.span,
             cyclic=True,
             )
         new_groups.extend(shards)
     groups = new_groups
     groups = [[_] for _ in groups]
     return groups
示例#37
0
 def _split_at_measure_boundaries(
     selections, 
     meters,
     use_messiaen_style_ties=False,
     ):
     from abjad.tools import metertools
     from abjad.tools import scoretools
     from abjad.tools import sequencetools
     from abjad.tools.topleveltools import inspect_
     from abjad.tools.topleveltools import mutate
     from abjad.tools.topleveltools import select
     meters = [metertools.Meter(_) for _ in meters]
     durations = [durationtools.Duration(_) for _ in meters]
     selections = sequencetools.flatten_sequence(selections)
     assert isinstance(selections, list), repr(selections)
     meter_duration = sum(durations)
     music_duration = sum(inspect_(_).get_duration() for _ in selections)
     if not meter_duration == music_duration:
         message = 'Duration of meters is {!s}'
         message += ' but duration of selections is {!s}:'
         message = message.format(meter_duration, music_duration)
         message += '\nmeters: {}.'.format(meters)
         message += '\nmusic: {}.'.format(selections)
         raise Exception(message)
     voice = scoretools.Voice(selections)
     mutate(voice[:]).split(
         durations=durations,
         tie_split_notes=True,
         use_messiaen_style_ties=use_messiaen_style_ties,
         )
     #raise Exception(voice)
     #selections = list(voice[:])
     #return selections
     components = mutate(voice).eject_contents()
     component_durations = [inspect_(_).get_duration() for _ in components]
     parts = sequencetools.partition_sequence_by_weights(
         component_durations,
         weights=durations,
         allow_part_weights=Exact,
         )
     part_lengths = [len(_) for _ in parts]
     parts = sequencetools.partition_sequence_by_counts(
         components,
         counts=part_lengths,
         overhang=Exact,
         )
     selections = [select(_) for _ in parts]
     return selections
 def _split_at_measure_boundaries(
     selections,
     meters,
     use_messiaen_style_ties=False,
 ):
     from abjad.tools import metertools
     from abjad.tools import scoretools
     from abjad.tools import sequencetools
     from abjad.tools.topleveltools import inspect_
     from abjad.tools.topleveltools import mutate
     from abjad.tools.topleveltools import select
     meters = [metertools.Meter(_) for _ in meters]
     durations = [durationtools.Duration(_) for _ in meters]
     selections = sequencetools.flatten_sequence(selections)
     assert isinstance(selections, list), repr(selections)
     meter_duration = sum(durations)
     music_duration = sum(inspect_(_).get_duration() for _ in selections)
     if not meter_duration == music_duration:
         message = 'Duration of meters is {!s}'
         message += ' but duration of selections is {!s}:'
         message = message.format(meter_duration, music_duration)
         message += '\nmeters: {}.'.format(meters)
         message += '\nmusic: {}.'.format(selections)
         raise Exception(message)
     voice = scoretools.Voice(selections)
     mutate(voice[:]).split(
         durations=durations,
         tie_split_notes=True,
         use_messiaen_style_ties=use_messiaen_style_ties,
     )
     #raise Exception(voice)
     #selections = list(voice[:])
     #return selections
     components = mutate(voice).eject_contents()
     component_durations = [inspect_(_).get_duration() for _ in components]
     parts = sequencetools.partition_sequence_by_weights(
         component_durations,
         weights=durations,
         allow_part_weights=Exact,
     )
     part_lengths = [len(_) for _ in parts]
     parts = sequencetools.partition_sequence_by_counts(
         components,
         counts=part_lengths,
         overhang=Exact,
     )
     selections = [select(_) for _ in parts]
     return selections
def partition(meter_list, weights_ratio, tempi):
    new_meter_list = [int(2 * x) for x in meter_list]
    assert sum(new_meter_list) == 2 * sum(meter_list)
    parts = sequencetools.partition_sequence_by_ratio_of_weights(
        new_meter_list, weights_ratio)
    counts = [len(x) for x in parts]
    #parts = sequencetools.partition_sequence_once_by_counts_without_overhang(
    #    meter_list, counts)
    parts = sequencetools.partition_sequence_by_counts(
        meter_list,
        counts,
        cyclic=False,
        overhang=False,
        )
    parts = sequencetools.zip_sequences([parts, tempi], cyclic=True)
    return parts
示例#40
0
 def _partition_selections(self, music):
     period = self.division_period or 1
     selections = [
         select(list(iterate(_).by_leaf())) for _ in music
         ]
     parts = sequencetools.partition_sequence_by_counts(
         selections, [period], cyclic=True, overhang=True)
     if len(parts[-1]) < period and 1 < len(parts):
         part = parts.pop()
         parts[-1].extend(part)
     selections = []
     for part in parts:
         selection = part[0]
         for next_selection in part[1:]:
             selection = selection + next_selection
         selections.append(selection)
     return selections
示例#41
0
    def __call__(self, expr, rotation=None):
        r'''Calls ratio selector callback on `expr`.

        Returns tuple of selections.
        '''
        assert isinstance(expr, tuple), repr(expr)
        assert len(expr) == 1, repr(expr)
        assert isinstance(expr[0], selectiontools.Selection), repr(expr)
        selection = expr[0]
        counts = mathtools.partition_integer_by_ratio(
            len(selection),
            self.ratio,
            )
        selections = sequencetools.partition_sequence_by_counts(
            selection,
            counts=counts,
            )
        return tuple(selections)
    def __call__(self, expr, rotation=None):
        r'''Calls ratio selector callback on `expr`.

        Returns tuple of selections.
        '''
        assert isinstance(expr, tuple), repr(expr)
        assert len(expr) == 1, repr(expr)
        assert isinstance(expr[0], selectiontools.Selection), repr(expr)
        selection = expr[0]
        counts = mathtools.partition_integer_by_ratio(
            len(selection),
            self.ratio,
        )
        selections = sequencetools.partition_sequence_by_counts(
            selection,
            counts=counts,
        )
        return tuple(selections)
示例#43
0
 def _burnish_each_division(class_, input_, divisions):
     left_classes = input_['left_classes']
     middle_classes = input_['middle_classes']
     right_classes = input_['right_classes']
     left_counts = input_['left_counts']
     left_counts = left_counts or datastructuretools.CyclicTuple([0])
     right_counts = input_['right_counts']
     right_counts = right_counts or datastructuretools.CyclicTuple([0])
     lefts_index, rights_index = 0, 0
     burnished_divisions = []
     for division_index, division in enumerate(divisions):
         left_count = left_counts[division_index]
         left = left_classes[lefts_index:lefts_index + left_count]
         lefts_index += left_count
         right_count = right_counts[division_index]
         right = right_classes[rights_index:rights_index + right_count]
         rights_index += right_count
         available_left_count = len(division)
         left_count = min([left_count, available_left_count])
         available_right_count = len(division) - left_count
         right_count = min([right_count, available_right_count])
         middle_count = len(division) - left_count - right_count
         left = left[:left_count]
         if middle_classes:
             middle = middle_count * [middle_classes[division_index]]
         else:
             middle = middle_count * [0]
         right = right[:right_count]
         left_part, middle_part, right_part = \
             sequencetools.partition_sequence_by_counts(
                 division,
                 [left_count, middle_count, right_count],
                 cyclic=False,
                 overhang=False,
                 )
         left_part = class_._burnish_division_part(left_part, left)
         middle_part = class_._burnish_division_part(middle_part, middle)
         right_part = class_._burnish_division_part(right_part, right)
         burnished_division = left_part + middle_part + right_part
         burnished_divisions.append(burnished_division)
     unburnished_weights = [mathtools.weight(x) for x in divisions]
     burnished_weights = [mathtools.weight(x) for x in burnished_divisions]
     assert burnished_weights == unburnished_weights
     return burnished_divisions
示例#44
0
 def _burnish_each_division(class_, input_, divisions):
     left_classes = input_['left_classes']
     middle_classes = input_['middle_classes']
     right_classes = input_['right_classes']
     left_counts = input_['left_counts']
     left_counts = left_counts or datastructuretools.CyclicTuple([0])
     right_counts = input_['right_counts']
     right_counts = right_counts or datastructuretools.CyclicTuple([0])
     lefts_index, rights_index = 0, 0
     burnished_divisions = []
     for division_index, division in enumerate(divisions):
         left_count = left_counts[division_index]
         left = left_classes[lefts_index:lefts_index + left_count]
         lefts_index += left_count
         right_count = right_counts[division_index]
         right = right_classes[rights_index:rights_index + right_count]
         rights_index += right_count
         available_left_count = len(division)
         left_count = min([left_count, available_left_count])
         available_right_count = len(division) - left_count
         right_count = min([right_count, available_right_count])
         middle_count = len(division) - left_count - right_count
         left = left[:left_count]
         if middle_classes:
             middle = middle_count * [middle_classes[division_index]]
         else:
             middle = middle_count * [0]
         right = right[:right_count]
         left_part, middle_part, right_part = \
             sequencetools.partition_sequence_by_counts(
                 division,
                 [left_count, middle_count, right_count],
                 cyclic=False,
                 overhang=False,
                 )
         left_part = class_._burnish_division_part(left_part, left)
         middle_part = class_._burnish_division_part(middle_part, middle)
         right_part = class_._burnish_division_part(right_part, right)
         burnished_division = left_part + middle_part + right_part
         burnished_divisions.append(burnished_division)
     unburnished_weights = [mathtools.weight(x) for x in divisions]
     burnished_weights = [mathtools.weight(x) for x in burnished_divisions]
     assert burnished_weights == unburnished_weights
     return burnished_divisions
示例#45
0
 def _handle_output_levels(self, message):
     contents = message.contents[2:]
     peak_levels = []
     rms_levels = []
     for peak, rms in sequencetools.partition_sequence_by_counts(
         contents, counts=[2], cyclic=True):
         peak_levels.append(peak)
         rms_levels.append(rms)
     self._output_meter_peak_levels = tuple(peak_levels)
     self._output_meter_rms_levels = tuple(rms_levels)
     systemtools.PubSub.notify(
         'server-meters',
         {
             'input_meter_peak_levels': self._input_meter_peak_levels,
             'input_meter_rms_levels': self._input_meter_rms_levels,
             'output_meter_peak_levels': self._output_meter_peak_levels,
             'output_meter_rms_levels': self._output_meter_rms_levels,
             },
         )
def partition_to_avoid_octave_adjacencies(l, direction):
    '''Partition to avoid octave adjacencies.
    '''

    assert direction in ('left', 'right')

    result = [[]]
    part = result[-1]

    for x in l:
        if not isinstance(x, (int, float, Fraction)):
            raise ValueError
        if x % 12 in [y % 12 for y in part]:
            first_value = [y for y in part if y % 12 == x % 12][0]
            first_index = part.index(first_value)
            ## partition current part into left and middle subparts
            old_part = part[:first_index+1]
            disputed_part = part[first_index+1:]
            new_part = []
            ## divvy up disputed part
            left, right = mathtools.partition_integer_into_halves(
                len(disputed_part), bigger = direction)

            disputed_parts = sequencetools.partition_sequence_by_counts(
                disputed_part, [left, right], cyclic=False, overhang=False)
            left_disputed_part, right_disputed_part = disputed_parts

            assert len(left_disputed_part) == left
            assert len(right_disputed_part) == right
            old_part.extend(left_disputed_part)
            new_part.extend(right_disputed_part)
            ## replace last sublist in result with old, trimmed part
            result[-1] = old_part
            ## append new part to result
            result.append(new_part)
            part = result[-1]
        part.append(x)

    result = [tuple(x) for x in result]

    return result
示例#47
0
 def _add_ties(self, result):
     from abjad.tools import selectiontools
     leaves = list(iterationtools.iterate_leaves_in_expr(result))
     written_durations = [leaf.written_duration for leaf in leaves]
     weights = [durationtools.Duration(numerator, self.talea_denominator) 
         for numerator in self.talea]
     parts = sequencetools.partition_sequence_by_weights_exactly(
         written_durations, weights=weights, cyclic=True, overhang=True)
     counts = [len(part) for part in parts]
     parts = sequencetools.partition_sequence_by_counts(leaves, counts)
     spanner_classes = (spannertools.TieSpanner,)
     for part in parts:
         part = selectiontools.SliceSelection(part)
         tie_spanner = spannertools.TieSpanner()
         # this is voodoo to temporarily neuter the contiguity constraint
         tie_spanner._contiguity_constraint = None
         for component in part:
             for spanner in component._get_spanners(
                 spanner_classes=spanner_classes):
                 spanner.detach()
         tie_spanner.extend(part)
示例#48
0
    def __call__(self, expr, rotation=None):
        r'''Iterates tuple `expr`.

        Returns tuple in which each item is a selection or component.
        '''
        assert isinstance(expr, tuple), repr(expr)
        if rotation is None:
            rotation = 0
        rotation = int(rotation)
        result = []
        counts = self.counts
        if self.rotate:
            counts = sequencetools.rotate_sequence(counts, -rotation)
        for subexpr in expr:
            groups = sequencetools.partition_sequence_by_counts(
                subexpr,
                [abs(_) for _ in counts],
                cyclic=self.cyclic,
                overhang=self.overhang,
            )
            if self.overhang and self.fuse_overhang and 1 < len(groups):
                last_count = counts[(len(groups) - 1) % len(counts)]
                if len(groups[-1]) != last_count:
                    last_group = groups.pop()
                    groups[-1] += last_group
            subresult = []
            for i, group in enumerate(groups):
                count = counts[i]
                if count < 0:
                    continue
                items = selectiontools.Selection(group)
                subresult.append(items)
            if self.nonempty and not subresult:
                group = selectiontools.Selection(groups[0])
                subresult.append(group)
            result.extend(subresult)
            if self.rotate:
                counts = sequencetools.rotate_sequence(counts, -1)
        return tuple(result)
示例#49
0
    def __call__(self, expr, rotation=None):
        r'''Iterates tuple `expr`.

        Returns tuple in which each item is a selection or component.
        '''
        assert isinstance(expr, tuple), repr(expr)
        if rotation is None:
            rotation = 0
        rotation = int(rotation)
        result = []
        counts = self.counts
        if self.rotate:
            counts = sequencetools.rotate_sequence(counts, -rotation)
        for subexpr in expr:
            groups = sequencetools.partition_sequence_by_counts(
                subexpr,
                [abs(_) for _ in counts],
                cyclic=self.cyclic,
                overhang=self.overhang,
                )
            if self.overhang and self.fuse_overhang and 1 < len(groups):
                last_count = counts[(len(groups) - 1) % len(counts)]
                if len(groups[-1]) != last_count:
                    last_group = groups.pop()
                    groups[-1] += last_group
            subresult = []
            for i, group in enumerate(groups):
                count = counts[i]
                if count < 0:
                    continue
                items = selectiontools.Selection(group)
                subresult.append(items)
            if self.nonempty and not subresult:
                group = selectiontools.Selection(groups[0])
                subresult.append(group)
            result.extend(subresult)
            if self.rotate:
                counts = sequencetools.rotate_sequence(counts, -1)
        return tuple(result)
def partition_sequence_extended_to_counts(sequence, counts, overhang=True):
    """Partition sequence extended to counts.

    ..  container:: example

        **Example 1.** Partition sequence extended to counts with overhang:

        ::

            >>> sequencetools.partition_sequence_extended_to_counts(
            ...     (1, 2, 3, 4), 
            ...     (6, 6, 6), 
            ...     overhang=True,
            ...     )
            [(1, 2, 3, 4, 1, 2), (3, 4, 1, 2, 3, 4), (1, 2, 3, 4, 1, 2), (3, 4)]

    ..  container:: example

        **Example 2.** Partition sequence extended to coutns without overhang:

        ::

            >>> sequencetools.partition_sequence_extended_to_counts(
            ...     (1, 2, 3, 4), 
            ...     (6, 6, 6), 
            ...     overhang=False,
            ...     )
            [(1, 2, 3, 4, 1, 2), (3, 4, 1, 2, 3, 4), (1, 2, 3, 4, 1, 2)]

    Returns sequence of sequence objects.
    """
    from abjad.tools import sequencetools

    n = int(math.ceil(float(sum(counts)) / len(sequence)))

    sequence = sequencetools.repeat_sequence_n_times(sequence, n)

    return sequencetools.partition_sequence_by_counts(sequence, counts, cyclic=False, overhang=overhang)
示例#51
0
    def make_spanner_score_05(self):
        r'''Make 200-note voice with slur spanner on every 20 notes.

        ::

            2.12 (r9724) initialization:        248,567 function calls

            2.12 (r9703) LilyPond format:       122,177 function calls
            2.12 (r9724) LilyPond format:       107,486 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [20],
                cyclic=True,
        ):
            slur = spannertools.Slur()
            topleveltools.attach(slur, part)
        return voice
示例#52
0
    def make_spanner_score_09(self):
        r'''Make 200-note voice with (vanilla) beam spanner on every 100 notes.

        ::

            2.12 (r9724) initialization:        249,339 function calls

            2.12 (r9703) LilyPond format:       121,497 function calls
            2.12 (r9724) LilyPond format:       128,494 function calls

        '''
        from abjad.tools import scoretools
        from abjad.tools import sequencetools
        from abjad.tools import spannertools
        from abjad.tools import topleveltools
        voice = scoretools.Voice(200 * scoretools.Note("c'16"))
        for part in sequencetools.partition_sequence_by_counts(
                voice[:],
            [100],
                cyclic=True,
        ):
            beam = spannertools.Beam()
            topleveltools.attach(beam, part)
        return voice
示例#53
0
 def _burnish_outer_divisions(class_, input_, divisions):
     for list_ in divisions:
         assert all(isinstance(_, int) for _ in list_), repr(list_)
     left_classes = input_['left_classes']
     middle_classes = input_['middle_classes']
     right_classes = input_['right_classes']
     left_counts = input_['left_counts']
     left_counts = left_counts or datastructuretools.CyclicTuple([0])
     right_counts = input_['right_counts']
     right_counts = right_counts or datastructuretools.CyclicTuple([0])
     burnished_divisions = []
     left_count = 0
     if left_counts:
         left_count = left_counts[0]
     left = left_classes[:left_count]
     right_count = 0
     if right_counts:
         right_count = right_counts[0]
     right = right_classes[:right_count]
     if len(divisions) == 1:
         available_left_count = len(divisions[0])
         left_count = min([left_count, available_left_count])
         available_right_count = len(divisions[0]) - left_count
         right_count = min([right_count, available_right_count])
         middle_count = len(divisions[0]) - left_count - right_count
         left = left[:left_count]
         if not middle_classes:
             middle_classes = [1]
         middle = [middle_classes[0]]
         middle = middle_count * middle
         right = right[:right_count]
         left_part, middle_part, right_part = \
             sequencetools.partition_sequence_by_counts(
                 divisions[0],
                 [left_count, middle_count, right_count],
                 cyclic=False,
                 overhang=Exact,
                 )
         left_part = class_._burnish_division_part(left_part, left)
         middle_part = class_._burnish_division_part(middle_part, middle)
         right_part = class_._burnish_division_part(right_part, right)
         burnished_division = left_part + middle_part + right_part
         burnished_divisions.append(burnished_division)
     else:
         # first division
         available_left_count = len(divisions[0])
         left_count = min([left_count, available_left_count])
         middle_count = len(divisions[0]) - left_count
         left = left[:left_count]
         if not middle_classes:
             middle_classes = [1]
         middle = [middle_classes[0]]
         middle = middle_count * middle
         left_part, middle_part = \
             sequencetools.partition_sequence_by_counts(
                 divisions[0],
                 [left_count, middle_count],
                 cyclic=False,
                 overhang=Exact,
                 )
         left_part = class_._burnish_division_part(left_part, left)
         middle_part = class_._burnish_division_part(middle_part, middle)
         burnished_division = left_part + middle_part
         burnished_divisions.append(burnished_division)
         # middle divisions
         for division in divisions[1:-1]:
             middle_part = division
             middle = len(division) * [middle_classes[0]]
             middle_part = class_._burnish_division_part(
                 middle_part,
                 middle,
                 )
             burnished_division = middle_part
             burnished_divisions.append(burnished_division)
         # last division:
         available_right_count = len(divisions[-1])
         right_count = min([right_count, available_right_count])
         middle_count = len(divisions[-1]) - right_count
         right = right[:right_count]
         middle = middle_count * [middle_classes[0]]
         middle_part, right_part = \
             sequencetools.partition_sequence_by_counts(
                 divisions[-1],
                 [middle_count, right_count],
                 cyclic=False,
                 overhang=Exact,
                 )
         middle_part = class_._burnish_division_part(middle_part, middle)
         right_part = class_._burnish_division_part(right_part, right)
         burnished_division = middle_part + right_part
         burnished_divisions.append(burnished_division)
     unburnished_weights = [mathtools.weight(x) for x in divisions]
     burnished_weights = [mathtools.weight(x) for x in burnished_divisions]
     #assert burnished_weights == unburnished_weights
     # TODO: make the following work on Python 3:
     #assert tuple(burnished_weights) == tuple(unburnished_weights)
     return burnished_divisions
示例#54
0
    def __call__(self, divisions=None):
        r'''Calls fuse-by-counts division callback.

        ..  container:: example

            **Example 1.** Returns divisions unfused:

            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts()

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> divisions = division_maker(input_divisions)
                >>> divisions
                [Division(2, 8), Division(2, 8), Division(4, 8), Division(4, 8), Division(2, 4)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    {
                        \time 2/8
                        c'4
                    }
                    {
                        c'4
                    }
                    {
                        \time 4/8
                        c'2
                    }
                    {
                        c'2
                    }
                    {
                        \time 2/4
                        c'2
                    }
                }

        ..  container:: example

            **Example 2.** Fuses divisions two at a time:

            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=[2],
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> divisions = division_maker(input_divisions)
                >>> divisions
                [Division(4, 8), Division(8, 8), Division(2, 4)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'2
                    c'1
                    c'2
                }

        ..  container:: example

            **Example 3a.** Fuses divisions two at a time.
            Then splits fused divisions by ``3/16`` durations.

            Remainders to the right:
            
            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=[2],
                ...     )
                >>> division_maker = division_maker.split_by_durations(
                ...     durations=[Duration(3, 16)],
                ...     remainder=Right,
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> division_lists = division_maker(input_divisions)
                >>> for division_list in division_lists:
                ...     division_list
                [Division(3, 16), Division(3, 16), Division(1, 8)]
                [Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(1, 16)]
                [Division(3, 16), Division(3, 16), Division(1, 8)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> divisions = sequencetools.flatten_sequence(division_lists)
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'8.
                    c'8.
                    c'8
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'16
                    c'8.
                    c'8.
                    c'8
                }

            **Example 3b.** Remainders to the left:
            
            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=[2],
                ...     )
                >>> division_maker = division_maker.split_by_durations(
                ...     durations=[Duration(3, 16)],
                ...     remainder=Left,
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> division_lists = division_maker(input_divisions)
                >>> for division_list in division_lists:
                ...     division_list
                [Division(1, 8), Division(3, 16), Division(3, 16)]
                [Division(1, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16)]
                [Division(1, 8), Division(3, 16), Division(3, 16)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> divisions = sequencetools.flatten_sequence(division_lists)
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'8
                    c'8.
                    c'8.
                    c'16
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8
                    c'8.
                    c'8.
                }

        ..  container:: example

            **Example 4.** Fuses all divisions:

            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=mathtools.Infinity,
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> divisions = division_maker(input_divisions)
                >>> divisions
                [Division(16, 8)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'\breve
                }

        ..  container:: example

            **Example 5a.** Fuses all divisions. Then splits fused divisions
            by ``3/8`` durations:

            Remainder at right:

            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=mathtools.Infinity,
                ...     )
                >>> division_maker = division_maker.split_by_durations(
                ...     durations=[Duration(3, 16)],
                ...     remainder=Right,
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> division_lists = division_maker(input_divisions)
                >>> for division_list in division_lists:
                ...     division_list
                [Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(1, 8)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> divisions = sequencetools.flatten_sequence(division_lists)
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8
                }

            **Example 5b.** Remainder at left:

            ::

                >>> division_maker = makertools.DivisionMaker()
                >>> division_maker = division_maker.fuse_by_counts(
                ...     counts=mathtools.Infinity,
                ...     )
                >>> division_maker = division_maker.split_by_durations(
                ...     durations=[Duration(3, 16)],
                ...     remainder=Left,
                ...     )

            ::

                >>> input_divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)]
                >>> division_lists = division_maker(input_divisions)
                >>> for division_list in division_lists:
                ...     division_list
                [Division(1, 8), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16), Division(3, 16)]

            ::

                >>> rhythm_maker = rhythmmakertools.NoteRhythmMaker()
                >>> divisions = sequencetools.flatten_sequence(division_lists)
                >>> music = rhythm_maker(divisions)
                >>> lilypond_file = rhythmmakertools.make_lilypond_file(
                ...     music,
                ...     divisions,
                ...     time_signatures=input_divisions,
                ...     )
                >>> show(lilypond_file) # doctest: +SKIP

            ..  doctest::

                >>> staff = rhythm_maker._get_rhythmic_staff(lilypond_file)
                >>> f(staff)
                \new RhythmicStaff {
                    c'8
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                    c'8.
                }

        ..  container:: example

            **Example 6.** Empty input:

            ::

                >>> input_divisions = []
                >>> division_lists = division_maker(input_divisions)
                >>> for division_list in division_lists:
                ...     division_list

        Returns list of division lists.
        '''
        divisions = divisions or ()
        divisions = self._coerce_divisions(divisions)
        if not divisions:
            pass
        elif (self.counts == mathtools.Infinity or 
            self.counts == mathtools.Infinity()):
            divisions = [sum(divisions)]
        elif self.counts:
            parts = sequencetools.partition_sequence_by_counts(
                divisions,
                self.counts,
                cyclic=self.cyclic,
                overhang=True,
                )
            divisions = [sum(_) for _ in parts]
        divisions = [durationtools.Division(_) for _ in divisions]
        if self.secondary_division_maker is None:
            return divisions
        division_lists = []
        for division in divisions:
            if self.secondary_division_maker is not None:
                division_list = self.secondary_division_maker([division])[0]
            else:
                division_list = [division]
            division_list = [durationtools.Division(_) for _ in division_list]
            division_lists.append(division_list)
        return division_lists
示例#55
0
    def partition_by_counts(self, counts, cyclic=False, overhang=False):
        r'''Partitions sequence by `counts`.

        ..  container:: example

            **Example 1.** Partitions sequence once by counts without overhang:

            ::

                >>> sequence_ = Sequence(range(10))
                >>> sequence_.partition_by_counts(
                ...     [3],
                ...     cyclic=False,
                ...     overhang=False,
                ...     )
                Sequence((Sequence((0, 1, 2)),))

        ..  container:: example

            **Example 2.** Partitions sequence once by counts without
            overhang:

            ::

                >>> sequence_ = Sequence(range(16))
                >>> sequence_.partition_by_counts(
                ...     [4, 3],
                ...     cyclic=False,
                ...     overhang=False,
                ...     )
                Sequence((Sequence((0, 1, 2, 3)), Sequence((4, 5, 6))))

        ..  container:: example

            **Example 3.** Partitions sequence cyclically by counts without
            overhang:

            ::

                >>> sequence_ = Sequence(range(10))
                >>> sequence_.partition_by_counts(
                ...     [3],
                ...     cyclic=True,
                ...     overhang=False,
                ...     )
                Sequence((Sequence((0, 1, 2)), Sequence((3, 4, 5)), Sequence((6, 7, 8))))

        ..  container:: example

            **Example 4.** Partitions sequence cyclically by counts without
            overhang:

            ::

                >>> sequence_ = Sequence(range(16))
                >>> result = sequence_.partition_by_counts(
                ...     [4, 3],
                ...     cyclic=True,
                ...     overhang=False,
                ...     )
                >>> for part in result:
                ...     part
                Sequence((0, 1, 2, 3))
                Sequence((4, 5, 6))
                Sequence((7, 8, 9, 10))
                Sequence((11, 12, 13))

        ..  container:: example

            **Example 5.** Partitions sequence once by counts with overhang:

            ::

                
                >>> sequence_ = Sequence(range(10))
                >>> sequence_.partition_by_counts(
                ...     [3],
                ...     cyclic=False,
                ...     overhang=True,
                ...     )
                Sequence((Sequence((0, 1, 2)), Sequence((3, 4, 5, 6, 7, 8, 9))))

        ..  container:: example

            **Example 6.** Partitions sequence once by counts with overhang:

            ::

                >>> sequence_ = Sequence(range(16))
                >>> result = sequence_.partition_by_counts(
                ...     [4, 3],
                ...     cyclic=False,
                ...     overhang=True,
                ...     )
                >>> for part in result:
                ...     part
                Sequence((0, 1, 2, 3))
                Sequence((4, 5, 6))
                Sequence((7, 8, 9, 10, 11, 12, 13, 14, 15))

        ..  container:: example

            **Example 7.** Partitions sequence cyclically by counts with
            overhang:

            ::

                >>> sequence_ = Sequence(range(10))
                >>> result = sequence_.partition_by_counts(
                ...     [3],
                ...     cyclic=True,
                ...     overhang=True,
                ...     )
                >>> for part in result:
                ...     part
                Sequence((0, 1, 2))
                Sequence((3, 4, 5))
                Sequence((6, 7, 8))
                Sequence((9,))

        ..  container:: example

            **Example 8.** Partitions sequence cyclically by counts with
            overhang:

            ::

                >>> sequence_ = Sequence(range(16))
                >>> result = sequence_.partition_by_counts(
                ...     [4, 3],
                ...     cyclic=True,
                ...     overhang=True,
                ...     )
                >>> for part in result:
                ...     part
                Sequence((0, 1, 2, 3))
                Sequence((4, 5, 6))
                Sequence((7, 8, 9, 10))
                Sequence((11, 12, 13))
                Sequence((14, 15))

        ..  container:: example

            **Example 9.** Partitions sequence once by counts and asserts
            that sequence partitions exactly (with no overhang):

            ::

                >>> sequence_ = Sequence(range(10))
                >>> sequence_.partition_by_counts(
                ...     [2, 3, 5],
                ...     cyclic=False,
                ...     overhang=Exact,
                ...     )
                Sequence((Sequence((0, 1)), Sequence((2, 3, 4)), Sequence((5, 6, 7, 8, 9))))

        ..  container:: example

            **Example 10.** Partitions sequence cyclically by counts and
            asserts that sequence partitions exactly:

            ::

                >>> sequence_ = Sequence(range(10))
                >>> result = sequence_.partition_by_counts(
                ...     [2],
                ...     cyclic=True,
                ...     overhang=Exact,
                ...     )
                >>> for part in result:
                ...     part
                Sequence((0, 1))
                Sequence((2, 3))
                Sequence((4, 5))
                Sequence((6, 7))
                Sequence((8, 9))

            Exact partitioning means partitioning with no overhang.

        ..  container:: example

            **Example 11.** Partitions string:

            ::

                >>> sequence_ = Sequence('some text')
                >>> sequence_.partition_by_counts(
                ...     [3],
                ...     cyclic=False,
                ...     overhang=True,
                ...     )
                Sequence((Sequence(('s', 'o', 'm')), Sequence(('e', ' ', 't', 'e', 'x', 't'))))

        Returns nested sequence.
        '''
        from abjad.tools import sequencetools
        items = self._items[:]
        subsequences = []
        parts = sequencetools.partition_sequence_by_counts(
            items,
            counts,
            cyclic=cyclic,
            overhang=overhang,
        )
        parts = [type(self)(_) for _ in parts]
        sequence = type(self)(parts)
        return sequence
示例#56
0
 def make_rhythm_region_expressions_for_voice(self, voice_name):
     from experimental.tools import musicexpressiontools
     voice_proxy = \
         self.score_specification.voice_data_structures_by_voice[voice_name]
     division_payload_expressions = \
         voice_proxy.payload_expressions_by_attribute['divisions']
     voice_proxy = \
         self.score_specification.single_context_set_expressions_by_context[voice_name]
     expressions = \
         voice_proxy.timespan_delimited_single_context_set_expressions_by_attribute['rhythm']
     timespan_delimited_single_context_rhythm_set_expressions = expressions
     voice_proxy = \
         self.score_specification.voice_data_structures_by_voice[voice_name]
     voice_division_list = voice_proxy.voice_division_list
     if not voice_division_list:
         return []
     division_region_durations = \
         [x.timespan.duration for x in division_payload_expressions]
     timespan_delimited_single_context_rhythm_set_expression_durations = [
         x.target_timespan.duration
         for x in timespan_delimited_single_context_rhythm_set_expressions
     ]
     assert sum(division_region_durations) == \
         sum(timespan_delimited_single_context_rhythm_set_expression_durations)
     timespan_delimited_single_context_rhythm_set_expression_merged_durations = \
         self._merge_duration_sequences(
             division_region_durations,
             timespan_delimited_single_context_rhythm_set_expression_durations)
     # assert that rhythm set expressions cover rhythm regions exactly
     assert sequencetools.partition_sequence_by_weights(
         timespan_delimited_single_context_rhythm_set_expression_merged_durations,
         timespan_delimited_single_context_rhythm_set_expression_durations)
     rhythm_region_start_division_duration_lists = \
             self._partition_sequence_by_backgrounded_weights(
             voice_division_list.divisions,
             timespan_delimited_single_context_rhythm_set_expression_merged_durations)
     #self._debug_values(rhythm_region_start_division_duration_lists, 'rrsddls')
     assert len(rhythm_region_start_division_duration_lists) == \
         len(timespan_delimited_single_context_rhythm_set_expression_merged_durations)
     rhythm_region_start_division_counts = \
         [len(l) for l in rhythm_region_start_division_duration_lists]
     rhythm_region_division_lists = \
         sequencetools.partition_sequence_by_counts(
         voice_division_list.divisions,
         rhythm_region_start_division_counts,
         cyclic=False,
         overhang=False)
     rhythm_region_division_lists = [
         musicexpressiontools.DivisionList(x, voice_name=voice_name)
         for x in rhythm_region_division_lists
     ]
     assert len(rhythm_region_division_lists) == \
         len(timespan_delimited_single_context_rhythm_set_expression_merged_durations)
     #self._debug_values(rhythm_region_division_lists, 'rrdls')
     rhythm_region_durations = \
         [x.duration for x in rhythm_region_division_lists]
     #self._debug(rhythm_region_durations, 'rrds')
     cumulative_sums = \
         mathtools.cumulative_sums(rhythm_region_durations)
     rhythm_region_start_offsets = cumulative_sums[:-1]
     rhythm_region_start_offsets = \
         [durationtools.Offset(x) for x in rhythm_region_start_offsets]
     timespan_delimited_single_context_rhythm_set_expression_duration_pairs = [
         (x, x.target_timespan.duration)
         for x in timespan_delimited_single_context_rhythm_set_expressions
     ]
     merged_duration_timespan_delimited_single_context_rhythm_set_expression_pairs = \
         self._pair_duration_sequence_elements_with_input_pair_values(
         timespan_delimited_single_context_rhythm_set_expression_merged_durations,
         timespan_delimited_single_context_rhythm_set_expression_duration_pairs)
     # the first column in pairs is not used for anything further at all is discarded
     timespan_delimited_single_context_rhythm_set_expressions = [
         x[-1] for x in
         merged_duration_timespan_delimited_single_context_rhythm_set_expression_pairs
     ]
     assert len(timespan_delimited_single_context_rhythm_set_expressions) == \
         len(rhythm_region_division_lists)
     rhythm_region_expressions = []
     for timespan_delimited_single_context_rhythm_set_expression, \
         rhythm_region_start_offset, rhythm_region_division_list in zip(
         timespan_delimited_single_context_rhythm_set_expressions,
         rhythm_region_start_offsets, rhythm_region_division_lists):
         #self._debug(timespan_delimited_single_context_rhythm_set_expression, 'tsscrsx')
         rhythm_region_expression = \
             timespan_delimited_single_context_rhythm_set_expression.evaluate(
             rhythm_region_division_list,
             rhythm_region_start_offset, voice_name)
         rhythm_region_expressions.append(rhythm_region_expression)
     #self._debug_values(rhythm_region_expressions, 'rrxs')
     rhythm_region_expressions = \
         self.merge_prolonging_rhythm_region_expressions(
         rhythm_region_expressions)
     #self._debug_values(rhythm_region_expressions, 'rrxs')
     return rhythm_region_expressions
示例#57
0
    def from_score(score, populate=True):
        r'''Makes pitch array from `score`.

        ..  container:: example

            **Example 1.** Makes empty pitch array from score:

            ::

                >>> score = Score([])
                >>> score.append(Staff("c'8 d'8 e'8 f'8"))
                >>> score.append(Staff("c'4 d'4"))
                >>> score.append(
                ...     Staff(
                ...     scoretools.FixedDurationTuplet(
                ...     Duration(2, 8), "c'8 d'8 e'8") * 2))

            ..  doctest::

                >>> print(format(score))
                \new Score <<
                    \new Staff {
                        c'8
                        d'8
                        e'8
                        f'8
                    }
                    \new Staff {
                        c'4
                        d'4
                    }
                    \new Staff {
                        \times 2/3 {
                            c'8
                            d'8
                            e'8
                        }
                        \times 2/3 {
                            c'8
                            d'8
                            e'8
                        }
                    }
                >>

            ::

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

            ::

                >>> array = pitchtools.PitchArray.from_score(
                ...     score, populate=False)

            ::

                >>> print(array)
                [     ] [     ] [     ] [     ]
                [                 ] [                 ]
                [ ] [     ] [ ] [ ] [     ] [ ]

        ..  container:: example

            **Example 2.** Makes populated pitch array from `score`:

            ::

                >>> score = Score([])
                >>> score.append(Staff("c'8 d'8 e'8 f'8"))
                >>> score.append(Staff("c'4 d'4"))
                >>> score.append(
                ...     Staff(
                ...     scoretools.FixedDurationTuplet(
                ...     Duration(2, 8), "c'8 d'8 e'8") * 2))

            ..  doctest::

                >>> print(format(score))
                \new Score <<
                    \new Staff {
                        c'8
                        d'8
                        e'8
                        f'8
                    }
                    \new Staff {
                        c'4
                        d'4
                    }
                    \new Staff {
                        \times 2/3 {
                            c'8
                            d'8
                            e'8
                        }
                        \times 2/3 {
                            c'8
                            d'8
                            e'8
                        }
                    }
                >>

            ::

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

            ::

                >>> array = pitchtools.PitchArray.from_score(
                ...     score, populate=True)

            ::

                >>> print(array)
                [c'     ] [d'     ] [e'     ] [f'     ]
                [c'                   ] [d'                   ]
                [c'] [d'     ] [e'] [c'] [d'     ] [e']

        Returns pitch array.
        '''
        from abjad.tools import pitchtools
        from abjad.tools import scoretools
        time_intervals = \
            PitchArray._get_composite_offset_difference_series_from_leaves_in_expr(
            score)
        array_width = len(time_intervals)
        array_depth = len(score)
        pitch_array = PitchArray(array_depth, array_width)
        items = scoretools.make_multiplied_quarter_notes(
            [0], time_intervals)
        for leaf_iterable, pitch_array_row in \
            zip(score, pitch_array.rows):
            durations = []
            for leaf in iterate(leaf_iterable).by_class(scoretools.Leaf):
                durations.append(leaf._get_duration())
            parts = mutate(items).split(
                durations,
                cyclic=False,
                fracture_spanners=False,
                )
            part_lengths = [len(part) for part in parts]
            cells = pitch_array_row.cells
            grouped_cells = sequencetools.partition_sequence_by_counts(
                cells,
                part_lengths,
                cyclic=False,
                overhang=False,
                )
            for group in grouped_cells:
                pitch_array_row.merge(group)
            leaves = iterate(leaf_iterable).by_class(scoretools.Leaf)
            if populate:
                for cell, leaf in zip(pitch_array_row.cells, leaves):
                    cell.pitches.extend(
                        pitchtools.list_named_pitches_in_expr(leaf))
        return pitch_array