def _update_all_leaf_indices_and_measure_numbers(component): r'''Call only when updating offsets. No separate state flags exist for leaf indices or measure numbers. ''' from abjad.tools import contexttools from abjad.tools import iterationtools parentage = component._get_parentage() score_root = parentage.root if isinstance(score_root, contexttools.Context): contexts = iterationtools.iterate_contexts_in_expr(score_root) for context in contexts: for leaf_index, leaf in enumerate( iterationtools.iterate_leaves_in_expr(context)): leaf._leaf_index = leaf_index for measure_index, measure in enumerate( iterationtools.iterate_measures_in_expr(context)): measure_number = measure_index + 1 measure._measure_number = measure_number else: for leaf_index, leaf in enumerate( iterationtools.iterate_leaves_in_expr(score_root)): leaf._leaf_index = leaf_index for measure_index, measure in enumerate( iterationtools.iterate_measures_in_expr(score_root)): measure_number = measure_index + 1 measure._measure_number = measure_number
def fill_measures_in_expr_with_minimal_number_of_notes(expr, decrease_durations_monotonically=True, iterctrl=None): '''Fill measures in `expr` with minimal number of notes that decrease durations monotonically: :: >>> measure = Measure((5, 18), []) :: >>> measuretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=True) .. doctest:: >>> f(measure) { \time 5/18 \scaleDurations #'(8 . 9) { c'4 ~ c'16 } } Fill measures in `expr` with minimal number of notes that increase durations monotonically: :: >>> measure = Measure((5, 18), []) :: >>> measuretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=False) .. doctest:: >>> f(measure) { \time 5/18 \scaleDurations #'(8 . 9) { c'16 ~ c'4 } } Returns none. ''' from abjad.tools import contexttools from abjad.tools import iterationtools if iterctrl is None: iterctrl = lambda measure, i: True for i, measure in enumerate(iterationtools.iterate_measures_in_expr(expr)): if iterctrl(measure, i): time_signature = measure.time_signature written_duration = time_signature.duration / time_signature.implied_prolation notes = notetools.make_notes(0, written_duration, decrease_durations_monotonically=decrease_durations_monotonically) measure[:] = notes
def _run(self, expr): violators = [] total = 0 for t in iterationtools.iterate_measures_in_expr(expr): parentage = t._get_parentage(include_self=False) if parentage.get_first(measuretools.Measure): violators.append(t) total += 1 return violators, total
def _run(self, expr): violators = [] total, bad = 0, 0 for measure in iterationtools.iterate_measures_in_expr(expr): time_signature = measure.time_signature if time_signature is not None: if measure._preprolated_duration != time_signature.duration: violators.append(measure) bad += 1 total += 1 return violators, total
def fill_measures_in_expr_with_time_signature_denominator_notes(expr, iterctrl=None): r"""Fill measures in `expr` with time signature denominator notes: :: >>> staff = Staff([Measure((3, 4), []), Measure((3, 16), []), Measure((3, 8), [])]) >>> measuretools.fill_measures_in_expr_with_time_signature_denominator_notes(staff) .. doctest:: >>> f(staff) \new Staff { { \time 3/4 c'4 c'4 c'4 } { \time 3/16 c'16 c'16 c'16 } { \time 3/8 c'8 c'8 c'8 } } Delete existing contents of measures in `expr`. Returns none. """ from abjad.tools import contexttools from abjad.tools import iterationtools if iterctrl is None: iterctrl = lambda measure, i: True for i, measure in enumerate(iterationtools.iterate_measures_in_expr(expr)): if iterctrl(measure, i): time_signature = measure.time_signature denominator = mathtools.greatest_power_of_two_less_equal(time_signature.denominator) numerator = time_signature.numerator notes = notetools.Note(0, (1, denominator)) * numerator measure[:] = notes
def move_measure_prolation_to_full_measure_tuplet(expr): '''Move measure prolation to full-measure tuplet. Turn non-power-of-two measures into power-of-two measures containing a single fixed-duration tuplet. Note that not all non-power-of-two measures can be made power-of-two. Returns None because processes potentially many measures. ''' from abjad.tools import contexttools from abjad.tools import iterationtools from abjad.tools import measuretools from abjad.tools import timesignaturetools from abjad.tools import tuplettools from abjad.tools.scoretools import attach for measure in iterationtools.iterate_measures_in_expr(expr): effective_time_signature = measure.time_signature if effective_time_signature.has_non_power_of_two_denominator: # find time signature and contents multipliers time_signature_multiplier = effective_time_signature.implied_prolation contents_multiplier = \ measure._get_likely_multiplier_of_components(measure[:]) # update non-power-of-two time signature to power-of-two power_of_two_time_signature = effective_time_signature.with_power_of_two_denominator( contents_multiplier) for mark in measure._get_marks(contexttools.TimeSignatureMark): mark.detach() attach(power_of_two_time_signature, measure) # find target duration and create tuplet target_duration = time_signature_multiplier * measure._contents_duration tuplet = tuplettools.FixedDurationTuplet(target_duration, measure[:]) # scale tuplet contents, if helpful if contents_multiplier is not None: numerator = contents_multiplier.numerator denominator = contents_multiplier.denominator pair = (denominator, numerator) inverse_multiplier = durationtools.Multiplier(*pair) tuplet._scale_contents(inverse_multiplier)
def fill_measures_in_expr_with_full_measure_spacer_skips(expr, iterctrl=None): '''Fill measures in `expr` with full-measure spacer skips. ''' from abjad.tools import contexttools from abjad.tools import iterationtools if iterctrl is None: iterctrl = lambda measure, i: True for i, measure in enumerate(iterationtools.iterate_measures_in_expr(expr)): if iterctrl(measure, i): skip = skiptools.Skip(1) # allow zero-update iteration time_signature = measure.time_signature skip.lilypond_duration_multiplier = \ time_signature.duration / time_signature.implied_prolation measure[:] = [skip] for spanner in measure._get_spanners(): spanner._remove(component)
def get_previous_measure_from_component(component): '''Get previous measure from `component`. When `component` is voice, staff or other sequential context, and when `component` contains a measure, return last measure in `component`. This starts the process of backwards measure iteration. :: >>> staff = Staff("abj: | 2/8 c'8 d'8 || 2/8 e'8 f'8 |") >>> measuretools.get_previous_measure_from_component(staff) Measure(2/8, [e'8, f'8]) When `component` is voice, staff or other sequential context, and when `component` contains no measure, raise missing measure error. When `component` is a measure and there is a measure immediately preceeding `component`, return measure immediately preceeding component. :: >>> staff = Staff("abj: | 2/8 c'8 d'8 || 2/8 e'8 f'8 |") >>> measuretools.get_previous_measure_from_component(staff[-1]) Measure(2/8, [c'8, d'8]) When `component` is a measure and there is no measure immediately preceeding `component`, return ``None``. :: >>> staff = Staff("abj: | 2/8 c'8 d'8 || 2/8 e'8 f'8 |") >>> measuretools.get_previous_measure_from_component(staff[0]) is None True When `component` is a leaf and there is a measure in the parentage of `component`, return the measure in the parentage of `component`. :: >>> staff = Staff("abj: | 2/8 c'8 d'8 || 2/8 e'8 f'8 |") >>> measuretools.get_previous_measure_from_component(staff.select_leaves()[0]) Measure(2/8, [c'8, d'8]) When `component` is a leaf and there is no measure in the parentage of `component`, raise missing measure error. ''' from abjad.tools import iterationtools from abjad.tools import measuretools if isinstance(component, leaftools.Leaf): for parent in component._get_parentage(include_self=False): if isinstance(parent, measuretools.Measure): return parent raise MissingMeasureError elif isinstance(component, measuretools.Measure): return component._get_in_my_logical_voice( -1, component_class=measuretools.Measure) elif isinstance(component, containertools.Container): return measuretools.get_measure_that_stops_with_container(component) elif isinstance(component, (list, tuple)): measure_generator = \ iterationtools.iterate_measures_in_expr(component, reverse=True) try: measure = measure_generator.next() return measure except StopIteration: raise MissingMeasureError else: message = 'unknown component: {!r}.' raise TypeError(message.format(component))