def durate_pitch_contour_reservoir(pitch_contour_reservoir): """ Durates pitch contour reservoir. """ names = ["First Violin", "Second Violin", "Viola", "Cello", "Bass"] durated_reservoir = {} for i, name in enumerate(names): long_duration = abjad.Duration(1, 2) * pow(2, i) short_duration = long_duration / 2 rest_duration = long_duration * abjad.Multiplier(3, 2) div = rest_duration // abjad.Duration(3, 2) mod = rest_duration % abjad.Duration(3, 2) initial_rest = abjad.MultimeasureRest((3, 2)) * div maker = abjad.LeafMaker() if mod: initial_rest += maker([None], mod) durated_contours = [tuple(initial_rest)] pitch_contours = pitch_contour_reservoir[name] durations = [long_duration, short_duration] counter = 0 maker = abjad.LeafMaker() for pitch_contour in pitch_contours: contour = [] for pitch in pitch_contour: leaves = maker([pitch], [durations[counter]]) contour.extend(leaves) counter = (counter + 1) % 2 durated_contours.append(tuple(contour)) durated_reservoir[name] = tuple(durated_contours) return durated_reservoir
def _make_measure( self, attack_points, pitches, ) -> None: r"""Converts a list of pitch and attack point individuals into a measure of music. """ dummy_container = abjad.Container() sorted_attack_points, sorted_pitches = self._sort_by_attack_point( attack_points[:], pitches[:], ) if not self._attack_points_mode: durations, pitches = self._convert_attack_points_to_durations( sorted_attack_points, sorted_pitches, ) notes = abjad.LeafMaker()( pitches, durations, ) dummy_container = abjad.Container(notes) else: notes = abjad.Selection() for i in range(self._units_per_window): if i in sorted_attack_points: pitch_index = sorted_attack_points.index(i) notes += abjad.LeafMaker()( [sorted_pitches[pitch_index]], [self._duration_unit], ) else: rest = abjad.Rest(self._duration_unit) notes += abjad.select(rest).leaves() dummy_container = abjad.Container(notes) # adding time signature if not self._omit_time_signature: if self._time_signatures is None: time_signature = abjad.TimeSignature((self._total_duration)) time_signature.simplify_ratio() abjad.attach( time_signature, dummy_container[0], ) mutate.auto_rewrite_meter(dummy_container) else: mutate.enforce_time_signature( dummy_container, self._time_signatures, ) return dummy_container[:]
def _make_basic_rhythm(self, time_signature_pairs, counts, denominator): """ Make a basic rhythm using ``time_signature_pairs``, ``counts`` and ``denominator``. """ total_duration = sum( abjad.Duration(pair) for pair in time_signature_pairs) talea = abjadext.rmakers.Talea( counts=counts, denominator=denominator, ) talea_index = 0 all_leaves = [] current_duration = abjad.Duration(0) while current_duration < total_duration: leaf_duration = talea[talea_index] if leaf_duration > 0: pitch = abjad.NamedPitch("c'") else: pitch = None leaf_duration = abs(leaf_duration) if (leaf_duration + current_duration) > total_duration: leaf_duration = total_duration - current_duration current_leaves = abjad.LeafMaker()([pitch], [leaf_duration]) all_leaves.extend(current_leaves) current_duration += leaf_duration talea_index += 1 music = abjad.Container(all_leaves) return music
def test_LilyPondParser__functions__relative_04(): maker = abjad.LeafMaker() pitches = [ ["a'", "c''", "e''"], ["f'", "a'", "c''"], ["a'", "c''", "e''"], ["f''", "a''", "c'''"], ["b", "b'", "e''"], ] leaves = maker(pitches, 1) target = abjad.Container(leaves) assert abjad.lilypond(target) == abjad.String.normalize(r""" { <a' c'' e''>1 <f' a' c''>1 <a' c'' e''>1 <f'' a'' c'''>1 <b b' e''>1 } """) string = r"""\relative c'' { <a c e>1 <f a c> <a c e> <f' a c> <b, e b,> }""" parser = abjad.parser.LilyPondParser() result = parser(string) assert abjad.lilypond(target) == abjad.lilypond( result) and target is not result
def calc_anchor(self): durs = [self.leaf.written_duration, self.anchor_dur] container = abjad.Container() pre_mult = self.leaf.written_duration - self.anchor_dur mult = pre_mult / self.leaf.written_duration if isinstance(self.leaf, abjad.Chord): pitches = [ abjad.NamedPitch(_) for _ in abjad.get.pitches(self.leaf) ] elif isinstance(self.leaf, abjad.Note): pitches = [ abjad.NamedPitch(_) for _ in abjad.get.pitches(self.leaf) ] pitches = pitches[0] else: pass maker = abjad.LeafMaker() new_leaves = [list_ for list_ in maker([pitches], durs)] indicators = abjad.get.indicators(self.leaf) for indicator in indicators: abjad.attach(indicator, new_leaves[0][0]) self.leaf.multiplier = mult abjad.attach( abjad.LilyPondLiteral(r"""\abjad-invisible-music""", format_slot="before"), new_leaves[1], ) abjad.annotate(new_leaves[1], "type", "spanner anchor") container.extend(new_leaves) return container
def _make_skips(self, current_stage): time_signatures = flatten_list(self._time_signatures[current_stage]) voice = abjad.Voice() skip_maker = abjad.LeafMaker(skips_instead_of_rests=True) for time_signature in time_signatures: skips = skip_maker(None, [time_signature]) voice.extend(skips) return voice
def abjad_format(self, duration=(4, 4)): maker = abjad.LeafMaker() duration = abjad.Duration(duration) selection = maker([tuple(self._pitches)], duration) chord = selection[0] markup = self._gen_markup_string() abjad.attach(markup, chord) return chord
def _flatten_trivial_tuplets(self, voice): for tuplet in abjad.iterate(voice).by_class(abjad.Tuplet): if len(tuplet) is 1: if isinstance(tuplet[0], (abjad.Rest, abjad.Skip)): pitch = None else: pitch = 0 duration = tuplet.multiplied_duration maker = abjad.LeafMaker() leaf = maker(pitch, duration) abjad.mutate([tuplet]).replace(leaf)
def _apply_pitches(self, selections, pitches): leaf_maker = abjad.LeafMaker() container = abjad.Container(selections) old_ties = [tie for tie in abjad.iterate( container).logical_ties(pitched=True)] pitches, durations, old_leaves = self._collect_pitches_durations_leaves( old_ties, pitches) new_leaves = [leaf for leaf in leaf_maker(pitches, durations)] for old_leaf, new_leaf in zip(old_leaves, new_leaves): parent = abjad.inspect(old_leaf).parentage().parent parent[parent.index(old_leaf)] = new_leaf return [container[:]]
def make_spacer_skip_measures(time_signatures): """Makes spacer skip measures. Returns a list. """ maker = abjad.LeafMaker(skips_instead_of_rests=True) measures = [] for time_signature in time_signatures: leaves = maker(None, [time_signature]) measure = abjad.Measure(time_signature, leaves) measures.append(measure) return measures
def _apply_division_masks(self, selections): import abjad from abjad.tools import rhythmmakertools if not self.division_masks: return selections new_selections = [] duration_specifier = self._get_duration_specifier() decrease_monotonic = duration_specifier.decrease_monotonic forbidden_duration = duration_specifier.forbidden_duration tie_specifier = self._get_tie_specifier() total_divisions = len(selections) division_masks = self.division_masks leaf_maker = abjad.LeafMaker( decrease_monotonic=decrease_monotonic, forbidden_duration=forbidden_duration, repeat_ties=tie_specifier.repeat_ties, ) previous_divisions_consumed = self._previous_divisions_consumed() for i, selection in enumerate(selections): matching_division_mask = division_masks.get_matching_pattern( i + previous_divisions_consumed, total_divisions + previous_divisions_consumed, rotation=self.previous_state.get('rotation'), ) if not matching_division_mask: new_selections.append(selection) continue duration = abjad.inspect(selection).get_duration() if isinstance( matching_division_mask, rhythmmakertools.SustainMask, ): leaf_maker = abjad.new( leaf_maker, use_multimeasure_rests=False, ) new_selection = leaf_maker([0], [duration]) else: use_multimeasure_rests = getattr( matching_division_mask, 'use_multimeasure_rests', False, ) leaf_maker = abjad.new( leaf_maker, use_multimeasure_rests=use_multimeasure_rests, ) new_selection = leaf_maker([None], [duration]) for component in abjad.iterate(selection).components(): abjad.detach(abjad.Tie, component) new_selections.append(new_selection) return new_selections
def _apply_pitches(self, selections, pitches): leaf_maker = abjad.LeafMaker() container = abjad.Container(selections) old_ties = [tie for tie in abjad.iterate(container).logical_ties()] pitches, durations, old_leaves = self._collect_pitches_durations_leaves( old_ties, pitches) new_leaves = [leaf for leaf in leaf_maker(pitches, durations)] for old_leaf, new_leaf in zip(old_leaves, new_leaves): indicators = abjad.get.indicators(old_leaf) for indicator in indicators: abjad.attach(indicator, new_leaf) parent = abjad.get.parentage(old_leaf).parent parent[parent.index(old_leaf)] = new_leaf return [container[:]]
def __call__(self, pulse_duration): r'''Generate Abjad score components: >>> leaf = abjad.rhythmtreetools.RhythmTreeLeaf(5) >>> leaf((1, 4)) Selection([Note("c'1"), Note("c'4")]) Returns sequence of components. ''' import abjad pulse_duration = abjad.Duration(pulse_duration) total_duration = pulse_duration * self.preprolated_duration maker = abjad.LeafMaker() if self.is_pitched: return maker(0, total_duration) return maker([None], total_duration)
def make_voices(self, phrases, durations): """Returns a list of named voices""" maker = abjad.LeafMaker() leaves = [] name = 'a' # going to create first named voice with this character for phrase in phrases: #print("Pitch, Duration: ", phrases, durations) leaf = maker(phrase, durations) #print("leaf: ", leaf) leaves.append(leaf) voice = self._create_voice(leaf, name) x = chr(ord(name) + 1) # unique name for voice name = x #print("voice after one iteration: ", voice) #for voice in self._voices: # abjad.f(voice) return self._voices
def _make_music(self, divisions): import abjad from abjad.tools import rhythmmakertools selections = [] duration_specifier = self._get_duration_specifier() tie_specifier = self._get_tie_specifier() tuplet_specifier = self._get_tuplet_specifier() leaf_maker = abjad.LeafMaker( decrease_monotonic=duration_specifier.decrease_monotonic, forbidden_duration=duration_specifier.forbidden_duration, diminution=tuplet_specifier.diminution, repeat_ties=tie_specifier.repeat_ties, ) for division in divisions: if (duration_specifier.spell_metrically is True or (duration_specifier.spell_metrically == 'unassignable' and not abjad.mathtools.is_assignable_integer( division.numerator))): meter = abjad.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 = leaf_maker(pitches=0, durations=durations) if (1 < len(selection) and not selection[0]._has_spanner(abjad.Tie)): tie = abjad.Tie(repeat=tie_specifier.repeat_ties) abjad.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) if duration_specifier.rewrite_meter: selections = duration_specifier._rewrite_meter_( selections, divisions, repeat_ties=tie_specifier.repeat_ties, ) return selections
def _rewrite_rest_filled_(self, selections): import abjad if not self.rewrite_rest_filled: return selections selections_ = [] maker = abjad.LeafMaker() for selection in selections: selection_ = [] for component in selection: if not (isinstance(component, abjad.Tuplet) and component._rest_filled()): selection_.append(component) continue duration = abjad.inspect(component).get_duration() rests = maker([None], [duration]) abjad.mutate(component[:]).replace(rests) component.multiplier = abjad.Multiplier(1) selection_.append(component) selection_ = abjad.select(selection_) selections_.append(selection_) return selections_
def make_basic_rhythm(time_signature_pairs, counts, denominator): # THIS IS HOW WE MAKE THE BASIC RHYTHM total_duration = sum(abjad.Duration(pair) for pair in time_signature_pairs) talea = abjadext.rmakers.Talea(counts=counts, denominator=denominator) talea_index = 0 all_leaves = [] current_duration = abjad.Duration(0) while current_duration < total_duration: leaf_duration = talea[talea_index] if leaf_duration > 0: pitch = abjad.NamedPitch("c'") else: pitch = None leaf_duration = abs(leaf_duration) if (leaf_duration + current_duration) > total_duration: leaf_duration = total_duration - current_duration current_leaves = abjad.LeafMaker()([pitch], [leaf_duration]) all_leaves.extend(current_leaves) current_duration += leaf_duration talea_index += 1 music = abjad.Container(all_leaves) return music
def sustain_notes( container: abjad.Container, *, sustain_multimeasure_rests: bool = True, rewrite_meter: bool = True, ) -> None: r"""Mutates an input container (of type |abjad.Container| or child class) in place and has no return value; this function will sustain all pitched leaves until the next pitched leaf, thus replacing all rests in between them. Basic usage: Simply call the function on a container. >>> staff = abjad.Staff(r"c'16 r8. d'16 r8. e'16 r8. f'16 r8.") >>> abjad.f(staff) \new Staff { c'16 r8. d'16 r8. e'16 r8. f'16 r8. } .. figure:: ../_images/sustain_notes-w1e1pmruyce.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { c'4 d'4 e'4 f'4 } .. figure:: ../_images/sustain_notes-ythfpvkrvue.png .. note:: Auxjad automatically adds this function as an extension method to |abjad.mutate()|. It can thus be used from either :func:`auxjad.mutate()` or |abjad.mutate()|. Therefore, the two lines below are equivalent: >>> auxjad.mutate(staff).close_containers() >>> abjad.mutate(staff).close_containers() Leaves with same pitch: Leaves are sustained until the next pitched leaf, even if the pitch is the same. >>> staff = abjad.Staff(r"c'16 r8. c'16 r8. c'16 r8. c'16 r8.") >>> abjad.f(staff) \new Staff { c'16 r8. c'16 r8. c'16 r8. c'16 r8. } .. figure:: ../_images/sustain_notes-oliqicqqw7q.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { c'4 c'4 c'4 c'4 } .. figure:: ../_images/sustain_notes-3alcbmhc2jt.png Consecutive leaves with the same pitch: Consecutive pitched leaves with a same pitch will not be tied. >>> staff = abjad.Staff( ... r"<c' e'>16 r8. <c' e'>4 <c' e'>4 <c' e'>16 r8." ... ) >>> abjad.f(staff) \new Staff { <c' e'>16 r8. <c' e'>4 <c' e'>4 <c' e'>16 r8. } .. figure:: ../_images/sustain_notes-ek4ujjintt8.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { <c' e'>4 <c' e'>4 <c' e'>4 <c' e'>4 } .. figure:: ../_images/sustain_notes-f7au6hojq99.png Tuplets: This function handles tuplets. >>> staff = abjad.Staff( ... r"\times 2/3 {c'4 d'4 r4} r8 e'8 \times 2/3 {f'8 r4}" ... ) >>> abjad.f(staff) \new Staff { \times 2/3 { c'4 d'4 r4 } r8 e'8 \times 2/3 { f'8 r4 } } .. figure:: ../_images/sustain_notes-nsjvhnyrkea.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { \times 2/3 { c'4 d'2 ~ } d'8 e'8 f'4 } .. figure:: ../_images/sustain_notes-26l9hob8wko.png Complex example: This function can handle containers with a mixture of notes, chords, and rests, as well as tuplets. >>> staff = abjad.Staff(r"c'16 r8. d'16 r8. r8 r32 <e' g'>32 r16 r4 " ... r"\times 2/3 {r4 f'4 r4} r4 g'8 r8 a'4 ~ " ... r"a'16 r8. b'4 c''8 r8 " ... r"r4. d''8 \times 4/5 {r8 d''2}" ... ) >>> abjad.f(staff) \new Staff { c'16 r8. d'16 r8. r8 r32 <e' g'>32 r16 r4 \times 2/3 { r4 f'4 r4 } r4 g'8 r8 a'4 ~ a'16 r8. b'4 c''8 r8 r4. d''8 \times 4/5 { r8 d''2 } } .. figure:: ../_images/sustain_notes-cpw7dvpegge.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { c'4 d'4 ~ d'8 ~ d'32 <e' g'>16. ~ <e' g'>4 ~ \times 2/3 { <e' g'>4 f'2 ~ } f'4 g'4 a'2 b'4 c''4 ~ c''4. d''8 ~ \times 4/5 { d''8 d''2 } } .. figure:: ../_images/sustain_notes-z8t2jwxsvar.png Multi-measure rests: This mutation also handles multi-measure rests, including ones with non-assignable durations: >>> staff = abjad.Staff(r"r4 c'16 r8. d'16 r4.. " ... r"R1" ... r"r4 e'4 r2" ... r"\time 5/8 r8 f'4 r4" ... r"R1 * 5/8 " ... r"r8 g'8 a'8 r4" ... ) >>> abjad.f(staff) \new Staff { r4 c'16 r8. d'16 r4.. R1 r4 e'4 r2 \time 5/8 r8 f'4 r4 R1 * 5/8 r8 g'8 a'8 r4 } .. figure:: ../_images/sustain_notes-mJOOARIUAp.png >>> auxjad.mutate(staff).sustain_notes() >>> abjad.f(staff) \new Staff { r4 c'4 d'2 ~ d'1 ~ d'4 e'2. ~ \time 5/8 e'8 f'2 ~ f'4. ~ f'4 f'8 g'4 a'4 } .. figure:: ../_images/sustain_notes-iLTiWERSvO.png ``sustain_multimeasure_rests``: By default, notes are tied across multi-measure rests. >>> staff = abjad.Staff(r"r4 c'16 r8. d'16 r4.. " ... r"R1" ... r"r4 e'4 r2" ... r"\time 5/8 r8 f'4 r4" ... r"R1 * 5/8 " ... r"r8 g'8 a'8 r4" ... ) >>> abjad.f(staff) \new Staff { r4 c'16 r8. d'16 r4.. R1 r4 e'4 r2 \time 5/8 r8 f'4 r4 R1 * 5/8 r8 g'8 a'8 r4 } .. figure:: ../_images/sustain_notes-P2CLdKi6Cs.png To disable sustaining across those, set ``sustain_multimeasure_rests`` to ``False``: >>> auxjad.mutate(staff).sustain_notes(sustain_multimeasure_rests=True) >>> abjad.f(staff) \new Staff { r4 c'4 d'2 R1 r4 e'2. ~ \time 5/8 e'8 f'2 R1 * 5/8 r8 g'8 a'4. } .. figure:: ../_images/sustain_notes-9WeilArLex.png ``rewrite_meter``: By default, |auxjad.mutate().auto_rewrite_meter()| is summoned after notes are sustained. >>> staff = abjad.Staff(r"r4 c'16 r8. d'16 r4.. " ... r"R1" ... r"r4 e'4 r2" ... r"\time 5/8 r8 f'4 r4" ... r"R1 * 5/8 " ... r"r8 g'8 a'8 r4" ... ) >>> abjad.f(staff) \new Staff { r4 c'16 r8. d'16 r4.. R1 r4 e'4 r2 \time 5/8 r8 f'4 r4 R1 * 5/8 r8 g'8 a'8 r4 } .. figure:: ../_images/sustain_notes-P2CLdKi6Cs.png To disable this behaviour, set ``rewrite_meter`` to ``False``: >>> auxjad.mutate(staff).sustain_notes(rewrite_meter=False) >>> abjad.f(staff) \new Staff { r4 c'16 ~ c'8. d'16 ~ d'4.. ~ d'1 ~ d'4 e'4 ~ e'2 ~ \time 5/8 e'8 f'4 ~ f'4 ~ f'2 ~ f'8 f'8 g'8 ~ a'8 a'4 } .. figure:: ../_images/sustain_notes-9WeilArLex.png .. warning:: The input container must be a contiguous logical voice. When dealing with a container with multiple subcontainers (e.g. a score containing multiple staves), the best approach is to cycle through these subcontainers, applying this function to them individually. """ if not isinstance(container, abjad.Container): raise TypeError("argument must be 'abjad.Container' or child class") if not abjad.select(container).leaves().are_contiguous_logical_voice(): raise ValueError("argument must be contiguous logical voice") if not isinstance(sustain_multimeasure_rests, bool): raise TypeError("'sustain_multimeasure_rests' must be 'bool'") if not isinstance(rewrite_meter, bool): raise TypeError("'rewrite_meter' must be 'bool'") leaves = abjad.select(container).leaves() pitch = None pitches = None for index, leaf in enumerate(leaves): if isinstance(leaf, (abjad.Rest, abjad.MultimeasureRest)): if isinstance(leaf, abjad.MultimeasureRest): if not sustain_multimeasure_rests: pitch = None pitches = None continue duration = abjad.inspect(leaf).duration() else: duration = leaf.written_duration if pitch is not None: replacement_leaf = abjad.LeafMaker()(pitch, duration) elif pitches is not None: replacement_leaf = abjad.LeafMaker()([pitches], [duration]) if pitch is not None or pitches is not None: for indicator in abjad.inspect(leaf).indicators(): abjad.attach( indicator, abjad.select(replacement_leaf).leaf(0), ) abjad.mutate(leaf).replace(replacement_leaf) previous_leaf = abjad.select(container).leaves()[index - 1] if abjad.inspect(previous_leaf).indicator(abjad.Tie) is None: if not isinstance(previous_leaf, abjad.MultimeasureRest): abjad.attach(abjad.Tie(), previous_leaf) elif isinstance(leaf, abjad.Note): pitch = leaf.written_pitch pitches = None elif isinstance(leaf, abjad.Chord): pitch = None pitches = [pitch for pitch in leaf.written_pitches] # rewriting meter if rewrite_meter: auto_rewrite_meter(container)
# else: # # note = abjad.Leaf(note, (1, 1)) # F_staff.append(abjad.Note.from_pitch_and_duration(note, (1, 1))) # abjad.attach(abjad.Clef("treble^8"), G_staff[0]) # abjad.attach(abjad.Clef("bass_8"), F_staff[0]) # staff = abjad.StaffGroup([G_staff, F_staff], lilypond_type="PianoStaff") # abjad.f(staff) # NO MICROTONAL for item, i in zip(num_pitches, range(len(num_pitches))): if isinstance(item, float): item = item - 0.5 num_pitches[i] = item # num_pitches.sort() maker = abjad.LeafMaker() num_pitches_notes = maker(num_pitches, (1, 1)) num_pitches_notes = abjad.Staff(num_pitches_notes) num_pitches_score = abjad.LilyPondFile.new(music=num_pitches_notes) abjad.f(num_pitches_score) pitches_up = [] pitches_down = [] pitch_range = abjad.PitchRange("[C2, G7]") treble_range = abjad.pitch.PitchRange("[C4, +inf]") for note in num_pitches: test1 = note in pitch_range test2 = note in treble_range if test1 is True and test2 is True: pitches_up.append(note) if test1 is True and test2 is False:
def to_score_markup(self): r""" Changes duration to score markup. .. container:: example Changes assignable duration to score markup: >>> markup = abjad.Duration(3, 16).to_score_markup() >>> abjad.show(markup) # doctest: +SKIP .. docs:: >>> abjad.f(markup) \markup { \score { \new Score \with { \override SpacingSpanner.spacing-increment = #0.5 proportionalNotationDuration = ##f } << \new RhythmicStaff \with { \remove Time_signature_engraver \remove Staff_symbol_engraver \override Stem.direction = #up \override Stem.length = #5 \override TupletBracket.bracket-visibility = ##t \override TupletBracket.direction = #up \override TupletBracket.minimum-length = #4 \override TupletBracket.padding = #1.25 \override TupletBracket.shorten-pair = #'(-1 . -1.5) \override TupletBracket.springs-and-rods = #ly:spanner::set-spacing-rods \override TupletNumber.font-size = #0 \override TupletNumber.text = #tuplet-number::calc-fraction-text tupletFullLength = ##t } { c'8. } >> \layout { indent = #0 ragged-right = ##t } } } .. container:: example Changes nonassignable duration to score markup: >>> markup = abjad.Duration(5, 16).to_score_markup() >>> abjad.show(markup) # doctest: +SKIP .. docs:: >>> abjad.f(markup) \markup { \score { \new Score \with { \override SpacingSpanner.spacing-increment = #0.5 proportionalNotationDuration = ##f } << \new RhythmicStaff \with { \remove Time_signature_engraver \remove Staff_symbol_engraver \override Stem.direction = #up \override Stem.length = #5 \override TupletBracket.bracket-visibility = ##t \override TupletBracket.direction = #up \override TupletBracket.minimum-length = #4 \override TupletBracket.padding = #1.25 \override TupletBracket.shorten-pair = #'(-1 . -1.5) \override TupletBracket.springs-and-rods = #ly:spanner::set-spacing-rods \override TupletNumber.font-size = #0 \override TupletNumber.text = #tuplet-number::calc-fraction-text tupletFullLength = ##t } { c'4 ~ c'16 } >> \layout { indent = #0 ragged-right = ##t } } } .. container:: example Override tuplet number text like this: >>> tuplet = abjad.Tuplet((5, 7), "c'16 c' c' c' c' c' c'") >>> abjad.attach(abjad.Beam(), tuplet[:]) >>> staff = abjad.Staff([tuplet], lilypond_type='RhythmicStaff') >>> duration = abjad.inspect(tuplet).duration() >>> markup = duration.to_score_markup() >>> markup = markup.scale((0.75, 0.75)) >>> abjad.override(tuplet).tuplet_number.text = markup >>> abjad.show(staff) # doctest: +SKIP .. docs:: >>> abjad.f(staff) \new RhythmicStaff { \override TupletNumber.text = \markup { \scale #'(0.75 . 0.75) \score { \new Score \with { \override SpacingSpanner.spacing-increment = #0.5 proportionalNotationDuration = ##f } << \new RhythmicStaff \with { \remove Time_signature_engraver \remove Staff_symbol_engraver \override Stem.direction = #up \override Stem.length = #5 \override TupletBracket.bracket-visibility = ##t \override TupletBracket.direction = #up \override TupletBracket.minimum-length = #4 \override TupletBracket.padding = #1.25 \override TupletBracket.shorten-pair = #'(-1 . -1.5) \override TupletBracket.springs-and-rods = #ly:spanner::set-spacing-rods \override TupletNumber.font-size = #0 \override TupletNumber.text = #tuplet-number::calc-fraction-text tupletFullLength = ##t } { c'4 ~ c'16 } >> \layout { indent = #0 ragged-right = ##t } } } \times 5/7 { c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 ] } \revert TupletNumber.text } Returns markup. """ import abjad maker = abjad.LeafMaker() notes = maker([0], [self]) markup = self._to_score_markup(notes) return markup
def sync_containers(containers: Union[Iterable[abjad.Container], abjad.Score, ], *, use_multimeasure_rests: bool = True, adjust_last_time_signature: bool = True, ) -> None: r"""Mutates two or more input containers in place and has no return value; this function finds the longest container among the inputs and adds rests to all the shorter ones, making them the same length. Input argument can be a single |abjad.Score| with multiple containers, or an iterable with elements of type |abjad.Container| or child classes. Basic usage: Input two or more containers. This function will fill the shortest ones with rests ensuring all their lengths become the same. >>> staff1 = abjad.Staff(r"\time 4/4 g'2.") >>> staff2 = abjad.Staff(r"\time 4/4 c'1") >>> abjad.show(staff1) .. docs:: \new Staff { \time 4/4 g'2. } .. figure:: ../_images/sync_containers-H7jNwGEtFQ.png >>> abjad.show(staff2) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-EjKqQCinPy.png >>> auxjad.mutate.sync_containers([staff1, staff2]) >>> abjad.show(staff1) .. docs:: \new Staff { \time 4/4 g'2. r4 } .. figure:: ../_images/sync_containers-akcdf8t9e5.png >>> abjad.show(staff2) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-l7tru1tjoli.png .. note:: Auxjad automatically adds this function as an extension function to |abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or |abjad.mutate| namespaces. Therefore, the two lines below are equivalent: >>> auxjad.mutate.sync_containers([container1, container2]) >>> abjad.mutate.sync_containers([container1, container2]) .. note:: When using |abjad.Container|'s, all time signatures in the output will be commented out with ``%%%.`` This is because Abjad only applies time signatures to containers that belong to a |abjad.Staff|. The present function works with either |abjad.Container| and |abjad.Staff|. >>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4") >>> abjad.show(container) .. docs:: { %%% \time 3/4 %%% c'4 d'4 e'4 } .. figure:: ../_images/sync_containers-9sl3dnd2uwn.png >>> staff = abjad.Staff([container]) >>> abjad.show(container) .. docs:: { \time 3/4 c'4 d'4 e'4 } .. figure:: ../_images/sync_containers-08v2pv2tmqqn.png Containers of same size: If all containers have the same size, no modification is applied. >>> container1 = abjad.Staff(r"\time 3/4 g'2.") >>> container2 = abjad.Staff(r"\time 3/4 c'2.") >>> auxjad.mutate.sync_containers([container1, container2]) >>> abjad.show(container1) .. docs:: \new Staff { \time 3/4 g'2. } .. figure:: ../_images/sync_containers-e0yszxejbh.png >>> abjad.show(container2) .. docs:: \new Staff { \time 3/4 c'2. } .. figure:: ../_images/sync_containers-2cgt4zds3h7.png Underfull containers: By default, this function closes the longest container by rewriting the time signature of its last measure if necessary (if it is underfull), and uses multi-measure rests whenever possible. >>> container1 = abjad.Staff(r"\time 4/4 g'1 | f'4") >>> container2 = abjad.Staff(r"\time 4/4 c'1") >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 f'4 } .. figure:: ../_images/sync_containers-udnAjAZtkw.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-cy8dL4UUWV.png >>> auxjad.mutate.sync_containers([container1, container2]) >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 \time 1/4 f'4 } .. figure:: ../_images/sync_containers-nztndgecrof.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 \time 1/4 R1 * 1/4 } .. figure:: ../_images/sync_containers-iaag195ty1d.png ``adjust_last_time_signature``: To allow containers to be left open (with underfull measures), set the keyword argument ``adjust_last_time_signature`` to ``False``. >>> container1 = abjad.Staff(r"\time 4/4 g'1 | f'4") >>> container2 = abjad.Staff(r"\time 4/4 c'1") >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 f'4 } .. figure:: ../_images/sync_containers-uldd5Vni8a.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-eTCrjHBr39.png >>> auxjad.mutate.sync_containers( ... [container1, container2], ... adjust_last_time_signature=False, ... ) >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 f'4 } .. figure:: ../_images/sync_containers-37iesjp4dqs.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 r4 } .. figure:: ../_images/sync_containers-lqm4itxlwu.png ``use_multimeasure_rests``: To disable multi-measure rests, set the keyword argument ``use_multimeasure_rests`` to ``False``. >>> container1 = abjad.Staff(r"\time 4/4 g'1 | f'4") >>> container2 = abjad.Staff(r"\time 4/4 c'1") >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 \time 1/4 f'4 } .. figure:: ../_images/sync_containers-Mbmjf7JLH8.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-3RZwROEIt1.png >>> auxjad.mutate.sync_containers( ... [container1, container2], ... use_multimeasure_rests=False, ... ) >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 g'1 \time 1/4 f'4 } .. figure:: ../_images/sync_containers-rhagiugx42o.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 \time 1/4 r4 } .. figure:: ../_images/sync_containers-oss03t1qnf8.png Adjusting last time signatures: When adjusting the last time signature, this function will maintain the same time effective signature for as long as possible and only add a new one at the last measure if its duration is shorter. >>> container1 = abjad.Staff(r"\time 7/4 a'1 ~ a'2.") >>> container2 = abjad.Staff(r"\time 3/4 c'2.") >>> abjad.show(container1) .. docs:: \new Staff { \time 7/4 a'1 ~ a'2. } .. figure:: ../_images/sync_containers-g61gTyfZGV.png >>> abjad.show(container2) .. docs:: \new Staff { \time 3/4 c'2. } .. figure:: ../_images/sync_containers-UZvmef5N16.png >>> auxjad.mutate.sync_containers([container1, container2]) >>> abjad.show(container1) .. docs:: \new Staff { \time 7/4 a'1 ~ a'2. } .. figure:: ../_images/sync_containers-dQnq2ASkTu.png >>> abjad.show(container2) .. docs:: \new Staff { \time 3/4 c'2. R1 * 3/4 \time 1/4 R1 * 1/4 } .. figure:: ../_images/sync_containers-jhx0r9skgwi.png Multiple input containers: This function can take an arbitrary number of containers. >>> container1 = abjad.Staff(r"\time 4/4 c'1 | g'4") >>> container2 = abjad.Staff(r"\time 4/4 c'1 | g'2") >>> container3 = abjad.Staff(r"\time 4/4 c'1 | g'2.") >>> container4 = abjad.Staff(r"\time 4/4 c'1") >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 c'1 g'4 } .. figure:: ../_images/sync_containers-epvaWYPYT7.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 g'2 } .. figure:: ../_images/sync_containers-Yja5mx93Fi.png >>> abjad.show(container3) .. docs:: \new Staff { \time 4/4 c'1 g'2. } .. figure:: ../_images/sync_containers-GTtAEELheA.png >>> abjad.show(container4) .. docs:: \new Staff { \time 4/4 c'1 } .. figure:: ../_images/sync_containers-VCFpuJX7ID.png >>> containers = [container1, ... container2, ... container3, ... container4, ... ] >>> auxjad.mutate.sync_containers(containers) >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 c'1 \time 3/4 g'4 r2 } .. figure:: ../_images/sync_containers-1wbsyvks33r.png >>> abjad.show(container2) .. docs:: \new Staff { \time 4/4 c'1 \time 3/4 g'2 r4 } .. figure:: ../_images/sync_containers-td1whqky24b.png >>> abjad.show(container3) .. docs:: \new Staff { \time 4/4 c'1 \time 3/4 g'2. } .. figure:: ../_images/sync_containers-g07scyil9jh.png >>> abjad.show(container4) .. docs:: \new Staff { \time 4/4 c'1 \time 3/4 R1 * 3/4 } .. figure:: ../_images/sync_containers-8b6vn3azaom.png Single input |abjad.Score|: This function can also take a single |abjad.Score| instead of multiple |abjad.Container|'s or |abjad.Staff|'s. >>> staff1 = abjad.Staff(r"\time 3/8 c'4. | d'4") >>> staff2 = abjad.Staff(r"\time 3/8 c'4. | d'8") >>> staff3 = abjad.Staff(r"\time 3/8 c'4. | d'16") >>> staff4 = abjad.Staff(r"\time 3/8 c'4.") >>> score = abjad.Score([staff1, ... staff2, ... staff3, ... staff4, ... ]) >>> auxjad.mutate.sync_containers(score) >>> abjad.show(score) .. docs:: \new Score << \new Staff { \time 3/8 c'4. \time 1/4 d'4 } \new Staff { \time 3/8 c'4. \time 1/4 d'8 r8 } \new Staff { \time 3/8 c'4. \time 1/4 d'16 r8. } \new Staff { \time 3/8 c'4. \time 1/4 R1 * 1/4 } >> .. figure:: ../_images/sync_containers-0g0651fs0luq.png Time signature changes: The containers can be of different length, can have different time signatures, and can contain time signature changes as well. >>> container1 = abjad.Staff(r"\time 4/4 c'4 d'4 e'4 f'4") >>> container2 = abjad.Staff(r"\time 3/4 a2. \time 4/4 c'4") >>> container3 = abjad.Staff(r"\time 5/4 g''1 ~ g''4") >>> container4 = abjad.Staff(r"\time 6/8 c'2") >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 c'4 d'4 e'4 f'4 } .. figure:: ../_images/sync_containers-qAt4FSyAIl.png >>> abjad.show(container2) .. docs:: \new Staff { \time 3/4 a2. \time 4/4 c'4 } .. figure:: ../_images/sync_containers-EKrqsCDVNs.png >>> abjad.show(container3) .. docs:: \new Staff { \time 5/4 g''1 ~ g''4 } .. figure:: ../_images/sync_containers-lw5fknvt4o.png >>> abjad.show(container4) .. docs:: \new Staff { \time 6/8 c'2 } .. figure:: ../_images/sync_containers-iXGajGKBZl.png >>> containers = [container1, ... container2, ... container3, ... container4, ... ] >>> auxjad.mutate.sync_containers(containers) >>> abjad.show(container1) .. docs:: \new Staff { \time 4/4 c'4 d'4 e'4 f'4 \time 1/4 R1 * 1/4 } .. figure:: ../_images/sync_containers-mec52wgbrz9.png >>> abjad.show(container2) .. docs:: \new Staff { \time 3/4 a2. \time 2/4 c'4 r4 } .. figure:: ../_images/sync_containers-33odhzqyo6r.png >>> abjad.show(container3) .. docs:: \new Staff { \time 5/4 g''1 ~ g''4 } .. figure:: ../_images/sync_containers-s7rmadmd1f.png >>> abjad.show(container4) .. docs:: \new Staff { \time 6/8 c'2 r4 \time 2/4 R1 * 1/2 } .. figure:: ../_images/sync_containers-msu922pcn6e.png Polymetric notation: It's important to note that LilyPond does not support simultanoues staves with different time signatures (i.e. polymetric notation) by default. In order to enable it, the ``"Timing_translator"`` and ``"Default_bar_line_engraver"`` must be removed from the ``Score`` context and added to the ``Staff`` context. Below is a full example of how this can be accomplished using Abjad. >>> container1 = abjad.Container(r"\time 4/4 c'4 d'4 e'4 f'4") >>> container2 = abjad.Container(r"\time 3/4 a2. \time 4/4 c'4") >>> container3 = abjad.Container(r"\time 5/4 g''1 ~ g''4") >>> container4 = abjad.Container(r"\time 6/8 c'2") >>> containers = [container1, ... container2, ... container3, ... container4, ... ] >>> auxjad.mutate.sync_containers(containers) >>> staves = [abjad.Staff([container1]), ... abjad.Staff([container2]), ... abjad.Staff([container3]), ... abjad.Staff([container4]), ... ] >>> score = abjad.Score(staves) >>> lilypond_file = abjad.LilyPondFile.new() >>> score_block = abjad.Block(name='score') >>> layout_block = abjad.Block(name='layout') >>> score_block.items.append(score) >>> score_block.items.append(layout_block) >>> lilypond_file.items.append(score_block) >>> layout_block.items.append( ... r''' ... \context { ... \Score ... \remove "Timing_translator" ... \remove "Default_bar_line_engraver" ... } ... \context { ... \Staff ... \consists "Timing_translator" ... \consists "Default_bar_line_engraver" ... } ... ''') >>> abjad.show(lilypond_file) .. docs:: \score { %! abjad.LilyPondFile._get_formatted_blocks() \new Score << \new Staff { { \time 4/4 c'4 d'4 e'4 f'4 \time 1/4 R1 * 1/4 } } \new Staff { { \time 3/4 a2. \time 2/4 c'4 r4 } } \new Staff { { \time 5/4 g''1 ~ g''4 } } \new Staff { { \time 6/8 c'2 r4 \time 2/4 R1 * 1/2 } } >> \layout { \context { \Score \remove "Timing_translator" \remove "Default_bar_line_engraver" } \context { \Staff \consists "Timing_translator" \consists "Default_bar_line_engraver" } } } %! abjad.LilyPondFile._get_formatted_blocks() .. figure:: ../_images/sync_containers-1lbrepesgil.png .. error:: If one or more containers is malformed, i.e. it has an underfilled measure before a time signature change, the function raises a :exc:`ValueError` exception. >>> container1 = abjad.Container(r"\time 4/4 g'1 | f'4") >>> container2 = abjad.Container(r"\time 5/4 c'1 | \time 4/4 d'4") >>> auxjad.mutate.sync_containers([container1, container2]) ValueError: at least one 'container' is malformed, with an underfull measure preceding a time signature change """ if not isinstance(containers, (Iterable, abjad.Score)): raise TypeError("argument must be 'abjad.Score' or iterable of " "'abjad.Container's") if isinstance(containers, abjad.Score): containers = containers[:] for container in containers: if not isinstance(container, abjad.Container): raise TypeError("argument must be 'abjad.Score' or iterable of " "'abjad.Container's") if not abjad.select(container).leaves().are_contiguous_logical_voice(): raise ValueError("argument must each be contiguous logical voice") try: get.selection_is_full(container[:]) except ValueError as err: raise ValueError("at least one 'container' is malformed, with an " "underfull measure preceding a time signature " "change") from err if not isinstance(use_multimeasure_rests, bool): raise TypeError("'use_multimeasure_rests' must be 'bool'") if not isinstance(adjust_last_time_signature, bool): raise TypeError("'adjust_last_time_signature' must be 'bool'") durations = [abjad.get.duration(container[:]) for container in containers] max_duration = max(durations) for container, duration in zip(containers, durations): duration_difference = max_duration - duration if duration_difference > abjad.Duration(0): # handling duration left in the last measure, if any if not get.selection_is_full(container[:]): duration_left = get.underfull_duration(container[:]) underfull_rests_duration = min(duration_difference, duration_left, ) underfull_rests = abjad.LeafMaker()(None, underfull_rests_duration, ) duration_difference -= underfull_rests_duration container.extend(underfull_rests) if (duration_difference == abjad.Duration(0) and adjust_last_time_signature): close_container(container) if duration_difference == abjad.Duration(0): continue # finding out last effective time signature for leaf in abjad.select(container).leaves()[::-1]: effective_time_signature = abjad.get.effective( leaf, abjad.TimeSignature, ) if effective_time_signature is not None: break else: effective_time_signature = abjad.TimeSignature((4, 4)) # creating new measures for any leftover duration measure_duration = effective_time_signature.duration while duration_difference > measure_duration: rests = abjad.LeafMaker()(None, measure_duration) duration_difference -= measure_duration container.extend(rests) if duration_difference > abjad.Duration(0): rests = abjad.LeafMaker()(None, duration_difference) if adjust_last_time_signature: rests_time_signature = abjad.TimeSignature( duration_difference, ) rests_time_signature.simplify_ratio() if rests_time_signature != effective_time_signature: abjad.attach(rests_time_signature, rests[0]) container.extend(rests) if use_multimeasure_rests: rests_to_multimeasure_rest(container[:]) else: # closing longest container if necessary if (adjust_last_time_signature and not get.selection_is_full(container[:])): close_container(container)
def make_monads(fractions: str, ) -> RhythmCommand: r""" Makes monads. .. container:: example >>> maker = baca.SegmentMaker( ... score_template=baca.SingleStaffScoreTemplate(), ... spacing=baca.minimum_duration((1, 12)), ... time_signatures=[(4, 4)], ... ) >>> maker( ... 'Music_Voice', ... baca.make_monads('2/5 2/5 1/5'), ... ) >>> lilypond_file = maker.run(environment='docs') >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> string = abjad.lilypond(lilypond_file[abjad.Score]) >>> print(string) <BLANKLINE> \context Score = "Score" << <BLANKLINE> \context GlobalContext = "Global_Context" << <BLANKLINE> \context GlobalSkips = "Global_Skips" { <BLANKLINE> % [Global_Skips measure 1] \baca-new-spacing-section #1 #12 \time 4/4 \baca-time-signature-color #'blue s1 * 1 <BLANKLINE> % [Global_Skips measure 2] \baca-new-spacing-section #1 #4 \time 1/4 \baca-time-signature-transparent s1 * 1/4 \once \override Score.BarLine.transparent = ##t \once \override Score.SpanBar.transparent = ##t <BLANKLINE> } <BLANKLINE> >> <BLANKLINE> \context MusicContext = "Music_Context" << <BLANKLINE> \context Staff = "Music_Staff" { <BLANKLINE> \context Voice = "Music_Voice" { <BLANKLINE> \tweak edge-height #'(0.7 . 0) \times 4/5 { <BLANKLINE> % [Music_Voice measure 1] \baca-not-yet-pitched-coloring b'2 - \abjad-dashed-line-with-hook - \baca-text-spanner-left-text "make_monads('2/5 2/5 1/5')" - \tweak bound-details.right.padding 2.75 - \tweak color #darkcyan - \tweak staff-padding 8 \bacaStartTextSpanRhythmAnnotation <BLANKLINE> } <BLANKLINE> \tweak edge-height #'(0.7 . 0) \times 4/5 { <BLANKLINE> \baca-not-yet-pitched-coloring b'2 <BLANKLINE> } <BLANKLINE> \tweak edge-height #'(0.7 . 0) \times 4/5 { <BLANKLINE> \baca-not-yet-pitched-coloring b'4 <> \bacaStopTextSpanRhythmAnnotation <BLANKLINE> } <BLANKLINE> << <BLANKLINE> \context Voice = "Music_Voice" { <BLANKLINE> % [Music_Voice measure 2] \abjad-invisible-music-coloring %@% \abjad-invisible-music \baca-not-yet-pitched-coloring b'1 * 1/4 %@% ^ \baca-duration-multiplier-markup #"1" #"4" <BLANKLINE> } <BLANKLINE> \context Voice = "Rest_Voice" { <BLANKLINE> % [Rest_Voice measure 2] \once \override Score.TimeSignature.X-extent = ##f \once \override MultiMeasureRest.transparent = ##t \stopStaff \once \override Staff.StaffSymbol.transparent = ##t \startStaff R1 * 1/4 %@% ^ \baca-duration-multiplier-markup #"1" #"4" <BLANKLINE> } <BLANKLINE> >> <BLANKLINE> } <BLANKLINE> } <BLANKLINE> >> <BLANKLINE> >> """ components: typing.List[abjad.Component] = [] maker = abjad.LeafMaker() pitch = 0 for fraction in fractions.split(): leaves = maker([pitch], [fraction]) components.extend(leaves) for tuplet in abjad.select(components).tuplets(): tuplet.multiplier = abjad.Multiplier(tuplet.multiplier) rhythm_maker = abjad.select(components) return RhythmCommand( rhythm_maker, annotation_spanner_color="#darkcyan", attach_not_yet_pitched=True, frame=inspect.currentframe(), )
def extend_notes(container: abjad.Container, max_note_duration: abjad.Duration, *, gap: abjad.Duration = abjad.Duration((0, 1)), gap_before_end: bool = False, use_multimeasure_rests: bool = True, rewrite_meter: bool = True, ) -> None: r"""Mutates an input |abjad.Container| (or child class) in place and has no return value; this function extends all logical ties (notes and chords) up to a given maximum note duration. Basic usage: This function will extend the duration of each logical tie up until the allowed maximum duration. >>> staff = abjad.Staff(r"c'16 r2... d'8 r2.. e'8. r16 r2. f'4 r2.") >>> abjad.show(staff) .. docs:: \new Staff { c'16 r2... d'8 r2.. e'8. r16 r2. f'4 r2. } .. figure:: ../_images/extend_notes-gJGtjtm3fu.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((1, 4))) >>> abjad.show(staff) .. docs:: \new Staff { c'4 r2. d'4 r2. e'4 r2. f'4 r2. } .. figure:: ../_images/extend_notes-6pjHLREOap.png .. note:: Auxjad automatically adds this function as an extension function to |abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or |abjad.mutate| namespaces. Therefore, the two lines below are equivalent: >>> auxjad.mutate.extend_notes(staff) >>> abjad.mutate.extend_notes(staff) Longer notes: This function will not alter the length of logical ties that are already equal to or larger than the maximum extension duration. >>> staff = abjad.Staff(r"c'16 r2... d'2 r2 e'2. r4 f'1") >>> abjad.show(staff) .. docs:: \new Staff { c'16 r2... d'2 r2 e'2. r4 f'1 } .. figure:: ../_images/extend_notes-56rOAsxHPP.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((1, 4))) >>> abjad.show(staff) .. docs:: \new Staff { c'4 r2. d'2 r2 e'2. r4 f'1 } .. figure:: ../_images/extend_notes-egF496w5Bs.png Chords: This function works with chords: >>> staff = abjad.Staff( ... r"\time 3/4 c'8 r8 r2 r4 <d' e' f'>4 r4 r8 g'16 r16 r2" ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'8 r8 r2 r4 <d' e' f'>4 r4 r8 g'16 r16 r2 } .. figure:: ../_images/extend_notes-2151PE127t.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((2, 4))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'2 r4 r4 <d' e' f'>2 r8 g'8 ~ g'4. r8 } .. figure:: ../_images/extend_notes-GVM7SBRQ5z.png Second positional argument: The second positional argument must be an |abjad.Duration| or objects that can instantiate an |abjad.Duration|, such as :obj:`str`, :obj:`tuple`, :obj:`int`, and :obj:`float`. The notes will be extended up to that duration, or until the next note if the full duration is not possible: >>> staff = abjad.Staff( ... r"c'16 r4.. d'16 r4.. e'16 r2... f'16 r4.. g'16 r4.." ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'16 r4.. d'16 r4.. e'16 r2... f'16 r4.. g'16 r4.. } .. figure:: ../_images/extend_notes-GfrvgpqH2J.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((3, 4))) >>> abjad.show(staff) .. docs:: \new Staff { c'2 d'2 e'2. r4 f'2 g'2 } .. figure:: ../_images/extend_notes-1vKtKyK7up.png Dynamics: Dynamics are preserved: >>> staff = abjad.Staff( ... r"c'16\ppp r2... d'16\ff r2... e'16\f r2... f'16\mp r2..." ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'16 \ppp r2... d'16 \ff r2... e'16 \f r2... f'16 \mp r2... } .. figure:: ../_images/extend_notes-rAHtip59b2.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((1, 4))) >>> abjad.show(staff) .. docs:: \new Staff { c'2. \ppp r4 d'2. \ff r4 e'2. \f r4 f'2. \mp r4 } .. figure:: ../_images/extend_notes-TNbei46PhS.png Time signatures changes: This function handles time signature changes: >>> staff = abjad.Staff( ... r"\time 3/4 c'16 r8. r2 " ... r"\time 2/4 d'8 r8 e'8 r8 " ... r"\time 3/4 r2 f'16 r8." ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'16 r8. r2 \time 2/4 d'8 r8 e'8 r8 \time 3/4 r2 f'16 r8. } .. figure:: ../_images/extend_notes-k8d4mKMaS7.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((3, 4))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'2. \time 2/4 d'4 e'4 ~ \time 3/4 e'2 f'4 } .. figure:: ../_images/extend_notes-5eDO8ehSld.png ``gap``: Use the argument ``gap`` to ensure that there a minimum gap is left between leaves when extending them: >>> staff = abjad.Staff(r"c'4 r4 d'4 r4 e'4 r2.") >>> abjad.show(staff) .. docs:: \new Staff { c'4 r4 d'4 r4 e'4 r2. } .. figure:: ../_images/extend_notes-zpAx8NYXof.png >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((2, 4)), ... gap=abjad.Duration((1, 16)), ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'4.. r16 d'4.. r16 e'2 r2 } .. figure:: ../_images/extend_notes-t1HIPtyJkn.png Note that this function will not shorten leaves, so previous leaves that had no gaps will still have no gaps between them. ``gap`` will only affect leaves that are extended by the function. >>> staff = abjad.Staff(r"c'2 d'4 r4 e'4 r4 f'2 ~ f'2 r2") >>> abjad.show(staff) .. docs:: \new Staff { c'2 d'4 r4 e'4 r4 f'2 ~ f'2 r2 } .. figure:: ../_images/extend_notes-ZfrusN3f8T.png >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((2, 4)), ... gap=abjad.Duration((1, 16)), ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'2 d'4.. r16 e'4.. r16 f'2 ~ f'2 r2 } .. figure:: ../_images/extend_notes-5iteVkhz3l.png ``gap_before_end``: By default, a when ``gap`` is present it is not applied to the last pitched at the end of the container. >>> staff = abjad.Staff(r"c'16 r8. d'16 r8. e'16 r8. f'16 r8.") >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((1, 4)), ... gap=abjad.Duration((1, 16)), ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'8. r16 d'8. r16 e'8. r16 f'4 } .. figure:: ../_images/extend_notes-LuCN8pgjLH.png Set ``gap_before_end`` to ``True`` to ensure that there is also a minimum gap at the end of the container. >>> staff = abjad.Staff(r"c'16 r8. d'16 r8. e'16 r8. f'16 r8.") >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((1, 4)), ... gap=abjad.Duration((1, 16)), ... gap_before_end=True, ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'8. r16 d'8. r16 e'8. r16 f'8. r16 } .. figure:: ../_images/extend_notes-LppuegmkEP.png ``use_multimeasure_rests``: By default, this function uses multi-measure rests >>> staff = abjad.Staff(r"\time 3/4 r8 c'8 r4 c'4 r2. r8 c'8 r2 r2.") >>> auxjad.mutate.extend_notes(staff, abjad.Duration((2, 4))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 r8 c'4. c'4 ~ c'4 r2 r8 c'8 ~ c'4. r8 R1 * 3/4 } .. figure:: ../_images/extend_notes-WaLYhL24UG.png Set the keyword argument ``use_multimeasure_rests`` to ``False`` to disable this behaviour. >>> staff = abjad.Staff(r"\time 3/4 r8 c'8 r4 c'4 r2. r8 c'8 r2 r2.") >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((2, 4)), ... use_multimeasure_rests=False, ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 r8 c'4. c'4 ~ c'4 r2 r8 c'8 ~ c'4. r8 r2. } .. figure:: ../_images/extend_notes-H1uDCqQ8iz.png ``rewrite_meter`` By default, this function applies |auxjad.mutate.auto_rewrite_meter()| at the end of its process. >>> staff = abjad.Staff(r"c'16 r4.. d'16 r4..") >>> abjad.show(staff) .. docs:: \new Staff { c'16 r4.. d'16 r4.. } .. figure:: ../_images/extend_notes-BcAYS4SvUL.png >>> auxjad.mutate.extend_notes(staff, abjad.Duration((1, 4))) >>> abjad.show(staff) .. docs:: \new Staff { c'4 r4 d'4 r4 } .. figure:: ../_images/extend_notes-QNEks8lUXB.png Set ``rewrite_meter`` to ``False`` to disable this. The main reason for doing this is performance: when multiple mutations are being applied, it is faster to rewrite the meter just once at the end. >>> staff = abjad.Staff(r"c'16 r4.. d'16 r4..") >>> auxjad.mutate.extend_notes(staff, ... abjad.Duration((1, 4)), ... rewrite_meter=False, ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'16 ~ c'8. r4 d'16 ~ d'8. r4 } .. figure:: ../_images/extend_notes-49jhNoSa9T.png .. warning:: This function does not support tuplets. Using a container with one or more tuplets will result in a :exc:`ValueError` exception being raised: >>> staff = abjad.Staff(r"c'4 r4 \times 2/3 {r4 d'4 r4} e'4 r2.") >>> auxjad.mutate.extend_notes(staff, abjad.Duration((1, 4))) ValueError: first positional argument contains one ore more tuplets, which are not currently supported """ if not isinstance(container, abjad.Container): raise TypeError("first positional argument must be 'abjad.Container' " "or child class") if len(abjad.select(container).tuplets()) > 0: raise ValueError("first positional argument contains one ore more " "tuplets, which are not currently supported") if not isinstance(max_note_duration, (abjad.Duration, str, tuple, int, float), ): raise TypeError("second positional argument must be 'abjad.Duration', " "'str', 'tuple', or a number") if not isinstance(max_note_duration, abjad.Duration): max_note_duration = abjad.Duration(max_note_duration) if gap is not None: if not isinstance(gap, (abjad.Duration, str, tuple, int, float)): raise TypeError("'gap' must be 'abjad.Duration', 'str', 'tuple', " "or a number") if not isinstance(gap, abjad.Duration): gap = abjad.Duration(gap) if not isinstance(gap_before_end, bool): raise TypeError("'gap_before_end' must be 'bool'") if not isinstance(use_multimeasure_rests, bool): raise TypeError("'use_multimeasure_rests' must be 'bool'") if not isinstance(rewrite_meter, bool): raise TypeError("'rewrite_meter' must be 'bool'") time_signatures = get.time_signature_list(container, implicit_common_time=False, ) groups = _groupped_logical_ties(container) for group_index, group in enumerate(groups): if not gap_before_end and group_index == len(groups) - 1: gap = abjad.Duration((0, 1)) if isinstance(group[0], (abjad.Rest, abjad.MultimeasureRest)): continue pitched_duration = 0 rest_duration = 0 for item in group: if isinstance(item, (abjad.Note, abjad.Chord)): pitched_duration += abjad.get.duration(item) else: rest_duration += abjad.get.duration(item) missing_duration = max_note_duration - pitched_duration available_duration = rest_duration - gap if missing_duration <= 0 or available_duration <= 0: continue else: extended_duration = min(missing_duration, available_duration) new_rest_duration = rest_duration - extended_duration for index, item in enumerate(group): if isinstance(item, (abjad.Rest, abjad.MultimeasureRest)): first_rest_index = index break if isinstance(group[first_rest_index - 1], abjad.Note): pitches = group[first_rest_index - 1].written_pitch elif isinstance(group[first_rest_index - 1], abjad.Chord): pitches = [pitch for pitch in group[first_rest_index - 1].written_pitches] if new_rest_duration > abjad.Duration((0, 1)): replacement_items = abjad.LeafMaker()( [pitches, None], [extended_duration, new_rest_duration], ) else: replacement_items = abjad.LeafMaker()([pitches], [extended_duration], ) abjad.mutate.replace(group[first_rest_index:], replacement_items) abjad.attach(abjad.Tie(), group[first_rest_index - 1]) mutate.enforce_time_signature(container, time_signatures, disable_rewrite_meter=True, ) if rewrite_meter: mutate.auto_rewrite_meter(container) if use_multimeasure_rests: mutate.rests_to_multimeasure_rest(container[:])
def _notate_music( self, dummy_container: abjad.Container, start: int, end: int, ) -> None: r'Handles the notation aspects of the looping window.' window_size = self._window_size # passing on indicators from the head of an initial splitted leaf for index in range(start - 1, -1, -1): if abjad.inspect(dummy_container[index]).indicator(abjad.Tie): inspect_contents = abjad.inspect(dummy_container[index - 1]) if index == 0 or not inspect_contents.indicator(abjad.Tie): inspect_contents = abjad.inspect(dummy_container[index]) for indicator in inspect_contents.indicators(): inspector = abjad.inspect(dummy_container[start]) if (not isinstance(indicator, (abjad.TimeSignature, abjad.Tie)) and inspector.indicator(type(indicator)) is None): abjad.attach(indicator, dummy_container[start]) # removing ties generated by the split mutation abjad.detach(abjad.Tie(), dummy_container[start - 1]) abjad.detach(abjad.Tie(), dummy_container[end - 1]) # handling initial dynamics and slurs start_head = abjad.select(dummy_container[start:]).logical_tie(0)[0] start_tail = abjad.select(dummy_container[start:]).logical_tie(0)[-1] if (abjad.inspect(start_head).indicator(abjad.StartSlur) is None and abjad.inspect(start_tail).indicator(abjad.StopSlur) is None): for leaf in dummy_container[start - 1::-1].leaves(): if abjad.inspect(leaf).indicator(abjad.StartSlur) is not None: abjad.attach(abjad.StartSlur(), start_head) break elif abjad.inspect(leaf).indicator(abjad.StopSlur) is not None: break if (abjad.inspect(start_head).indicator(abjad.Dynamic) is None and not isinstance(start_head, ( abjad.Rest, abjad.MultimeasureRest, ))): for leaf in dummy_container[start - 1::-1].leaves(): dynamic = abjad.inspect(leaf).indicator(abjad.Dynamic) if dynamic is not None: abjad.attach(dynamic, start_head) break # appending rests if necessary contents_dur = abjad.inspect(dummy_container[start:end]).duration() if contents_dur < window_size.duration: missing_dur = window_size.duration - contents_dur rests = abjad.LeafMaker()(None, missing_dur) dummy_container.extend(rests) end += len(rests) # transforming abjad.Selection -> abjad.Container for rewrite_meter dummy_container = abjad.Container( abjad.mutate(dummy_container[start:end]).copy()) # rewriting meter if not self._disable_rewrite_meter: mutate(dummy_container).auto_rewrite_meter( meter_list=[abjad.TimeSignature(window_size)], boundary_depth=self._boundary_depth, maximum_dot_count=self._maximum_dot_count, rewrite_tuplets=self._rewrite_tuplets, prettify_rewrite_meter=self._prettify_rewrite_meter, extract_trivial_tuplets=self._extract_trivial_tuplets, fuse_across_groups_of_beats=self._fuse_across_groups_of_beats, fuse_quadruple_meter=self._fuse_quadruple_meter, fuse_triple_meter=self._fuse_triple_meter, ) abjad.attach( abjad.TimeSignature(window_size), abjad.select(dummy_container).leaf(0), ) mutate(dummy_container[:]).reposition_dynamics() mutate(dummy_container[:]).reposition_slurs() self._current_window = dummy_container[:] dummy_container[:] = []
def test_example_of_usage_02(): random.seed(18762) pitch_selector = auxjad.TenneySelector( ["c'", "fs'", "bf'", "e''", "a''", "d'''"]) duration_selector = auxjad.TenneySelector([ (1, 16), (2, 16), (3, 16), (4, 16), (5, 16), (6, 16), ]) pitches = [] durations = [] for _ in range(12): pitches.append(pitch_selector()) durations.append(duration_selector()) notes = abjad.LeafMaker()(pitches, durations) container = abjad.Container(notes) looper = auxjad.LeafLooper(container, window_size=4) staff = abjad.Staff(looper.output_n(7)) looper.window_size = 2 staff.append(looper.output_n(4)) assert format(staff) == abjad.String.normalize(r""" \new Staff { \time 11/16 a''16 d'''8 ~ d'''8. c'16 ~ c'8. e''16 \time 7/8 d'''4 ~ d'''16 c'16 ~ c'8. e''16 bf'4 \time 3/4 c'4 e''16 bf'8. ~ bf'16 fs'8. \time 5/8 e''16 bf'16 ~ bf'8. fs'16 ~ fs'8 a''8 \time 7/8 bf'4 fs'8 ~ fs'16 a''8 d'''16 ~ d'''4 \time 11/16 fs'8. a''8 d'''4 ~ d'''16 c'16 \time 3/4 a''8 d'''8 ~ d'''8. c'16 d'''4 \time 3/8 d'''4 ~ d'''16 c'16 \time 5/16 c'16 d'''4 \time 5/8 d'''4 a''4. \time 11/16 a''4. e''16 ~ e''4 } """)
def _make_leaf(self, pitch, duration_string): duration = abjad.Duration(duration_string) maker = abjad.LeafMaker() leaves = maker([pitch], [duration]) return leaves
def extract_trivial_tuplets(selection: abjad.Selection) -> None: r"""Mutates an input |abjad.Selection| in place and has no return value; this function looks for tuplets filled with rests or with tied notes or chords and replaces them with a single leaf. Basic usage: Usage is simple: >>> staff = abjad.Staff( ... r"\times 2/3 {r4 r2} \times 2/3 {c'8 ~ c'8 ~ c'2}" ... ) >>> abjad.f(container) { \times 2/3 { r4 r2 } \times 2/3 { c'8 ~ c'8 ~ c'2 } } .. figure:: ../_images/extract_trivial_tuplets-4htz2xebxwf.png >>> auxjad.mutate(container[:]).extract_trivial_tuplets() >>> abjad.f(container) { r2 c'2 } .. figure:: ../_images/extract_trivial_tuplets-2dbuwo4erhb.png It also works with containers with tuplets within tuplets. >>> container = abjad.Container(r"\times 4/5 {r2. \times 2/3 {r2 r4}}") >>> abjad.f(container) { \times 4/5 { r2. \times 2/3 { r2 r4 } } } .. figure:: ../_images/extract_trivial_tuplets-8d5bcyxcmhc.png >>> auxjad.mutate(container[:]).extract_trivial_tuplets() >>> abjad.f(container) { r1 } .. figure:: ../_images/extract_trivial_tuplets-2a2fvwimyrx.png >>> container = abjad.Container( ... r"\times 4/5 {c'2. ~ \times 2/3 {c'2 ~ c'4}}" ... ) >>> abjad.f(container) { \times 4/5 { c'2. ~ \times 2/3 { c'2 ~ c'4 } } } .. figure:: ../_images/extract_trivial_tuplets-xka6r5iyo4l.png >>> auxjad.mutate(staff[:]).extract_trivial_tuplets() >>> abjad.f(container) { c'1 } .. figure:: ../_images/extract_trivial_tuplets-f1qxi44xcsw.png .. note:: Auxjad automatically adds this function as an extension method to |abjad.mutate()|. It can thus be used from either :func:`auxjad.mutate()` or |abjad.mutate()|. Therefore, the two lines below are equivalent: >>> auxjad.mutate(staff[:]).extract_trivial_tuplets() >>> abjad.mutate(staff[:]).extract_trivial_tuplets() Partial extraction: This function also extracts tuplets within tuplets. >>> container = abjad.Container( ... r"r2 \times 2/3 {r2 r4} \times 4/5 {c'2. \times 2/3 {r2 r4}}" ... ) >>> abjad.f(container) { r2 \times 2/3 { r2 r4 } \times 4/5 { c'2. \times 2/3 { r2 r4 } } } .. figure:: ../_images/extract_trivial_tuplets-adibnkb1mbs.png >>> auxjad.mutate(container[:]).extract_trivial_tuplets() >>> abjad.f(container) { r2 r2 \times 4/5 { c'2. r2 } } .. figure:: ../_images/extract_trivial_tuplets-xldohyedqs.png .. tip:: Use |auxjad.mutate().rests_to_multimeasure_rest()| to replace measures filled with rests by a single multi-measure rest. That function makes use of |auxjad.mutate().extract_trivial_tuplets()|, so it is not necessary to flatten the empty tuplets beforehand. Time signature changes: Works with measures with any time signature. >>> container = abjad.Staff(r"\time 3/4 r2. \times 3/2 {r4 r4}") >>> auxjad.mutate(container[:]).extract_trivial_tuplets() >>> abjad.f(container) \new Staff { \time 3/4 r2. r2. } .. figure:: ../_images/extract_trivial_tuplets-sa1tqmvtkx.png Non-assignable durations: This function also extracts tuplets which sum up to a non-assignable duration. In this case, it creates multiple leaves and substitutes them for the original tuplet. Indicators are passed on to the first leaf of the new leaves. >>> staff = abjad.Staff(r"\time 6/4 c'4\f \times 5/6 {g1.\p}") >>> abjad.f(staff) \new Staff { \time 6/4 c'4 \f \tweak text #tuplet-number::calc-fraction-text \times 5/6 { g1. \p } } .. figure:: ../_images/extract_trivial_tuplets-l4kp9g5v7m.png >>> abjad.mutate(staff[:]).extract_trivial_tuplets() >>> abjad.f(staff) \new Staff { \time 6/4 c'4 \f g1 \p ~ g4 } .. figure:: ../_images/extract_trivial_tuplets-8r40ndemvpn.png .. note:: When using |abjad.Container|'s, all time signatures in the output will be commented out with ``%%%.`` This is because Abjad only applies time signatures to containers that belong to a |abjad.Staff|. The present function works with either |abjad.Container| and |abjad.Staff|. >>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4") >>> abjad.f(container) { %%% \time 3/4 %%% c'4 d'4 e'4 } .. figure:: ../_images/extract_trivial_tuplets-6wymsb7z1n4.png >>> staff = abjad.Staff([container]) >>> abjad.f(container) { \time 3/4 c'4 d'4 e'4 } .. figure:: ../_images/extract_trivial_tuplets-moavfyqtxza.png .. warning:: The input selection must be a contiguous logical voice. When dealing with a container with multiple subcontainers (e.g. a score containing multiple staves), the best approach is to cycle through these subcontainers, applying this function to them individually. """ if not isinstance(selection, abjad.Selection): raise TypeError("argument must be 'abjad.Selection'") tuplets = selection.tuplets() if len(tuplets) == 0: return for tuplet in tuplets: leaves = abjad.select(tuplet).leaves() if (all(isinstance(leaf, abjad.Rest) for leaf in leaves) and len(leaves) > 1): duration = tuplet.multiplied_duration rests = abjad.LeafMaker()(None, duration) time_signature = abjad.inspect(leaves[0]).indicator( abjad.TimeSignature) if time_signature is not None: abjad.attach(time_signature, rests[0]) abjad.mutate(tuplet).replace(rests) if tuplet.sustained(): duration = tuplet.multiplied_duration n_elements = len(tuplet) after_tie = abjad.inspect(leaves[-1]).indicator(abjad.Tie) for _ in range(n_elements - 1): tuplet.pop(-1) if not after_tie: abjad.detach(abjad.Tie(), leaves[0]) if duration.is_assignable: leaves[0].written_duration = duration abjad.mutate(tuplet).extract() elif duration.has_power_of_two_denominator: if isinstance(leaves[0], abjad.Note): pitch = leaves[0].written_pitch elif isinstance(leaves[0], abjad.Chord): pitch = leaves[0].written_pitches else: pitch = None notes = abjad.LeafMaker()(pitch, duration) indicators = abjad.inspect(leaves[0]).indicators() for indicator in indicators: abjad.attach(indicator, notes[0]) abjad.mutate(leaves[0]).replace(notes) abjad.mutate(tuplet).extract() else: continue for tuplet in tuplets: if tuplet.trivializable(): tuplet.trivialize() abjad.mutate(tuplet).extract()
denominator = 16 talea = abjadext.rmakers.Talea(counts=counts, denominator=denominator) talea_index = 0 all_leaves = [] current_duration = abjad.Duration(0) while current_duration < total_duration: leaf_duration = talea[talea_index] if leaf_duration > 0: pitch = abjad.NamedPitch("c'") else: pitch = None leaf_duration = abs(leaf_duration) if (leaf_duration + current_duration) > total_duration: leaf_duration = total_duration - current_duration current_leaves = abjad.LeafMaker()([pitch], [leaf_duration]) all_leaves.extend(current_leaves) current_duration += leaf_duration talea_index += 1 music = abjad.Container(all_leaves) shards = abjad.mutate(music[:]).split(time_signature_pairs) for i, shard in enumerate(shards): measure = abjad.Measure(time_signature_pairs[i]) abjad.mutate(shard).wrap(measure) # pitches = abjad.CyclicTuple(["d'", "a''", "gs'", "fs'"]) # pitches = abjad.CyclicTuple(["c'", "c''"]) # pitches = abjad.CyclicTuple([0, 2, 4, 5, 7, 9, 11, 12])
def fill_with_rests( container: abjad.Container, *, disable_rewrite_meter: bool = False, prettify_rewrite_meter: bool = True, boundary_depth: Optional[int] = None, maximum_dot_count: Optional[int] = None, rewrite_tuplets: bool = True, extract_trivial_tuplets: bool = True, fuse_across_groups_of_beats: bool = True, fuse_quadruple_meter: bool = True, fuse_triple_meter: bool = True, split_quadruple_meter: bool = True, ) -> None: r"""Mutates an input container (of type |abjad.Container| or child class) in place and has no return value; this function fills a container with rests in order to make it full. Basic usage: Returns the missing duration of the last measure of any container or child class. If no time signature is encountered, it uses LilyPond's convention and considers the container as in 4/4. >>> container1 = abjad.Container(r"c'4 d'4 e'4 f'4") >>> container2 = abjad.Container(r"c'4 d'4 e'4") >>> container3 = abjad.Container(r"c'4 d'4 e'4 f'4 | c'4") >>> container4 = abjad.Container(r"c'4 d'4 e'4 f'4 | c'4 d'4 e'4 f'4") >>> auxjad.mutate(container1).fill_with_rests() >>> auxjad.mutate(container2).fill_with_rests() >>> auxjad.mutate(container3).fill_with_rests() >>> auxjad.mutate(container4).fill_with_rests() >>> abjad.f(container1) { c'4 d'4 e'4 f'4 } .. figure:: ../_images/fill_with_rests-up297scg6t.png >>> abjad.f(container2) { c'4 d'4 e'4 r4 } .. figure:: ../_images/fill_with_rests-azrrw0z0buw.png >>> abjad.f(container3) { c'4 d'4 e'4 f'4 c'4 r2. } .. figure:: ../_images/fill_with_rests-jtyw5ikc0k.png >>> abjad.f(container4) { c'4 d'4 e'4 f'4 c'4 d'4 e'4 f'4 } .. figure:: ../_images/fill_with_rests-xjkm2vzjfpr.png .. note:: Auxjad automatically adds this function as an extension method to |abjad.mutate()|. It can thus be used from either :func:`auxjad.mutate()` or |abjad.mutate()|. Therefore, the two lines below are equivalent: >>> auxjad.mutate(staff).fill_with_rests() >>> abjad.mutate(staff).fill_with_rests() Time signature changes: Handles any time signatures as well as changes of time signature. >>> staff1 = abjad.Staff(r"\time 4/4 c'4 d'4 e'4 f'4 g'") >>> staff2 = abjad.Staff(r"\time 3/4 a2. \time 2/4 c'4") >>> staff3 = abjad.Staff(r"\time 5/4 g1 ~ g4 \time 4/4 af'2") >>> auxjad.mutate(staff1).fill_with_rests() >>> auxjad.mutate(staff2).fill_with_rests() >>> auxjad.mutate(staff3).fill_with_rests() >>> abjad.f(staff1) { \time 4/4 c'4 d'4 e'4 f'4 g'4 r2. } .. figure:: ../_images/fill_with_rests-7zydps2jsb.png >>> abjad.f(staff2) { \time 3/4 a2. \time 2/4 c'4 r4 } .. figure:: ../_images/fill_with_rests-1lphcrl5pnr.png >>> abjad.f(staff3) { \time 5/4 g1 ~ g4 \time 4/4 af'2 r2 } .. figure:: ../_images/fill_with_rests-e00jvx986r.png .. note:: When using |abjad.Container|'s, all time signatures in the output will be commented out with ``%%%.`` This is because Abjad only applies time signatures to containers that belong to a |abjad.Staff|. The present function works with either |abjad.Container| and |abjad.Staff|. >>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4") >>> abjad.f(container) { %%% \time 3/4 %%% c'4 d'4 e'4 } .. figure:: ../_images/fill_with_rests-b0qflg50qfn.png >>> staff = abjad.Staff([container]) >>> abjad.f(container) { \time 3/4 c'4 d'4 e'4 } .. figure:: ../_images/fill_with_rests-qtaswjiecg.png Partial time signatures: Correctly handles partial time signatures. >>> staff = abjad.Staff(r"c'4 d'4 e'4 f'4 g'4") >>> time_signature = abjad.TimeSignature((3, 4), partial=(1, 4)) >>> abjad.attach(time_signature, staff[0]) >>> auxjad.mutate(staff).fill_with_rests() >>> abjad.f(staff) { \partial 4 \time 3/4 c'4 d'4 e'4 f'4 g'4 r2 } .. figure:: ../_images/fill_with_rests-9smva9ajdi.png ``disable_rewrite_meter``: By default, this class applies the |abjad.mutate().rewrite_meter()| mutation to the last measure when rests are added. >>> staff = abjad.Staff(r"\time 4/4 c'8 d'4 e'4") >>> auxjad.mutate(staff).fill_with_rests() >>> abjad.f(staff) \new Staff { \time 4/4 c'8 d'4 e'8 ~ e'8 r4. } .. figure:: ../_images/fill_with_rests-n83nmnfh92c.png Call this function with the optional keyword argument ``disable_rewrite_meter`` set to ``True`` in order to disable this behaviour. >>> staff = abjad.Staff(r"\time 4/4 c'8 d'4 e'4") >>> auxjad.mutate(staff, disable_rewrite_meter=True).fill_with_rests() >>> abjad.f(staff) \new Staff { \time 4/4 c'8 d'4 e'4 r4. } .. figure:: ../_images/fill_with_rests-9rg2i4n1vhr.png .. note:: This function also accepts the arguments ``boundary_depth``, ``maximum_dot_count``, and ``rewrite_tuplets``, which are passed on to |abjad.mutate().rewrite_meter()|, and ``fuse_across_groups_of_beats``, ``fuse_quadruple_meter``, ``fuse_triple_meter``, ``extract_trivial_tuplets``, and ``split_quadruple_meter``, which are passed on to |auxjad.mutate().prettify_rewrite_meter()| (the latter can be disabled by setting ``prettify_rewrite_meter`` to ``False``). See the documentation of those functions for more details on these arguments. .. error:: If a container is malformed, i.e. it has an underfilled measure before a time signature change, the function raises a :exc:`ValueError` exception. >>> container = abjad.Container(r"\time 5/4 g''1 \time 4/4 f'4") >>> auxjad.mutate(container).fill_with_rests() ValueError: 'container' is malformed, with an underfull measure preceding a time signature change .. warning:: The input container must be a contiguous logical voice. When dealing with a container with multiple subcontainers (e.g. a score containing multiple staves), the best approach is to cycle through these subcontainers, applying this function to them individually. """ if not isinstance(container, abjad.Container): raise TypeError("argument must be 'abjad.Container' or child class") if not abjad.select(container).leaves().are_contiguous_logical_voice(): raise ValueError("argument must be contiguous logical voice") try: if not inspect(container[:]).selection_is_full(): underfull_rests = abjad.LeafMaker()( None, inspect(container[:]).underfull_duration(), ) container.extend(underfull_rests) else: return except ValueError as err: raise ValueError("'container' is malformed, with an underfull measure " "preceding a time signature change") from err if not disable_rewrite_meter: time_signatures = inspect(container).extract_time_signatures( do_not_use_none=True, ) measures = abjad.select(container[:]).group_by_measure() abjad.mutate(measures[-1]).rewrite_meter( time_signatures[-1], boundary_depth=boundary_depth, maximum_dot_count=maximum_dot_count, rewrite_tuplets=rewrite_tuplets, ) if prettify_rewrite_meter: measures = abjad.select(container[:]).group_by_measure() prettify_rewrite_meter_function( measures[-1], time_signatures[-1], extract_trivial_tuplets=extract_trivial_tuplets, fuse_across_groups_of_beats=fuse_across_groups_of_beats, fuse_quadruple_meter=fuse_quadruple_meter, fuse_triple_meter=fuse_triple_meter, split_quadruple_meter=split_quadruple_meter, )
def contract_notes(container: abjad.Container, max_contraction_duration: abjad.Duration, *, minimum_duration: abjad.Duration = abjad.Duration((0, 1)), use_multimeasure_rests: bool = True, rewrite_meter: bool = True, ) -> None: r"""Mutates an input |abjad.Container| (or child class) in place and has no return value; this function contracts all logical ties (notes and chords) by a maximum contraction duration. Basic usage: This function will contract the duration of each logical tie up by the allowed maximum contraction duration. >>> staff = abjad.Staff(r"c'4 r2. d'2 r2 e'2. r4 f'1") >>> abjad.show(staff) .. docs:: \new Staff { c'4 r2. d'2 r2 e'2. r4 f'1 } .. figure:: ../_images/contract_notes-DtvjEcpLMF.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 8))) >>> abjad.show(staff) .. docs:: \new Staff { c'8 r2.. d'4. r8 r2 e'2 ~ e'8 r4. f'2.. r8 } .. figure:: ../_images/contract_notes-PEgTVggwUR.png .. note:: Auxjad automatically adds this function as an extension function to |abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or |abjad.mutate| namespaces. Therefore, the two lines below are equivalent: >>> auxjad.mutate.contract_notes(staff) >>> abjad.mutate.contract_notes(staff) Chords: This function works with chords: >>> staff = abjad.Staff(r"\time 3/4 c'2. <d' e' f'>2 r4 g'4 r2") >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'2. <d' e' f'>2 r4 g'4 r2 } .. figure:: ../_images/contract_notes-MtQM9vn5rV.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 16))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'2 ~ c'8. r16 <d' e' f'>4.. r16 r4 g'8. r16 r2 } .. figure:: ../_images/contract_notes-3KViO6UZ74.png Second positional argument: The second positional argument must be an |abjad.Duration| or objects that can instantiate an |abjad.Duration|, such as :obj:`str`, :obj:`tuple`, :obj:`int`, and :obj:`float`. The notes will be contract by up to that duration, or until the note is removed: >>> staff = abjad.Staff( ... r"c'4 r2. d'2 r2 e'2. r4 f'1" ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'4 r2. d'2 r2 e'2. r4 f'1 } .. figure:: ../_images/contract_notes-OgFmg6p3VP.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 2))) >>> abjad.show(staff) .. docs:: \new Staff { R1 R1 e'4 r2. f'2 r2 } .. figure:: ../_images/contract_notes-YfZ3maHywo.png Dynamics: Dynamics are preserved: >>> staff = abjad.Staff(r"c'4\ppp r2. d'2\ff r2 e'2.\f r4 f'1\mp") >>> abjad.show(staff) .. docs:: \new Staff { c'4 \ppp r2. d'2 \ff r2 e'2. \f r4 f'1 \mp } .. figure:: ../_images/contract_notes-zKIFJdZuSX.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 8))) >>> abjad.show(staff) .. docs:: \new Staff { c'8 \ppp r2.. d'4. \ff r8 r2 e'2 \f ~ e'8 r4. f'2.. \mp r8 } .. figure:: ../_images/contract_notes-iKVB9DmxJf.png Time signatures changes: This function handles time signature changes: >>> staff = abjad.Staff( ... r"\time 3/4 c'4 r2 " ... r"\time 2/4 d'2 " ... r"\time 3/4 e'2. " ... r"\time 4/4 f'1" ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'4 r2 \time 2/4 d'2 \time 3/4 e'2. \time 4/4 f'1 } .. figure:: ../_images/contract_notes-cpRcyhRgB7.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((3, 4))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 c'8 r8 r2 \time 2/4 d'4. r8 \time 3/4 e'2 ~ e'8 r8 \time 4/4 f'2.. r8 } .. figure:: ../_images/contract_notes-R6hnRYZU68.png ``minimum_duration``: Use the argument ``minimum_duration`` to ensure that notes will not be contracted further than this value: >>> staff = abjad.Staff(r"c'4 r2. d'2 r2 e'2. r4 f'1") >>> abjad.show(staff) .. docs:: \new Staff { c'4 r2. d'2 r2 e'2. r4 f'1 } .. figure:: ../_images/contract_notes-lzHgoaJ2Es.png >>> auxjad.mutate.contract_notes(staff, ... abjad.Duration((1, 2)), ... minimum_duration=abjad.Duration((1, 8)), ... ) >>> abjad.show(staff) .. docs:: \new Staff { c'8 r2.. d'8 r2.. e'4 r2. f'2 r2 } .. figure:: ../_images/contract_notes-o5lELCkJm8.png ``use_multimeasure_rests``: By default, this function uses multi-measure rests >>> staff = abjad.Staff( ... r"\time 4/4 c'4 r2. \time 3/4 d'4 r2 \time 4/4 e'4 r2." ... ) >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 2))) >>> abjad.show(staff) .. docs:: \new Staff { \time 4/4 R1 \time 3/4 R1 * 3/4 \time 4/4 R1 } .. figure:: ../_images/contract_notes-olfdBpIydF.png Set the keyword argument ``use_multimeasure_rests`` to ``False`` to disable this behaviour. >>> staff = abjad.Staff( ... r"\time 4/4 c'4 r2. \time 3/4 d'4 r2 \time 4/4 e'4 r2." ... ) >>> auxjad.mutate.contract_notes(staff, ... abjad.Duration((1, 2)), ... use_multimeasure_rests=False, ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 4/4 r1 \time 3/4 r2. \time 4/4 r1 } .. figure:: ../_images/contract_notes-VNPRYNnFl5.png ``rewrite_meter`` By default, this function applies |auxjad.mutate.auto_rewrite_meter()| at the end of its process. >>> staff = abjad.Staff(r"\time 3/4 r8 c'8 ~ c'2 r8 d'8 ~ d'2") >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 r8 c'8 ~ c'2 r8 d'8 ~ d'2 } .. figure:: ../_images/contract_notes-rGCxpXl3rI.png >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 8))) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 r8 c'8 ~ c'4. ~ r8 r8 d'8 ~ d'4. ~ r8 } .. figure:: ../_images/contract_notes-NoBsRNQJos.png Set ``rewrite_meter`` to ``False`` to disable this. The main reason for doing this is performance: when multiple mutations are being applied, it is faster to rewrite the meter just once at the end. >>> staff = abjad.Staff(r"\time 3/4 r8 c'8 ~ c'2 r8 d'8 ~ d'2") >>> auxjad.mutate.contract_notes(staff, ... abjad.Duration((1, 8)), ... rewrite_meter=False, ... ) >>> abjad.show(staff) .. docs:: \new Staff { \time 3/4 r8 c'2 ~ r8 r8 d'2 ~ r8 } .. figure:: ../_images/contract_notes-VNHowP6bFi.png .. warning:: This function does not support tuplets. Using a container with one or more tuplets will result in a :exc:`ValueError` exception being raised: >>> staff = abjad.Staff(r"c'4 r4 \times 2/3 {r4 d'4 r4} e'4 r2.") >>> auxjad.mutate.contract_notes(staff, abjad.Duration((1, 8))) ValueError: first positional argument contains one ore more tuplets, which are not currently supported """ if not isinstance(container, abjad.Container): raise TypeError("first positional argument must be 'abjad.Container' " "or child class") if len(abjad.select(container).tuplets()) > 0: raise ValueError("first positional argument contains one ore more " "tuplets, which are not currently supported") if not isinstance(max_contraction_duration, (abjad.Duration, str, tuple, int, float), ): raise TypeError("second positional argument must be 'abjad.Duration', " "'str', 'tuple', or a number") if not isinstance(max_contraction_duration, abjad.Duration): max_contraction_duration = abjad.Duration(max_contraction_duration) if minimum_duration is not None: if not isinstance(minimum_duration, (abjad.Duration, str, tuple, int, float, )): raise TypeError("'minimum_duration' must be 'abjad.Duration', " "'str', 'tuple', or a number") if not isinstance(minimum_duration, abjad.Duration): minimum_duration = abjad.Duration(minimum_duration) if not isinstance(use_multimeasure_rests, bool): raise TypeError("'use_multimeasure_rests' must be 'bool'") if not isinstance(rewrite_meter, bool): raise TypeError("'rewrite_meter' must be 'bool'") time_signatures = get.time_signature_list(container, implicit_common_time=False, ) for logical_tie in abjad.select(container).logical_ties(): if isinstance(logical_tie.head, (abjad.Rest, abjad.MultimeasureRest)): continue total_duration = abjad.get.duration(logical_tie) if total_duration <= minimum_duration: continue rest_duration = min(max_contraction_duration, total_duration - minimum_duration ) if rest_duration == abjad.Duration((0, 1)): continue pitched_duration = total_duration - rest_duration indicators = abjad.get.indicators(logical_tie.head) if pitched_duration > abjad.Duration((0, 1)): if isinstance(logical_tie.head, abjad.Note): pitches = logical_tie.head.written_pitch elif isinstance(logical_tie.head, abjad.Chord): pitches = [pitch for pitch in logical_tie.head.written_pitches] replacement_items = abjad.LeafMaker()( [pitches, None], [pitched_duration, rest_duration], ) if len(indicators) > 0: for indicator in indicators: abjad.attach(indicator, replacement_items[0]) else: replacement_items = abjad.LeafMaker()([None], [rest_duration]) abjad.mutate.replace(logical_tie, replacement_items) mutate.enforce_time_signature(container, time_signatures, disable_rewrite_meter=True, ) if rewrite_meter: mutate.auto_rewrite_meter(container) if use_multimeasure_rests: mutate.rests_to_multimeasure_rest(container[:])