def _set_duration(self, new_duration, use_messiaen_style_ties=False): from abjad.tools import scoretools from abjad.tools import spannertools new_duration = durationtools.Duration(new_duration) # change LilyPond multiplier if leaf already has LilyPond multiplier if self._get_indicators(durationtools.Multiplier): detach(durationtools.Multiplier, self) multiplier = new_duration.__div__(self.written_duration) attach(multiplier, self) return [self] # change written duration if new duration is assignable try: self.written_duration = new_duration return [self] except AssignabilityError: pass # make new notes or tuplets if new duration is nonassignable components = scoretools.make_notes( 0, new_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) if isinstance(components[0], scoretools.Leaf): tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for x, component in zip(all_leaves, components): x.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) parentage = self._get_parentage() if not parentage._get_spanners(spannertools.Tie): #if spannertools.Tie._attachment_test(self): tie = spannertools.Tie() if tie._attachment_test(self): tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, all_leaves) return all_leaves else: assert isinstance(components[0], scoretools.Tuplet) tuplet = components[0] components = tuplet[:] tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for x, component in zip(all_leaves, components): x.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) if not self._get_spanners(spannertools.Tie): #if spannertools.Tie._attachment_test(self): tie = spannertools.Tie() if tie._attachment_test(self): tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, all_leaves) tuplet_multiplier = tuplet.multiplier scoretools.Tuplet(tuplet_multiplier, all_leaves) return [tuplet]
def _make_ties_across_divisions(self, music): if not self.tie_across_divisions: return if self.tie_across_divisions == True: for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = next( iterate(division_one).by_class(prototype=scoretools.Leaf, reverse=True)) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf)) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) elif isinstance(self.tie_across_divisions, (tuple, list)): tie_across_divisions = datastructuretools.CyclicTuple( self.tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(music) for i, pair in enumerate(pairs): indicator = tie_across_divisions[i] if not bool(indicator): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) else: raise TypeError(self.tie_across_divisions)
def _attach_tie_spanner_to_leaf_pair(self, use_messiaen_style_ties=False): from abjad.tools import scoretools from abjad.tools import spannertools assert len(self) == 2 left_leaf, right_leaf = self assert isinstance(left_leaf, scoretools.Leaf), left_leaf assert isinstance(right_leaf, scoretools.Leaf), right_leaf left_logical_tie = left_leaf._get_logical_tie() right_logical_tie = right_leaf._get_logical_tie() prototype = (spannertools.Tie, ) if left_logical_tie == right_logical_tie: return try: left_tie_spanner = left_leaf._get_spanner(prototype) except MissingSpannerError: left_tie_spanner = None try: right_tie_spanner = right_leaf._get_spanner(prototype) except MissingSpannerError: right_tie_spanner = None if left_tie_spanner is not None and right_tie_spanner is not None: left_tie_spanner._fuse_by_reference(right_tie_spanner) elif left_tie_spanner is not None and right_tie_spanner is None: left_tie_spanner._append(right_leaf) elif left_tie_spanner is None and right_tie_spanner is not None: right_tie_spanner._append_left(left_leaf) elif left_tie_spanner is None and right_tie_spanner is None: tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, [left_leaf, right_leaf])
def _do_tie_consecutive_notes(self, divisions): if not self.tie_consecutive_notes: return leaves = select(divisions).by_leaf() for leaf in leaves: detach(spannertools.Tie, leaf) pairs = itertools.groupby(leaves, lambda _: _.__class__) def _get_pitches(component): if isinstance(component, scoretools.Note): return component.written_pitch elif isinstance(component, scoretools.Chord): return component.written_pitches else: raise TypeError(component) for class_, group in pairs: group = list(group) if not isinstance(group[0], (scoretools.Note, scoretools.Chord)): continue subpairs = itertools.groupby(group, lambda _: _get_pitches(_)) for pitches, subgroup in subpairs: subgroup = list(subgroup) if len(subgroup) == 1: continue tie = spannertools.Tie() assert tie._attachment_test_all(subgroup) attach(tie, subgroup)
def edit_second_violin_voice(score, durated_reservoir): r'''Edits second violin voice. ''' voice = score['Second Violin Voice'] descents = durated_reservoir['Second Violin'] last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() copied_descent = list(copied_descent) copied_descent[-1].written_duration = durationtools.Duration(1, 1) copied_descent.append(scoretools.Note('a2')) for leaf in copied_descent: articulation = indicatortools.Articulation('accent') attach(articulation, leaf) articulation = indicatortools.Articulation('tenuto') attach(articulation, leaf) voice.extend(copied_descent) final_sustain = [] for _ in range(32): final_sustain.append(scoretools.Note('a1.')) final_sustain.append(scoretools.Note('a2')) articulation = indicatortools.Articulation('accent') attach(articulation, final_sustain[0]) articulation = indicatortools.Articulation('tenuto') attach(articulation, final_sustain[0]) voice.extend(final_sustain) tie = spannertools.Tie() attach(tie, final_sustain) voice.extend('r4 r2.')
def _add_or_remove_notes_to_achieve_written_duration( self, new_written_duration): from abjad.tools import scoretools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools import scoretools new_written_duration = durationtools.Duration(new_written_duration) if new_written_duration.is_assignable: self[0].written_duration = new_written_duration for leaf in self[1:]: parent = leaf._parent if parent: index = parent.index(leaf) del(parent[index]) first = self[0] for spanner in first._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, first) elif new_written_duration.has_power_of_two_denominator: durations = scoretools.make_notes(0, [new_written_duration]) for leaf, token in zip(self, durations): leaf.written_duration = token.written_duration if len(self) == len(durations): pass elif len(durations) < len(self): for leaf in self[len(durations):]: parent = leaf._parent if parent: index = parent.index(leaf) del(parent[index]) elif len(self) < len(durations): for spanner in self[0]._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, self[0]) difference = len(durations) - len(self) extra_leaves = self[0] * difference for extra_leaf in extra_leaves: for spanner in extra_leaf._get_spanners(): spanner._remove(extra_leaf) extra_tokens = durations[len(self):] for leaf, token in zip(extra_leaves, extra_tokens): leaf.written_duration = token.written_duration ties = self[-1]._get_spanners(spannertools.Tie) if not ties: tie = spannertools.Tie() attach(tie, list(self)) self[-1]._splice(extra_leaves, grow_spanners=True) else: durations = scoretools.make_notes(0, new_written_duration) assert isinstance(durations[0], scoretools.Tuplet) fmtuplet = durations[0] new_logical_tie_written = \ fmtuplet[0]._get_logical_tie()._preprolated_duration self._add_or_remove_notes_to_achieve_written_duration( new_logical_tie_written) multiplier = fmtuplet.multiplier scoretools.Tuplet(multiplier, self.leaves) return self[0]._get_logical_tie()
def _do_tie_consecutive_notes(self, divisions): if not self.tie_consecutive_notes: return leaves = list(iterate(divisions).by_leaf()) for leaf in leaves: detach(spannertools.Tie, leaf) pairs = itertools.groupby(leaves, lambda _: _.__class__) for class_, group in pairs: group = list(group) if isinstance(group[0], scoretools.Note): if 1 < len(group): attach(spannertools.Tie(), group)
def _do_tie_across_divisions(self, divisions): if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, patterntools.Pattern): tie_across_divisions = patterntools.Pattern.from_vector( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() if tie_spanner._attachment_test_all(combined_logical_tie): attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def _notate_leaves( self, grace_handler=None, voice=None, ): for leaf in iterate(voice).by_leaf(): if leaf._has_indicator(indicatortools.Annotation): annotation = leaf._get_indicator(indicatortools.Annotation) pitches, grace_container = grace_handler(annotation.value) if not pitches: new_leaf = scoretools.Rest(leaf) elif 1 < len(pitches): new_leaf = scoretools.Chord(leaf) new_leaf.written_pitches = pitches else: new_leaf = scoretools.Note(leaf) new_leaf.written_pitch = pitches[0] if grace_container: attach(grace_container, new_leaf) tie = spannertools.Tie() if tie._attachment_test(new_leaf): attach(tie, new_leaf) mutate(leaf).replace(new_leaf) else: previous_leaf = leaf._get_leaf(-1) if isinstance(previous_leaf, scoretools.Rest): new_leaf = type(previous_leaf)( leaf.written_duration, ) elif isinstance(previous_leaf, scoretools.Note): new_leaf = type(previous_leaf)( previous_leaf.written_pitch, leaf.written_duration, ) else: new_leaf = type(previous_leaf)( previous_leaf.written_pitch, leaf.written_duration, ) mutate(leaf).replace(new_leaf) tie = inspect_(previous_leaf).get_spanner(spannertools.Tie) if tie is not None: tie._append(new_leaf) if leaf._has_indicator(indicatortools.Tempo): tempo = leaf._get_indicator(indicatortools.Tempo) detach(indicatortools.Tempo, leaf) attach(tempo, new_leaf)
def _make_music(self, divisions, rotation): from abjad.tools import rhythmmakertools selections = [] duration_specifier = self._get_duration_spelling_specifier() tie_specifier = self._get_tie_specifier() tuplet_specifier = self._get_tuplet_spelling_specifier() for division in divisions: if (duration_specifier.spell_metrically == True or (duration_specifier.spell_metrically == 'unassignable' and not mathtools.is_assignable_integer(division.numerator))): meter = metertools.Meter(division) rhythm_tree_container = meter.root_node durations = [_.duration for _ in rhythm_tree_container] elif isinstance(duration_specifier.spell_metrically, rhythmmakertools.PartitionTable): partition_table = duration_specifier.spell_metrically durations = partition_table.respell_division(division) else: durations = [division] selection = scoretools.make_leaves( pitches=0, durations=durations, decrease_durations_monotonically=\ duration_specifier.decrease_durations_monotonically, forbidden_written_duration=\ duration_specifier.forbidden_written_duration, is_diminution=tuplet_specifier.is_diminution, use_messiaen_style_ties=tie_specifier.use_messiaen_style_ties, ) if (1 < len(selection) and not selection[0]._has_spanner(spannertools.Tie)): tie = spannertools.Tie(use_messiaen_style_ties=tie_specifier. use_messiaen_style_ties, ) attach(tie, selection[:]) selections.append(selection) selections = self._apply_burnish_specifier(selections) beam_specifier = self._get_beam_specifier() beam_specifier(selections) selections = self._apply_division_masks(selections, rotation) if duration_specifier.rewrite_meter: selections = duration_specifier._rewrite_meter_( selections, divisions, use_messiaen_style_ties=tie_specifier.use_messiaen_style_ties, ) return selections
def edit_first_violin_voice(score, durated_reservoir): r'''Edits first violin voice. ''' voice = score['First Violin Voice'] descents = durated_reservoir['First Violin'] descents = selectiontools.Selection(descents) last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() voice.extend(copied_descent) final_sustain_rhythm = [(6, 4)] * 43 + [(1, 2)] final_sustain_notes = scoretools.make_notes(["c'"], final_sustain_rhythm) voice.extend(final_sustain_notes) tie = spannertools.Tie() attach(tie, final_sustain_notes) voice.extend('r4 r2.')
def recurse(node, tuplet_duration): basic_prolated_duration = tuplet_duration / node._contents_duration basic_written_duration = \ basic_prolated_duration.equal_or_greater_power_of_two tuplet = scoretools.FixedDurationTuplet(tuplet_duration, []) for child in node.children: if isinstance(child, type(self)): tuplet.extend(recurse( child, child.preprolated_duration * basic_written_duration)) else: leaves = child(basic_written_duration) tuplet.extend(leaves) if 1 < len(leaves): tie = spannertools.Tie() attach(tie, leaves) if tuplet.multiplier == 1: return tuplet[:] return [tuplet]
def _make_ties_across_divisions(self, divisions): from abjad.tools import rhythmmakertools if not self.tie_across_divisions: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, rhythmmakertools.BooleanPattern): tie_across_divisions = \ rhythmmakertools.BooleanPattern.from_sequence( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def edit_viola_voice(score, durated_reservoir): r'''Edits viola voice. ''' voice = score['Viola Voice'] descents = durated_reservoir['Viola'] for leaf in descents[-1]: articulation = indicatortools.Articulation('accent') attach(articulation, leaf) articulation = indicatortools.Articulation('tenuto') attach(articulation, leaf) last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() for leaf in copied_descent: if leaf.written_duration == durationtools.Duration(4, 4): leaf.written_duration = durationtools.Duration(8, 4) else: leaf.written_duration = durationtools.Duration(4, 4) voice.extend(copied_descent) bridge = scoretools.Note('e1') articulation = indicatortools.Articulation('tenuto') attach(articulation, bridge) articulation = indicatortools.Articulation('accent') attach(articulation, bridge) voice.append(bridge) final_sustain_rhythm = [(6, 4)] * 21 + [(1, 2)] final_sustain_notes = scoretools.make_notes(['e'], final_sustain_rhythm) articulation = indicatortools.Articulation('accent') attach(articulation, final_sustain_notes[0]) articulation = indicatortools.Articulation('tenuto') attach(articulation, final_sustain_notes[0]) voice.extend(final_sustain_notes) tie = spannertools.Tie() attach(tie, final_sustain_notes) voice.extend('r4 r2.')
def _apply_spanners(self, leaves): spanner_references = { spannertools.Beam: None, spannertools.Slur: None, } first_leaf = leaves[0] for leaf, next_leaf in \ sequencetools.iterate_sequence_nwise(leaves, wrapped=True): span_events = self._get_span_events(leaf) for current_class, directions in span_events.items(): starting, stopping = [], [] for direction in directions: if direction == Left: starting.append(Left) else: stopping.append(Right) # apply undirected events immediately, # and do not maintain a reference to them if current_class is spannertools.Tie: if next_leaf is first_leaf: message = 'unterminated {} at {}.' message = message.format(current_class.__name__, leaf) raise Exception(message) previous_tie = [ x for x in leaf._get_spanners() if isinstance(x, spannertools.Tie) ] if previous_tie: previous_tie[0]._append(next_leaf) else: tie = spannertools.Tie() attach(tie, (leaf, next_leaf)) elif current_class is spannertools.Beam: # A beam may begin and end on the same leaf # but only one beam spanner may cover any given leaf, # and starting events are processed before ending ones for _ in starting: if spanner_references[current_class] is not None: message = 'already have beam.' raise Exception(message) else: spanner_references[current_class] = current_class() for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None elif current_class is spannertools.Slur: # Slurs process stop events before start events, # they must contain more than one leaf, # but they can stop on a leaf and start on the same leaf. for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None else: message = 'can not end: {}.' message = message.format(current_class.__name) raise Exception(message) for _ in starting: if spanner_references[current_class] is None: spanner_references[current_class] = current_class() else: message = 'already have: {}.' message = message.format(current_class.__name) raise Exception(message) # append leaf to all tracked spanners, for current_class, instance in spanner_references.items(): if instance is not None: instance._append(leaf) # check for unterminated spanners for current_class, instance in spanner_references.items(): if instance is not None: message = 'unterminated {}.' message = message.format(current_class.__name__) raise Exception(message)
def make_tied_leaf( kind, duration, decrease_durations_monotonically=True, forbidden_written_duration=None, pitches=None, tie_parts=True, ): r'''Make tied `kind` with `duration`. .. container:: example **Example 1.** Make note: :: >>> leaves = scoretools.make_tied_leaf( ... Note, ... Duration(1, 2), ... pitches='C#5', ... ) >>> staff = Staff(leaves) >>> time_signature = TimeSignature((2, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 2/4 cs''2 } .. container:: example **Example 2.** Make note and forbid half notes: :: >>> leaves = scoretools.make_tied_leaf( ... Note, ... Duration(1, 2), ... pitches='C#5', ... forbidden_written_duration=Duration(1, 2), ... ) >>> staff = Staff(leaves) >>> time_signature = TimeSignature((2, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 2/4 cs''4 ~ cs''4 } .. container:: example **Example 3.** Make tied note with half notes forbidden and durations decreasing monotonically: :: >>> leaves = scoretools.make_tied_leaf( ... Note, ... Duration(9, 8), ... pitches='C#5', ... forbidden_written_duration=Duration(1, 2), ... decrease_durations_monotonically=True, ... ) >>> staff = Staff(leaves) >>> time_signature = TimeSignature((9, 8)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 9/8 cs''4 ~ cs''4 ~ cs''4 ~ cs''4 ~ cs''8 } .. container:: example **Example 4.** Make tied note with half notes forbidden and durations increasing monotonically: :: >>> leaves = scoretools.make_tied_leaf( ... Note, ... Duration(9, 8), ... pitches='C#5', ... forbidden_written_duration=Duration(1, 2), ... decrease_durations_monotonically=False, ... ) >>> staff = Staff(leaves) >>> time_signature = TimeSignature((9, 8)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 9/8 cs''8 ~ cs''4 ~ cs''4 ~ cs''4 ~ cs''4 } Returns selection of unincorporated leaves. ''' from abjad.tools import scoretools from abjad.tools import spannertools # check input duration = durationtools.Duration(duration) if forbidden_written_duration is not None: forbidden_written_duration = \ durationtools.Duration(forbidden_written_duration) assert forbidden_written_duration.is_assignable assert forbidden_written_duration.numerator == 1 # find preferred numerator of written durations if necessary if forbidden_written_duration is not None and \ forbidden_written_duration <= duration: denominators = [ 2 * forbidden_written_duration.denominator, duration.denominator, ] denominator = mathtools.least_common_multiple(*denominators) forbidden_written_duration = \ mathtools.NonreducedFraction(forbidden_written_duration) forbidden_written_duration = \ forbidden_written_duration.with_denominator(denominator) duration = mathtools.NonreducedFraction(duration) duration = duration.with_denominator(denominator) forbidden_numerator = forbidden_written_duration.numerator assert forbidden_numerator % 2 == 0 preferred_numerator = forbidden_numerator / 2 # make written duration numerators numerators = [] parts = mathtools.partition_integer_into_canonic_parts(duration.numerator) if forbidden_written_duration is not None and \ forbidden_written_duration <= duration: for part in parts: if forbidden_numerator <= part: better_parts = \ mathtools.partition_integer_into_parts_less_than_double( part, preferred_numerator) numerators.extend(better_parts) else: numerators.append(part) else: numerators = parts # reverse numerators if necessary if not decrease_durations_monotonically: numerators = list(reversed(numerators)) # make one leaf per written duration result = [] for numerator in numerators: written_duration = \ durationtools.Duration(numerator, duration.denominator) if not pitches is None: args = (pitches, written_duration) else: args = (written_duration, ) result.append(kind(*args)) # apply tie spanner if required if tie_parts and 1 < len(result): if not issubclass(kind, (scoretools.Rest, scoretools.Skip)): tie = spannertools.Tie() attach(tie, result) # return result result = selectiontools.Selection(result) return result
def make_leaves_from_talea( talea, talea_denominator, decrease_durations_monotonically=True, forbidden_written_duration=None, spell_metrically=None, use_messiaen_style_ties=False, ): r'''Makes leaves from `talea`. Interprets positive elements in `talea` as notes numerators. Interprets negative elements in `talea` as rests numerators. Sets the pitch of all notes to middle C. .. container:: example **Example 1.** Makes leaves from talea: :: >>> leaves = scoretools.make_leaves_from_talea([3, -3, 5, -5], 16) >>> staff = Staff(leaves) >>> staff.context_name = 'RhythmicStaff' >>> time_signature = TimeSignature((4, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new RhythmicStaff { \time 4/4 c'8. r8. c'4 ~ c'16 r4 r16 } .. container:: example **Example 2.** Increases durations monotonically: :: >>> leaves = scoretools.make_leaves_from_talea( ... [3, -3, 5, -5], 16, ... decrease_durations_monotonically=False, ... ) >>> staff = Staff(leaves) >>> staff.context_name = 'RhythmicStaff' >>> time_signature = TimeSignature((4, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new RhythmicStaff { \time 4/4 c'8. r8. c'16 ~ c'4 r16 r4 } .. container:: example **Example 3.** Forbids written durations greater than or equal to a half note: :: >>> leaves = scoretools.make_leaves_from_talea( ... [3, -3, 5, -5], 16, ... forbidden_written_duration=Duration(1, 4), ... ) >>> staff = Staff(leaves) >>> staff.context_name = 'RhythmicStaff' >>> time_signature = TimeSignature((4, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new RhythmicStaff { \time 4/4 c'8. r8. c'8 ~ c'8 ~ c'16 r8 r8 r16 } .. container:: example **Example 4.** Spells unassignable durations metrically: :: >>> leaves = scoretools.make_leaves_from_talea( ... [3, -3, 5, -5], 16, ... spell_metrically='unassignable', ... ) >>> staff = Staff(leaves) >>> staff.context_name = 'RhythmicStaff' >>> time_signature = TimeSignature((4, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new RhythmicStaff { \time 4/4 c'8. r8. c'8. ~ c'8 r8. r8 } .. container:: example **Example 5.** Uses Messiaen-style ties: :: >>> leaves = scoretools.make_leaves_from_talea( ... [5, 9], 8, ... spell_metrically='unassignable', ... use_messiaen_style_ties=True, ... ) >>> staff = Staff(leaves) >>> staff.context_name = 'RhythmicStaff' >>> time_signature = TimeSignature((4, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new RhythmicStaff { \time 4/4 c'4. c'4 \repeatTie c'4. c'4. \repeatTie c'4. \repeatTie } Returns selection. ''' from abjad.tools import metertools from abjad.tools import scoretools from abjad.tools import spannertools assert all(x != 0 for x in talea), repr(talea) result = [] for note_value in talea: if 0 < note_value: pitches = [0] else: pitches = [None] division = durationtools.Duration( abs(note_value), talea_denominator, ) if (spell_metrically is True or (spell_metrically == 'unassignable' and not mathtools.is_assignable_integer(division.numerator))): meter = metertools.Meter(division) rhythm_tree_container = meter.root_node durations = [_.duration for _ in rhythm_tree_container] else: durations = [division] leaves = scoretools.make_leaves( pitches, durations, decrease_durations_monotonically=decrease_durations_monotonically, forbidden_written_duration=forbidden_written_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) if (1 < len(leaves) and not leaves[0]._has_spanner(spannertools.Tie) and not isinstance(leaves[0], scoretools.Rest)): tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, leaves[:]) result.extend(leaves) result = selectiontools.Selection(result) return result