def _get_sounding_pitch(self): if "sounding pitch" in inspect(self).indicators(str): return self.written_pitch else: instrument = self._get_effective(instruments.Instrument) if instrument: sounding_pitch = instrument.middle_c_sounding_pitch else: sounding_pitch = NamedPitch("C4") interval = NamedPitch("C4") - sounding_pitch sounding_pitch = interval.transpose(self.written_pitch) return sounding_pitch
def _get_sounding_pitch(self): if "sounding pitch" in inspect(self).indicators(str): return self.written_pitch else: instrument = self._get_effective(instruments.Instrument) if instrument: sounding_pitch = instrument.middle_c_sounding_pitch else: sounding_pitch = NamedPitch("C4") interval = NamedPitch("C4") - sounding_pitch sounding_pitch = interval.transpose(self.written_pitch) return sounding_pitch
def _get_sounding_pitch(self): import abjad if 'sounding pitch' in abjad.inspect(self).indicators(str): return self.written_pitch else: instrument = self._get_effective(abjad.Instrument) if instrument: sounding_pitch = instrument.middle_c_sounding_pitch else: sounding_pitch = NamedPitch('C4') interval = NamedPitch('C4') - sounding_pitch sounding_pitch = interval.transpose(self.written_pitch) return sounding_pitch
def __init__( self, *, interval: typing.Union[str, NamedInterval] = None, is_harmonic: bool = None, left_broken: bool = None, pitch: typing.Union[str, NamedPitch] = None, right_broken: bool = None, ) -> None: Spanner.__init__(self) if interval is not None and pitch is not None: message = 'only pitch or interval, not both:' message += f' {interval!r} + {pitch!r}.' raise Exception(message) if interval is not None: interval = NamedInterval(interval) self._interval = interval if is_harmonic is not None: is_harmonic = bool(is_harmonic) self._is_harmonic = is_harmonic if left_broken is not None: left_broken = bool(left_broken) self._left_broken = left_broken if pitch is not None: pitch = NamedPitch(pitch) self._pitch = pitch if right_broken is not None: right_broken = bool(right_broken) self._right_broken = right_broken
def _clef_name_to_staff_position_zero(self, clef_name): return { 'treble': NamedPitch('B4'), 'alto': NamedPitch('C4'), 'tenor': NamedPitch('A3'), 'bass': NamedPitch('D3'), 'french': NamedPitch('D5'), 'soprano': NamedPitch('G4'), 'mezzosoprano': NamedPitch('E4'), 'baritone': NamedPitch('F3'), 'varbaritone': NamedPitch('F3'), 'percussion': None, 'tab': None, }[clef_name]
def written_pitch(self, argument): if argument is None: if self.note_head is not None: self.note_head.written_pitch = None else: if self.note_head is None: self.note_head = NoteHead(self, written_pitch=None) else: pitch = NamedPitch(argument) self.note_head.written_pitch = pitch
def from_selection(selection) -> "Clef": """ Makes clef from ``selection``. .. container:: example >>> maker = abjad.NoteMaker() >>> notes = maker(range(-12, -6), [(1, 4)]) >>> staff = abjad.Staff(notes) >>> abjad.Clef.from_selection(staff) Clef('bass') Choses between treble and bass based on minimal number of ledger lines. """ pitches = iterate(selection).pitches() diatonic_pitch_numbers = [ pitch._get_diatonic_pitch_number() for pitch in pitches ] max_diatonic_pitch_number = max(diatonic_pitch_numbers) min_diatonic_pitch_number = min(diatonic_pitch_numbers) lowest_treble_line_pitch = NamedPitch("E4") lowest_treble_line_diatonic_pitch_number = ( lowest_treble_line_pitch._get_diatonic_pitch_number() ) candidate_steps_below_treble = ( lowest_treble_line_diatonic_pitch_number - min_diatonic_pitch_number ) highest_bass_line_pitch = NamedPitch("A3") highest_bass_line_diatonic_pitch_number = ( highest_bass_line_pitch._get_diatonic_pitch_number() ) candidate_steps_above_bass = ( max_diatonic_pitch_number - highest_bass_line_diatonic_pitch_number ) if candidate_steps_above_bass < candidate_steps_below_treble: return Clef("bass") else: return Clef("treble")
def __init__( self, *, interval: typing.Union[str, NamedInterval] = None, pitch: typing.Union[str, NamedPitch] = None, tweaks: LilyPondTweakManager = None, ) -> None: if interval is not None: interval = NamedInterval(interval) self._interval = interval if pitch is not None: pitch = NamedPitch(pitch) self._pitch = pitch if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def from_selection(selection) -> "Clef": """ Makes clef from ``selection``. .. container:: example >>> maker = abjad.NoteMaker() >>> notes = maker(range(-12, -6), [(1, 4)]) >>> staff = abjad.Staff(notes) >>> abjad.Clef.from_selection(staff) Clef('bass') Choses between treble and bass based on minimal number of ledger lines. """ pitches = iterate(selection).pitches() diatonic_pitch_numbers = [ pitch._get_diatonic_pitch_number() for pitch in pitches ] max_diatonic_pitch_number = max(diatonic_pitch_numbers) min_diatonic_pitch_number = min(diatonic_pitch_numbers) lowest_treble_line_pitch = NamedPitch("E4") lowest_treble_line_diatonic_pitch_number = ( lowest_treble_line_pitch._get_diatonic_pitch_number() ) candidate_steps_below_treble = ( lowest_treble_line_diatonic_pitch_number - min_diatonic_pitch_number ) highest_bass_line_pitch = NamedPitch("A3") highest_bass_line_diatonic_pitch_number = ( highest_bass_line_pitch._get_diatonic_pitch_number() ) candidate_steps_above_bass = ( max_diatonic_pitch_number - highest_bass_line_diatonic_pitch_number ) if candidate_steps_above_bass < candidate_steps_below_treble: return Clef("bass") else: return Clef("treble")
def __init__( self, *arguments, multiplier: typings.DurationTyping = None, tag: str = None, ) -> None: from abjad.ly import drums from .Chord import Chord assert len(arguments) in (0, 1, 2) if len(arguments) == 1 and isinstance(arguments[0], str): string = f"{{ {arguments[0]} }}" parsed = parse(string) assert len(parsed) == 1 and isinstance(parsed[0], Leaf) arguments = tuple([parsed[0]]) written_pitch = None is_cautionary = False is_forced = False is_parenthesized = False if len(arguments) == 1 and isinstance(arguments[0], Leaf): leaf = arguments[0] written_pitch = None written_duration = leaf.written_duration if multiplier is None: multiplier = leaf.multiplier if isinstance(leaf, Note) and leaf.note_head is not None: written_pitch = leaf.note_head.written_pitch is_cautionary = leaf.note_head.is_cautionary is_forced = leaf.note_head.is_forced is_parenthesized = leaf.note_head.is_parenthesized # TODO: move into separate from_chord() constructor: elif isinstance(leaf, Chord): written_pitches = [x.written_pitch for x in leaf.note_heads] if written_pitches: written_pitch = written_pitches[0] is_cautionary = leaf.note_heads[0].is_cautionary is_forced = leaf.note_heads[0].is_forced is_parenthesized = leaf.note_heads[0].is_parenthesized elif len(arguments) == 2: written_pitch, written_duration = arguments elif len(arguments) == 0: written_pitch = NamedPitch("C4") written_duration = Duration(1, 4) else: raise ValueError("can not initialize note from {arguments!r}.") Leaf.__init__(self, written_duration, multiplier=multiplier, tag=tag) if written_pitch is not None: if written_pitch not in drums: self.note_head = NoteHead( written_pitch=written_pitch, is_cautionary=is_cautionary, is_forced=is_forced, is_parenthesized=is_parenthesized, ) else: assert isinstance(written_pitch, str), repr(written_pitch) self.note_head = DrumNoteHead( written_pitch=written_pitch, is_cautionary=is_cautionary, is_forced=is_forced, is_parenthesized=is_parenthesized, ) else: self._note_head = None if len(arguments) == 1 and isinstance(arguments[0], Leaf): self._copy_override_and_set_from_leaf(arguments[0])
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).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).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 written_pitch(self, argument): written_pitch = NamedPitch(argument) self._written_pitch = written_pitch if self.alternative is not None: self.alternative[0].written_pitch = written_pitch
def _clef_name_to_staff_position_zero(self, clef_name): return { "treble": NamedPitch("B4"), "alto": NamedPitch("C4"), "varC": NamedPitch("C4"), "tenor": NamedPitch("A3"), "tenorvarC": NamedPitch("A3"), "bass": NamedPitch("D3"), "french": NamedPitch("D5"), "soprano": NamedPitch("G4"), "mezzosoprano": NamedPitch("E4"), "baritone": NamedPitch("F3"), "varbaritone": NamedPitch("F3"), "percussion": None, "tab": None, }[clef_name]
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.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 { \time 3/4 s1 * 3/4 \time 4/8 s1 * 1/2 \time 1/4 s1 * 1/4 } \new RhythmicStaff { c'8 [ c'8 c'8 c'8 c'8 c'8 ] c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] c'8 [ c'8 ] } >> .. 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.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 { \time 6/8 s1 * 3/4 \time 4/8 s1 * 1/2 \time 2/8 s1 * 1/4 } \new RhythmicStaff { c'8 [ c'8 c'8 c'8 c'8 c'8 ] c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] c'8 [ c'8 ] } >> .. 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.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 { \time 3/4 s1 * 3/4 \time 4/8 s1 * 1/2 \time 1/4 s1 * 1/4 } \new Staff { c'8 [ c'8 c'8 c'8 c'8 c'8 ] c'16 [ c'16 c'16 c'16 c'16 c'16 c'16 c'16 ] c'8 [ c'8 ] } >> .. 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.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.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'] >>> literal = abjad.LilyPondLiteral(r'\voiceOne', "opening") >>> abjad.attach(literal, voice_1) >>> voice_2 = lilypond_file['Voice_2'] >>> literal = abjad.LilyPondLiteral(r'\voiceTwo', "opening") >>> abjad.attach(literal, voice_2) >>> abjad.show(lilypond_file) # doctest: +SKIP .. docs:: >>> abjad.f(lilypond_file[abjad.Score]) \new Score << \new GlobalContext { s1 * 3/4 s1 * 1/2 s1 * 1/4 } \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, Selection): pass elif isinstance(selections, list): for selection in selections: if not isinstance(selection, Selection): raise TypeError(f"must be selection: {selection!r}.") elif isinstance(selections, dict): for selection in selections.values(): if not isinstance(selection, Selection): raise TypeError(f"must be selection: {selection!r}.") else: raise TypeError(f"must be list or dictionary: {selections!r}.") score = Score() lilypond_file = LilyPondFile.new( score, includes=["default.ily", "rhythm-maker-docs.ily"] ) if pitched_staff is None: if isinstance(selections, (list, Selection)): selections_ = selections elif isinstance(selections, dict): selections_ = selections.values() else: raise TypeError(selections) for note in select(selections_).notes(): if note.written_pitch != NamedPitch("c'"): pitched_staff = True break chords = select(selections_).chords() if chords: pitched_staff = True if isinstance(selections, (list, Selection)): if divisions is None: duration = abjad_inspect(selections).duration() divisions = [duration] time_signatures = time_signatures or divisions time_signatures = [TimeSignature(_) for _ in time_signatures] if pitched_staff: staff = Staff() else: staff = Staff(lilypond_type="RhythmicStaff") staff.extend(selections) 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, simultaneous=True) if divisions is None: duration = abjad_inspect(staff).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.abc.Sequence), repr(divisions) time_signatures = time_signatures or divisions context = Context(lilypond_type="GlobalContext") skips = [] for time_signature in time_signatures: skip = Skip(1) skip.multiplier = time_signature attach(time_signature, skip, context="Score") skips.append(skip) context.extend(skips) score.insert(0, context) return lilypond_file