def _copy_override_and_set_from_leaf(self, leaf): if getattr(leaf, '_lilypond_grob_name_manager', None) is not None: self._lilypond_grob_name_manager = copy.copy(override(leaf)) if getattr(leaf, '_lilypond_setting_name_manager', None) is not None: self._lilypond_setting_name_manager = copy.copy(setting(leaf)) new_wrappers = [] for wrapper in leaf._wrappers: new_wrapper = copy.copy(wrapper) new_wrappers.append(new_wrapper) for new_wrapper in new_wrappers: attach(new_wrapper, self)
def __illustrate__(self): """ Illustrates articulation. Returns LilyPond file. """ note = abjad.Note("c'4") articulation = copy.copy(self) attach(articulation, note) lilypond_file = abjad.LilyPondFile.new(note) return lilypond_file
def __call__(self, expr, timespan=None): r'''Calls handler on `expr`. Returns none. ''' prototype = (scoretools.Note, scoretools.Chord) hash_mark_counts = datastructuretools.CyclicTuple( self.hash_mark_counts) leaves = iterate(expr).by_class(prototype) for i, leaf in enumerate(leaves): hash_mark_count = hash_mark_counts[i] stem_tremolo = indicatortools.StemTremolo(hash_mark_count) attach(stem_tremolo, leaf)
def __copy__(self, *arguments): r'''Shallow copies leaf. Returns new leaf. ''' new = Component.__copy__(self, *arguments) grace_container = self._grace_container if grace_container is not None: new_grace_container = grace_container._copy_with_children() attach(new_grace_container, new) after_grace_container = self._after_grace_container if after_grace_container is not None: new_after_grace_container = \ after_grace_container._copy_with_children() attach(new_after_grace_container, new) return new
def __call__(self, expr): r'''Calls handler on `expr`. Returns none. ''' prototype = (scoretools.Note, scoretools.Chord) hash_mark_counts = datastructuretools.CyclicTuple( self.hash_mark_counts) leaves = list(iterate(expr).by_class(prototype)) total_length = len(leaves) for i, leaf in enumerate(leaves): if self.pattern is not None: if not self.pattern.matches_index(i, total_length): continue hash_mark_count = hash_mark_counts[i] stem_tremolo = indicatortools.StemTremolo(hash_mark_count) attach(stem_tremolo, leaf)
def _set_duration(self, new_duration, repeat_ties=False): import abjad new_duration = Duration(new_duration) # change LilyPond multiplier if leaf already has LilyPond multiplier if self._get_indicators(Multiplier): detach(Multiplier, self) multiplier = new_duration.__div__(self.written_duration) attach(multiplier, self) return select(self) # change written duration if new duration is assignable try: self.written_duration = new_duration return select(self) except AssignabilityError: pass # make new notes or tuplets if new duration is nonassignable maker = abjad.NoteMaker(repeat_ties=repeat_ties, ) components = maker(0, new_duration) if isinstance(components[0], abjad.Leaf): tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for leaf, component in zip(all_leaves, components): leaf.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) parentage = abjad.inspect(self).get_parentage() if not abjad.inspect(parentage).get_spanners(abjad.Tie): tie = abjad.Tie() if tie._attachment_test(self): tie = abjad.Tie(repeat=repeat_ties) attach(tie, all_leaves) return select(all_leaves) else: assert isinstance(components[0], abjad.Tuplet) tuplet = components[0] components = tuplet[:] tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for leaf, component in zip(all_leaves, components): leaf.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) if not self._get_spanners(abjad.Tie): tie = abjad.Tie() if tie._attachment_test(self): tie = abjad.Tie(repeat=repeat_ties) attach(tie, all_leaves) multiplier = tuplet.multiplier tuplet = abjad.Tuplet(multiplier, []) abjad.mutate(all_leaves).wrap(tuplet) return select(tuplet)
def save_composition(name: str, agent_name: str, composition: CompositionEnvironment, out_dir: str): score = Score() staff_group = scoretools.StaffGroup([], context_name='StaffGroup') for voice in composition.voices + composition.given_voices: staff = Staff([voice]) if voice.name == "cantus": attach(Clef("alto"), staff) attach(composition.composition_parameters.scale.key_signature, staff) staff_group.append(staff) tempo = Tempo(Duration(4, 4), 60) attach(tempo, staff_group[0]) score.append(staff_group) score.add_final_bar_line() lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.composer = markuptools.Markup(agent_name) lilypond_file.header_block.title = markuptools.Markup(name) lilypond_file.header_block.tagline = markuptools.Markup() midi_block = lilypondfiletools.Block(name="midi") context_block = lilypondfiletools.Block(name="context") channel_mapping = lilypondfiletools.Block(name="score") # channel_mapping.midiChannelMapping = "instrument" # context_block.items.append(channel_mapping) # midi_block.items.append(context_block) lilypond_file.score_block.items.append(midi_block) layout_block = lilypondfiletools.Block(name="layout") lilypond_file.score_block.items.append(layout_block) filename = name + ".ly" if not os.path.exists(out_dir): os.makedirs(out_dir) out_path = os.path.join(out_dir, filename) with open(out_path, mode="w") as f: f.write(format(lilypond_file))
def rhythm( class_, selections, divisions=None, attach_lilypond_voice_commands=None, implicit_scaling=None, pitched_staff=None, simultaneous_selections=None, time_signatures=None, ): r'''Makes rhythm-styled LilyPond file. .. container:: example Makes rhythmic staff: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> score = lilypond_file[abjad.Score] >>> abjad.f(score) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new RhythmicStaff { { % measure \time 3/4 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 1/4 c'8 [ c'8 ] } % measure } >> .. container:: example Set time signatures explicitly: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... [(6, 8), (4, 8), (2, 8)], ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> score = lilypond_file[abjad.Score] >>> abjad.f(score) \new Score << \new GlobalContext { { % measure \time 6/8 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 2/8 s1 * 1/4 } % measure } \new RhythmicStaff { { % measure \time 6/8 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 2/8 c'8 [ c'8 ] } % measure } >> .. container:: example Makes pitched staff: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... pitched_staff=True, ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> abjad.f(lilypond_file[abjad.Score]) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new Staff { { % measure \time 3/4 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 1/4 c'8 [ c'8 ] } % measure } >> .. container:: example Makes simultaneous voices: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> for note in abjad.iterate(selections).components(abjad.Note): ... note.written_pitch = abjad.NamedPitch("e'") ... >>> selection_1 = selections[0] + selections[1] + selections[2] >>> selections = [ ... maker(12 * [0], [(1, 16)]), ... maker(16 * [0], [(1, 32)]), ... maker(4 * [0], [(1, 16)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> selection_2 = selections[0] + selections[1] + selections[2] >>> selections = { ... 'Voice 1': selection_1, ... 'Voice 2': selection_2, ... } >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... ) >>> voice_1 = lilypond_file['Voice 1'] >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1) >>> voice_2 = lilypond_file['Voice 2'] >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> abjad.f(lilypond_file[abjad.Score]) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new Staff << \context Voice = "Voice 1" { \voiceOne e'8 [ e'8 e'8 e'8 e'8 e'8 ] e'16 [ e'16 e'16 e'16 e'16 e'16 e'16 e'16 ] e'8 [ e'8 ] } \context Voice = "Voice 2" { \voiceTwo c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] c'32 [ c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 ] c'16 [ c'16 c'16 c'16 ] } >> >> Returns LilyPond file. ''' if isinstance(selections, list): for selection in selections: if not isinstance(selection, Selection): message = f'must be selection: {selection!r}.' raise TypeError(message) elif isinstance(selections, dict): for selection in selections.values(): if not isinstance(selection, Selection): message = f'must be selection: {selection!r}.' raise TypeError(message) else: message = f'must be list or dictionary: {selections!r}.' raise TypeError(message) score = Score() lilypond_file = LilyPondFile.new( score, includes=['default.ily', 'rhythm-maker-docs.ily'], ) if pitched_staff is None: if isinstance(selections, list): selections_ = selections elif isinstance(selections, dict): selections_ = selections.values() else: raise TypeError(selections) for note in iterate(selections_).leaves(Note): if note.written_pitch != NamedPitch("c'"): pitched_staff = True break if isinstance(selections, list): if divisions is None: duration = abjad_inspect(selections).get_duration() divisions = [duration] time_signatures = time_signatures or divisions maker = MeasureMaker(implicit_scaling=implicit_scaling) measures = maker(time_signatures) if pitched_staff: staff = Staff(measures) else: staff = Staff(measures, lilypond_type='RhythmicStaff') selections = sequence(selections).flatten(depth=-1) selections_ = copy.deepcopy(selections) try: agent = mutate(staff) measures = agent.replace_measure_contents(selections) except StopIteration: if pitched_staff: staff = Staff(selections_) else: staff = Staff( selections_, lilypond_type='RhythmicStaff', ) elif isinstance(selections, dict): voices = [] for voice_name in sorted(selections): selections_ = selections[voice_name] selections_ = sequence(selections_).flatten(depth=-1) selections_ = copy.deepcopy(selections_) voice = Voice(selections_, name=voice_name) if attach_lilypond_voice_commands: voice_name_to_command_string = { 'Voice 1': 'voiceOne', 'Voice 2': 'voiceTwo', 'Voice 3': 'voiceThree', 'Voice 4': 'voiceFour', } command_string = voice_name_to_command_string.get( voice_name, ) if command_string: command = LilyPondLiteral('\\' + command_string) attach(command, voice) voices.append(voice) staff = Staff(voices, is_simultaneous=True) if divisions is None: duration = abjad_inspect(staff).get_duration() divisions = [duration] else: message = 'must be list or dictionary of selections:' message += f' {selections!r}.' raise TypeError(message) score.append(staff) assert isinstance(divisions, collections.Sequence), repr(divisions) time_signatures = time_signatures or divisions context = Context(lilypond_type='GlobalContext') maker = MeasureMaker(implicit_scaling=implicit_scaling) measures = maker(time_signatures) context.extend(measures) score.insert(0, context) return lilypond_file
def attach_defaults(self, argument) -> typing.List: r'''Attaches defaults to all staff and staff group contexts in ``argument`` when ``argument`` is a score. Attaches defaults to ``argument`` (without iterating ``argument``) when ``argument`` is a staff or staff group. Returns list of one wrapper for every indicator attached. ''' assert isinstance(argument, (Score, Staff, StaffGroup)), repr(argument) wrappers: typing.List[Wrapper] = [] tag = Tags().REMOVE_ALL_EMPTY_STAVES empty_prototype = (MultimeasureRest, Skip) prototype = (Staff, StaffGroup) if isinstance(argument, Score): staff__groups = select(argument).components(prototype) staves = select(argument).components(Staff) elif isinstance(argument, Staff): staff__groups = [argument] staves = [argument] else: assert isinstance(argument, StaffGroup), repr(argument) staff__groups = [argument] staves = [] for staff__group in staff__groups: leaf = None voices = select(staff__group).components(Voice) # find first leaf in first nonempty voice for voice in voices: leaves = select(voice).leaves() if not all(isinstance(_, empty_prototype) for _ in leaves): leaf = inspect(voice).get_leaf(0) # otherwise, find first leaf in voice in non-removable staff if leaf is None: for voice in voices: voice_might_vanish = False for component in inspect(voice).get_parentage(): if inspect(component).get_annotation(tag) is True: voice_might_vanish = True if not voice_might_vanish: leaf = inspect(voice).get_leaf(0) if leaf is not None: break # otherwise, as last resort find first leaf in first voice if leaf is None: leaf = inspect(voices[0]).get_leaf(0) if leaf is None: continue instrument = inspect(leaf).get_indicator(Instrument) if instrument is None: string = 'default_instrument' instrument = inspect(staff__group).get_annotation(string) if instrument is not None: wrapper = attach(instrument, leaf, tag='ST1', wrapper=True) wrappers.append(wrapper) margin_markup = inspect(leaf).get_indicator(MarginMarkup) if margin_markup is None: string = 'default_margin_markup' margin_markup = inspect(staff__group).get_annotation(string) if margin_markup is not None: wrapper = attach( margin_markup, leaf, tag=Tag('-PARTS').prepend('ST2'), wrapper=True, ) wrappers.append(wrapper) for staff in staves: leaf = inspect(staff).get_leaf(0) clef = inspect(leaf).get_indicator(Clef) if clef is not None: continue clef = inspect(staff).get_annotation('default_clef') if clef is not None: wrapper = attach(clef, leaf, tag='ST3', wrapper=True) wrappers.append(wrapper) return wrappers
def _split_by_durations( self, durations, cyclic=False, fracture_spanners=False, tie_split_notes=True, repeat_ties=False, ): import abjad durations = [Duration(_) for _ in durations] durations = abjad.sequence(durations) leaf_duration = abjad.inspect(self).get_duration() if cyclic: durations = durations.repeat_to_weight(leaf_duration) if sum(durations) < leaf_duration: last_duration = leaf_duration - sum(durations) durations = list(durations) durations.append(last_duration) durations = abjad.sequence(durations) durations = durations.truncate(weight=leaf_duration) result_selections = [] # detach grace containers grace_container = self._detach_grace_container() after_grace_container = self._detach_after_grace_container() leaf_prolation = abjad.inspect(self).get_parentage().prolation for duration in durations: new_leaf = copy.copy(self) preprolated_duration = duration / leaf_prolation selection = new_leaf._set_duration( preprolated_duration, repeat_ties=repeat_ties, ) result_selections.append(selection) result_components = abjad.sequence(result_selections).flatten(depth=-1) result_components = select(result_components) result_leaves = select(result_components).leaves() assert all(isinstance(_, abjad.Selection) for _ in result_selections) assert all(isinstance(_, Component) for _ in result_components) assert result_leaves.are_leaves() if abjad.inspect(self).has_spanner(abjad.Tie): for leaf in result_leaves: detach(abjad.Tie, leaf) # strip result leaves of indicators (other than multipliers) for leaf in result_leaves: multiplier = abjad.inspect(leaf).get_indicator(Multiplier) detach(object, leaf) if multiplier is not None: attach(multiplier, leaf) # replace leaf with flattened result selection = select(self) parent, start, stop = selection._get_parent_and_start_stop_indices() if parent: parent.__setitem__(slice(start, stop + 1), result_components) else: selection._give_dominant_spanners(result_components) selection._withdraw_from_crossing_spanners() # fracture spanners if fracture_spanners: first_selection = result_selections[0] for spanner in abjad.inspect(first_selection[-1]).get_spanners(): index = spanner._index(first_selection[-1]) spanner._fracture(index, direction=abjad.Right) last_selection = result_selections[-1] for spanner in abjad.inspect(last_selection[0]).get_spanners(): index = spanner._index(last_selection[0]) spanner._fracture(index, direction=abjad.Left) for middle_selection in result_selections[1:-1]: spanners = abjad.inspect(middle_selection[0]).get_spanners() for spanner in spanners: index = spanner._index(middle_selection[0]) spanner._fracture(index, direction=abjad.Left) spanners = abjad.inspect(middle_selection[-1]).get_spanners() for spanner in spanners: index = spanner._index(middle_selection[-1]) spanner._fracture(index, direction=abjad.Right) # move indicators first_result_leaf = result_leaves[0] last_result_leaf = result_leaves[-1] for indicator in abjad.inspect(self).get_indicators(): if isinstance(indicator, Multiplier): continue detach(indicator, self) direction = getattr(indicator, '_time_orientation', abjad.Left) if direction == abjad.Left: attach(indicator, first_result_leaf) elif direction == abjad.Right: attach(indicator, last_result_leaf) else: raise ValueError(direction) # move grace containers if grace_container is not None: container = grace_container[0] assert isinstance(container, abjad.GraceContainer), repr(container) attach(container, first_result_leaf) if after_grace_container is not None: container = after_grace_container[0] prototype = abjad.AfterGraceContainer assert isinstance(container, prototype), repr(container) attach(container, last_result_leaf) if isinstance(result_components[0], abjad.Tuplet): abjad.mutate(result_components).fuse() # tie split notes if isinstance(self, (abjad.Note, abjad.Chord)) and tie_split_notes: result_leaves._attach_tie_spanner_to_leaves( repeat_ties=repeat_ties, ) assert isinstance(result_selections, list), repr(result_selections) assert all(isinstance(_, abjad.Selection) for _ in result_selections) return result_selections
def rhythm( class_, selections, divisions=None, attach_lilypond_voice_commands=None, implicit_scaling=None, pitched_staff=None, simultaneous_selections=None, time_signatures=None, ): r""" Makes rhythm-styled LilyPond file. .. container:: example Makes rhythmic staff: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> score = lilypond_file[abjad.Score] >>> abjad.f(score) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new RhythmicStaff { { % measure \time 3/4 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 1/4 c'8 [ c'8 ] } % measure } >> .. container:: example Set time signatures explicitly: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... [(6, 8), (4, 8), (2, 8)], ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> score = lilypond_file[abjad.Score] >>> abjad.f(score) \new Score << \new GlobalContext { { % measure \time 6/8 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 2/8 s1 * 1/4 } % measure } \new RhythmicStaff { { % measure \time 6/8 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 2/8 c'8 [ c'8 ] } % measure } >> .. container:: example Makes pitched staff: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... pitched_staff=True, ... ) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> abjad.f(lilypond_file[abjad.Score]) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new Staff { { % measure \time 3/4 c'8 [ c'8 c'8 c'8 c'8 c'8 ] } % measure { % measure \time 4/8 c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] } % measure { % measure \time 1/4 c'8 [ c'8 ] } % measure } >> .. container:: example Makes simultaneous voices: >>> divisions = [(3, 4), (4, 8), (1, 4)] >>> maker = abjad.NoteMaker() >>> selections = [ ... maker(6 * [0], [(1, 8)]), ... maker(8 * [0], [(1, 16)]), ... maker(2 * [0], [(1, 8)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> for note in abjad.iterate(selections).components(abjad.Note): ... note.written_pitch = abjad.NamedPitch("e'") ... >>> selection_1 = selections[0] + selections[1] + selections[2] >>> selections = [ ... maker(12 * [0], [(1, 16)]), ... maker(16 * [0], [(1, 32)]), ... maker(4 * [0], [(1, 16)]), ... ] >>> for selection in selections: ... abjad.attach(abjad.Beam(), selection[:]) ... >>> selection_2 = selections[0] + selections[1] + selections[2] >>> selections = { ... 'Voice 1': selection_1, ... 'Voice 2': selection_2, ... } >>> lilypond_file = abjad.LilyPondFile.rhythm( ... selections, ... divisions, ... ) >>> voice_1 = lilypond_file['Voice 1'] >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1) >>> voice_2 = lilypond_file['Voice 2'] >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> abjad.f(lilypond_file[abjad.Score]) \new Score << \new GlobalContext { { % measure \time 3/4 s1 * 3/4 } % measure { % measure \time 4/8 s1 * 1/2 } % measure { % measure \time 1/4 s1 * 1/4 } % measure } \new Staff << \context Voice = "Voice 1" { \voiceOne e'8 [ e'8 e'8 e'8 e'8 e'8 ] e'16 [ e'16 e'16 e'16 e'16 e'16 e'16 e'16 ] e'8 [ e'8 ] } \context Voice = "Voice 2" { \voiceTwo c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] c'32 [ c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 c'32 ] c'16 [ c'16 c'16 c'16 ] } >> >> Returns LilyPond file. """ if isinstance(selections, list): for selection in selections: if not isinstance(selection, Selection): message = f'must be selection: {selection!r}.' raise TypeError(message) elif isinstance(selections, dict): for selection in selections.values(): if not isinstance(selection, Selection): message = f'must be selection: {selection!r}.' raise TypeError(message) else: message = f'must be list or dictionary: {selections!r}.' raise TypeError(message) score = Score() lilypond_file = LilyPondFile.new( score, includes=['default.ily', 'rhythm-maker-docs.ily'], ) if pitched_staff is None: if isinstance(selections, list): selections_ = selections elif isinstance(selections, dict): selections_ = selections.values() else: raise TypeError(selections) for note in iterate(selections_).leaves(Note): if note.written_pitch != NamedPitch("c'"): pitched_staff = True break if isinstance(selections, list): if divisions is None: duration = abjad_inspect(selections).get_duration() divisions = [duration] time_signatures = time_signatures or divisions maker = MeasureMaker(implicit_scaling=implicit_scaling) measures = maker(time_signatures) if pitched_staff: staff = Staff(measures) else: staff = Staff(measures, lilypond_type='RhythmicStaff') selections = sequence(selections).flatten(depth=-1) selections_ = copy.deepcopy(selections) try: agent = mutate(staff) measures = agent.replace_measure_contents(selections) except StopIteration: if pitched_staff: staff = Staff(selections_) else: staff = Staff( selections_, lilypond_type='RhythmicStaff', ) elif isinstance(selections, dict): voices = [] for voice_name in sorted(selections): selections_ = selections[voice_name] selections_ = sequence(selections_).flatten(depth=-1) selections_ = copy.deepcopy(selections_) voice = Voice(selections_, name=voice_name) if attach_lilypond_voice_commands: voice_name_to_command_string = { 'Voice 1': 'voiceOne', 'Voice 2': 'voiceTwo', 'Voice 3': 'voiceThree', 'Voice 4': 'voiceFour', } command_string = voice_name_to_command_string.get( voice_name, ) if command_string: command = LilyPondLiteral('\\' + command_string) attach(command, voice) voices.append(voice) staff = Staff(voices, is_simultaneous=True) if divisions is None: duration = abjad_inspect(staff).get_duration() divisions = [duration] else: message = 'must be list or dictionary of selections:' message += f' {selections!r}.' raise TypeError(message) score.append(staff) assert isinstance(divisions, collections.Sequence), repr(divisions) time_signatures = time_signatures or divisions context = Context(lilypond_type='GlobalContext') maker = MeasureMaker(implicit_scaling=implicit_scaling) measures = maker(time_signatures) context.extend(measures) score.insert(0, context) return lilypond_file