def __or__(self, expr): r'''Logical OR of two payload expressions. Payload expression must be able to fuse. Returns timespan inventory. ''' assert self._can_fuse(expr) if isinstance(self.payload, scoretools.Container): selection = select(self.payload[0], contiguous=True) left = mutate(selection).copy()[0] selection = select(expr.payload[0], contiguous=True) right = mutate(selection).copy()[0] payload = scoretools.Container([left, right]) for component in payload[:]: component._extract() payload = scoretools.Container([payload]) else: payload = self.payload + expr.payload result = type(self)( [], start_offset=self.timespan.start_offset, voice_name=self.voice_name, ) result._payload = payload return timespantools.TimespanInventory([result])
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. .. container:: example For examples: :: >>> string = r"c'4 \times 2/3 { d'8 r8 e'8 } r16 f'16 g'8 a'4" >>> staff = Staff(string) >>> show(staff) # doctest: +SKIP .. container:: example **Example 1.** >>> selector = selectortools.Selector() >>> selector = selector.get_slice(start=-4) >>> selections = selector(staff) :: >>> for selection in selections: ... selection ... Selection([Rest('r16'), Note("f'16"), Note("g'8"), Note("a'4")]) Returns tuple of selections. Returns tuple of selections or tuple of selections with offset. ''' assert isinstance(expr, tuple), repr(expr) prototype = (scoretools.Container, selectiontools.Selection) result = [] if self.apply_to_each: for subexpr in expr: try: subresult = self._get_item(subexpr) if not isinstance(subresult, prototype): subresult = select(subresult) if isinstance(subresult, selectiontools.Selection): if subresult: result.append(subresult) else: result.append(subresult) except IndexError: pass else: try: subresult = self._get_item(expr) subresult = select(subresult) if isinstance(subresult, selectiontools.Selection): if subresult: result.extend(subresult) else: result.extend(subresult) except IndexError: pass return tuple(result)
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) prototype = (scoretools.Container, selectiontools.Selection) result = [] argument = slice(self.start, self.stop) if self.apply_to_each: for subexpr in expr: try: subresult = subexpr.__getitem__(argument) if not isinstance(subresult, prototype): subresult = select(subresult) if isinstance(subresult, selectiontools.Selection): if subresult: result.append(subresult) else: result.append(subresult) except IndexError: pass else: try: subresult = select(expr.__getitem__(argument)) if isinstance(subresult, selectiontools.Selection): if subresult: result.extend(subresult) else: result.extend(subresult) except IndexError: pass return tuple(result)
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 __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. .. container:: example For examples: :: >>> string = r"c'4 \times 2/3 { d'8 r8 e'8 } r16 f'16 g'8 a'4" >>> staff = Staff(string) >>> show(staff) # doctest: +SKIP .. container:: example **Example 1.** >>> selector = selectortools.Selector() >>> selector = selector.get_slice(start=-4) >>> selections = selector(staff) :: >>> for selection in selections: ... selection Selection(Rest('r16'), Note("f'16"), Note("g'8"), Note("a'4")) Returns tuple of selections. Returns tuple of selections or tuple of selections with offset. ''' assert isinstance(expr, tuple), repr(expr) prototype = (scoretools.Container, selectiontools.Selection) result = [] if self.apply_to_each: for subexpr in expr: try: subresult = self._get_item(subexpr) if not isinstance(subresult, prototype): subresult = select(subresult) if isinstance(subresult, selectiontools.Selection): if subresult: result.append(subresult) else: result.append(subresult) except IndexError: pass else: try: subresult = self._get_item(expr) subresult = select(subresult) if isinstance(subresult, selectiontools.Selection): if subresult: result.extend(subresult) else: result.extend(subresult) except IndexError: pass return tuple(result)
def __illustrate__(self): r'''Illustrates pitch range. :: >>> show(pitch_range) # doctest: +SKIP Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import lilypondfiletools from abjad.tools import indicatortools 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 start_pitch_clef = indicatortools.Clef.from_selection(self.start_pitch) stop_pitch_clef = indicatortools.Clef.from_selection(self.stop_pitch) start_note = scoretools.Note(self.start_pitch, 1) stop_note = scoretools.Note(self.stop_pitch, 1) glissando = spannertools.Glissando() if start_pitch_clef == stop_pitch_clef: if start_pitch_clef == indicatortools.Clef('bass'): bass_staff = scoretools.Staff() attach(indicatortools.Clef('bass'), bass_staff) bass_staff.extend([start_note, stop_note]) bass_leaves = select(bass_staff).by_leaf() attach(glissando, bass_leaves) score = scoretools.Score([bass_staff]) else: treble_staff = scoretools.Staff() attach(indicatortools.Clef('treble'), treble_staff) treble_staff.extend([start_note, stop_note]) treble_leaves = select(treble_staff).by_leaf() attach(glissando, treble_leaves) score = scoretools.Score([treble_staff]) else: result = scoretools.make_empty_piano_score() score, treble_staff, bass_staff = result bass_staff.extend([start_note, stop_note]) treble_staff.extend(scoretools.Skip(1) * 2) bass_leaves = select(bass_staff).by_leaf() attach(glissando, bass_leaves) attach(indicatortools.StaffChange(treble_staff), bass_staff[1]) for leaf in iterate(score).by_class(scoretools.Leaf): attach(durationtools.Multiplier(1, 4), leaf) override(score).bar_line.stencil = False override(score).span_bar.stencil = False override(score).glissando.thickness = 2 override(score).time_signature.stencil = False lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.tagline = False return lilypond_file
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. Returns tuple in which each item is a selection or component. ''' from abjad.tools import scoretools from abjad.tools import selectiontools from abjad.tools.topleveltools import select assert isinstance(expr, tuple), repr(expr) result = [] for subexpr in expr: if isinstance(subexpr, scoretools.Leaf): subexpr = selectiontools.Selection([subexpr]) subresult = [] if self.with_previous_leaf: first_leaf = subexpr[0] previous_leaf = first_leaf._get_leaf(-1) if previous_leaf is not None: subresult.append(previous_leaf) if isinstance(subexpr, selectiontools.Selection): subresult.extend(subexpr) else: subresult.append(subexpr) if self.with_next_leaf: last_leaf = subexpr[-1] next_leaf = last_leaf._get_leaf(1) if next_leaf is not None: subresult.append(next_leaf) subresult = select(subresult) result.append(subresult) return tuple(result)
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 __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple in which each item is a selection or component. ''' from abjad.tools import selectiontools from abjad.tools.topleveltools import select assert isinstance(expr, tuple), repr(tuple) result = [] for subexpr in expr: subresult = [] if self.with_previous_leaf: first_leaf = subexpr[0] previous_leaf = first_leaf._get_leaf(-1) if previous_leaf is not None: subresult.append(previous_leaf) if isinstance(subexpr, selectiontools.Selection): subresult.extend(subexpr) else: subresult.append(subexpr) if self.with_next_leaf: last_leaf = subexpr[-1] next_leaf = last_leaf._get_leaf(1) if next_leaf is not None: subresult.append(next_leaf) subresult = select(subresult) result.append(subresult) return tuple(result)
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 __init__( self, component=None, cross_offset=None, include_self=True, ): from abjad.tools import scoretools assert isinstance(component, (scoretools.Component, type(None))) if component is None: music = () else: music = list(select(component).by_class()) if not include_self: music.remove(component) result = [] if cross_offset is None: result = music else: for x in music: append_x = True if not (x._get_timespan().start_offset < cross_offset and cross_offset < x._get_timespan().stop_offset): append_x = False if append_x: result.append(x) Selection.__init__(self, result) self._component = component
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 _notate( self, attach_tempos=True, attack_point_optimizer=None, grace_handler=None, ): voice = scoretools.Voice() # generate the first beat = self.items[0] components = beat.q_grid(beat.beatspan) if attach_tempos: attachment_target = components[0] leaves = select(attachment_target).by_leaf() if isinstance(attachment_target, scoretools.Container): attachment_target = 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_nwise(self.items): components = beat_two.q_grid(beat_two.beatspan) if (beat_two.tempo != beat_one.tempo) and attach_tempos: attachment_target = components[0] leaves = select(attachment_target).by_leaf() if isinstance(attachment_target, scoretools.Container): attachment_target = leaves[0] tempo = copy.copy(beat_two.tempo) attach(tempo, attachment_target) voice.extend(components) # apply logical ties, pitches, grace containers self._notate_leaves( grace_handler=grace_handler, voice=voice, ) # partition logical ties in voice attack_point_optimizer(voice) return voice
def add_final_bar_line(self, abbreviation="|."): r"""Add final bar line to end of score. >>> staff = Staff("c'4 d'4 e'4 f'4") >>> score = Score([staff]) .. doctest:: >>> print format(score) \new Score << \new Staff { c'4 d'4 e'4 f'4 } >> :: >>> show(score) # doctest: +SKIP :: >>> score.add_final_bar_line() BarLine('|.') .. doctest:: >>> print format(score) \new Score << \new Staff { c'4 d'4 e'4 f'4 \bar "|." } >> :: >>> show(score) # doctest: +SKIP Returns bar line. """ from abjad.tools import scoretools from abjad.tools import indicatortools selection = select(self) last_leaf = selection._get_component(scoretools.Leaf, -1) double_bar = indicatortools.BarLine(abbreviation) attach(double_bar, last_leaf) return double_bar
def __call__(self, selections): r'''Calls beam specifier on `selections`. Returns none. ''' 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 leaves = select(components).by_leaf() #attach(beam, components) attach(beam, leaves) 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 leaves = select(selection).by_leaf() attach(beam, leaves)
def _cleanup(self, parsed): container = scoretools.Container() for x in parsed: container.append(x) parsed = container leaves = select(parsed).by_leaf() if leaves: self._apply_spanners(leaves) for leaf in leaves: detach(indicatortools.Annotation, leaf) if 1 < self._toplevel_component_count: return parsed return parsed[0]
def __call__(self, expr): r'''Iterates tuple `expr`. ''' result = [] subresult = [] subresult.extend(expr[:1]) for subexpr in expr[1:]: try: that_timespan = subresult[-1]._get_timespan() except AttributeError: that_timespan = subresult[-1].get_timespan() try: this_timespan = subexpr._get_timespan() except AttributeError: this_timespan = subexpr.get_timespan() if that_timespan.stop_offset == this_timespan.start_offset: subresult.append(subexpr) else: result.append(select(subresult)) subresult = [subexpr] if subresult: result.append(select(subresult)) return tuple(result)
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. ''' result = [] subresult = [] subresult.extend(expr[:1]) for subexpr in expr[1:]: try: that_timespan = subresult[-1]._get_timespan() except AttributeError: that_timespan = subresult[-1].get_timespan() try: this_timespan = subexpr._get_timespan() except AttributeError: this_timespan = subexpr.get_timespan() if that_timespan.stop_offset == this_timespan.start_offset: subresult.append(subexpr) else: result.append(select(subresult)) subresult = [subexpr] if subresult: result.append(select(subresult)) return tuple(result)
def __call__(self, expr): r'''Iterates `expr`. ''' prototype = (scoretools.Container, selectiontools.Selection) result = [] for subexpr in expr: try: subresult = subexpr.__getitem__(self.argument) if not isinstance(subresult, prototype): subresult = select(subresult) result.append(subresult) except IndexError: pass return tuple(result)
def _split_at_measure_boundaries( selections, meters, use_messiaen_style_ties=False, ): from abjad.tools import metertools from abjad.tools import scoretools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ from abjad.tools.topleveltools import mutate from abjad.tools.topleveltools import select meters = [metertools.Meter(_) for _ in meters] durations = [durationtools.Duration(_) for _ in meters] selections = sequencetools.flatten_sequence(selections) assert isinstance(selections, list), repr(selections) meter_duration = sum(durations) music_duration = sum(inspect_(_).get_duration() for _ in selections) if not meter_duration == music_duration: message = 'Duration of meters is {!s}' message += ' but duration of selections is {!s}:' message = message.format(meter_duration, music_duration) message += '\nmeters: {}.'.format(meters) message += '\nmusic: {}.'.format(selections) raise Exception(message) voice = scoretools.Voice(selections) mutate(voice[:]).split( durations=durations, tie_split_notes=True, use_messiaen_style_ties=use_messiaen_style_ties, ) #raise Exception(voice) #selections = list(voice[:]) #return selections components = mutate(voice).eject_contents() component_durations = [inspect_(_).get_duration() for _ in components] parts = sequencetools.partition_sequence_by_weights( component_durations, weights=durations, allow_part_weights=Exact, ) part_lengths = [len(_) for _ in parts] parts = sequencetools.partition_sequence_by_counts( components, counts=part_lengths, overhang=Exact, ) selections = [select(_) for _ in parts] return selections
def get_measure(expr, measure_number): r'''Gets measure `measure_number` in `expr`. :: >>> staff = Staff("abj: | 2/8 c'8 d'8 || 2/8 e'8 f'8 || 2/8 g'8 a'8 |") >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { { \time 2/8 c'8 d'8 } { e'8 f'8 } { g'8 a'8 } } :: >>> scoretools.get_measure(staff, 3) Measure((2, 8), "g'8 a'8") Note that measures number from ``1``. ''' from abjad.tools import scoretools # check input if measure_number < 1: message = 'must be positive integer: {!r}.' message = message.format(measure_number) raise ValueError(message) # calculate measure index measure_index = measure_number - 1 # return measure selection = select(expr) return selection._get_component(scoretools.Measure, measure_index)
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) result = [] prototype = self.prototype if not isinstance(prototype, tuple): prototype = (prototype,) for subexpr in expr: subresult = iterate(subexpr).by_class(prototype) subresult = select(subresult) if subresult: result.append(subresult) return tuple(result)
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) result = [] prototype = self.prototype if not isinstance(prototype, tuple): prototype = (prototype, ) for subexpr in expr: subresult = iterate(subexpr).by_class(prototype) subresult = select(subresult) if subresult: result.append(subresult) return tuple(result)
def make_nested_tuplet( tuplet_duration, outer_tuplet_proportions, inner_tuplet_subdivision_count, ): r'''Makes nested tuplet. ''' outer_tuplet = scoretools.Tuplet.from_duration_and_ratio( tuplet_duration, outer_tuplet_proportions) inner_tuplet_proportions = inner_tuplet_subdivision_count * [1] selector = select().by_leaf(flatten=True) last_leaf = selector(outer_tuplet)[-1] right_logical_tie = inspect_(last_leaf).get_logical_tie() right_logical_tie.to_tuplet(inner_tuplet_proportions) return outer_tuplet
def __call__(self, expr): r'''Selects components from `expr`. Returns a selection of selections or containers. ''' prototype = (scoretools.Container, selectiontools.Selection) if not isinstance(expr, prototype): expr = select(expr) expr = (expr,) assert all(isinstance(x, prototype) for x in expr), expr callbacks = self.callbacks or () for callback in callbacks: expr = callback(expr) assert all(isinstance(x, prototype) for x in expr), \ (expr, callback) return selectiontools.Selection(expr)
def __call__(self, expr): r'''Selects components from component or selection `expr`. Returns a selection of selections or containers. ''' prototype = ( scoretools.Component, selectiontools.Selection, ) if not isinstance(expr, prototype): expr = select(expr) expr = (expr, ) assert all(isinstance(x, prototype) for x in expr), repr(expr) callbacks = self.callbacks or () for callback in callbacks: expr = callback(expr) return selectiontools.Selection(expr)
def edit_first_violin_voice(score, durated_reservoir): r'''Edits first violin voice. ''' voice = score['First Violin Voice'] descents = durated_reservoir['First Violin'] descents = selectiontools.Selection(descents) last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() voice.extend(copied_descent) final_sustain_rhythm = [(6, 4)] * 43 + [(1, 2)] final_sustain_notes = scoretools.make_notes(["c'"], final_sustain_rhythm) voice.extend(final_sustain_notes) tie = spannertools.Tie() attach(tie, final_sustain_notes) voice.extend('r4 r2.')
def make_desordre_cell(pitches): '''The function constructs and returns a *Désordre cell*. `pitches` is a list of numbers or, more generally, pitch tokens. ''' notes = [scoretools.Note(pitch, (1, 8)) for pitch in pitches] beam = spannertools.Beam() attach(beam, notes) slur = spannertools.Slur() attach(slur, notes) clef = indicatortools.Dynamic('f') attach(clef, notes[0]) dynamic = indicatortools.Dynamic('p') attach(dynamic, notes[1]) # make the lower voice lower_voice = scoretools.Voice(notes) lower_voice.name = 'RH Lower Voice' command = indicatortools.LilyPondCommand('voiceTwo') attach(command, lower_voice) n = int(math.ceil(len(pitches) / 2.)) chord = scoretools.Chord([pitches[0], pitches[0] + 12], (n, 8)) articulation = indicatortools.Articulation('>') attach(articulation, chord) # make the upper voice upper_voice = scoretools.Voice([chord]) upper_voice.name = 'RH Upper Voice' command = indicatortools.LilyPondCommand('voiceOne') attach(command, upper_voice) # combine them together container = scoretools.Container([lower_voice, upper_voice]) container.is_simultaneous = True # make all 1/8 beats breakable leaves = select(lower_voice).by_leaf() for leaf in leaves[:-1]: bar_line = indicatortools.BarLine('') attach(bar_line, leaf) return container
def from_selection( cls, selection, item_class=None, custom_identifier=None, ): r'''Makes pitch segment from `selection`. :: >>> staff_1 = Staff("c'4 <d' fs' a'>4 b2") >>> staff_2 = Staff("c4. r8 g2") >>> selection = select((staff_1, staff_2)) >>> pitch_segment = pitchtools.PitchSegment.from_selection( ... selection) >>> pitch_segment PitchSegment(["c'", "d'", "fs'", "a'", 'b', 'c', 'g']) :: >>> show(pitch_segment) # doctest: +SKIP Returns pitch segment. ''' from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools import selectiontools if not isinstance(selection, selectiontools.Selection): selection = select(selection) named_pitches = [] for component in iterate(selection).by_class( (scoretools.Note, scoretools.Chord)): if hasattr(component, 'written_pitches'): named_pitches.extend(component.written_pitches) elif hasattr(component, 'written_pitch'): named_pitches.append(component.written_pitch) return cls( tokens=named_pitches, item_class=item_class, custom_identifier=custom_identifier, )
def __call__(self, beatspan): r'''Calls q-grid. ''' result = self.root_node(beatspan) result_leaves = [] for x in result: if isinstance(x, scoretools.Container): leaves = select(x).leaves() result_leaves.extend(leaves) else: result_leaves.append(x) for result_leaf, q_grid_leaf in zip(result_leaves, self.leaves[:-1]): if q_grid_leaf.q_event_proxies: q_events = [ q_event_proxy.q_event for q_event_proxy in q_grid_leaf.q_event_proxies ] q_events.sort(key=lambda x: 0 if x.index is None else x.index) annotation = {'q_events': tuple(q_events)} attach(annotation, result_leaf) return result
def __call__(self, beatspan): r'''Calls q-grid. ''' result = self.root_node(beatspan) result_leaves = [] for x in result: if isinstance(x, scoretools.Container): leaves = select(x).by_leaf() result_leaves.extend(leaves) else: result_leaves.append(x) for result_leaf, q_grid_leaf in zip(result_leaves, self.leaves[:-1]): if q_grid_leaf.q_event_proxies: q_events = [q_event_proxy.q_event for q_event_proxy in q_grid_leaf.q_event_proxies] q_events.sort( key=lambda x: 0 if x.index is None else x.index) annotation = indicatortools.Annotation( 'q_events', tuple(q_events)) attach(annotation, result_leaf) return result
def from_selection( cls, selection, item_class=None, ): r'''Makes pitch segment from `selection`. :: >>> staff_1 = Staff("c'4 <d' fs' a'>4 b2") >>> staff_2 = Staff("c4. r8 g2") >>> selection = select((staff_1, staff_2)) >>> pitch_segment = pitchtools.PitchSegment.from_selection( ... selection) >>> pitch_segment PitchSegment(["c'", "d'", "fs'", "a'", 'b', 'c', 'g']) :: >>> show(pitch_segment) # doctest: +SKIP Returns pitch segment. ''' from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools import selectiontools if not isinstance(selection, selectiontools.Selection): selection = select(selection) named_pitches = [] for component in iterate(selection).by_class( (scoretools.Note, scoretools.Chord)): if hasattr(component, 'written_pitches'): named_pitches.extend(component.written_pitches) elif hasattr(component, 'written_pitch'): named_pitches.append(component.written_pitch) return cls( items=named_pitches, item_class=item_class, )
def edit_viola_voice(score, durated_reservoir): r'''Edits viola voice. ''' voice = score['Viola Voice'] descents = durated_reservoir['Viola'] for leaf in descents[-1]: articulation = indicatortools.Articulation('accent') attach(articulation, leaf) articulation = indicatortools.Articulation('tenuto') attach(articulation, leaf) last_descent = select(descents[-1]) copied_descent = mutate(last_descent).copy() for leaf in copied_descent: if leaf.written_duration == durationtools.Duration(4, 4): leaf.written_duration = durationtools.Duration(8, 4) else: leaf.written_duration = durationtools.Duration(4, 4) voice.extend(copied_descent) bridge = scoretools.Note('e1') articulation = indicatortools.Articulation('tenuto') attach(articulation, bridge) articulation = indicatortools.Articulation('accent') attach(articulation, bridge) voice.append(bridge) final_sustain_rhythm = [(6, 4)] * 21 + [(1, 2)] final_sustain_notes = scoretools.make_notes(['e'], final_sustain_rhythm) articulation = indicatortools.Articulation('accent') attach(articulation, final_sustain_notes[0]) articulation = indicatortools.Articulation('tenuto') attach(articulation, final_sustain_notes[0]) voice.extend(final_sustain_notes) tie = spannertools.Tie() attach(tie, final_sustain_notes) voice.extend('r4 r2.')
def make_score_with_indicators_03(self): r'''Make 200-note staff with dynamic on every note. :: 2.12 (r9704) initialization: 53,450,195 function calls (!!) 2.12 (r9710) initialization: 2,124,500 function calls 2.12 (r9724) initialization: 2,122,591 function calls 2.12 (r9704) LilyPond format: 533,927 function calls 2.12 (r9710) LilyPond format: 91,280 function calls 2.12 (r9724) LilyPond format: 96,806 function calls ''' from abjad.tools import indicatortools from abjad.tools import scoretools from abjad.tools import topleveltools staff = scoretools.Staff(200 * scoretools.Note("c'16")) selector = topleveltools.select().by_leaf(flatten=True) for note in selector(staff): dynamic = indicatortools.Dynamic('f') topleveltools.attach(dynamic, note) return staff
def __call__(self, expr, seed=None): r'''Selects components from component or selection `expr`. Returns a selection of selections or containers. ''' if seed is None: seed = 0 seed = int(seed) prototype = ( scoretools.Component, selectiontools.Selection, ) if not isinstance(expr, prototype): expr = select(expr) expr = (expr,) assert all(isinstance(x, prototype) for x in expr), repr(expr) callbacks = self.callbacks or () for i, callback in enumerate(callbacks, seed): try: expr = callback(expr, seed=i) except TypeError: expr = callback(expr) return selectiontools.Selection(expr)
def _split( self, durations, cyclic=False, fracture_spanners=False, tie_split_notes=True, use_messiaen_style_ties=False, ): from abjad.tools import pitchtools from abjad.tools import selectiontools from abjad.tools import scoretools from abjad.tools import spannertools durations = [durationtools.Duration(x) for x in durations] if cyclic: durations = sequencetools.repeat_sequence_to_weight( durations, self._get_duration()) durations = [durationtools.Duration(x) for x in durations] if sum(durations) < self._get_duration(): last_duration = self._get_duration() - sum(durations) durations.append(last_duration) sequencetools.truncate_sequence( durations, weight=self._get_duration(), ) result = [] leaf_prolation = self._get_parentage(include_self=False).prolation timespan = self._get_timespan() start_offset = timespan.start_offset for duration in durations: new_leaf = copy.copy(self) preprolated_duration = duration / leaf_prolation shard = new_leaf._set_duration( preprolated_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) for x in shard: if isinstance(x, scoretools.Leaf): x_duration = x.written_duration * leaf_prolation else: x_duration = x.multiplied_duration * leaf_prolation stop_offset = x_duration + start_offset x._start_offset = start_offset x._stop_offset = stop_offset x._timespan = timespantools.Timespan( start_offset=start_offset, stop_offset=stop_offset, ) start_offset = stop_offset shard = [x._get_parentage().root for x in shard] result.append(shard) flattened_result = sequencetools.flatten_sequence(result) flattened_result = selectiontools.SliceSelection(flattened_result) prototype = (spannertools.Tie,) parentage = self._get_parentage() if parentage._get_spanners(prototype=prototype): selection = select(flattened_result) for component in selection: # TODO: make top-level detach() work here for spanner in component._get_spanners(prototype): spanner._sever_all_components() #detach(prototype, component) # replace leaf with flattened result selection = selectiontools.SliceSelection(self) parent, start, stop = selection._get_parent_and_start_stop_indices() if parent: parent.__setitem__(slice(start, stop + 1), flattened_result) else: selection._give_dominant_spanners(flattened_result) selection._withdraw_from_crossing_spanners() # fracture spanners if fracture_spanners: first_shard = result[0] for spanner in first_shard[-1]._get_spanners(): index = spanner._index(first_shard[-1]) spanner._fracture(index, direction=Right) last_shard = result[-1] for spanner in last_shard[0]._get_spanners(): index = spanner._index(last_shard[0]) spanner._fracture(index, direction=Left) for middle_shard in result[1:-1]: for spanner in middle_shard[0]._get_spanners(): index = spanner._index(middle_shard[0]) spanner._fracture(index, direction=Left) for spanner in middle_shard[-1]._get_spanners(): index = spanner._index(middle_shard[-1]) spanner._fracture(index, direction=Right) # adjust first leaf first_leaf = flattened_result[0] self._detach_grace_containers(kind='after') # adjust any middle leaves for middle_leaf in flattened_result[1:-1]: middle_leaf._detach_grace_containers(kind='grace') self._detach_grace_containers(kind='after') detach(object, middle_leaf) # adjust last leaf last_leaf = flattened_result[-1] last_leaf._detach_grace_containers(kind='grace') detach(object, last_leaf) # tie split notes, rests and chords as specified if pitchtools.Pitch.is_pitch_carrier(self) and tie_split_notes: flattened_result_leaves = iterate(flattened_result).by_class( scoretools.Leaf) # TODO: implement SliceSelection._attach_tie_spanner_to_leaves() for leaf_pair in sequencetools.iterate_sequence_nwise( flattened_result_leaves): selection = selectiontools.ContiguousSelection(leaf_pair) selection._attach_tie_spanner_to_leaf_pair( use_messiaen_style_ties=use_messiaen_style_ties, ) # return result return result
def _split( self, durations, cyclic=False, fracture_spanners=False, tie_split_notes=True, use_messiaen_style_ties=False, ): from abjad.tools import pitchtools from abjad.tools import selectiontools from abjad.tools import scoretools from abjad.tools import spannertools durations = [durationtools.Duration(x) for x in durations] if cyclic: durations = sequencetools.repeat_sequence_to_weight( durations, self._get_duration()) durations = [durationtools.Duration(x) for x in durations] if sum(durations) < self._get_duration(): last_duration = self._get_duration() - sum(durations) durations.append(last_duration) sequencetools.truncate_sequence( durations, weight=self._get_duration(), ) result = [] leaf_prolation = self._get_parentage(include_self=False).prolation timespan = self._get_timespan() start_offset = timespan.start_offset for duration in durations: new_leaf = copy.copy(self) preprolated_duration = duration / leaf_prolation shard = new_leaf._set_duration( preprolated_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) for x in shard: if isinstance(x, scoretools.Leaf): x_duration = x.written_duration * leaf_prolation else: x_duration = x.multiplied_duration * leaf_prolation stop_offset = x_duration + start_offset x._start_offset = start_offset x._stop_offset = stop_offset x._timespan = timespantools.Timespan( start_offset=start_offset, stop_offset=stop_offset, ) start_offset = stop_offset shard = [x._get_parentage().root for x in shard] result.append(shard) flattened_result = sequencetools.flatten_sequence(result) flattened_result = selectiontools.Selection(flattened_result) prototype = (spannertools.Tie,) parentage = self._get_parentage() if parentage._get_spanners(prototype=prototype): selection = select(flattened_result) for component in selection: # TODO: make top-level detach() work here for spanner in component._get_spanners(prototype): spanner._sever_all_components() #detach(prototype, component) # replace leaf with flattened result selection = selectiontools.Selection(self) parent, start, stop = selection._get_parent_and_start_stop_indices() if parent: parent.__setitem__(slice(start, stop + 1), flattened_result) else: selection._give_dominant_spanners(flattened_result) selection._withdraw_from_crossing_spanners() # fracture spanners if fracture_spanners: first_shard = result[0] for spanner in first_shard[-1]._get_spanners(): index = spanner._index(first_shard[-1]) spanner._fracture(index, direction=Right) last_shard = result[-1] for spanner in last_shard[0]._get_spanners(): index = spanner._index(last_shard[0]) spanner._fracture(index, direction=Left) for middle_shard in result[1:-1]: for spanner in middle_shard[0]._get_spanners(): index = spanner._index(middle_shard[0]) spanner._fracture(index, direction=Left) for spanner in middle_shard[-1]._get_spanners(): index = spanner._index(middle_shard[-1]) spanner._fracture(index, direction=Right) # adjust first leaf first_leaf = flattened_result[0] self._detach_grace_containers(kind='after') # adjust any middle leaves for middle_leaf in flattened_result[1:-1]: middle_leaf._detach_grace_containers(kind='grace') self._detach_grace_containers(kind='after') detach(object, middle_leaf) # adjust last leaf last_leaf = flattened_result[-1] last_leaf._detach_grace_containers(kind='grace') detach(object, last_leaf) # tie split notes, rests and chords as specified if pitchtools.Pitch.is_pitch_carrier(self) and tie_split_notes: flattened_result_leaves = iterate(flattened_result).by_class( scoretools.Leaf) # TODO: implement Selection._attach_tie_spanner_to_leaves() for leaf_pair in sequencetools.iterate_sequence_nwise( flattened_result_leaves): selection = selectiontools.Selection(leaf_pair) selection._attach_tie_spanner_to_leaf_pair( use_messiaen_style_ties=use_messiaen_style_ties, ) # return result return result
def _at_least_two_leaves(self, component_expression): leaves = select(component_expression).by_leaf() return 1 < len(leaves)
def add_final_bar_line( self, abbreviation='|.', to_each_voice=False, ): r'''Add final bar line to end of score. >>> staff = Staff("c'4 d'4 e'4 f'4") >>> score = Score([staff]) .. doctest:: >>> print(format(score)) \new Score << \new Staff { c'4 d'4 e'4 f'4 } >> :: >>> show(score) # doctest: +SKIP :: >>> score.add_final_bar_line() BarLine('|.') .. doctest:: >>> print(format(score)) \new Score << \new Staff { c'4 d'4 e'4 f'4 \bar "|." } >> :: >>> show(score) # doctest: +SKIP Set `to_each_voice` to true to make part extraction easier. Returns bar line. ''' from abjad.tools import scoretools from abjad.tools import indicatortools double_bar = indicatortools.BarLine(abbreviation) if not to_each_voice: selection = select(self) last_leaf = selection._get_component(scoretools.Leaf, -1) attach(double_bar, last_leaf) else: for voice in iterate(self).by_class(scoretools.Voice): selection = select(voice) last_leaf = selection._get_component(scoretools.Leaf, -1) attach(double_bar, last_leaf) return double_bar
def add_final_markup(self, markup, extra_offset=None): r'''Adds `markup` to end of score: :: >>> staff = Staff("c'4 d'4 e'4 f'4") >>> score = Score([staff]) >>> place = Markup('Bremen - Boston - LA.', direction=Down) >>> date = Markup('Jul 2010 - May 2011.') >>> markup = Markup.right_column([place, date], direction=Down) >>> markup = markup.italic() >>> markup = score.add_final_markup(markup, extra_offset=(0.5, -2)) :: >>> print(format(markup)) _ \markup { \italic \right-column { "Bremen - Boston - LA." "Jul 2010 - May 2011." } } .. doctest:: >>> print(format(score)) \new Score << \new Staff { c'4 d'4 e'4 \once \override TextScript #'extra-offset = #'(0.5 . -2) f'4 _ \markup { \italic \right-column { "Bremen - Boston - LA." "Jul 2010 - May 2011." } } } >> :: >>> show(staff) # doctest: +SKIP Returns `markup`. ''' from abjad.tools import markuptools from abjad.tools import scoretools selection = select(self) last_leaf = selection._get_component(scoretools.Leaf, -1) # TODO: copy markup direction from markup input markup = markup = markuptools.Markup(markup, Down) attach(markup, last_leaf) if extra_offset is not None: override(last_leaf).text_script.extra_offset = extra_offset return markup
def add_final_markup(self, markup, extra_offset=None): r'''Adds `markup` to end of score. .. container:: example **Example 1.** Adds markup to last leaf: :: >>> staff = Staff("c'4 d'4 e'4 f'4") >>> score = Score([staff]) >>> place = Markup('Bremen - Boston - LA.', direction=Down) >>> date = Markup('July 2010 - May 2011.') >>> markup = Markup.right_column([place, date], direction=Down) >>> markup = markup.italic() >>> markup = score.add_final_markup( ... markup, ... extra_offset=(0.5, -2), ... ) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(score)) \new Score << \new Staff { c'4 d'4 e'4 \once \override TextScript #'extra-offset = #'(0.5 . -2) f'4 _ \markup { \italic \right-column { "Bremen - Boston - LA." "July 2010 - May 2011." } } } >> .. container:: example **Example 2.** Adds markup to last multimeasure rest: :: >>> staff = Staff("c'4 d'4 e'4 f'4") >>> staff.append(MultimeasureRest(Duration(4, 4))) >>> score = Score([staff]) >>> place = Markup('Bremen - Boston - LA.', direction=Down) >>> date = Markup('July 2010 - May 2011.') >>> markup = Markup.right_column([place, date], direction=Down) >>> markup = markup.italic() >>> markup = score.add_final_markup( ... markup, ... extra_offset=(14.5, -2), ... ) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(score)) \new Score << \new Staff { c'4 d'4 e'4 f'4 \once \override MultiMeasureRestText #'extra-offset = #'(14.5 . -2) R1 _ \markup { \italic \right-column { "Bremen - Boston - LA." "July 2010 - May 2011." } } } >> Returns none. ''' from abjad.tools import markuptools from abjad.tools import scoretools selection = select(self) last_leaf = selection._get_component(scoretools.Leaf, -1) markup = copy.copy(markup) attach(markup, last_leaf) if extra_offset is not None: if isinstance(last_leaf, scoretools.MultimeasureRest): grob_proxy = override(last_leaf).multi_measure_rest_text else: grob_proxy = override(last_leaf).text_script grob_proxy.extra_offset = extra_offset return markup