def _scale(self, multiplier=None): from abjad.tools import indicatortools if multiplier is None: return multiplier = durationtools.Multiplier(multiplier) old_time_signature = self.time_signature if mathtools.is_nonnegative_integer_power_of_two(multiplier) and \ 1 <= multiplier: old_numerator = old_time_signature.numerator old_denominator = old_time_signature.denominator new_denominator = old_denominator // multiplier.numerator pair = (old_numerator, new_denominator) new_time_signature = indicatortools.TimeSignature(pair) else: old_denominator = old_time_signature.denominator old_duration = old_time_signature.duration new_duration = multiplier * old_duration new_time_signature = \ self._duration_and_possible_denominators_to_time_signature( new_duration, [old_denominator], multiplier.denominator, ) detach(indicatortools.TimeSignature, self) attach(new_time_signature, self) contents_multiplier_denominator = \ mathtools.greatest_power_of_two_less_equal(multiplier.denominator) pair = (multiplier.numerator, contents_multiplier_denominator) contents_multiplier = durationtools.Multiplier(*pair) self._scale_contents(contents_multiplier)
def make_skips( written_duration, multiplied_durations, ): '''Make `written_duration` skips with `multiplied_durations`: :: >>> scoretools.make_skips( ... Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]) Selection(Skip('s4 * 2'), Skip('s4 * 4/3'), Skip('s4 * 1'), Skip('s4 * 4/5')) Useful for making invisible layout voices. Returns selection. ''' from abjad.tools import scoretools # initialize skips and written duration skips = [] written_duration = durationtools.Duration(written_duration) # make skips for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) skip = scoretools.Skip(written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, skip) skips.append(skip) # return skips skips = selectiontools.Selection(skips) return skips
def edit_second_violin_voice(score, durated_reservoir): r'''Edits second violin voice. ''' voice = score['Second Violin Voice'] descents = durated_reservoir['Second Violin'] last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() copied_descent = list(copied_descent) copied_descent[-1].written_duration = durationtools.Duration(1, 1) copied_descent.append(scoretools.Note('a2')) for leaf in copied_descent: articulation = indicatortools.Articulation('accent') attach(articulation, leaf) articulation = indicatortools.Articulation('tenuto') attach(articulation, leaf) voice.extend(copied_descent) final_sustain = [] for _ in range(32): final_sustain.append(scoretools.Note('a1.')) final_sustain.append(scoretools.Note('a2')) articulation = indicatortools.Articulation('accent') attach(articulation, final_sustain[0]) articulation = indicatortools.Articulation('tenuto') attach(articulation, final_sustain[0]) voice.extend(final_sustain) tie = spannertools.Tie() attach(tie, final_sustain) voice.extend('r4 r2.')
def _construct_context_specced_music(self, context, optional_id, optional_context_mod, music): known_contexts = { "ChoirStaff": scoretools.StaffGroup, "GrandStaff": scoretools.StaffGroup, "PianoStaff": scoretools.StaffGroup, "Score": scoretools.Score, "Staff": scoretools.Staff, "StaffGroup": scoretools.StaffGroup, "Voice": scoretools.Voice, } context_name = context if context in known_contexts: context = known_contexts[context]([]) else: message = "context type {!r} not supported." message = message.format(context) raise Exception(message) if context_name in ("GrandStaff", "PianoStaff"): context.context_name = context_name if optional_id is not None: context.name = optional_id if optional_context_mod is not None: for x in optional_context_mod: print(x) # TODO: impelement context mods on contexts pass context.is_simultaneous = music.is_simultaneous # add children while len(music): component = music.pop(0) context.append(component) indicators = music._indicator_expressions for indicator in indicators: attach(indicator, context) return context
def make_notes_with_multiplied_durations( pitch, written_duration, multiplied_durations, ): '''Make `written_duration` notes with `pitch` and `multiplied_durations`: :: >>> args = [0, Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]] >>> scoretools.make_notes_with_multiplied_durations(*args) Selection(Note("c'4 * 2"), Note("c'4 * 4/3"), Note("c'4 * 1"), Note("c'4 * 4/5")) Useful for making spatially positioned notes. Returns list of notes. ''' from abjad.tools import scoretools from abjad.tools import selectiontools # initialize input written_duration = durationtools.Duration(written_duration) # make notes notes = [] for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) note = scoretools.Note(pitch, written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, note) notes.append(note) # return notes notes = selectiontools.Selection(notes) return notes
def _make_music(self, divisions, rotation): from abjad.tools import rhythmmakertools selections = [] for division in divisions: prototype = mathtools.NonreducedFraction assert isinstance(division, prototype), division for division in divisions: container = self._make_container(division) selection = selectiontools.Selection(container) selections.append(selection) beam_specifier = self._get_beam_specifier() if beam_specifier.beam_divisions_together: durations = [] for selection in selections: duration = selection.get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, nibs_towards_nonbeamable_components=False, ) components = [] for selection in selections: components.extend(selection) attach(beam, components) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() attach(beam, selection) return selections
def _apply_beam_specifier(self, selections): from abjad.tools import rhythmmakertools beam_specifier = self.beam_specifier if beam_specifier is None: beam_specifier = rhythmmakertools.BeamSpecifier() if beam_specifier.beam_divisions_together: durations = [] for x in selections: if isinstance(x, selectiontools.Selection): duration = x.get_duration() else: duration = x._get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, ) components = [] for x in selections: if isinstance(x, selectiontools.Selection): components.extend(x) elif isinstance(x, scoretools.Tuplet): components.append(x) else: raise TypeError(x) attach(beam, components) elif beam_specifier.beam_each_division: for cell in selections: beam = spannertools.MultipartBeam() attach(beam, cell)
def make_score_with_indicators_01(self): r'''Make 200-note voice with dynamic on every 20th note: :: 2.12 (r9704) initialization: 630,433 function calls 2.12 (r9710) initialization: 235,120 function calls 2.12 r(9726) initialization: 235,126 function calls 2.12 (r9704) LilyPond format: 136,637 function calls 2.12 (r9710) LilyPond format: 82,730 function calls 2.12 (r9726) LilyPond format: 88,382 function calls ''' from abjad.tools import indicatortools from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import topleveltools staff = scoretools.Staff(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( staff[:], [20], cyclic=True, ): dynamic = indicatortools.Dynamic('f') topleveltools.attach(dynamic, part[0]) return staff
def make_score_with_indicators_02(self): r'''Make 200-note staff with dynamic on every 4th note. :: 2.12 (r9704) initialization: 4,632,761 function calls 2.12 (r9710) initialization: 327,280 function calls 2.12 (r9726) initialization: 325,371 function calls 2.12 (r9704) LilyPond format: 220,277 function calls 2.12 (r9710) LilyPond format: 84,530 function calls 2.12 (r9726) LilyPond format: 90,056 function calls ''' from abjad.tools import indicatortools from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import topleveltools staff = scoretools.Staff(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( staff[:], [4], cyclic=True, ): dynamic = indicatortools.Dynamic('f') topleveltools.attach(dynamic, part[0]) return staff
def __illustrate__(self, **kwargs): r'''Illustrates segment. Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import indicatortools from abjad.tools import lilypondfiletools from abjad.tools import markuptools from abjad.tools import scoretools from abjad.tools import schemetools from abjad.tools.topleveltools import attach from abjad.tools.topleveltools import override from abjad.tools.topleveltools import select from abjad.tools.topleveltools import set_ notes = [] for item in self: note = scoretools.Note(item, durationtools.Duration(1, 8)) notes.append(note) voice = scoretools.Voice(notes) staff = scoretools.Staff([voice]) score = scoretools.Score([staff]) score.add_final_bar_line() override(score).bar_line.transparent = True override(score).bar_number.stencil = False override(score).beam.stencil = False override(score).flag.stencil = False override(score).stem.stencil = False override(score).time_signature.stencil = False string = 'override Score.BarLine.transparent = ##f' command = indicatortools.LilyPondCommand(string, format_slot='after') last_leaf = select().by_leaf()(score)[-1][-1] attach(command, last_leaf) moment = schemetools.SchemeMoment((1, 12)) set_(score).proportional_notation_duration = moment lilypond_file = lilypondfiletools.make_basic_lilypond_file( global_staff_size=12, music=score, ) if 'title' in kwargs: title = kwargs.get('title') if not isinstance(title, markuptools.Markup): title = markuptools.Markup(title) lilypond_file.header_block.title = title if 'subtitle' in kwargs: markup = markuptools.Markup(kwargs.get('subtitle')) lilypond_file.header_block.subtitle = markup command = indicatortools.LilyPondCommand('accidentalStyle forget') lilypond_file.layout_block.items.append(command) lilypond_file.layout_block.indent = 0 string = 'markup-system-spacing.padding = 8' command = indicatortools.LilyPondCommand(string, prefix='') lilypond_file.paper_block.items.append(command) string = 'system-system-spacing.padding = 10' command = indicatortools.LilyPondCommand(string, prefix='') lilypond_file.paper_block.items.append(command) string = 'top-markup-spacing.padding = 4' command = indicatortools.LilyPondCommand(string, prefix='') lilypond_file.paper_block.items.append(command) return lilypond_file
def make_hairpin_score_03(self): r'''Make 200-note voice with crescendo spanner on every 100 notes. :: 2.12 (r9726) initialization: 249,363 function calls 2.12 (r9726) initialization: 249,363 function calls 2.12 (r9726) LilyPond format: 133,898 function calls 2.12 (r9728) LilyPond format: 128,948 function calls ''' from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import spannertools from abjad.tools import topleveltools voice = scoretools.Voice(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( voice[:], [100], cyclic=True, ): crescendo = spannertools.Crescendo() topleveltools.attach(crescendo, part) return voice
def _do_tie_consecutive_notes(self, divisions): if not self.tie_consecutive_notes: return leaves = select(divisions).by_leaf() for leaf in leaves: detach(spannertools.Tie, leaf) pairs = itertools.groupby(leaves, lambda _: _.__class__) def _get_pitches(component): if isinstance(component, scoretools.Note): return component.written_pitch elif isinstance(component, scoretools.Chord): return component.written_pitches else: raise TypeError(component) for class_, group in pairs: group = list(group) if not isinstance(group[0], (scoretools.Note, scoretools.Chord)): continue subpairs = itertools.groupby(group, lambda _: _get_pitches(_)) for pitches, subgroup in subpairs: subgroup = list(subgroup) if len(subgroup) == 1: continue tie = spannertools.Tie() assert tie._attachment_test_all(subgroup) attach(tie, subgroup)
def p_leaf__leaf_body__post_events(self, p): r'''leaf : leaf_body post_events ''' p[0] = p[1] if p[2]: annotation = {'post events': p[2]} attach(annotation, p[0])
def label_leaves_in_expr_with_pitch_numbers(expr, markup_direction=Down): r'''Label leaves in `expr` with pitch numbers: :: >>> staff = Staff(scoretools.make_leaves([None, 12, [13, 14, 15], None], [(1, 4)])) >>> labeltools.label_leaves_in_expr_with_pitch_numbers(staff) >>> print(format(staff)) \new Staff { r4 c''4 _ \markup { \small 12 } <cs'' d'' ef''>4 _ \markup { \column { \small 15 \small 14 \small 13 } } r4 } :: >>> show(staff) # doctest: +SKIP Returns none. ''' for leaf in iterate(expr).by_class(scoretools.Leaf): for pitch in reversed(pitchtools.PitchSegment.from_selection(leaf)): if pitch is not None: label = markuptools.MarkupCommand('small', str(pitch.pitch_number)) markup = markuptools.Markup(label, markup_direction) attach(markup, leaf)
def __call__(self, expr): r'''Calls handler on `expr`. Returns none. ''' assert self.dynamics_talea, repr(self.dynamics_talea) groups = [] classes = (scoretools.Note, scoretools.Chord) for i, group in enumerate(iterate(expr).by_run(classes)): spanner = spannertools.TextSpanner() attach(spanner, group) override(spanner).text_spanner.dash_fraction = 1 dynamic_string = self.dynamics_talea[i] dynamicup = markuptools.Markup([ markuptools.MarkupCommand('dynamic', dynamic_string), markuptools.MarkupCommand('hspace', 0.75)]) override(spanner).text_spanner.bound_details__left__text = \ dynamicup nib_markup = markuptools.Markup( markuptools.MarkupCommand( 'draw-line', schemetools.SchemePair(0, 1))) override(spanner).text_spanner.bound_details__right__text = \ nib_markup override(spanner).text_spanner.bound_details__right__padding = \ -0.2 override(spanner).text_spanner.bound_details__left__stencil_align_dir_y = 0 return groups
def make_spanner_score_01(self): r'''Make 200-note voice with durated complex beam spanner on every 4 notes. :: 2.12 (r9710) initialization: 248,654 function calls 2.12 (r9724) initialization: 248,660 function calls 2.12 (r9703) LilyPond format: 425,848 function calls 2.12 (r9710) LilyPond format: 426,652 function calls 2.12 (r9724) LilyPond format: 441,884 function calls ''' from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import spannertools from abjad.tools import topleveltools voice = scoretools.Voice(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( voice[:], [4], cyclic=True, ): beam = spannertools.DuratedComplexBeam() topleveltools.attach(beam, part) return voice
def __call__(self, divisions, seeds=None): r'''Calls talea rhythm-maker on `divisions`. Returns either list of tuplets or else list of note-lists. ''' duration_pairs, seeds = RhythmMaker.__call__(self, divisions, seeds) octuplet = self._prepare_input(seeds) talea, prolation_addenda = octuplet[:2] secondary_divisions = octuplet[-1] taleas = (talea, prolation_addenda, secondary_divisions) result = self._scale_taleas( duration_pairs, self.talea_denominator, taleas) duration_pairs, lcd, talea, prolation_addenda, secondary_divisions = \ result secondary_duration_pairs = self._make_secondary_duration_pairs( duration_pairs, secondary_divisions) septuplet = (talea, prolation_addenda) + octuplet[2:-1] numeric_map = self._make_numeric_map( secondary_duration_pairs, septuplet) leaf_lists = self._make_leaf_lists(numeric_map, lcd) if not prolation_addenda: result = leaf_lists else: tuplets = self._make_tuplets(secondary_duration_pairs, leaf_lists) result = tuplets if self.beam_each_cell: for cell in result: beam = spannertools.MultipartBeam() attach(beam, cell) if self.tie_split_notes: self._add_ties(result) assert isinstance(result, list), repr(result) assert all(isinstance(x, selectiontools.Selection) for x in result) or \ all(isinstance(x, scoretools.Tuplet) for x in result) return result
def make_spanner_score_02(self): r'''Make 200-note voice with durated complex beam spanner on every 20 notes. :: 2.12 (r9710) initialization: 250,954 function calls 2.12 (r9724) initialization: 248,717 function calls 2.12 (r9703) LilyPond format: 495,768 function calls 2.12 (r9710) LilyPond format: 496,572 function calls 2.12 (r9724) LilyPond format: 511,471 function calls ''' from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import spannertools from abjad.tools import topleveltools voice = scoretools.Voice(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( voice[:], [20], cyclic=True, ): beam = spannertools.DuratedComplexBeam() topleveltools.attach(beam, part) return voice
def _attach_tie_spanner_to_leaf_pair(self): from abjad.tools import scoretools from abjad.tools import spannertools assert len(self) == 2 left_leaf, right_leaf = self assert isinstance(left_leaf, scoretools.Leaf), left_leaf assert isinstance(right_leaf, scoretools.Leaf), right_leaf left_logical_tie = left_leaf._get_logical_tie() right_logical_tie = right_leaf._get_logical_tie() prototype = (spannertools.Tie,) if left_logical_tie == right_logical_tie: return try: left_tie_spanner = left_leaf._get_spanner(prototype) except MissingSpannerError: left_tie_spanner = None try: right_tie_spanner = right_leaf._get_spanner(prototype) except MissingSpannerError: right_tie_spanner = None if left_tie_spanner is not None and right_tie_spanner is not None: left_tie_spanner._fuse_by_reference(right_tie_spanner) elif left_tie_spanner is not None and right_tie_spanner is None: left_tie_spanner._append(right_leaf) elif left_tie_spanner is None and right_tie_spanner is not None: right_tie_spanner._append_left(left_leaf) elif left_tie_spanner is None and right_tie_spanner is None: tie = spannertools.Tie() attach(tie, [left_leaf, right_leaf])
def make_spanner_score_03(self): r'''Make 200-note voice with durated complex beam spanner on every 100 notes. :: 2.12 (r9710) initialization: 251,606 function calls 2.12 (r9724) initialization: 249,369 function calls 2.12 (r9703) LilyPond format: 509,752 function calls 2.12 (r9710) LilyPond format: 510,556 function calls 2.12 (r9724) LilyPond format: 525,463 function calls ''' from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools import spannertools from abjad.tools import topleveltools voice = scoretools.Voice(200 * scoretools.Note("c'16")) for part in sequencetools.partition_sequence_by_counts( voice[:], [100], cyclic=True, ): beam = spannertools.DuratedComplexBeam() topleveltools.attach(beam, part) return voice
def p_leaf__leaf_body__post_events(self, p): r'''leaf : leaf_body post_events ''' p[0] = p[1] if p[2]: annotation = indicatortools.Annotation('post events', p[2]) attach(annotation, p[0])
def __call__(self, logical_ties, timespan=None, offset=0): r'''Calls note and chord hairpin handler on `logical_ties` with `offset`. Returns none. ''' groups = self._group_contiguous_logical_ties(logical_ties) for group in groups: notes = [] for logical_tie in group: for note in logical_tie: notes.append(note) if len(notes) <= 1: continue total_notes = len(notes) notes_to_span = [] for i, note in enumerate(notes): if self._index_matches_patterns(i, total_notes): notes_to_span.append(note) if not notes_to_span: continue descriptor = ' '.join([_ for _ in self.hairpin_token if _]) hairpin = spannertools.Hairpin( descriptor=descriptor, include_rests=False, ) attach(hairpin, notes_to_span)
def _make_music(self, divisions, seeds): from abjad.tools import rhythmmakertools selections = [] for division in divisions: assert isinstance(division, durationtools.Division), division for division in divisions: container = self._make_container(division) selection = selectiontools.Selection(container) selections.append(selection) beam_specifier = self.beam_specifier if not beam_specifier: beam_specifier = rhythmmakertools.BeamSpecifier() if beam_specifier.beam_divisions_together: durations = [] for selection in selections: duration = selection.get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, nibs_towards_nonbeamable_components=False, ) components = [] for selection in selections: components.extend(selection) attach(beam, components) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() attach(beam, selection) return selections
def label_leaves_in_expr_with_pitch_numbers(expr, markup_direction=Down): r'''Label leaves in `expr` with pitch numbers: :: >>> staff = Staff(scoretools.make_leaves([None, 12, [13, 14, 15], None], [(1, 4)])) >>> labeltools.label_leaves_in_expr_with_pitch_numbers(staff) >>> print format(staff) \new Staff { r4 c''4 _ \markup { \small 12 } <cs'' d'' ef''>4 _ \markup { \column { \small 15 \small 14 \small 13 } } r4 } :: >>> show(staff) # doctest: +SKIP Returns none. ''' for leaf in iterate(expr).by_class(scoretools.Leaf): for pitch in reversed(pitchtools.PitchSegment.from_selection(leaf)): if pitch is not None: label = markuptools.MarkupCommand('small', str(pitch.pitch_number)) markup = markuptools.Markup(label, markup_direction) attach(markup, leaf)
def apply_final_bar_lines(score): r'''Applies final bar lines to score. ''' for voice in iterate(score).by_class(scoretools.Voice): bar_line = indicatortools.BarLine('|.') attach(bar_line, voice[-1])
def apply_page_breaks(score): r'''Applies page breaks to score. ''' bell_voice = score['Bell Voice'] measure_indices = [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 72, 79, 86, 93, 100, ] for measure_index in measure_indices: command = indicatortools.LilyPondCommand('break', 'after') attach(command, bell_voice[measure_index])
def skip(self, duration): r'''Handles LilyPond ``\skip`` command. ''' leaf = scoretools.Skip(duration.duration) if duration.multiplier is not None: attach(duration.multiplier, leaf) return leaf
def _bracket_inner_nodes(self, leaf_list_stack, node, voice): from abjad.tools import durationtools from abjad.tools import markuptools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools.topleveltools import attach if len(node): if node.level: leaf_list_stack.append([]) for child_node in node: self._bracket_inner_nodes( leaf_list_stack, child_node, voice, ) if node.level: bracket = spannertools.HorizontalBracketSpanner() attach(bracket, leaf_list_stack[-1]) if node.level == 1: node_index = node.parent.index(node) level_one_first_leaf = leaf_list_stack[-1][0] string = r'\bold {{ {} }}'.format(node_index) markup = markuptools.Markup(string, Up) attach(markup, level_one_first_leaf) leaf_list_stack.pop() elif node.payload: note = scoretools.Note( node.payload, durationtools.Duration(1, 8), ) voice.append(note) for leaf_list in leaf_list_stack: leaf_list.append(note)
def _make_music(self, divisions, rotation): selections = [] for division in divisions: prototype = mathtools.NonreducedFraction assert isinstance(division, prototype), division for division in divisions: container = self._make_container(division) selection = selectiontools.Selection(container) selections.append(selection) beam_specifier = self._get_beam_specifier() if beam_specifier.beam_divisions_together: durations = [] for selection in selections: duration = selection.get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, nibs_towards_nonbeamable_components=False, ) components = [] for selection in selections: components.extend(selection) leaves = select(components).by_leaf() #attach(beam, components) attach(beam, leaves) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() leaves = select(selection).by_leaf() #attach(beam, selection) attach(beam, leaves) return selections
def _make_music(self, duration_pairs, seeds): from abjad.tools import rhythmmakertools selections = [] specifier = self.duration_spelling_specifier if specifier is None: specifier = rhythmmakertools.DurationSpellingSpecifier() for duration_pair in duration_pairs: selection = scoretools.make_leaves( pitches=0, durations=[duration_pair], decrease_durations_monotonically=\ specifier.decrease_durations_monotonically, forbidden_written_duration=\ specifier.forbidden_written_duration, ) selections.append(selection) beam_specifier = self.beam_specifier if beam_specifier is None: beam_specifier = rhythmmakertools.BeamSpecifier() if beam_specifier.beam_divisions_together: for component in iterate(selections).by_class(): detach(spannertools.Beam, component) beam = spannertools.MultipartBeam() leaves = iterate(selections).by_class(scoretools.Leaf) leaves = list(leaves) attach(beam, leaves) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() attach(beam, selection) return selections
def _attach_tie_spanner_to_leaf_pair(self, use_messiaen_style_ties=False): from abjad.tools import scoretools from abjad.tools import spannertools assert len(self) == 2 left_leaf, right_leaf = self assert isinstance(left_leaf, scoretools.Leaf), left_leaf assert isinstance(right_leaf, scoretools.Leaf), right_leaf left_logical_tie = left_leaf._get_logical_tie() right_logical_tie = right_leaf._get_logical_tie() prototype = (spannertools.Tie, ) if left_logical_tie == right_logical_tie: return try: left_tie_spanner = left_leaf._get_spanner(prototype) except MissingSpannerError: left_tie_spanner = None try: right_tie_spanner = right_leaf._get_spanner(prototype) except MissingSpannerError: right_tie_spanner = None if left_tie_spanner is not None and right_tie_spanner is not None: left_tie_spanner._fuse_by_reference(right_tie_spanner) elif left_tie_spanner is not None and right_tie_spanner is None: left_tie_spanner._append(right_leaf) elif left_tie_spanner is None and right_tie_spanner is not None: right_tie_spanner._append_left(left_leaf) elif left_tie_spanner is None and right_tie_spanner is None: tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, [left_leaf, right_leaf])
def label_leaves_in_expr_with_leaf_indices(expr, markup_direction=Down): r'''Label leaves in `expr` with leaf indices: :: >>> staff = Staff("c'8 d'8 e'8 f'8") >>> labeltools.label_leaves_in_expr_with_leaf_indices(staff) >>> print(format(staff)) \new Staff { c'8 _ \markup { \small 0 } d'8 _ \markup { \small 1 } e'8 _ \markup { \small 2 } f'8 _ \markup { \small 3 } } :: >>> show(staff) # doctest: +SKIP Returns none. ''' for i, leaf in enumerate(iterate(expr).by_class(scoretools.Leaf)): label = markuptools.MarkupCommand('small', str(i)) markup = markuptools.Markup(label, markup_direction) attach(markup, leaf)
def _beam_rhythm_containers(self, rhythm_containers): beam_specifier = self.source_expression.beam_specifier beam_specifier = beam_specifier or rhythmmakertools.BeamSpecifier() beam_divisions_together = beam_specifier.beam_divisions_together beam_each_division = beam_specifier.beam_each_division if beam_divisions_together: for container in iterate(rhythm_containers).by_class(): spanners = container._get_spanners(spannertools.Beam) for spanner in spanners: spanner._sever_all_components() durations = [x._get_duration() for x in rhythm_containers] beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, ) attach(beam, rhythm_containers) elif beam_each_division: for container in iterate(rhythm_containers).by_class(): spanners = container._get_spanners(spannertools.Beam) for spanner in spanners: spanner._sever_all_components() for rhythm_container in rhythm_containers: duration = rhythm_container._get_duration() beam = spannertools.DuratedComplexBeam( durations=[duration], span_beam_count=1, ) attach(beam, rhythm_container)
def apply_spanners(self, score): spanner_groups = { # 'groups': lambda score: groupby( # score, # key=lambda x: get_named_annotation(x, 'groups'), # eqcheck=contains_any, # ), 'notation': group_events( lambda x: get_named_annotation(x, 'notation'), ), 'instrument': group_events( lambda x: ( get_named_annotation(x, 'part'), get_named_annotation(x, 'instrument'), ) ), } # groups classes = (scoretools.Chord, scoretools.Rest) chords_iterator = list(topleveltools.iterate(score).by_class(classes)) tie_groups = get_tie_groups(list(chords_iterator)) for tie_group in tie_groups: if isinstance(tie_group[0], scoretools.Chord): spanner = NotationSpanner(key='groups', value=True) topleveltools.attach(spanner, tie_group) # notation, instrument for spanner_name, group_fn in spanner_groups.items(): classes = (scoretools.Chord, scoretools.Rest) chords_iterator = topleveltools.iterate(score).by_class(classes) for k, g in group_fn(chords_iterator): group = list(g) if k and isinstance(group[0], scoretools.Chord): spanner = NotationSpanner(key=spanner_name, value=k) topleveltools.attach(spanner, group)
def execute_against_score(self, score): r'''Execute markup set expression against `score`. ''' markup = self.source_expression.payload for leaf in self._iterate_selected_leaves_in_score(score): new_markup = markuptools.Markup(markup) attach(new_markup, leaf)
def _copy_with_indicators_but_without_children_or_spanners(self): new = Component._copy_with_indicators_but_without_children_or_spanners(self) for grace_container in self._get_grace_containers(): new_grace_container = \ grace_container._copy_with_children_and_indicators_but_without_spanners() attach(new_grace_container, new) return new
def __call__(self, expr, offset=0): leaves = list(iterate(expr).by_class(scoretools.Leaf)) groups = list(iterate(leaves).by_run( (scoretools.Note, scoretools.Chord))) hairpin_tokens = datastructuretools.CyclicTuple(self.hairpin_tokens) for i, group in enumerate(groups): if not isinstance(group, selectiontools.SliceSelection): group = selectiontools.SliceSelection(group) is_short_group = False hairpin_token = hairpin_tokens[offset + i] if len(group) == 1: is_short_group = True elif self.minimum_duration is not None: if group.get_duration() < self.minimum_duration: is_short_group = True if is_short_group: start_dynamic = hairpin_token[0] #indicatortools.Dynamic(start_dynamic)(group[0]) command = indicatortools.LilyPondCommand(start_dynamic, 'right') attach(command, group[0]) else: descriptor = ' '.join([x for x in hairpin_token if x]) hairpin = spannertools.Hairpin( descriptor=descriptor, include_rests=False, ) attach(hairpin, group) return expr
def __illustrate__(self): r'''Illustrates pitch segment. :: >>> named_pitch_segment = pitchtools.PitchSegment( ... ['bf,', 'aqs', "fs'", "g'", 'bqf', "g'"], ... item_class=NamedPitch, ... ) >>> show(named_pitch_segment) # doctest: +SKIP Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import lilypondfiletools from abjad.tools import markuptools from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools.topleveltools import attach from abjad.tools.topleveltools import iterate from abjad.tools.topleveltools import override named_pitches = [pitchtools.NamedPitch(x) for x in self] notes = scoretools.make_notes(named_pitches, [1]) score, treble_staff, bass_staff = \ scoretools.make_piano_sketch_score_from_leaves(notes) for leaf in iterate(score).by_class(scoretools.Leaf): attach(durationtools.Multiplier(1, 8), leaf) override(score).rest.transparent = True lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.tagline = markuptools.Markup('""') return lilypond_file
def _notate(self, grace_handler, attack_point_optimizer, attach_tempos): voice = scoretools.Voice() # generate the first beat = self.items[0] components = beat.q_grid(beat.beatspan) if attach_tempos: attachment_target = components[0] if isinstance(attachment_target, scoretools.Container): attachment_target = attachment_target.select_leaves()[0] tempo = copy.copy(beat.tempo) attach(tempo, attachment_target) voice.extend(components) # generate the rest pairwise, comparing tempi for beat_one, beat_two in \ sequencetools.iterate_sequence_pairwise_strict(self.items): components = beat_two.q_grid(beat_two.beatspan) if (beat_two.tempo != beat_one.tempo) and attach_tempos: attachment_target = components[0] if isinstance(attachment_target, scoretools.Container): attachment_target = attachment_target.select_leaves()[0] tempo = copy.copy(beat_two.tempo) attach(tempo, attachment_target) voice.extend(components) # apply logical ties, pitches, grace containers self._notate_leaves_pairwise(voice, grace_handler) # partition logical ties in voice attack_point_optimizer(voice) return voice
def _apply(self, selections): if self.beam_divisions_together: durations = [] for selection in selections: if isinstance(selection, selectiontools.Selection): duration = selection.get_duration() else: duration = selection._get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, ) components = [] for selection in selections: if isinstance(selection, selectiontools.Selection): components.extend(selection) elif isinstance(selection, scoretools.Tuplet): components.append(selection) else: raise TypeError(selection) if self.stemlet_length is not None: grob_proxy = override(beam).staff.stem grob_proxy.stemlet_length = self.stemlet_length attach(beam, components) elif self.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam(beam_rests=self.beam_rests) if self.stemlet_length is not None: grob_proxy = override(beam).staff.stem grob_proxy.stemlet_length = self.stemlet_length attach(beam, selection)
def __illustrate__(self): r'''Illustrates pitch segment. :: >>> named_pitch_segment = pitchtools.PitchSegment( ... ['bf,', 'aqs', "fs'", "g'", 'bqf', "g'"], ... item_class=NamedPitch, ... ) >>> show(named_pitch_segment) # doctest: +SKIP Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import lilypondfiletools from abjad.tools import markuptools from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools.topleveltools import attach from abjad.tools.topleveltools import iterate from abjad.tools.topleveltools import override named_pitches = [pitchtools.NamedPitch(x) for x in self] notes = scoretools.make_notes(named_pitches, [1]) score, treble_staff, bass_staff = \ scoretools.make_piano_sketch_score_from_leaves(notes) for leaf in iterate(score).by_class(scoretools.Leaf): attach(durationtools.Multiplier(1, 8), leaf) override(score).rest.transparent = True lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.tagline = markuptools.Markup('""') return lilypond_file