def edit_cello_voice(score, durated_reservoir): r'''Edits cello voice. ''' voice = score['Cello Voice'] descents = durated_reservoir['Cello'] logical_tie = inspect_(voice[-1]).get_logical_tie() for leaf in logical_tie.leaves: parent = leaf._get_parentage().parent index = parent.index(leaf) parent[index] = scoretools.Chord(['e,', 'a,'], leaf.written_duration) selection = voice[-len(descents[-1]):] unison_descent = mutate(selection).copy() voice.extend(unison_descent) for chord in unison_descent: index = inspect_(chord).get_parentage().parent.index(chord) parent[index] = scoretools.Note( chord.written_pitches[1], chord.written_duration) articulation = indicatortools.Articulation('accent') attach(articulation, parent[index]) articulation = indicatortools.Articulation('tenuto') attach(articulation, parent[index]) voice.extend('a,1. ~ a,2') voice.extend('b,1 ~ b,1. ~ b,1.') voice.extend('a,1. ~ a,1. ~ a,1. ~ a,1. ~ a,1. ~ a,2') voice.extend('r4 r2.')
def _format_leaf_nucleus(self): from abjad.tools import systemtools indent = systemtools.LilyPondFormatManager.indent result = [] note_heads = self.note_heads if any('\n' in format(x) for x in note_heads): for note_head in note_heads: current_format = format(note_head) format_list = current_format.split('\n') format_list = [indent + x for x in format_list] result.extend(format_list) result.insert(0, '<') result.append('>') result = '\n'.join(result) result += str(self._formatted_duration) elif inspect_(self).has_indicator(indicatortools.Tremolo): reattack_duration = self._get_tremolo_reattack_duration() duration_string = reattack_duration.lilypond_duration_string durated_pitches = [] for note_head in note_heads: durated_pitch = format(note_head) + duration_string durated_pitches.append(durated_pitch) tremolo = inspect_(self).get_indicator(indicatortools.Tremolo) if tremolo.is_slurred: durated_pitches[0] = durated_pitches[0] + r' \(' durated_pitches[-1] = durated_pitches[-1] + r' \)' result = ' '.join(durated_pitches) else: result.extend([format(_) for _ in note_heads]) result = '<%s>%s' % (' '.join(result), self._formatted_duration) # single string, but wrapped in list bc contribution return ['nucleus', [result]]
def execute_against_score(self, score): r'''Execute pitch-class transform expression against `score`. ''' pitch_class_transform_expression = self.source_expression.payload for leaf in self._iterate_selected_leaves_in_score(score): assert isinstance(leaf, (scoretools.Note, scoretools.Chord)) if isinstance(leaf, scoretools.Note): sounding_pitch = inspect_(leaf).get_sounding_pitch() sounding_pitch_number = sounding_pitch.pitch_number transformed_pitch_class = \ pitch_class_transform_expression(sounding_pitch_number) #leaf.sounding_pitch = transformed_pitch_class # TODO: FIXME leaf.written_pitch = transformed_pitch_class elif isinstance(leaf, scoretools.Chord): transformed_pitch_classes = [] for sounding_pitch_number in leaf.sounding_pitches: sounding_pitch = inspect_(leaf).get_sounding_pitch() sounding_pitch_number = sounding_pitch.pitch_number transformed_pitch_class = \ pitch_class_transform_expression(sounding_pitch_number) transformed_pitch_classes.append(transformed_pitch_class) leaf[:] = transformed_pitch_classes else: raise TypeError(leaf)
def _make_bow_direction_change_contributions( self, bow_contact_point=None, leaf=None, lilypond_format_bundle=None, ): direction_change = None next_leaf = inspect_(leaf).get_leaf(1) this_contact_point = bow_contact_point next_contact_point = inspect_(next_leaf).get_indicator( indicatortools.BowContactPoint) if self._is_my_first_leaf(leaf): if this_contact_point < next_contact_point: direction_change = Up elif next_contact_point < this_contact_point: direction_change = Down else: previous_leaf = inspect_(leaf).get_leaf(-1) previous_contact_point = inspect_(previous_leaf ).get_indicator(indicatortools.BowContactPoint) if (previous_contact_point < this_contact_point and next_contact_point < this_contact_point): direction_change = Down elif (this_contact_point < previous_contact_point and this_contact_point < next_contact_point): direction_change = Up if direction_change is None: return if direction_change == Up: articulation = indicatortools.Articulation('upbow', Up) elif direction_change == Down: articulation = indicatortools.Articulation('downbow', Up) string = str(articulation) lilypond_format_bundle.right.articulations.append(string)
def __contains__(self, arg): r'''Is true when pitch range contains `arg`. Otherwise false. Returns boolean. ''' from abjad.tools import pitchtools from abjad.tools import scoretools if hasattr(arg, '_has_effective_indicator') and \ arg._has_effective_indicator(indicatortools.IsUnpitched): return True elif isinstance(arg, (int, long, float)): pitch = pitchtools.NamedPitch(arg) return self._contains_pitch(pitch) elif isinstance(arg, pitchtools.NamedPitch): return self._contains_pitch(arg) elif isinstance(arg, scoretools.Note): sounding_pitch = inspect_(arg).get_sounding_pitch() return self._contains_pitch(sounding_pitch) elif isinstance(arg, scoretools.Chord): sounding_pitches = inspect_(arg).get_sounding_pitches() return all(self._contains_pitch(x) for x in sounding_pitches) elif isinstance(arg, (scoretools.Rest, scoretools.Skip)): return True elif isinstance(arg, scoretools.Container): return all(x in self for x in arg.select_leaves()) else: pitches = pitchtools.list_named_pitches_in_expr(arg) if pitches: return all(self._contains_pitch(x) for x in pitches) else: try: return all(self._contains_pitch(x) for x in arg) except TypeError: return False return False
def __call__( self, expr, timespan=None, offset=0, skip_first=0, skip_last=0, ): r'''Calls handler on `expr` with keywords. Returns none. ''' articulation_lists = datastructuretools.CyclicTuple( self.articulation_lists) prototype = (scoretools.Note, scoretools.Chord) notes_and_chords = list(iterate(expr).by_class(prototype)) notes_and_chords = notes_and_chords[skip_first:] if skip_last: notes_and_chords = notes_and_chords[:-skip_last] i = 0 for note_or_chord in notes_and_chords: logical_tie = inspect_(note_or_chord).get_logical_tie() duration = logical_tie.get_duration() articulation_list = articulation_lists[offset+i] if articulation_list is None: i += 1 continue articulation_list = [ indicatortools.Articulation(_) for _ in articulation_list ] if self.minimum_duration is not None: if duration <= self.minimum_duration: continue if self.maximum_duration is not None: if self.maximum_duration < duration: continue if self.minimum_written_pitch is not None: if isinstance(note_or_chord, scoretools.Note): minimum_written_pitch = note_or_chord.written_pitch else: minimum_written_pitch = note_or_chord.writen_pitches[0] if minimum_written_pitch < self.minimum_written_pitch: continue if self.maximum_written_pitch is not None: if isinstance(note_or_chord, scoretools.Note): maximum_written_pitch = note_or_chord.written_pitch else: maximum_written_pitch = note_or_chord.written_pitches[-1] if self.maximum_written_pitch < maximum_written_pitch: continue logical_tie = inspect_(note_or_chord).get_logical_tie() if note_or_chord is logical_tie.head: for articulation in articulation_list: # TODO: make new(articulation) work articulation = copy.copy(articulation) attach(articulation, note_or_chord) i += 1 return expr
def __call__( self, expr, timespan=None, offset=0, skip_first=0, skip_last=0, ): r'''Calls handler on `expr` with keywords. Returns none. ''' articulation_lists = datastructuretools.CyclicTuple( self.articulation_lists) prototype = (scoretools.Note, scoretools.Chord) notes_and_chords = list(iterate(expr).by_class(prototype)) notes_and_chords = notes_and_chords[skip_first:] if skip_last: notes_and_chords = notes_and_chords[:-skip_last] i = 0 for note_or_chord in notes_and_chords: logical_tie = inspect_(note_or_chord).get_logical_tie() duration = logical_tie.get_duration() articulation_list = articulation_lists[offset + i] if articulation_list is None: i += 1 continue articulation_list = [ indicatortools.Articulation(_) for _ in articulation_list ] if self.minimum_duration is not None: if duration <= self.minimum_duration: continue if self.maximum_duration is not None: if self.maximum_duration < duration: continue if self.minimum_written_pitch is not None: if isinstance(note_or_chord, scoretools.Note): minimum_written_pitch = note_or_chord.written_pitch else: minimum_written_pitch = note_or_chord.writen_pitches[0] if minimum_written_pitch < self.minimum_written_pitch: continue if self.maximum_written_pitch is not None: if isinstance(note_or_chord, scoretools.Note): maximum_written_pitch = note_or_chord.written_pitch else: maximum_written_pitch = note_or_chord.written_pitches[-1] if self.maximum_written_pitch < maximum_written_pitch: continue logical_tie = inspect_(note_or_chord).get_logical_tie() if note_or_chord is logical_tie.head: for articulation in articulation_list: # TODO: make new(articulation) work articulation = copy.copy(articulation) attach(articulation, note_or_chord) i += 1 return expr
def _check_score(score): if inspect_(score).is_well_formed(): return violations = inspect_(score).tabulate_well_formedness_violations() message = 'score is not well-formed: {!r}.' message = message.format(score) message += '\n' message += violations raise Exception(message)
def _get_lilypond_format_bundle(self, leaf): from abjad.tools import lilypondnametools from abjad.tools import markuptools from abjad.tools import scoretools lilypond_format_bundle = self._get_basic_lilypond_format_bundle(leaf) prototype = ( scoretools.Rest, scoretools.MultimeasureRest, scoretools.Skip, ) if isinstance(leaf, prototype): return lilypond_format_bundle logical_tie = inspect_(leaf).get_logical_tie() if leaf is logical_tie.head: previous_leaf = leaf._get_leaf(-1) if previous_leaf is not None and \ not isinstance(previous_leaf, prototype) and \ inspect_(previous_leaf).get_spanners(type(self)): grob_override = lilypondnametools.LilyPondGrobOverride( grob_name='TrillSpanner', is_once=True, property_path=( 'bound-details', 'left', 'text', ), value=markuptools.Markup(r'\null'), ) string = grob_override.override_string lilypond_format_bundle.grob_overrides.append(string) if self.interval is not None: string = r'\pitchedTrill' lilypond_format_bundle.opening.spanners.append(string) if hasattr(leaf, 'written_pitch'): written_pitch = leaf.written_pitch elif hasattr(leaf, 'written_pitches'): if 0 < self.interval.semitones: written_pitch = max(leaf.written_pitches) elif self.interval.semitones < 0: written_pitch = min(leaf.written_pitches) trill_pitch = written_pitch.transpose(self.interval) string = r'\startTrillSpan {!s}'.format(trill_pitch) else: string = r'\startTrillSpan' lilypond_format_bundle.right.trill_pitches.append(string) if leaf is logical_tie.tail: next_leaf = leaf._get_leaf(1) if next_leaf is not None: string = r'<> \stopTrillSpan' lilypond_format_bundle.after.commands.append(string) else: string = r'\stopTrillSpan' lilypond_format_bundle.right.spanner_stops.append(string) return lilypond_format_bundle
def _collect_indicators(component): from abjad.tools import markuptools from abjad.tools.topleveltools import inspect_ expressions = [] for parent in inspect_(component).get_parentage(include_self=True): result = inspect_(parent).get_indicators(unwrap=False) expressions.extend(result) result = parent._get_spanner_indicators(unwrap=False) expressions.extend(result) up_markup = [] down_markup = [] neutral_markup = [] scoped_expressions = [] nonscoped_expressions = [] # classify expressions attached to component for expression in expressions: # skip nonprinting indicators like annotation indicator = expression.indicator if not hasattr(indicator, '_lilypond_format') and \ not hasattr(indicator, '_get_lilypond_format_bundle'): continue elif expression.is_annotation: continue # skip comments and commands unless attached directly to us elif expression.scope is None and \ hasattr(expression.indicator, '_format_leaf_children') and \ not getattr(expression.indicator, '_format_leaf_children') and\ expression.component is not component: continue # store markup elif isinstance(expression.indicator, markuptools.Markup): if expression.indicator.direction == Up: up_markup.append(expression.indicator) elif expression.indicator.direction == Down: down_markup.append(expression.indicator) elif expression.indicator.direction in (Center, None): neutral_markup.append(expression.indicator) # store scoped expressions elif expression.scope is not None: if expression._is_formattable_for_component(component): scoped_expressions.append(expression) # store nonscoped expressions else: nonscoped_expressions.append(expression) indicators = ( up_markup, down_markup, neutral_markup, scoped_expressions, nonscoped_expressions, ) return indicators
def by_spanner( self, prototype=None, reverse=False, ): r'''Iterates spanners forward in `expr`: :: >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 f'8 b'8 c''8") >>> attach(Slur(), staff[:4]) >>> attach(Slur(), staff[4:]) >>> attach(Beam(), staff[:]) :: >>> for spanner in iterate(staff).by_spanner(): ... spanner ... Beam("c'8, d'8, ... [5] ..., b'8, c''8") Slur("c'8, d'8, e'8, f'8") Slur("g'8, a'8, f'8, b'8, c''8") Iterates spanners backward in `expr`: :: >>> for spanner in iterate(staff).by_spanner(reverse=True): ... spanner ... Beam("c'8, d'8, ... [5] ..., b'8, c''8") Slur("g'8, a'8, f'8, b'8, c''8") Slur("c'8, d'8, e'8, f'8") Returns generator. ''' visited_spanners = set() for component in self.by_class(reverse=reverse): spanners = inspect_(component).get_spanners(prototype=prototype) spanners = sorted( spanners, key=lambda x: ( type(x).__name__, inspect_(x).get_timespan(), ), ) for spanner in spanners: if spanner in visited_spanners: continue visited_spanners.add(spanner) yield spanner
def by_spanner( self, prototype=None, reverse=False, ): r'''Iterates spanners forward in `expr`: :: >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 f'8 b'8 c''8") >>> attach(Slur(), staff[:4]) >>> attach(Slur(), staff[4:]) >>> attach(Beam(), staff[:]) :: >>> for spanner in iterate(staff).by_spanner(): ... spanner ... Beam("c'8, d'8, ... [5] ..., b'8, c''8") Slur("c'8, d'8, e'8, f'8") Slur("g'8, a'8, f'8, b'8, c''8") Iterates spanners backward in `expr`: :: >>> for spanner in iterate(staff).by_spanner(reverse=True): ... spanner ... Beam("c'8, d'8, ... [5] ..., b'8, c''8") Slur("g'8, a'8, f'8, b'8, c''8") Slur("c'8, d'8, e'8, f'8") Returns generator. ''' visited_spanners = set() for component in self.by_class(reverse=reverse): spanners = inspect_(component).get_spanners(prototype=prototype) spanners = sorted(spanners, key=lambda x: ( type(x).__name__, inspect_(x).get_timespan(), ), ) for spanner in spanners: if spanner in visited_spanners: continue visited_spanners.add(spanner) yield spanner
def _split_payload_at_offsets(self, offsets): assert isinstance(self.payload, scoretools.Container) music = self.payload self._payload = scoretools.Container() shards = mutate([music]).split( offsets, cyclic=False, fracture_spanners=True, ) shards = [shard[0] for shard in shards] for shard in shards: if not inspect_(shard).is_well_formed(): inspect_(shard).tabulate_well_formedness_violations_in_expr() return shards
def _do_tie_across_divisions(self, divisions): from abjad.tools import rhythmmakertools if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, patterntools.Pattern): tie_across_divisions = patterntools.Pattern.from_vector( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
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 _do_tie_across_divisions(self, divisions): if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, patterntools.Pattern): tie_across_divisions = patterntools.Pattern.from_vector( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() if tie_spanner._attachment_test_all(combined_logical_tie): attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
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 meters = [metertools.Meter(_) for _ in meters] durations = [durationtools.Duration(_) for _ in meters] music = sequencetools.flatten_sequence(selections) assert isinstance(music, list), repr(music) total_duration = sum(durations) music_duration = sum(inspect_(_).get_duration() for _ in music) assert total_duration == music_duration voice = scoretools.Voice(music) mutate(voice[:]).split( durations=durations, tie_split_notes=True, use_messiaen_style_ties=use_messiaen_style_ties, ) selections = list(voice[:]) return selections
def execute_against_score(self, score): r'''Execute pitch set expression against `score`. ''' statal_server_cursor = self.source_expression.payload leaves = list(self._iterate_selected_leaves_in_score(score)) assert all(isinstance(leaf, (scoretools.Note, scoretools.Chord)) for leaf in leaves) if self.level is None: level = -1 else: level = self.level if self.node_count is None: node_count = len(leaves) else: node_count = self.node_count pitch_numbers = \ statal_server_cursor(n=node_count, level=level) pitch_numbers = \ datastructuretools.CyclicTuple(pitch_numbers) for i, leaf in enumerate(leaves): #leaf.sounding_pitch = pitch_numbers[i] sounding_pitch = pitch_numbers[i] instrument = leaf._get_effective(instrumenttools.Instrument) if instrument: reference_pitch = instrument.sounding_pitch_of_written_middle_c else: reference_pitch = pitchtools.NamedPitch('C4') t_n = reference_pitch - pitchtools.NamedPitch('C4') written_pitch = pitchtools.transpose_pitch_carrier_by_interval( sounding_pitch, t_n) leaf.written_pitch = written_pitch assert inspect_(leaf).get_sounding_pitch() == sounding_pitch
def _apply_preferred_denominator(self, selections, divisions): from abjad.tools import scoretools if not self.preferred_denominator: return tuplets = iterate(selections).by_class(scoretools.Tuplet) tuplets = list(tuplets) if divisions is None: divisions = len(tuplets) * [None] assert len(selections) == len(divisions) assert len(tuplets) == len(divisions) for tuplet, division in zip(tuplets, divisions): if self.preferred_denominator == 'divisions': tuplet.preferred_denominator = division.numerator elif isinstance( self.preferred_denominator, durationtools.Duration): unit_duration = self.preferred_denominator assert unit_duration.numerator == 1 duration = inspect_(tuplet).get_duration() denominator = unit_duration.denominator nonreduced_fraction = duration.with_denominator(denominator) tuplet.preferred_denominator = nonreduced_fraction.numerator elif mathtools.is_positive_integer(self.preferred_denominator): tuplet.preferred_denominator = self.preferred_denominator else: message = 'invalid value for preferred denominator: {!r}.' message = message.format(self.preferred_denominator) raise Exception(message)
def _to_logical_measure_number( self, component, logical_measure_number_start_offsets, ): from abjad.tools import mathtools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ inspector = inspect_(component) component_start_offset = inspector.get_timespan().start_offset logical_measure_number_start_offsets = \ logical_measure_number_start_offsets[:] logical_measure_number_start_offsets.append(mathtools.Infinity()) pairs = sequencetools.iterate_sequence_nwise( logical_measure_number_start_offsets, n=2, ) for logical_measure_index, pair in enumerate(pairs): if pair[0] <= component_start_offset < pair[-1]: logical_measure_number = logical_measure_index + 1 return logical_measure_number message = 'can not find logical measure number: {!r}, {!r}.' message = message.format( component, logical_measure_number_start_offsets, ) raise ValueError(message)
def execute_against_score(self, score): r'''Execute pitch set expression against `score`. ''' statal_server_cursor = self.source_expression.payload leaves = list(self._iterate_selected_leaves_in_score(score)) assert all( isinstance(leaf, (scoretools.Note, scoretools.Chord)) for leaf in leaves) if self.level is None: level = -1 else: level = self.level if self.node_count is None: node_count = len(leaves) else: node_count = self.node_count pitch_numbers = \ statal_server_cursor(n=node_count, level=level) pitch_numbers = \ datastructuretools.CyclicTuple(pitch_numbers) for i, leaf in enumerate(leaves): #leaf.sounding_pitch = pitch_numbers[i] sounding_pitch = pitch_numbers[i] instrument = leaf._get_effective(instrumenttools.Instrument) if instrument: reference_pitch = instrument.sounding_pitch_of_written_middle_c else: reference_pitch = pitchtools.NamedPitch('C4') t_n = reference_pitch - pitchtools.NamedPitch('C4') written_pitch = pitchtools.transpose_pitch_carrier_by_interval( sounding_pitch, t_n) leaf.written_pitch = written_pitch assert inspect_(leaf).get_sounding_pitch() == sounding_pitch
def _check_well_formedness(self, selections): for component in iterate(selections).by_class(): inspector = inspect_(component) if not inspector.is_well_formed(): report = inspector.tabulate_well_formedness_violations() report = repr(component) + '\n' + report raise Exception(report)
def _to_logical_measure_number( self, component, logical_measure_number_start_offsets, ): from abjad.tools import mathtools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ inspector = inspect_(component) component_start_offset = inspector.get_timespan()._start_offset logical_measure_number_start_offsets = \ logical_measure_number_start_offsets[:] logical_measure_number_start_offsets.append(mathtools.Infinity()) pairs = sequencetools.iterate_sequence_nwise( logical_measure_number_start_offsets, n=2, ) for logical_measure_index, pair in enumerate(pairs): if pair[0] <= component_start_offset < pair[-1]: logical_measure_number = logical_measure_index + 1 return logical_measure_number message = 'can not find logical measure number: {!r}, {!r}.' message = message.format( component, logical_measure_number_start_offsets, ) raise ValueError(message)
def detach(prototype, component_expression=None): r'''Detaches from `component_expression` all items matching `prototype`. Returns tuple of zero or more detached items. ''' from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools import topleveltools if isinstance(prototype, spannertools.Spanner): prototype._detach() return assert component_expression is not None spanners = [] grace_containers = [] inspector = topleveltools.inspect_(component_expression) if isinstance(prototype, type): if issubclass(prototype, spannertools.Spanner): spanners = inspector.get_spanners(prototype) elif issubclass(prototype, scoretools.GraceContainer): grace_containers = inspector.get_grace_containers(prototype) else: assert hasattr(component_expression, '_indicator_expressions') result = [] for x in component_expression._indicator_expressions[:]: if isinstance(x, prototype): component_expression._indicator_expressions.remove(x) result.append(x) # indicator is a expression elif hasattr(x, 'indicator') and \ isinstance(x.indicator, prototype): x._detach() result.append(x.indicator) result = tuple(result) return result else: if isinstance(prototype, spannertools.Spanner): spanners = inspector.get_spanners(prototype) elif isinstance(prototype, scoretools.GraceContainer): grace_containers = inspector.get_grace_containers(prototype) else: assert hasattr(component_expression, '_indicator_expressions') result = [] for x in component_expression._indicator_expressions[:]: if x == prototype: component_expression._indicator_expressions.remove(x) result.append(x) # indicator is a expression elif hasattr(x, 'indicator') and x.indicator == prototype: x._detach() result.append(x.indicator) result = tuple(result) return result items = [] items.extend(spanners) items.extend(grace_containers) for item in items: item._detach() items = tuple(items) return items
def _fracture_right(self, i): self, left, right = ComplexBeam._fracture_right(self, i) weights = [ inspect_(left).get_duration(), inspect_(right).get_duration(), ] assert sum(self.durations) == sum(weights) split_durations = sequencetools.split_sequence( self.durations, weights, cyclic=False, overhang=False, ) left_durations, right_durations = split_durations left._durations = left_durations right._durations = right_durations return self, left, right
def _get_logical_measure_start_offsets(self, component): from abjad.tools import durationtools from abjad.tools import indicatortools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ from abjad.tools.topleveltools import iterate expressions = [] prototype = indicatortools.TimeSignature components = self._iterate_entire_score(component) for component in components: expressions_ = component._get_indicators( prototype, unwrap=False, ) expressions.extend(expressions_) pairs = [] for expression in expressions: inspector = inspect_(expression.component) start_offset = inspector.get_timespan().start_offset time_signature = expression.indicator pair = start_offset, time_signature pairs.append(pair) offset_zero = durationtools.Offset(0) default_time_signature = indicatortools.TimeSignature((4, 4)) default_pair = (offset_zero, default_time_signature) if pairs and not pairs[0] == offset_zero: pairs.insert(0, default_pair) elif not pairs: pairs = [default_pair] pairs.sort(key=lambda x: x[0]) parentage = component._get_parentage() score_root = parentage.root inspector = inspect_(score_root) score_stop_offset = inspector.get_timespan().stop_offset dummy_last_pair = (score_stop_offset, None) pairs.append(dummy_last_pair) measure_start_offsets = [] pairs = sequencetools.iterate_sequence_nwise(pairs, n=2) for current_pair, next_pair in pairs: current_start_offset, current_time_signature = current_pair next_start_offset, next_time_signature = next_pair measure_start_offset = current_start_offset while measure_start_offset < next_start_offset: measure_start_offsets.append(measure_start_offset) measure_start_offset += current_time_signature.duration return measure_start_offsets
def _format_before_leaf(self, leaf): from abjad.tools import scoretools if not isinstance(leaf, scoretools.Leaf): return [] result = [] #if self._is_beamable_component(leaf, beam_rests=self.beam_rests): if self._is_beamable_component(leaf): if self._is_exterior_leaf(leaf): left, right = self._get_left_right_for_exterior_leaf(leaf) elif self._is_just_left_of_gap(leaf): left = leaf.written_duration.flag_count if self.nibs_towards_nonbeamable_components: right = self.span_beam_count else: next_leaf = inspect_(leaf).get_leaf(1) if self._is_beamable_component( next_leaf, beam_rests=self.beam_rests, ): right = self.span_beam_count else: right = 0 elif self._is_just_right_of_gap(leaf): if self.nibs_towards_nonbeamable_components: left = self.span_beam_count else: previous_leaf = inspect_(leaf).get_leaf(-1) if self._is_beamable_component( previous_leaf, beam_rests=self.beam_rests, ): left = self.span_beam_count else: left = 0 right = leaf.written_duration.flag_count else: assert self._is_interior_leaf(leaf) left, right = self._get_left_right_for_interior_leaf(leaf) if left is not None: string = r'\set stemLeftBeamCount = #{}'.format(left) result.append(string) if right is not None: string = r'\set stemRightBeamCount = #{}'.format(right) result.append(string) return result
def _get_tremolo_reattack_duration(self): tremolos = inspect_(self).get_indicators(indicatortools.Tremolo) if not tremolos: return tremolo = tremolos[0] exponent = 2 + tremolo.beam_count denominator = 2 ** exponent reattack_duration = durationtools.Duration(1, denominator) return reattack_duration
def _next_leaf_is_bowed(self, leaf): if self._is_my_last_leaf(leaf): return False prototype = ( scoretools.MultimeasureRest, scoretools.Rest, scoretools.Skip, ) next_leaf = inspect_(leaf).get_leaf(1) if next_leaf is None or isinstance(next_leaf, prototype): return False next_contact_point = inspect_(next_leaf).get_indicator( indicatortools.BowContactPoint) if next_contact_point is None: return False elif next_contact_point.contact_point is None: return False return True
def _get_tremolo_reattack_duration(self): tremolos = inspect_(self).get_indicators(indicatortools.Tremolo) if not tremolos: return tremolo = tremolos[0] exponent = 2 + tremolo.beam_count denominator = 2**exponent reattack_duration = durationtools.Duration(1, denominator) return reattack_duration
def _make_ties_across_divisions(self, music): if not self.tie_across_divisions: return if self.tie_across_divisions == True: for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True)) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf)) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) elif isinstance(self.tie_across_divisions, (tuple, list)): tie_across_divisions = datastructuretools.CyclicTuple( self.tie_across_divisions ) pairs = sequencetools.iterate_sequence_nwise(music) for i, pair in enumerate(pairs): indicator = tie_across_divisions[i] if not bool(indicator): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) else: raise TypeError(self.tie_across_divisions)
def _make_ties_across_divisions(self, music): if not self.tie_across_divisions: return if self.tie_across_divisions == True: for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = next( iterate(division_one).by_class(prototype=scoretools.Leaf, reverse=True)) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf)) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) elif isinstance(self.tie_across_divisions, (tuple, list)): tie_across_divisions = datastructuretools.CyclicTuple( self.tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(music) for i, pair in enumerate(pairs): indicator = tie_across_divisions[i] if not bool(indicator): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) else: raise TypeError(self.tie_across_divisions)
def __call__(self, logical_ties): r'''Calls hairpin handler on `logical_ties`. Returns none. ''' if (self.span == 'contiguous notes and chords' or isinstance(self.span, (tuple, list))): groups = self._group_contiguous_logical_ties(logical_ties) elif self.span == 'nontrivial ties': groups = [[_] for _ in logical_ties] else: raise ValueError(self.span) if isinstance(self.span, (tuple, list)): if not self.enchain_hairpins: groups = self._partition_groups(groups) else: groups = self._partition_enchained_groups(groups) hairpin_tokens = self.hairpin_tokens for group_index, group in enumerate(groups): notes = [] for logical_tie in group: for note in logical_tie: notes.append(note) if len(notes) == 0: continue total_notes = len(notes) notes_to_span = [] for note_index, note in enumerate(notes): if self._index_matches_patterns(note_index, total_notes): notes_to_span.append(note) if not notes_to_span: continue if self.include_following_rests: last_note = notes_to_span[-1] next_leaf = inspect_(last_note).get_leaf(1) prototype = (scoretools.Rest, scoretools.MultimeasureRest) if isinstance(next_leaf, prototype): notes_to_span.append(next_leaf) if len(notes_to_span) == 1 and self.omit_lone_note_dynamic: continue if len(notes_to_span) == 1 and not self.omit_lone_note_dynamic: hairpin_token = hairpin_tokens[group_index] start_dynamic = hairpin_token[0] dynamic = indicatortools.Dynamic(start_dynamic) attach(dynamic, notes[0]) continue hairpin_token = hairpin_tokens[group_index] if hairpin_token is None: continue descriptor = ' '.join([_ for _ in hairpin_token if _]) include_rests = bool(self.include_following_rests) hairpin = spannertools.Hairpin( descriptor=descriptor, include_rests=include_rests, ) attach(hairpin, notes_to_span)
def _apply_logical_tie_masks(self, selections): from abjad.tools import rhythmmakertools if self.logical_tie_masks is None: return selections # wrap every selection in a temporary container; # this allows the call to mutate().replace() to work containers = [] for selection in selections: container = scoretools.Container(selection) attach('temporary container', container) containers.append(container) logical_ties = iterate(selections).by_logical_tie() logical_ties = list(logical_ties) total_logical_ties = len(logical_ties) for index, logical_tie in enumerate(logical_ties[:]): matching_mask = self.logical_tie_masks.get_matching_pattern( index, total_logical_ties, ) if not isinstance(matching_mask, rhythmmakertools.SilenceMask): continue if isinstance(logical_tie.head, scoretools.Rest): continue for leaf in logical_tie: rest = scoretools.Rest(leaf.written_duration) inspector = inspect_(leaf) if inspector.has_indicator(durationtools.Multiplier): multiplier = inspector.get_indicator( durationtools.Multiplier, ) multiplier = durationtools.Multiplier(multiplier) attach(multiplier, rest) mutate(leaf).replace([rest]) detach(spannertools.Tie, rest) # remove every temporary container and recreate selections new_selections = [] for container in containers: inspector = inspect_(container) assert inspector.get_indicator(str) == 'temporary container' new_selection = mutate(container).eject_contents() new_selections.append(new_selection) return new_selections
def _make_ties_across_divisions(self, divisions): from abjad.tools import rhythmmakertools if not self.tie_across_divisions: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, rhythmmakertools.BooleanPattern): tie_across_divisions = \ rhythmmakertools.BooleanPattern.from_sequence( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def _format_repeat_tremolo_command(self): tremolo = inspect_(self).get_indicator(indicatortools.Tremolo) reattack_duration = self._get_tremolo_reattack_duration() repeat_count = self.written_duration / reattack_duration / 2 if not mathtools.is_integer_equivalent_expr(repeat_count): message = 'can not tremolo duration {} with {} beams.' message = message.format(self.written_duration, tremolo.beam_count) raise Exception(message) repeat_count = int(repeat_count) command = r'\repeat tremolo {}'.format(repeat_count) return command
def _configure_messiaen_style_tie_spanners(self, divisions): tie_spanners = set() prototype = spannertools.Tie for leaf in iterate(divisions).by_class(scoretools.Leaf): tie_spanners_ = inspect_(leaf).get_spanners( prototype=spannertools.Tie, in_parentage=True, ) tie_spanners.update(tie_spanners_) for tie_spanner in tie_spanners: tie_spanner._use_messiaen_style_ties = True
def _configure_messiaen_style_ties(self, divisions): if not self.use_messiaen_style_ties: return tie_spanners = set() for leaf in iterate(divisions).by_class(scoretools.Leaf): tie_spanners_ = inspect_(leaf).get_spanners( prototype=spannertools.Tie, in_parentage=True, ) tie_spanners.update(tie_spanners_) for tie_spanner in tie_spanners: tie_spanner._use_messiaen_style_ties = True
def __contains__(self, arg): r'''Is true when pitch range contains `arg`. Otherwise false. Returns boolean. ''' from abjad.tools import pitchtools from abjad.tools import scoretools if (hasattr(arg, '_has_effective_indicator') and arg._has_effective_indicator(indicatortools.IsUnpitched)): return True elif isinstance(arg, (int, float)): pitch = pitchtools.NamedPitch(arg) return self._contains_pitch(pitch) elif isinstance(arg, pitchtools.NamedPitch): return self._contains_pitch(arg) elif isinstance(arg, scoretools.Note): sounding_pitch = inspect_(arg).get_sounding_pitch() return self._contains_pitch(sounding_pitch) elif isinstance(arg, scoretools.Chord): sounding_pitches = inspect_(arg).get_sounding_pitches() return all(self._contains_pitch(x) for x in sounding_pitches) try: arg = type(self)(arg) return self.__lt__(arg) except TypeError: pass elif isinstance(arg, (scoretools.Rest, scoretools.Skip)): return True elif isinstance(arg, scoretools.Container): return all(x in self for x in arg.select_leaves()) else: pitches = pitchtools.list_named_pitches_in_expr(arg) if pitches: return all(self._contains_pitch(x) for x in pitches) else: try: return all(self._contains_pitch(x) for x in arg) except TypeError: return False return False
def __call__(self, expr): r'''Calls duration inequality on `expr`. Returns true or false. ''' if isinstance(expr, scoretools.Component): duration = inspect_(expr).get_duration() elif isinstance(expr, selectiontools.Selection): duration = expr.get_duration() else: duration = durationtools.Duration(expr) result = self._operator_function(duration, self._duration) return result