def rotate(self, n=1): r"""Rotates register inflection by `n`. :: >>> import consort >>> inflection = consort.RegisterInflection.zigzag().rotate(1) >>> print(format(inflection)) consort.tools.RegisterInflection( inflections=pitchtools.IntervalSegment( ( pitchtools.NumberedInterval(6), pitchtools.NumberedInterval(-6), pitchtools.NumberedInterval(3), pitchtools.NumberedInterval(-3), ), item_class=pitchtools.NumberedInterval, ), ratio=mathtools.Ratio((1, 1, 1)), ) Emits new register inflection. """ return new( self, inflections=sequencetools.rotate_sequence(self.inflections, n), ratio=sequencetools.rotate_sequence(self.ratio, n), )
def yield_all_rotations_of_sequence(sequence, n=1): '''Yields all `n`-rotations of `sequence`. :: >>> list(sequencetools.yield_all_rotations_of_sequence([1, 2, 3, 4], -1)) [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]] Yields rotations up to but not including identity. Returns generator of `sequence` objects. ''' from abjad.tools import sequencetools len_sequence = len(sequence) total_rotations_yielded = 0 yield sequencetools.rotate_sequence(sequence, 0) total_rotations_yielded += 1 index = n while True: rotation = sequencetools.rotate_sequence(sequence, index) if len_sequence <= total_rotations_yielded: break elif rotation == sequence: break else: yield rotation total_rotations_yielded += 1 index += n
def rotate(self, rotation): r'''Rotates pitch specifier. :: >>> pitch_specifier = consort.PitchSpecifier( ... pitch_segments=( ... "c' e' g'", ... "fs' gs'", ... "b", ... ), ... ratio=(1, 2, 3), ... ) >>> rotated_pitch_specifier = pitch_specifier.rotate(1) >>> print(format(rotated_pitch_specifier)) consort.tools.PitchSpecifier( pitch_segments=( pitchtools.PitchSegment( ( pitchtools.NamedPitch('b'), ), item_class=pitchtools.NamedPitch, ), pitchtools.PitchSegment( ( pitchtools.NamedPitch("c'"), pitchtools.NamedPitch('f'), pitchtools.NamedPitch('a'), ), item_class=pitchtools.NamedPitch, ), pitchtools.PitchSegment( ( pitchtools.NamedPitch("fs'"), pitchtools.NamedPitch("e'"), ), item_class=pitchtools.NamedPitch, ), ), ratio=mathtools.Ratio((3, 1, 2)), ) Returns new pitch specifier. ''' rotation = int(rotation) pitch_segments = tuple( _.rotate(rotation, transpose=True) for _ in self.pitch_segments ) pitch_segments = sequencetools.rotate_sequence( pitch_segments, rotation) ratio = sequencetools.rotate_sequence(self.ratio, rotation) return new( self, pitch_segments=pitch_segments, ratio=ratio, )
def _make_music(self, duration_pairs, seeds): from abjad.tools import rhythmmakertools tuplets = [] if not isinstance(seeds, int): seeds = 0 tuplet_ratios = datastructuretools.CyclicTuple( sequencetools.rotate_sequence(self.tuplet_ratios, seeds) ) beam_specifier = self.beam_specifier if beam_specifier is None: beam_specifier = rhythmmakertools.BeamSpecifier() tuplet_spelling_specifier = self.tuplet_spelling_specifier if tuplet_spelling_specifier is None: tuplet_spelling_specifier = \ rhythmmakertools.TupletSpellingSpecifier() for duration_index, duration_pair in enumerate(duration_pairs): ratio = tuplet_ratios[duration_index] duration = durationtools.Duration(duration_pair) tuplet = self._make_tuplet( duration, ratio, avoid_dots=tuplet_spelling_specifier.avoid_dots, is_diminution=tuplet_spelling_specifier.is_diminution, ) if beam_specifier.beam_each_division: beam = spannertools.MultipartBeam() attach(beam, tuplet) tuplets.append(tuplet) if beam_specifier.beam_divisions_together: beam = spannertools.MultipartBeam() attach(beam, tuplets) selections = [selectiontools.Selection(x) for x in tuplets] return selections
def rotate(self, rotation): r'''Rotate division list by `rotation`. :: >>> divisions = [(3, 16), (4, 16), (3, 16), (4, 16)] >>> division_list = musicexpressiontools.DivisionList( ... divisions, Offset(5), 'Voice 1') :: >>> result = division_list.rotate(-1) :: >>> print result.storage_format musicexpressiontools.DivisionList( [Division('[4, 16]', start_offset=Offset(5, 1)), Division('[3, 16]', start_offset=Offset(21, 4)), Division('[4, 16]', start_offset=Offset(87, 16)), Division('[3, 16]', start_offset=Offset(91, 16))], start_offset=durationtools.Offset(5, 1), voice_name='Voice 1' ) Emit newly constructed division list. ''' divisions = sequencetools.rotate_sequence(self.divisions, rotation) return self.new(divisions=divisions)
def rotate(self, rotation): r'''Rotate division list by `rotation`. :: >>> divisions = [(3, 16), (4, 16), (3, 16), (4, 16)] >>> division_list = musicexpressiontools.DivisionList( ... divisions, Offset(5), 'Voice 1') :: >>> result = division_list.rotate(-1) :: >>> print(format(result)) musicexpressiontools.DivisionList( [ durationtools.Division(4, 16), durationtools.Division(3, 16), durationtools.Division(4, 16), durationtools.Division(3, 16), ], start_offset=durationtools.Offset(5, 1), voice_name='Voice 1', ) Emit newly constructed division list. ''' divisions = sequencetools.rotate_sequence(self.divisions, rotation) return new(self, divisions=divisions)
def rotate(self, n): r'''Rotates pitch segment. :: >>> result = numbered_pitch_segment.rotate(1) >>> result PitchSegment([7, -2, -1.5, 6, 7, -1.5]) :: >>> show(result) # doctest: +SKIP :: >>> result = named_pitch_segment.rotate(-2) >>> result PitchSegment(["fs'", "g'", 'bqf', "g'", 'bf,', 'aqs']) :: >>> show(result) # doctest: +SKIP Returns new pitch segment. ''' from abjad.tools import sequencetools tokens = sequencetools.rotate_sequence(self._collection, n) return new(self, tokens=tokens)
def _initialize_with_mode_name(self, mode_name): mdi_segment = [] m2 = pitchtools.NamedInterval('minor', 2) M2 = pitchtools.NamedInterval('major', 2) A2 = pitchtools.NamedInterval('augmented', 2) dorian = [M2, m2, M2, M2, M2, m2, M2] if mode_name == 'dorian': mdi_segment.extend(sequencetools.rotate_sequence(dorian, 0)) elif mode_name == 'phrygian': mdi_segment.extend(sequencetools.rotate_sequence(dorian, -1)) elif mode_name == 'lydian': mdi_segment.extend(sequencetools.rotate_sequence(dorian, -2)) elif mode_name == 'mixolydian': mdi_segment.extend(sequencetools.rotate_sequence(dorian, -3)) elif mode_name in ('aeolian', 'minor', 'natural minor'): mdi_segment.extend(sequencetools.rotate_sequence(dorian, -4)) elif mode_name == 'locrian': mdi_segment.extend(sequencetools.rotate_sequence(dorian, -5)) elif mode_name in ('ionian', 'major'): mdi_segment.extend(sequencetools.rotate_sequence(dorian, -6)) elif mode_name == 'melodic minor': mdi_segment.extend([M2, m2, M2, M2, M2, M2, m2]) elif mode_name == 'harmonic minor': mdi_segment.extend([M2, m2, M2, M2, m2, A2, m2]) else: message = 'unknown mode name: {!r}.' message = message.format(mode_name) raise ValueError(message) return pitchtools.IntervalSegment( items=mdi_segment, item_class=pitchtools.NamedInterval, )
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 _invert_chord_quality(intervals, inversion): if isinstance(inversion, int): intervals = sequencetools.rotate_sequence(intervals, -inversion) rotation = -inversion elif inversion == 'root': rotation = 0 elif inversion == 'first': intervals = sequencetools.rotate_sequence(intervals, -1) rotation = -1 elif inversion == 'second': intervals = sequencetools.rotate_sequence(intervals, -2) rotation = -2 elif inversion == 'third': intervals = sequencetools.rotate_sequence(intervals, -3) rotation = -3 elif inversion == 'fourth': intervals = sequencetools.rotate_sequence(intervals, -4) rotation = -4 else: message = 'unknown chord inversion: {!r}.' raise ValueError(message.format(inversion)) return intervals, rotation
def yield_all_rotations_of_sequence(sequence, n=1): '''Yields all `n`-rotations of `sequence`. :: >>> list(sequencetools.yield_all_rotations_of_sequence([1, 2, 3, 4], -1)) [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]] Yields rotations up to but not including identity. Returns generator. ''' from abjad.tools import sequencetools if not isinstance(sequence, collections.Sequence): message = 'must by sequence {!r}.' message = message.format(sequence) raise Exception(message) sequence_type = type(sequence) len_sequence = len(sequence) total_rotations_yielded = 0 yield sequencetools.rotate_sequence(sequence, 0) total_rotations_yielded += 1 index = n while True: rotation = sequencetools.rotate_sequence(sequence, index) if len_sequence <= total_rotations_yielded: break elif rotation == sequence: break else: yield rotation total_rotations_yielded += 1 index += n
def __call__( self, durations=None, layer=None, division_masks=None, division_mask_seed=None, padding=None, seed=None, start_offset=None, timespan_specifier=None, voice_name=None, ): seed = seed or 0 rotation_indices = self.rotation_indices or (0,) rotation_indices = datastructuretools.CyclicTuple(rotation_indices) primary_durations = durations start_offset = start_offset or 0 if self.discard_inner_offsets: secondary_durations = [sum(primary_durations)] else: secondary_durations = sequencetools.rotate_sequence( primary_durations, rotation_indices[seed], ) primary_timespans = self.primary_music_specifier( durations=primary_durations, layer=layer, division_masks=division_masks, division_mask_seed=division_mask_seed, padding=padding, seed=seed, start_offset=start_offset, timespan_specifier=timespan_specifier, voice_name=self.primary_voice_name, ) secondary_timespans = self.secondary_music_specifier( durations=secondary_durations, layer=layer, division_masks=division_masks, division_mask_seed=division_mask_seed, padding=padding, seed=seed, start_offset=start_offset, timespan_specifier=timespan_specifier, voice_name=self.secondary_voice_name, ) timespans = primary_timespans[:] + secondary_timespans[:] timespans = timespantools.TimespanInventory(timespans) timespans.sort() return timespans
def _make_timespans( self, layer=None, music_specifiers=None, target_timespan=None, timespan_inventory=None, ): new_timespans = timespantools.TimespanInventory() if not self.voice_names and not self.labels: return new_timespans rotation_indices = self.rotation_indices or (0,) rotation_indices = datastructuretools.CyclicTuple(rotation_indices) context_counter = collections.Counter() preexisting_timespans = self._collect_preexisting_timespans( target_timespan=target_timespan, timespan_inventory=timespan_inventory, ) partitioned_timespans = self._partition_preexisting_timespans( preexisting_timespans) for group_index, group in enumerate(partitioned_timespans): rotation_index = rotation_indices[group_index] offsets = set() offsets.add(group.start_offset) offsets.add(group.stop_offset) for timespan in group: if self.include_inner_starts: offsets.add(timespan.start_offset) if self.include_inner_stops: offsets.add(timespan.stop_offset) offsets = tuple(sorted(offsets)) durations = mathtools.difference_series(offsets) durations = sequencetools.rotate_sequence( durations, rotation_index) start_offset = offsets[0] for context_name, music_specifier in music_specifiers.items(): context_seed = context_counter[context_name] timespans = music_specifier( durations=durations, layer=layer, division_masks=self.division_masks, padding=self.padding, seed=context_seed, start_offset=start_offset, timespan_specifier=self.timespan_specifier, voice_name=context_name, ) context_counter[context_name] += 1 new_timespans.extend(timespans) return new_timespans
def rotate(self, n, transpose=False): r'''Rotates pitch segment. :: >>> result = numbered_pitch_segment.rotate(1) >>> result PitchSegment([7, -2, -1.5, 6, 7, -1.5]) :: >>> show(result) # doctest: +SKIP :: >>> result = named_pitch_segment.rotate(-2) >>> result PitchSegment(["fs'", "g'", 'bqf', "g'", 'bf,', 'aqs']) :: >>> show(result) # doctest: +SKIP :: >>> pitch_segment = pitchtools.PitchSegment("c' d' e' f'") >>> result = pitch_segment.rotate(-1, transpose=True) >>> result PitchSegment(["c'", "d'", "ef'", 'bf']) :: >>> show(result) # doctest: +SKIP Returns new pitch segment. ''' from abjad.tools import sequencetools rotated_pitches = sequencetools.rotate_sequence( self._collection, n) new_segment = new(self, items=rotated_pitches) if transpose: if self[0] != new_segment[0]: interval = new_segment[0] - self[0] new_segment = new_segment.transpose(interval) return new_segment
def rotate(self, n): r'''Rotate pitch segment: :: >>> numbered_pitch_segment.rotate(1) PitchSegment([7, -2, -1.5, 6, 7, -1.5]) :: >>> named_pitch_segment.rotate(-2) PitchSegment(["fs'", "g'", 'bqf', "g'", 'bf,', 'aqs']) Emit new pitch segment. ''' from abjad.tools import sequencetools tokens = sequencetools.rotate_sequence(self._collection, n) return self.new(tokens=tokens)
def rotate(self, n): r'''Rotate payload expression. :: >>> result = payload_expression.rotate(-1) :: >>> print result.storage_format musicexpressiontools.IterablePayloadExpression( payload=((2, 16), (4, 16)) ) Returns newly constructed payload expression. ''' payload = sequencetools.rotate_sequence(self.payload, n) result = self.new(payload=payload) return result
def rotate(self, n=0): r"""Rotates talea by `n`. .. container:: example :: >>> rotated_talea = talea.rotate(1) >>> print format(rotated_talea) rhythmmakertools.Talea( counts=(1, 2, 1, 3, 2, 4, 1), denominator=16, ) Returns new talea. """ counts = tuple(sequencetools.rotate_sequence(self.counts, n)) result = type(self)(counts=counts, denominator=self.denominator) return result
def rotate(self, n): r'''Rotate payload expression. :: >>> result = payload_expression.rotate(-1) :: >>> print(format(result)) musicexpressiontools.IterablePayloadExpression( payload=( (2, 16), (4, 16), ), ) Returns newly constructed payload expression. ''' payload = sequencetools.rotate_sequence(self.payload, n) result = new(self, payload=payload) return result
def rotate(self, n): r'''Rotate pitch-class segment: :: >>> pitchtools.PitchClassSegment( ... tokens=[-2, -1.5, 6, 7, -1.5, 7], ... ).rotate(1) PitchClassSegment([7, 10, 10.5, 6, 7, 10.5]) :: >>> pitchtools.PitchClassSegment( ... tokens=['c', 'ef', 'bqs,', 'd'], ... ).rotate(-2) PitchClassSegment(['bqs', 'd', 'c', 'ef']) Emit new pitch-class segment. ''' from abjad.tools import sequencetools tokens = sequencetools.rotate_sequence(self._collection, n) return self.new(tokens=tokens)
def rotate(self, n=0): r'''Rotates talea by `n`. .. container:: example :: >>> rotated_talea = talea.rotate(1) >>> print(format(rotated_talea)) rhythmmakertools.Talea( counts=(1, 2, 1, 3, 2, 4, 1), denominator=16, ) Returns new talea. ''' counts = tuple(sequencetools.rotate_sequence(self.counts, n)) result = type(self)( counts=counts, denominator=self.denominator, ) return result
def rotate(self, n, transpose=False): r"""Rotate pitch-class segment: :: >>> pitchtools.PitchClassSegment( ... tokens=[-2, -1.5, 6, 7, -1.5, 7], ... ).rotate(1) PitchClassSegment([7, 10, 10.5, 6, 7, 10.5]) :: >>> pitchtools.PitchClassSegment( ... tokens=['c', 'ef', 'bqs,', 'd'], ... ).rotate(-2) PitchClassSegment(['bqs', 'd', 'c', 'ef']) If `transpose` is true, transpose the rotated segment to begin at the same pitch class as this segment: :: >>> pitchtools.PitchClassSegment( ... tokens=['c', 'b', 'd'] ... ).rotate(1, transpose=True) PitchClassSegment(['c', 'bf', 'a']) Returns new pitch-class segment. """ from abjad.tools import sequencetools tokens = sequencetools.rotate_sequence(self._collection, n) new_segment = new(self, tokens=tokens) if transpose: interval_of_transposition = float(self[0]) - float(new_segment[0]) new_segment = new_segment.transpose(interval_of_transposition) return new_segment
def rotate(self, n, transpose=False): r'''Rotate pitch-class segment: :: >>> pitchtools.PitchClassSegment( ... items=[-2, -1.5, 6, 7, -1.5, 7], ... ).rotate(1) PitchClassSegment([7, 10, 10.5, 6, 7, 10.5]) :: >>> pitchtools.PitchClassSegment( ... items=['c', 'ef', 'bqs,', 'd'], ... ).rotate(-2) PitchClassSegment(['bqs', 'd', 'c', 'ef']) If `transpose` is true, transpose the rotated segment to begin at the same pitch class as this segment: :: >>> pitchtools.PitchClassSegment( ... items=['c', 'b', 'd'] ... ).rotate(1, transpose=True) PitchClassSegment(['c', 'bf', 'a']) Returns new pitch-class segment. ''' from abjad.tools import sequencetools items = sequencetools.rotate_sequence(self._collection, n) new_segment = new(self, items=items) if transpose: interval_of_transposition = float(self[0]) - float(new_segment[0]) new_segment = new_segment.transpose(interval_of_transposition) return new_segment
def __call__(self, divisions=None): r'''Calls division-maker on `divisions`. .. container:: example Calls division-maker on division with no remainder: :: >>> maker = makertools.DivisionMaker( ... cyclic=True, ... pattern=[(1, 4)], ... ) >>> lists = maker([(3, 4)]) >>> for list_ in lists: ... list_ [Division(1, 4), Division(1, 4), Division(1, 4)] .. container:: example Calls division-maker cyclically on each division. Positions remainders to the right of each output list: :: >>> maker = makertools.DivisionMaker( ... pattern=[(1, 4)], ... ) >>> lists = maker([(7, 8)]) >>> for list_ in lists: ... list_ [Division(1, 4), Division(1, 4), Division(1, 4), Division(1, 8)] Positions remainder at right of output because divison-maker `remainder` defaults to right. .. container:: example Calls division-maker with pattern set to none: :: >>> maker = makertools.DivisionMaker() >>> lists = maker([(6, 32)]) >>> for list_ in lists: ... list_ [Division(6, 32)] Returns input division unchanged. .. container:: example Calls division-maker on nothing: :: >>> maker = makertools.DivisionMaker(pattern=[(1, 4)]) >>> maker() [] Returns empty list. .. container:: example Call division-maker on multiple divisions: :: >>> maker = makertools.DivisionMaker( ... cyclic=True, ... pattern=[(1, 4)], ... ) >>> lists = maker([(2, 4), (3, 4)]) >>> for list_ in lists: ... list_ [Division(1, 4), Division(1, 4)] [Division(1, 4), Division(1, 4), Division(1, 4)] Returns possibly empty list of division lists. ''' divisions = divisions or [] if not divisions: return [] division_lists = [] for i, division in enumerate(divisions): input_division = durationtools.Division(division) input_duration = durationtools.Duration(input_division) assert 0 < input_division, repr(input_division) if not self.pattern: division_list = [input_division] division_lists.append(division_list) continue division_list = list(self.pattern) pattern_rotation_index = self.pattern_rotation_index or 0 pattern_rotation_index *= i division_list = sequencetools.rotate_sequence( division_list, pattern_rotation_index, ) if self.cyclic: division_list = sequencetools.repeat_sequence_to_weight( division_list, input_division, allow_total=Less, ) total_duration = durationtools.Duration(sum(division_list)) if total_duration == input_duration: division_lists.append(division_list) continue if self.remainder is None: message = 'can not fill {} from {} exactly.' message = message.format(input_division, self.pattern) raise Exception(message) remainder = input_division - total_duration remainder = durationtools.Duration(remainder) remainder = durationtools.Division(remainder) if self.remainder == Left: if self.remainder_fuse_threshold is None: division_list.insert(0, remainder) elif remainder <= self.remainder_fuse_threshold: #division_list[0] += remainder fused_value = division_list[0] + remainder fused_value = durationtools.Division(fused_value) division_list[0] = fused_value else: division_list.insert(0, remainder) elif self.remainder == Right: if self.remainder_fuse_threshold is None: division_list.append(remainder) elif remainder <= self.remainder_fuse_threshold: #division_list[-1] += remainder fused_value = division_list[-1] + remainder fused_value = durationtools.Division(fused_value) division_list[-1] = fused_value else: division_list.append(remainder) else: raise ValueError((self.remainder, remainder)) total_duration = durationtools.Duration(sum(division_list)) pair = total_duration, input_duration assert total_duration == input_duration, pair division_lists.append(division_list) return division_lists
def __call__(self, divisions=None): r'''Calls division-maker on `divisions`. .. container:: example **Example 1.** Splits divisions without remainder: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... cyclic=True, ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(3, 4)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [Division((1, 4)), Division((1, 4)), Division((1, 4))] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 3/4 c'4 c'4 c'4 } } .. container:: example **Example 2.** Splits divisions with remainder: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(7, 8)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [Division((1, 4)), Division((1, 4)), Division((1, 4)), Division((1, 8))] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 7/8 c'4 c'4 c'4 c'8 } } Positions remainder at right of output because divison-maker `remainder` defaults to right. .. container:: example **Example 3.** Multiple divisions: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... cyclic=True, ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(2, 4), (3, 4)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [Division((1, 4)), Division((1, 4))] [Division((1, 4)), Division((1, 4)), Division((1, 4))] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 2/4 c'4 c'4 } { \time 3/4 c'4 c'4 c'4 } } .. container:: example **Example 4.** No durations: :: >>> maker = makertools.SplitByDurationsDivisionCallback() :: >>> time_signatures = [(6, 32)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [Division((6, 32))] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 6/32 c'8. } } Returns input division unchanged. .. container:: example **Example 5.** Empty input: :: >>> maker = makertools.SplitByDurationsDivisionCallback(durations=[(1, 4)]) >>> maker() [] Returns empty list. .. container:: example **Example 6.** Works with start offset: :: >>> callback = makertools.SplitByDurationsDivisionCallback( ... cyclic=True, ... durations=[(1, 4)], ... ) :: >>> divisions = [(2, 4), (3, 4)] >>> divisions = [durationtools.Division(_) for _ in divisions] >>> divisions[0]._start_offset = Offset(1, 4) >>> divisions [Division((2, 4), start_offset=Offset(1, 4)), Division((3, 4))] :: >>> division_lists = callback(divisions) >>> for division_list in division_lists: ... division_list [Division((1, 4), start_offset=Offset(1, 4)), Division((1, 4), start_offset=Offset(1, 2))] [Division((1, 4), start_offset=Offset(3, 4)), Division((1, 4), start_offset=Offset(1, 1)), Division((1, 4), start_offset=Offset(5, 4))] **Example 7.** Works with start offset: :: >>> 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, ... ) :: >>> divisions = [(2, 8), (2, 8), (4, 8), (4, 8), (2, 4)] >>> divisions = [durationtools.Division(_) for _ in divisions] >>> divisions[0]._start_offset = Offset(1, 4) :: >>> division_lists = division_maker(divisions) >>> len(division_lists) 1 :: >>> for division in division_lists[0]: ... division Division((1, 8), start_offset=Offset(1, 4)) Division((3, 16), start_offset=Offset(3, 8)) Division((3, 16), start_offset=Offset(9, 16)) Division((3, 16), start_offset=Offset(3, 4)) Division((3, 16), start_offset=Offset(15, 16)) Division((3, 16), start_offset=Offset(9, 8)) Division((3, 16), start_offset=Offset(21, 16)) Division((3, 16), start_offset=Offset(3, 2)) Division((3, 16), start_offset=Offset(27, 16)) Division((3, 16), start_offset=Offset(15, 8)) Division((3, 16), start_offset=Offset(33, 16)) Returns possibly empty list of division lists. ''' from experimental import makertools divisions = divisions or [] if not divisions: return divisions divisions, start_offset = makertools.DivisionMaker._to_divisions( divisions) start_offset = divisions[0].start_offset division_lists = [] for i, division in enumerate(divisions): input_division = durationtools.Division(division) input_duration = durationtools.Duration(input_division) input_meter = metertools.Meter(input_division) assert 0 < input_division, repr(input_division) if not self.durations: division_list = [input_division] division_lists.append(division_list) continue if input_meter.is_simple or not self.durations: durations = self.durations[:] elif input_meter.is_compound: multiplier = self.compound_meter_multiplier durations = [ durationtools.Duration(multiplier * _) for _ in self.durations ] division_list = list(durations) pattern_rotation_index = self.pattern_rotation_index or 0 pattern_rotation_index *= i division_list = sequencetools.rotate_sequence( division_list, pattern_rotation_index, ) if self.cyclic: division_list = sequencetools.repeat_sequence_to_weight( division_list, input_division, allow_total=Less, ) total_duration = durationtools.Duration(sum(division_list)) if total_duration == input_duration: division_lists.append(division_list) continue if self.remainder is None: message = 'can not fill {} from {} exactly.' message = message.format(input_division, durations) raise Exception(message) remainder = input_division - total_duration remainder = durationtools.Division(remainder) if self.remainder == Left: if self.remainder_fuse_threshold is None: division_list.insert(0, remainder) elif remainder <= self.remainder_fuse_threshold: fused_value = division_list[0] + remainder fused_value = durationtools.Division(fused_value) division_list[0] = fused_value else: division_list.insert(0, remainder) elif self.remainder == Right: if self.remainder_fuse_threshold is None: division_list.append(remainder) elif remainder <= self.remainder_fuse_threshold: fused_value = division_list[-1] + remainder fused_value = durationtools.Division(fused_value) division_list[-1] = fused_value else: division_list.append(remainder) else: raise ValueError((self.remainder, remainder)) total_duration = durationtools.Duration(sum(division_list)) pair = total_duration, input_duration assert total_duration == input_duration, pair division_lists.append(division_list) for _ in division_lists: assert isinstance(_, list), repr(_) division_lists, start_offset = makertools.DivisionMaker._to_divisions( division_lists, start_offset ) return division_lists
def _trivial_helper(self, sequence_, rotation): if isinstance(rotation, int) and len(sequence_): return sequencetools.rotate_sequence(sequence_, rotation) return sequence_
chunk.registration.percussion.tokens = [alsfo, alsfo, alsfo, alsfo] chunk.troping.guitar.tokens = [('C2-1', ), ('C2-2', ), None, None] chunk.troping.percussion.tokens = [('C2-1', ), ('C2-2', ), ('C2-3', ), ('C2-3', )] chunk.articulations.guitar.tokens = [[2, 1, 1, 1], art(['>', '.']), art(['^', '.']), None, None] chunk.articulations.percussion.tokens = [[2, 1, 2], art(['>', '.']), art(['^', '.']), art(['>', '.'])] pattern = baca.tools.helianthate( [['f', 'mp', 'mf'], ['f', 'mp', 'mf', 'mp', 'ff']], 1, 1) pattern = sequencetools.flatten_sequence(pattern, classes=(list,)) chunk.dynamics.flute.tokens = [[2, 3], None, ('terraces', pattern)] chunk.dynamics.guitar.tokens = [[2, 1, 1, 1], p_f, dyn('sfp'), ('rest-terminated <', 'f', 'ff'), ('rest-terminated <', 'f', 'ff')] pattern = sequencetools.rotate_sequence(pattern, -1 * len(pattern) // 3) chunk.dynamics.accordion.proportions = (2, 2, 1) chunk.dynamics.accordion.tokens = [[2, 2, 1], None, ('terraces', pattern), ('rest-terminated <', 'p', 'f')] chunk.dynamics.percussion.tokens = [[2, 1, 2], f_p, dyn('sfp'), pp_p] chunk.note_heads.flute.tokens = [[2, 3], None, ['la']] chunk.note_heads.guitar.tokens = [[2, 1, 1, 1], None, None, ['la'], ['la']] chunk.note_heads.accordion.tokens = [None, ['cross'], ['cross'], ['la']] chunk.trills.flute.tokens = [[2, 3], None, ('rest-delimited', 'R')] chunk.trills.accordion.tokens = [[2, 2, 1], None, ('rest-delimited', 'bg'), None] chunk.directives.guitar.tokens = [None, None, ['RH hiss', 'glissandi'], None] chunk.directives.accordion.tokens = [None, None, None, 'bellows air'] chunk.directives.percussion.tokens = [None, None, None, None]
def _trivial_helper(self, talea, seeds): if isinstance(seeds, int) and len(talea): return sequencetools.rotate_sequence(talea, seeds) return talea
def rotate(self, rotation): r'''Rotates pitch operation specifier. :: >>> pitch_operation_specifier = consort.PitchOperationSpecifier( ... pitch_operations=( ... pitchtools.PitchOperation(( ... pitchtools.Rotation(1), ... pitchtools.Transposition(1), ... )), ... None, ... pitchtools.PitchOperation(( ... pitchtools.Rotation(-1), ... pitchtools.Transposition(-1), ... )) ... ), ... ratio=(1, 2, 1), ... ) >>> rotated_specifier = pitch_operation_specifier.rotate(1) >>> print(format(rotated_specifier)) consort.tools.PitchOperationSpecifier( pitch_operations=( pitchtools.PitchOperation( operators=( pitchtools.Rotation( index=-1, transpose=True, ), pitchtools.Transposition( index=-1, ), ), ), pitchtools.PitchOperation( operators=( pitchtools.Rotation( index=1, transpose=True, ), pitchtools.Transposition( index=1, ), ), ), None, ), ratio=mathtools.Ratio((1, 1, 2)), ) Returns new pitch specifier. ''' rotation = int(rotation) pitch_operations = sequencetools.rotate_sequence( self.pitch_operations, rotation) ratio = sequencetools.rotate_sequence(self.ratio, rotation) return new( self, pitch_operations=pitch_operations, ratio=ratio, )
def _trivial_helper(self, talea, rotation): if isinstance(rotation, int) and len(talea): return sequencetools.rotate_sequence(talea, rotation) return talea
def _rotate_tuple(expr, n): if expr is not None: return tuple(sequencetools.rotate_sequence(expr, n))
def rotate(self, n=0): r'''Rotates tuplet rhythm-maker. .. container:: example :: >>> maker = rhythmmakertools.TupletRhythmMaker( ... tuplet_ratios=[(2, 3), (1, -2, 1), (1, 2, 3)], ... ) >>> rotated_maker = maker.rotate(n=1) :: >>> print format(rotated_maker) rhythmmakertools.TupletRhythmMaker( tuplet_ratios=( mathtools.Ratio(3, 1, 2), mathtools.Ratio(3, 2), mathtools.Ratio(1, 1, -2), ), ) :: >>> divisions = [(1, 2), (3, 8), (5, 16)] >>> music = rotated_maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 1/2 \times 2/3 { c'4. c'8 c'4 } } { \time 3/8 \tweak #'text #tuplet-number::calc-fraction-text \times 3/5 { c'4. c'4 } } { \time 5/16 \tweak #'text #tuplet-number::calc-fraction-text \times 5/6 { c'16. [ c'16. ] r8. } } } Returns new tuplet rhythm-maker. ''' from abjad.tools import rhythmmakertools tuplet_ratios = [] for ratio in sequencetools.rotate_sequence(self.tuplet_ratios, n): ratio = sequencetools.rotate_sequence(ratio, n) ratio = mathtools.Ratio(ratio) tuplet_ratios.append(ratio) tuplet_ratios = tuple(tuplet_ratios) maker = new( self, tuplet_ratios=tuplet_ratios, ) return maker
def __call__(self, divisions=None): r'''Calls division-maker on `divisions`. .. container:: example **Example 1.** NonreducedFraction without remainder: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... cyclic=True, ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(3, 4)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [NonreducedFraction(1, 4), NonreducedFraction(1, 4), NonreducedFraction(1, 4)] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 3/4 c'4 c'4 c'4 } } .. container:: example **Example 2.** NonreducedFraction with remainder: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(7, 8)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [NonreducedFraction(1, 4), NonreducedFraction(1, 4), NonreducedFraction(1, 4), NonreducedFraction(1, 8)] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 7/8 c'4 c'4 c'4 c'8 } } Positions remainder at right of output because divison-maker `remainder` defaults to right. .. container:: example **Example 3.** Multiple divisions: :: >>> maker = makertools.SplitByDurationsDivisionCallback( ... cyclic=True, ... durations=[(1, 4)], ... ) :: >>> time_signatures = [(2, 4), (3, 4)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [NonreducedFraction(1, 4), NonreducedFraction(1, 4)] [NonreducedFraction(1, 4), NonreducedFraction(1, 4), NonreducedFraction(1, 4)] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 2/4 c'4 c'4 } { \time 3/4 c'4 c'4 c'4 } } .. container:: example **Example 4.** No durations: :: >>> maker = makertools.SplitByDurationsDivisionCallback() :: >>> time_signatures = [(6, 32)] >>> division_lists = maker(time_signatures) >>> for division_list in division_lists: ... division_list [NonreducedFraction(6, 32)] :: >>> maker = rhythmmakertools.NoteRhythmMaker() >>> divisions = sequencetools.flatten_sequence(division_lists) >>> music = maker(divisions) >>> lilypond_file = rhythmmakertools.make_lilypond_file( ... music, ... divisions, ... time_signatures=time_signatures, ... ) >>> show(lilypond_file) # doctest: +SKIP .. doctest:: >>> staff = maker._get_rhythmic_staff(lilypond_file) >>> f(staff) \new RhythmicStaff { { \time 6/32 c'8. } } Returns input division unchanged. .. container:: example **Example 5.** Empty input: :: >>> maker = makertools.SplitByDurationsDivisionCallback(durations=[(1, 4)]) >>> maker() [] Returns empty list. Returns possibly empty list of division lists. ''' divisions = divisions or [] if not divisions: return divisions division_lists = [] for i, division in enumerate(divisions): input_division = mathtools.NonreducedFraction(division) input_duration = durationtools.Duration(input_division) input_meter = metertools.Meter(input_division) assert 0 < input_division, repr(input_division) if not self.durations: division_list = [input_division] division_lists.append(division_list) continue if input_meter.is_simple or not self.durations: durations = self.durations[:] elif input_meter.is_compound: multiplier = self.compound_meter_multiplier durations = [ mathtools.NonreducedFraction(multiplier * _) for _ in self.durations ] #division_list = list(self.durations) division_list = list(durations) pattern_rotation_index = self.pattern_rotation_index or 0 pattern_rotation_index *= i division_list = sequencetools.rotate_sequence( division_list, pattern_rotation_index, ) if self.cyclic: division_list = sequencetools.repeat_sequence_to_weight( division_list, input_division, allow_total=Less, ) total_duration = durationtools.Duration(sum(division_list)) if total_duration == input_duration: division_lists.append(division_list) continue if self.remainder is None: message = 'can not fill {} from {} exactly.' #message = message.format(input_division, self.durations) message = message.format(input_division, durations) raise Exception(message) remainder = input_division - total_duration remainder = durationtools.Duration(remainder) remainder = mathtools.NonreducedFraction(remainder) if self.remainder == Left: if self.remainder_fuse_threshold is None: division_list.insert(0, remainder) elif remainder <= self.remainder_fuse_threshold: fused_value = division_list[0] + remainder fused_value = mathtools.NonreducedFraction(fused_value) division_list[0] = fused_value else: division_list.insert(0, remainder) elif self.remainder == Right: if self.remainder_fuse_threshold is None: division_list.append(remainder) elif remainder <= self.remainder_fuse_threshold: fused_value = division_list[-1] + remainder fused_value = mathtools.NonreducedFraction(fused_value) division_list[-1] = fused_value else: division_list.append(remainder) else: raise ValueError((self.remainder, remainder)) total_duration = durationtools.Duration(sum(division_list)) pair = total_duration, input_duration assert total_duration == input_duration, pair division_lists.append(division_list) for _ in division_lists: assert isinstance(_, list), repr(_) return division_lists