def _make_leaf(self, pitch, duration_string, indication): duration = abjad.Duration(duration_string) leaves = abjad.scoretools.make_leaves( [pitch], [duration], ) if indication in ('-', '>'): indication = Articulation(indication) first_component = leaves[0] first_leaf = abjad.inspect_(first_component).get_leaf(0) abjad.attach(indication, first_leaf) elif indication is None: pass elif indication.endswith('z'): markup = abjad.Markup(indication, direction=Down) markup = markup.dynamic() first_component = leaves[0] first_leaf = abjad.inspect_(first_component).get_leaf(0) abjad.attach(markup, first_leaf) else: message = 'unrecognized indication: {!r}.' message = message.format(indication) raise ValueError(message) for leaf in abjad.iterate(leaves).by_leaf(): if abjad.Duration(1, 16) < leaf.written_duration: tremolo = abjad.indicatortools.StemTremolo(16) abjad.attach(tremolo, leaf) return leaves
def __call__( self, segment_metadata=None, previous_segment_metadata=None, ): r'''Calls segment-maker. Returns LilyPond file. ''' self._segment_metadata = segment_metadata or \ abjad.datastructuretools.TypedOrderedDict() self._previous_segment_metadata = previous_segment_metadata or \ abjad.datastructuretools.TypedOrderedDict() self._make_score() self._make_music() self._add_final_bar_line() self._add_final_markup() self._make_lilypond_file() self._configure_lilypond_file() score_block = self._lilypond_file['score'] score = score_block['Score'] if not abjad.inspect_(score).is_well_formed(): inspector = abjad.inspect_(score) string = inspector.tabulate_well_formedness_violations() raise Exception(string) return self._lilypond_file, self._segment_metadata
def _make_time_signatures(self, tuplets): time_signatures = [] denominators = range(self.denominator, 2 * self.denominator) for tuplet in tuplets: duration = abjad.inspect_(tuplet).get_duration() duration = abjad.mathtools.NonreducedFraction(duration) for denominator in denominators: duration = duration.with_denominator(denominator) if duration.denominator == denominator: time_signatures.append(duration) break else: duration = abjad.inspect_(tuplet).get_duration() duration = abjad.mathtools.NonreducedFraction(duration) time_signatures.append(duration) tuplet_count = len(tuplets) time_signature_count = len(time_signatures) pair = (tuplet_count, time_signature_count) assert len(tuplets) == len(time_signatures), pair for tuplet, time_signature in zip(tuplets, time_signatures): tuplet_duration = abjad.inspect_(tuplet).get_duration() time_signature = abjad.Duration(time_signature) assert tuplet_duration == time_signature, repr(( tuplet_duration, time_signature, )) return time_signatures
def _adjust_stems(self): measures = self._partition_music_into_measures() down_beam_positions = (-4.5, -4.5) up_beam_positions = (5.5, 5.5) for measure in measures: voice_numbers = [] for component in measure: for note in component: assert isinstance(note, abjad.Note), repr(note) voice_number = abjad.inspect_(note).get_indicator(int) voice_numbers.append(voice_number) if len(set(voice_numbers)) == 1: continue for component in measure: for note in component: voice_number = abjad.inspect_(note).get_indicator(int) if voice_number == 1: abjad.override(note).stem.direction = Up abjad.override(note).beam.positions = up_beam_positions elif voice_number == 2: abjad.override(note).stem.direction = Up abjad.override(note).beam.positions = up_beam_positions elif voice_number == 3: abjad.override(note).stem.direction = Down abjad.override(note).beam.positions = down_beam_positions else: raise ValueError(voice_number)
def _populate_time_signature_context(self): time_signature_context = self._score['Time Signature Context'] music_voice = self._score['Music Voice'] measure_durations = [] current_duration = abjad.Duration(0) ideal_measure_duration = abjad.Duration(4, 4) for component in music_voice: component_duration = abjad.inspect_(component).get_duration() candidate_duration = current_duration + component_duration if ideal_measure_duration < candidate_duration: if 0 < current_duration: measure_durations.append(current_duration) current_duration = component_duration else: current_duration = candidate_duration measure_durations.append(current_duration) measures = abjad.scoretools.make_spacer_skip_measures( measure_durations) time_signature_context.extend(measures) for measure in abjad.iterate(time_signature_context).by_class(abjad.Measure): time_signature = abjad.inspect_(measure).get_indicator(abjad.TimeSignature) if time_signature.denominator < 4: fraction = abjad.mathtools.NonreducedFraction( time_signature.pair) fraction = fraction.with_multiple_of_denominator(4) abjad.detach(time_signature, measure) new_time_signature = abjad.TimeSignature(fraction) abjad.attach(new_time_signature, measure)
def __call__(self, music, name=None): leaves = list(iterate(music).by_leaf()) weights = [] weighted_pitches = [] for leaf in leaves: weight = float(inspect_(leaf).get_duration()) if isinstance(leaf, scoretools.Note): pitch = float(leaf.written_pitch) weighted_pitch = pitch * weight weights.append(weight) weighted_pitches.append(weighted_pitch) elif isinstance(leaf, scoretools.Chord): for pitch in leaf.written_pitches: pitch = float(pitch) weighted_pitch = pitch * weight weighted_pitches.append(weighted_pitch) weights.append(weight) sum_of_weights = sum(weights) sum_of_weighted_pitches = sum(weighted_pitches) weighted_average = sum_of_weighted_pitches / sum_of_weights #print(music, weighted_average) clef = inspect_(leaves[0]).get_effective(indicatortools.Clef) octavation_spanner = None if clef == indicatortools.Clef('treble'): if int(pitchtools.NamedPitch('C6')) <= int(weighted_average): octavation_spanner = spannertools.OctavationSpanner() elif clef == indicatortools.Clef('bass'): pass if octavation_spanner is not None: attach(octavation_spanner, music)
def _replace(self, old_leaf, new_leaf): grace_containers = inspect_(old_leaf).get_grace_containers('after') if grace_containers: old_grace_container = grace_containers[0] grace_notes = list(iterate(old_grace_container).by_leaf()) detach(scoretools.GraceContainer, old_leaf) indicator_expressions = inspect_(old_leaf).get_indicators(unwrap=False) #for indicator_expression in indicator_expressions: # detach(indicator, old_leaf) timespan = old_leaf._timespan start_offset = old_leaf._start_offset stop_offset = old_leaf._stop_offset logical_measure_number = old_leaf._logical_measure_number mutate(old_leaf).replace(new_leaf) new_leaf._timespan = timespan new_leaf._start_offset = start_offset new_leaf._stop_offset = stop_offset new_leaf._logical_measure_number = logical_measure_number if grace_containers: new_grace_container = scoretools.GraceContainer( grace_notes, kind='after', ) attach(new_grace_container, new_leaf) for indicator_expression in indicator_expressions: attach(indicator_expression, new_leaf)
def _populate_pitch_staff(self): pitch_staff = self._score['Pitch Staff'] if self.clef is not None: clef = abjad.Clef(self.clef) abjad.attach(clef, pitch_staff) if not self.notes: return if not self.pitches: bow_location_voice = self._score['Bow Location Voice'] total_duration = abjad.inspect_(bow_location_voice).get_duration() skip = abjad.Skip(1) multiplier = abjad.Multiplier(total_duration) abjad.attach(multiplier, skip) pitch_staff.append(skip) else: durations = [] current_duration = abjad.Duration(0) leaf_indices = [_[0] for _ in self.pitches] leaf_index = -1 for expression in self.notes: if expression == '|': continue leaf_index += 1 staff_position, duration, articulation = expression duration = abjad.Duration(duration) if leaf_index in leaf_indices and abjad.Duration(0) < current_duration: durations.append(current_duration) current_duration = duration else: current_duration += duration if abjad.Duration(0) < current_duration: durations.append(current_duration) assert len(durations) == len(self.pitches) notes = [] for leaf_index, pitch in self.pitches: if pitch == 'skip': skip = abjad.Skip(abjad.Duration(1)) notes.append(skip) continue parenthesize = False if pitch.endswith('()'): parenthesize = True pitch = pitch.strip('()') pitch = abjad.NamedPitch(pitch) note = abjad.Note(pitch, abjad.Duration(1)) if parenthesize: note.note_head.is_parenthesized = True notes.append(note) for note, duration in zip(notes, durations): multiplier = abjad.Multiplier(duration) abjad.attach(multiplier, note) pitch_staff.extend(notes) first_leaf = abjad.inspect_(pitch_staff).get_leaf(n=0) clef = abjad.Clef('bass') if isinstance(first_leaf, abjad.Note): if abjad.NamedPitch('C4') < first_leaf.written_pitch: clef = abjad.Clef('treble') abjad.attach(clef, pitch_staff)
def make_annotated_phrase(phrase, color=None): duration = inspect_(phrase).get_duration() annotated_phrase = scoretools.FixedDurationTuplet(duration) durations = [inspect_(_).get_duration() for _ in phrase] leaves = scoretools.make_leaves([0], durations) annotated_phrase.extend(leaves) if color: override(annotated_phrase).tuplet_bracket.color = color return annotated_phrase
def __contains__(self, component): if self._timespan_map is None: message = 'must construct timespan map first.' raise Exception(message) voice = abjad.inspect_(component).get_parentage().get_first( abjad.scoretools.Voice) component_timespan = abjad.inspect_(component).get_timespan() for voice_name, scope_timespan in self._timespan_map: if voice_name == voice.name: if component_timespan.starts_during_timespan(scope_timespan): return True return False
def _get_offsets(self, start_stage, stop_stage): context = self._score['Time Signature Context'] result = self._stage_number_to_measure_indices(start_stage) start_measure_index, stop_measure_index = result start_measure = context[start_measure_index] assert isinstance(start_measure, abjad.Measure), start_measure start_offset = abjad.inspect_(start_measure).get_timespan().start_offset result = self._stage_number_to_measure_indices(stop_stage) start_measure_index, stop_measure_index = result stop_measure = context[stop_measure_index] assert isinstance(stop_measure, abjad.Measure), stop_measure stop_offset = abjad.inspect_(stop_measure).get_timespan().stop_offset return start_offset, stop_offset
def _populate_underlying_dynamics_voice(self): if not self.notes: return underlying_dynamics_voice = self._score['Underlying Dynamics Voice'] durations = self._get_bow_location_durations() skips = abjad.scoretools.make_skips(abjad.Duration(1), durations) underlying_dynamics_voice.extend(skips) if not self.underlying_dynamics: return for index, string in self.underlying_dynamics: skip = underlying_dynamics_voice[index] if string in ('<', '>'): indicator = abjad.LilyPondCommand( string, format_slot='right', ) elif string == '-|': indicator = abjad.LilyPondCommand( '<', format_slot='right', ) stencil = abjad.schemetools.Scheme('constante-hairpin') abjad.override(skip).hairpin.stencil = stencil elif string == '<!': indicator = abjad.LilyPondCommand( '<', format_slot='right', ) stencil = abjad.schemetools.Scheme('flared-hairpin') abjad.override(skip).hairpin.stencil = stencil elif string == '!>': indicator = abjad.LilyPondCommand( '>', format_slot='right', ) stencil = abjad.schemetools.Scheme('flared-hairpin') abjad.override(skip).hairpin.stencil = stencil else: indicator = abjad.Dynamic(string) abjad.attach(indicator, skip) last_skip = skips[-1] prototype = abjad.LilyPondCommand if not abjad.inspect_(last_skip).has_indicator(prototype): if not abjad.inspect_(last_skip).has_indicator(abjad.Dynamic): indicator = abjad.LilyPondCommand( '!', format_slot='right', ) abjad.attach(indicator, last_skip)
def _make_new_leaf(self, old_leaf): duration = old_leaf.written_duration if isinstance(self.leaf, scoretools.Note): new_leaf = scoretools.Note(self.leaf.written_pitch, duration) elif isinstance(self.leaf, scoretools.Chord): new_leaf = scoretools.Chord(self.leaf.written_pitches, duration) elif isinstance(self.leaf, scoretools.Rest): new_leaf = scoretools.Rest(duration) elif isinstance(self.leaf, scoretools.Skip): new_leaf = scoretools.Skip(duration) prototype = durationtools.Multiplier if inspect_(old_leaf).has_indicator(prototype): multiplier = inspect_(old_leaf).get_indicator(prototype) attach(multiplier, new_leaf) return new_leaf
def _get_grace_logical_ties(logical_tie): logical_ties = [] head = logical_tie.head previous_leaf = inspect_(head).get_leaf(-1) if previous_leaf is None: return logical_ties grace_containers = inspect_(previous_leaf).get_grace_containers( 'after') if grace_containers: grace_container = grace_containers[0] for logical_tie in iterate(grace_container).by_logical_tie( pitched=True, ): logical_ties.append(logical_tie) return logical_ties
def __call__(self, segment_maker): r'''Calls spacing specifier. Returns none. ''' score = segment_maker._score skip_context = score['Time Signature Context Skips'] leaves = abjad.iterate(score).by_leaf() minimum_leaf_durations_by_measure = \ self._get_minimum_leaf_durations_by_measure(skip_context, leaves) fermata_start_offsets = getattr( segment_maker, '_fermata_start_offsets', [], ) skips = abjad.iterate(skip_context).by_leaf(abjad.scoretools.Skip) for measure_index, skip in enumerate(skips): measure_timespan = abjad.inspect_(skip).get_timespan() if (self.fermata_measure_width is not None and measure_timespan.start_offset in fermata_start_offsets): duration = self.fermata_measure_width else: duration = minimum_leaf_durations_by_measure[measure_index] if self.minimum_width is not None: if self.minimum_width < duration: duration = self.minimum_width if self.multiplier is not None: duration = duration / self.multiplier command = abjad.indicatortools.LilyPondCommand('newSpacingSection') abjad.attach(command, skip) moment = abjad.schemetools.SchemeMoment(duration) abjad.set_(skip).score.proportional_notation_duration = moment
def _has_forbidden_annotation(self, leaf): if self.forbidden_annotations is None: return False for forbidden_annotation in self.forbidden_annotations: if abjad.inspect_(leaf).get_annotation(forbidden_annotation): return True return False
def __call__(self, logical_ties): r"""Calls trill specifier. Returns none. """ if isinstance(logical_ties[0], abjad.scoretools.Leaf): logical_ties = [abjad.selectiontools.LogicalTie(_) for _ in logical_ties] for logical_tie in logical_ties: written_duration = abjad.durationtools.Duration(0) for note in logical_tie: written_duration += note.written_duration if self.minimum_written_duration is not None: if written_duration < self.minimum_written_duration: continue if self.maximum_written_duration is not None: if self.maximum_written_duration <= written_duration: continue spanner = abjad.spannertools.TrillSpanner( interval=self.interval, is_harmonic=self.is_harmonic, pitch=self.pitch ) leaves = [] for note in logical_tie: leaves.append(note) skip_spanner = False for leaf in leaves: if self._has_forbidden_annotation(leaf): skip_spanner = True break if skip_spanner: continue next_leaf = abjad.inspect_(leaves[-1]).get_leaf(1) if next_leaf is not None: leaves.append(next_leaf) if 1 < len(leaves): abjad.attach(spanner, leaves)
def _compound_scope_to_logical_ties( self, compound_scope, include_rests=False, ): import huitzil timespan_map, timespans = [], [] for scope in compound_scope.simple_scopes: start_stage, stop_stage = scope.stages offsets = self._get_offsets(start_stage, stop_stage) timespan = abjad.timespantools.Timespan(*offsets) timespan_map.append((scope.voice_name, timespan)) timespans.append(timespan) compound_scope._timespan_map = timespan_map voice_names = [_[0] for _ in timespan_map] compound_scope._voice_names = tuple(voice_names) logical_ties = [] if include_rests: prototype = (abjad.Note, abjad.Chord, abjad.Rest) else: prototype = (abjad.Note, abjad.Chord) for note in abjad.iterate(self._score).by_timeline(prototype): if note in compound_scope: logical_tie = abjad.inspect_(note).get_logical_tie() if logical_tie.head is note: logical_ties.append(logical_tie) start_offset = min(_.start_offset for _ in timespans) stop_offset = max(_.stop_offset for _ in timespans) timespan = abjad.timespantools.Timespan(start_offset, stop_offset) return logical_ties, timespan
def __call__(self, music, name=None): import consort leaves = list(iterate(music).by_leaf()) weights = [] weighted_pitches = [] for leaf in leaves: weight = float(inspect_(leaf).get_duration()) if isinstance(leaf, scoretools.Note): pitch = float(leaf.written_pitch) weighted_pitch = pitch * weight weights.append(weight) weighted_pitches.append(weighted_pitch) elif isinstance(leaf, scoretools.Chord): for pitch in leaf.written_pitches: pitch = float(pitch) weighted_pitch = pitch * weight weighted_pitches.append(weighted_pitch) weights.append(weight) sum_of_weights = sum(weights) sum_of_weighted_pitches = sum(weighted_pitches) weighted_average = sum_of_weighted_pitches / sum_of_weights if weighted_average < 0: clef_spanner = consort.ClefSpanner('bass') else: clef_spanner = consort.ClefSpanner('treble') attach(clef_spanner, music, name=name)
def _get_instrument(logical_tie, music_specifier): if music_specifier.instrument is not None: return music_specifier.instrument component = logical_tie.head prototype = instrumenttools.Instrument instrument = inspect_(component).get_effective(prototype) return instrument
def _partition_music_into_measures(self): context = self._score['Time Signature Context'] measure_durations = [abjad.inspect_(_).get_duration() for _ in context] music_voice = self._score['Music Voice'] component_durations = [ abjad.inspect_(_).get_duration() for _ in music_voice] measure_parts = abjad.sequencetools.partition_sequence_by_weights( component_durations, measure_durations, ) measure_counts = [len(_) for _ in measure_parts] parts = abjad.sequencetools.partition_sequence_by_counts( music_voice[:], measure_counts, ) return parts
def _get_score_pitch_classes(self, score): result = [] notes = [] for note in abjad.iterate(score).by_class(with_grace_notes=True): if not isinstance(note, abjad.Note): continue if abjad.inspect_(note).get_indicator(self._foreshadow_tag): continue if abjad.inspect_(note).get_indicator(self._recollection_tag): continue notes.append(note) notes.sort(key=lambda _: abjad.inspect_(_).get_timespan().start_offset) for note in notes: pitch_class = note.written_pitch.numbered_pitch_class result.append(pitch_class) return result
def _raise_duration(self): if not self.calculate_duration: return music_voice = self._score['Music Voice'] duration = abjad.inspect_(music_voice).get_duration(in_seconds=True) string = '%.2f seconds' % float(duration) raise Exception(string)
def test_make_measures_02(): t = abjad.Voice([abjad.Note(n, (1, 8)) for n in range(8)]) assert len(t) == 8 leaves_before = abjad.iterate(t).by_leaf() leaves_before = list(leaves_before) lidercfeny.etc.transforms.make_measures(t, [(n, 8) for n in (2, 3, 3)]) assert len(t) == 3 leaves_after = abjad.iterate(t).by_leaf() leaves_after = list(leaves_after) assert leaves_before == leaves_after for i, x in enumerate(t): assert isinstance(x, abjad.Measure) if i == 0: assert abjad.inspect_(x).get_duration() == abjad.Duration(2, 8) else: assert abjad.inspect_(x).get_duration() == abjad.Duration(3, 8)
def populate_one_dynamics_voice( dynamics_voice, nv_durations, dd, is_first, nv_gliss, ): leaves = abjad.scoretools.make_notes_with_multiplied_durations( 0, abjad.Duration(1, 16), nv_durations) leaves = list(leaves) for i in range(len(leaves)): d = dd[i] if d == 's': leaves[i] = abjad.Skip(leaves[i]) else: pitch_number = dynamics_string_to_chromatic_pitch_number(d) leaves[i].written_pitch = pitch_number dynamics_voice.extend(leaves) if is_first: voice_modulus = 0 else: voice_modulus = 1 for i in range(len(dynamics_voice) - 1): if i % 2 == voice_modulus: current_leaf = dynamics_voice[i] if isinstance(current_leaf, abjad.Note): next_leaf = dynamics_voice[i+1] if not isinstance(next_leaf, abjad.Note): next_leaf = abjad.Note( current_leaf.written_pitch, next_leaf.written_duration, #next_leaf.lilypond_duration_multiplier, ) if abjad.inspect_(next_leaf).has_indicator( abjad.Multiplier): inspector = multiplier = abjad.inspect_(next_leaf) multiplier = inspector.get_indicator(abjad.Multiplier) abjad.attach(multiplier, next_leaf) dynamics_voice[i+1] = next_leaf #abjad.Glissando([current_leaf, next_leaf]) abjad.attach(abjad.Glissando(), [current_leaf, next_leaf]) gliss_indicator = nv_gliss[i] # flat glissando indicating subito dynamic change # at following event if gliss_indicator == 0: next_leaf.written_pitch = current_leaf.written_pitch
def _collect_logical_ties(container): logical_ties = [] for leaf in iterate(container).by_class(scoretools.Note): leaf_logical_tie = inspect_(leaf).get_logical_tie() if leaf is not leaf_logical_tie.head: continue logical_ties.append(leaf_logical_tie) return logical_ties
def _get_first_leaf(self, music): first_item = music[0] if isinstance(first_item, abjad.selectiontools.Selection): first_component = first_item[0] else: first_component = first_item first_leaf = abjad.inspect_(first_component).get_leaf(0) assert isinstance(first_leaf, abjad.scoretools.Leaf), repr(first_leaf) return first_leaf
def _get_pitch_range( instrument, logical_tie, ): prototype = pitchtools.PitchRange component = logical_tie.head pitch_range = inspect_(component).get_effective(prototype) if pitch_range is None and instrument is not None: pitch_range = instrument.pitch_range return pitch_range
def _set_pitch(self, leaf, pitch): string = 'not yet pitched' if abjad.inspect_(leaf).has_indicator(string): abjad.detach(string, leaf) if isinstance(leaf, abjad.Note): leaf.written_pitch = pitch elif isinstance(leaf, abjad.Chord): raise NotImplementedError if self.allow_repeated_pitches: abjad.attach('repeated pitch allowed', leaf)
def _get_lilypond_format_bundle(self, component): import consort parentage = inspect_(component).get_parentage() prototype = scoretools.GraceContainer grace_container = None for parent in parentage: if isinstance(parent, prototype): grace_container = parent break if grace_container is None: return prototype = consort.ConsortTrillSpanner carrier = grace_container._carrier spanners = inspect_(carrier).get_spanners(prototype) if not spanners: return bundle = systemtools.LilyPondFormatBundle() bundle.right.spanner_stops.append(r'\stopTrillSpan') return bundle