def _add_or_remove_notes_to_achieve_written_duration( self, new_written_duration): from abjad.tools import scoretools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools import scoretools new_written_duration = durationtools.Duration(new_written_duration) if new_written_duration.is_assignable: self[0].written_duration = new_written_duration for leaf in self[1:]: parent = leaf._parent if parent: index = parent.index(leaf) del(parent[index]) first = self[0] for spanner in first._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, first) elif new_written_duration.has_power_of_two_denominator: durations = scoretools.make_notes(0, [new_written_duration]) for leaf, token in zip(self, durations): leaf.written_duration = token.written_duration if len(self) == len(durations): pass elif len(durations) < len(self): for leaf in self[len(durations):]: parent = leaf._parent if parent: index = parent.index(leaf) del(parent[index]) elif len(self) < len(durations): for spanner in self[0]._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, self[0]) difference = len(durations) - len(self) extra_leaves = self[0] * difference for extra_leaf in extra_leaves: for spanner in extra_leaf._get_spanners(): spanner._remove(extra_leaf) extra_tokens = durations[len(self):] for leaf, token in zip(extra_leaves, extra_tokens): leaf.written_duration = token.written_duration ties = self[-1]._get_spanners(spannertools.Tie) if not ties: tie = spannertools.Tie() attach(tie, list(self)) self[-1]._splice(extra_leaves, grow_spanners=True) else: durations = scoretools.make_notes(0, new_written_duration) assert isinstance(durations[0], scoretools.Tuplet) fmtuplet = durations[0] new_logical_tie_written = \ fmtuplet[0]._get_logical_tie()._preprolated_duration self._add_or_remove_notes_to_achieve_written_duration( new_logical_tie_written) multiplier = fmtuplet.multiplier scoretools.Tuplet(multiplier, self.leaves) return self[0]._get_logical_tie()
def _make_music(self, divisions, seeds): #assert not seeds, repr(seeds) if seeds is None: seeds = 0 selections = [] divisions = [durationtools.Division(_) for _ in divisions] denominators = datastructuretools.CyclicTuple(self.denominators) extra_counts_per_division = self.extra_counts_per_division or (0,) extra_counts_per_division = datastructuretools.CyclicTuple( extra_counts_per_division ) for i, division in enumerate(divisions, seeds): # not yet extended to work with non-power-of-two divisions assert mathtools.is_positive_integer_power_of_two( division.denominator), repr(division) denominator = denominators[i] extra_count = extra_counts_per_division[i] basic_duration = durationtools.Duration(1, denominator) unprolated_note_count = None if division < 2 * basic_duration: notes = scoretools.make_notes([0], [division]) else: unprolated_note_count = division / basic_duration unprolated_note_count = int(unprolated_note_count) unprolated_note_count = unprolated_note_count or 1 if 0 < extra_count: modulus = unprolated_note_count extra_count = extra_count % modulus elif extra_count < 0: modulus = int(math.ceil(unprolated_note_count / 2.0)) extra_count = abs(extra_count) % modulus extra_count *= -1 note_count = unprolated_note_count + extra_count durations = note_count * [basic_duration] notes = scoretools.make_notes([0], durations) assert all( _.written_duration.denominator == denominator for _ in notes ) tuplet_duration = durationtools.Duration(division) tuplet = scoretools.FixedDurationTuplet( duration=tuplet_duration, music=notes, ) if unprolated_note_count is not None: preferred_denominator = unprolated_note_count tuplet.preferred_denominator = preferred_denominator selection = selectiontools.Selection(tuplet) selections.append(selection) self._apply_beam_specifier(selections) return selections
def _set_duration(self, new_duration, use_messiaen_style_ties=False): from abjad.tools import scoretools from abjad.tools import spannertools new_duration = durationtools.Duration(new_duration) # change LilyPond multiplier if leaf already has LilyPond multiplier if self._get_indicators(durationtools.Multiplier): detach(durationtools.Multiplier, self) multiplier = new_duration.__div__(self.written_duration) attach(multiplier, self) return [self] # change written duration if new duration is assignable try: self.written_duration = new_duration return [self] except AssignabilityError: pass # make new notes or tuplets if new duration is nonassignable components = scoretools.make_notes( 0, new_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) if isinstance(components[0], scoretools.Leaf): tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for x, component in zip(all_leaves, components): x.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) parentage = self._get_parentage() if not parentage._get_spanners(spannertools.Tie): #if spannertools.Tie._attachment_test(self): tie = spannertools.Tie() if tie._attachment_test(self): tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, all_leaves) return all_leaves else: assert isinstance(components[0], scoretools.Tuplet) tuplet = components[0] components = tuplet[:] tied_leaf_count = len(components) - 1 tied_leaves = tied_leaf_count * self all_leaves = [self] + tied_leaves for x, component in zip(all_leaves, components): x.written_duration = component.written_duration self._splice(tied_leaves, grow_spanners=True) if not self._get_spanners(spannertools.Tie): #if spannertools.Tie._attachment_test(self): tie = spannertools.Tie() if tie._attachment_test(self): tie = spannertools.Tie( use_messiaen_style_ties=use_messiaen_style_ties, ) attach(tie, all_leaves) tuplet_multiplier = tuplet.multiplier scoretools.Tuplet(tuplet_multiplier, all_leaves) return [tuplet]
def _to_tuplet_with_ratio(self, proportions, is_diminution=True): from abjad.tools import scoretools from abjad.tools import scoretools # check input proportions = mathtools.Ratio(proportions) # find target duration of fixed-duration tuplet target_duration = self.written_duration # find basic duration of note in tuplet basic_prolated_duration = target_duration / sum(proportions) # find basic written duration of note in tuplet basic_written_duration = basic_prolated_duration.equal_or_greater_assignable # find written duration of each note in tuplet written_durations = [x * basic_written_duration for x in proportions] # make tuplet notes try: notes = [scoretools.Note(0, x) for x in written_durations] except AssignabilityError: denominator = target_duration._denominator note_durations = [durationtools.Duration(x, denominator) for x in proportions] notes = scoretools.make_notes(0, note_durations) # make tuplet tuplet = scoretools.FixedDurationTuplet(target_duration, notes) # fix tuplet contents if necessary tuplet._fix() # change prolation if necessary if not tuplet.multiplier == 1: if is_diminution: if not tuplet.is_diminution: tuplet.toggle_prolation() else: if tuplet.is_diminution: tuplet.toggle_prolation() # return tuplet return tuplet
def _make_container(self, division): from abjad.tools import rhythmmakertools duration_spelling_specifier = self.duration_spelling_specifier if duration_spelling_specifier is None: duration_spelling_specifier = \ rhythmmakertools.DurationSpellingSpecifier() forbidden_written_duration = \ duration_spelling_specifier.forbidden_written_duration time_signature = indicatortools.TimeSignature(division) implied_prolation = time_signature.implied_prolation numerator, denominator = division.pair denominator = mathtools.greatest_power_of_two_less_equal(denominator) assert mathtools.is_positive_integer_power_of_two(denominator) exponent = self.exponent or 0 denominator_multiplier = 2**exponent denominator *= denominator_multiplier unit_duration = durationtools.Duration(1, denominator) if forbidden_written_duration is not None: multiplier = 1 while forbidden_written_duration <= unit_duration: unit_duration /= 2 multiplier *= 2 numerator *= multiplier numerator *= denominator_multiplier notes = scoretools.make_notes(numerator * [0], [unit_duration]) if implied_prolation == 1: result = scoretools.Container(notes) else: multiplier = implied_prolation result = scoretools.Tuplet(multiplier, notes) return result
def __illustrate__(self): r'''Illustrates pitch segment. :: >>> named_pitch_segment = pitchtools.PitchSegment( ... ['bf,', 'aqs', "fs'", "g'", 'bqf', "g'"], ... item_class=NamedPitch, ... ) >>> show(named_pitch_segment) # doctest: +SKIP Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import lilypondfiletools from abjad.tools import markuptools from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools.topleveltools import attach from abjad.tools.topleveltools import iterate from abjad.tools.topleveltools import override named_pitches = [pitchtools.NamedPitch(x) for x in self] notes = scoretools.make_notes(named_pitches, [1]) score, treble_staff, bass_staff = \ scoretools.make_piano_sketch_score_from_leaves(notes) for leaf in iterate(score).by_class(scoretools.Leaf): attach(durationtools.Multiplier(1, 8), leaf) override(score).rest.transparent = True lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.tagline = markuptools.Markup('""') return lilypond_file
def __illustrate__(self): r'''Illustrates pitch segment. :: >>> named_pitch_segment = pitchtools.PitchSegment( ... ['bf,', 'aqs', "fs'", "g'", 'bqf', "g'"], ... item_class=NamedPitch, ... ) >>> show(named_pitch_segment) # doctest: +SKIP Returns LilyPond file. ''' from abjad.tools import durationtools from abjad.tools import lilypondfiletools from abjad.tools import markuptools from abjad.tools import pitchtools from abjad.tools import scoretools from abjad.tools.topleveltools import attach from abjad.tools.topleveltools import iterate from abjad.tools.topleveltools import override named_pitches = [pitchtools.NamedPitch(x) for x in self] notes = scoretools.make_notes(named_pitches, [1]) score, treble_staff, bass_staff = \ scoretools.make_piano_sketch_score_from_leaves(notes) for leaf in iterate(score).by_class(scoretools.Leaf): attach(durationtools.Multiplier(1, 8), leaf) override(score).rest.transparent = True lilypond_file = lilypondfiletools.make_basic_lilypond_file(score) lilypond_file.header_block.tagline = markuptools.Markup('""') return lilypond_file
def _make_container(self, division): from abjad.tools import rhythmmakertools duration_spelling_specifier = self._get_duration_spelling_specifier() forbidden_written_duration = \ duration_spelling_specifier.forbidden_written_duration time_signature = indicatortools.TimeSignature(division) implied_prolation = time_signature.implied_prolation numerator, denominator = division.pair denominator = mathtools.greatest_power_of_two_less_equal(denominator) assert mathtools.is_positive_integer_power_of_two(denominator) exponent = self.exponent or 0 denominator_multiplier = 2 ** exponent denominator *= denominator_multiplier unit_duration = durationtools.Duration(1, denominator) if forbidden_written_duration is not None: multiplier = 1 while forbidden_written_duration <= unit_duration: unit_duration /= 2 multiplier *= 2 numerator *= multiplier numerator *= denominator_multiplier notes = scoretools.make_notes(numerator * [0], [unit_duration]) if implied_prolation == 1: result = scoretools.Container(notes) else: multiplier = implied_prolation result = scoretools.Tuplet(multiplier, notes) return result
def __call__(self, pulse_duration): r'''Calls q-grid leaf. Returns selection of notes. ''' pulse_duration = durationtools.Duration(pulse_duration) total_duration = pulse_duration * self.preprolated_duration return scoretools.make_notes(0, total_duration)
def _make_container(self, division): numerator, denominator = division # eventually allow for non-power-of-two divisions assert mathtools.is_positive_integer_power_of_two(denominator) denominator_multiplier = 2 ** self.denominator_multiplier_exponent denominator *= denominator_multiplier unit_duration = durationtools.Duration(1, denominator) numerator *= denominator_multiplier notes = scoretools.make_notes(numerator * [0], [unit_duration]) container = scoretools.Container(notes) if self.beam_each_cell: beam = spannertools.MultipartBeam() attach(beam, container) return container
def __call__(self, pulse_duration): r'''Generate Abjad score components: :: >>> leaf = rhythmtreetools.RhythmTreeLeaf(5) >>> leaf((1, 4)) Selection(Note("c'1"), Note("c'4")) Returns sequence of components. ''' pulse_duration = durationtools.Duration(pulse_duration) total_duration = pulse_duration * self.preprolated_duration if self.is_pitched: return scoretools.make_notes(0, total_duration) return scoretools.make_rests(total_duration)
def _simplify_tuplets(self, selections): tuplet_spelling_specifier = self._get_tuplet_spelling_specifier() if not tuplet_spelling_specifier.simplify_tuplets: return for tuplet in iterate(selections).by_class(scoretools.Tuplet): if tuplet.is_trivial: continue duration = tuplet._get_duration() if all(isinstance(x, scoretools.Rest) for x in tuplet): rests = scoretools.make_rests([duration]) tuplet[:] = rests elif all(isinstance(x, scoretools.Note) for x in tuplet): logical_ties = set([x._get_logical_tie() for x in tuplet]) if len(logical_ties) == 1: notes = scoretools.make_notes([0], [duration]) tuplet[:] = notes
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_repeated_notes(count, duration=durationtools.Duration(1, 8)): r'''Make `count` repeated notes with note head-assignable `duration`: :: >>> scoretools.make_repeated_notes(4) Selection(Note("c'8"), Note("c'8"), Note("c'8"), Note("c'8")) Make `count` repeated logical ties with tied `duration`: :: >>> notes = scoretools.make_repeated_notes(2, (5, 16)) >>> voice = Voice(notes) .. doctest:: >>> print(format(voice)) \new Voice { c'4 ~ c'16 c'4 ~ c'16 } Make ad hoc tuplet holding `count` repeated notes with non-power-of-two `duration`: :: >>> scoretools.make_repeated_notes(3, (1, 12)) Selection(Tuplet(Multiplier(2, 3), "c'8 c'8 c'8"),) Set pitch of all notes created to middle C. Returns list of zero or more newly constructed notes or list of one newly constructed tuplet. ''' from abjad.tools import scoretools return scoretools.make_notes([0] * count, [duration])
def _to_tuplet_with_ratio(self, proportions, is_diminution=True): from abjad.tools import scoretools # check input proportions = mathtools.Ratio(proportions) # find target duration of fixed-duration tuplet target_duration = self.written_duration # find basic duration of note in tuplet basic_prolated_duration = target_duration / sum(proportions.numbers) # find basic written duration of note in tuplet basic_written_duration = \ basic_prolated_duration.equal_or_greater_assignable # find written duration of each note in tuplet written_durations = [ _ * basic_written_duration for _ in proportions.numbers ] # make tuplet notes try: notes = [scoretools.Note(0, x) for x in written_durations] except AssignabilityError: denominator = target_duration._denominator note_durations = [ durationtools.Duration(_, denominator) for _ in proportions.numbers ] notes = scoretools.make_notes(0, note_durations) # make tuplet tuplet = scoretools.FixedDurationTuplet(target_duration, notes) # fix tuplet contents if necessary tuplet._fix() # change prolation if necessary if not tuplet.multiplier == 1: if is_diminution: if not tuplet.is_diminution: tuplet.toggle_prolation() else: if tuplet.is_diminution: tuplet.toggle_prolation() # return tuplet return tuplet
def __call__( self, logical_tie, seed=0, ): assert isinstance(logical_tie, selectiontools.LogicalTie) if self.counts is None: return previous_leaf = logical_tie.head._get_leaf(-1) if previous_leaf is None: return silence_prototype = ( scoretools.Rest, scoretools.MultimeasureRest, scoretools.Skip, ) if self.only_if_preceded_by_silence: if not isinstance(previous_leaf, silence_prototype): return if self.only_if_preceded_by_nonsilence: if isinstance(previous_leaf, silence_prototype): return grace_count = self.counts[seed] if not grace_count: return kind = 'after' leaf_to_attach_to = previous_leaf leaves = [] notes = scoretools.make_notes([0], [(1, 16)] * grace_count) leaves.extend(notes) assert len(leaves) grace_container = scoretools.GraceContainer( leaves, kind=kind, ) override(grace_container).flag.stroke_style = \ schemetools.Scheme('grace', force_quotes=True) override(grace_container).script.font_size = 0.5 attach(grace_container, leaf_to_attach_to)
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_illustration(self): analysis = ChromaAnalysis(self) analysis.read() chroma_mean = self._normalize(analysis.mean) chroma_std = self._normalize(analysis.std) v_mean = scoretools.Voice([]) v_std = scoretools.Voice([]) staff = scoretools.Staff([v_mean, v_std]) staff.is_simultaneous = True pitches = [x / 2. for x in range(0, 24)] v_mean.extend(scoretools.make_notes(pitches, (1, 4))) v_std.extend(scoretools.Skip((1, 4)) * len(v_mean)) for i, val in enumerate(chroma_mean): x_extent = (0, 1.25) y_extent = ((val * -5.) - 0.75, (val * 5.) + 0.75) markup = markuptools.Markup.filled_box(x_extent, y_extent, 1) markup = markuptools.Markup(markup, 'up') attach(markup, v_mean[i]) color = (90 - int(val * 90)) color = schemetools.SchemeColor('grey{}'.format(color)) override(v_mean[i]).text_script.color = color for i, val in enumerate(chroma_std): x_extent = (0, 1.25) y_extent = ((val * -5.) - 0.75, (val * 5.) + 0.75) markup = markuptools.Markup.filled_box(x_extent, y_extent, 1) markup = markuptools.Markup(markup, 'down') attach(markup, v_std[i]) color = (90 - int(val * 90)) color = schemetools.SchemeColor('grey{}'.format(color)) override(v_std[i]).text_script.color = color override(v_mean).text_script.staff_padding = 1.5 override(v_std).text_script.staff_padding = 3.0 override(staff).stem.transparent = True staff.remove_commands.append('Time_signature_engraver') staff.remove_commands.append('Bar_engraver') score = scoretools.Score([staff]) illustration = score.__illustrate__() return illustration
def make_notes(self, n=None, written_duration=None): r'''Makes first `n` notes in pitch segment. Set `n` equal to `n` or length of segment. Set `written_duration` equal to `written_duration` or ``1/8``: :: >>> notes = named_pitch_segment.make_notes() >>> staff = Staff(notes) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { bf,8 aqs8 fs'8 g'8 bqf8 g'8 } Allows nonassignable `written_duration`: :: >>> notes = named_pitch_segment.make_notes(4, Duration(5, 16)) >>> staff = Staff(notes) >>> time_signature = TimeSignature((5, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 5/4 bf,4 ~ bf,16 aqs4 ~ aqs16 fs'4 ~ fs'16 g'4 ~ g'16 } Returns list of notes. ''' from abjad.tools import durationtools from abjad.tools import scoretools n = n or len(self) written_duration = written_duration or durationtools.Duration(1, 8) result = scoretools.make_notes([0] * n, [written_duration]) for i, logical_tie in enumerate(iterate(result).by_logical_tie()): pitch = self[i % len(self)] for note in logical_tie: note.written_pitch = pitch return result
def _make_gridded_test_rhythm(grid_length, rhythm_number, denominator=16): r'''Make test rhythm number `rhythm_number` that fits `grid_length`. Returns selection of one or more possibly tied notes. .. container:: example **Example 1.** The eight test rhythms that fit a length-``4`` grid: :: >>> from abjad.tools.metertools import Meter >>> for rhythm_number in range(8): ... notes = Meter._make_gridded_test_rhythm( ... 4, rhythm_number, denominator=4) ... measure = Measure((4, 4), notes) ... print '{}\t{}'.format(rhythm_number, str(measure)) ... 0 |4/4 c'1| 1 |4/4 c'2. c'4| 2 |4/4 c'2 c'4 c'4| 3 |4/4 c'2 c'2| 4 |4/4 c'4 c'4 c'2| 5 |4/4 c'4 c'4 c'4 c'4| 6 |4/4 c'4 c'2 c'4| 7 |4/4 c'4 c'2.| .. container:: example **Example 2.** The sixteenth test rhythms for that a length-``5`` grid: :: >>> for rhythm_number in range(16): ... notes = Meter._make_gridded_test_rhythm( ... 5, rhythm_number, denominator=4) ... measure = Measure((5, 4), notes) ... print '{}\t{}'.format(rhythm_number, str(measure)) ... 0 |5/4 c'1 ~ c'4| 1 |5/4 c'1 c'4| 2 |5/4 c'2. c'4 c'4| 3 |5/4 c'2. c'2| 4 |5/4 c'2 c'4 c'2| 5 |5/4 c'2 c'4 c'4 c'4| 6 |5/4 c'2 c'2 c'4| 7 |5/4 c'2 c'2.| 8 |5/4 c'4 c'4 c'2.| 9 |5/4 c'4 c'4 c'2 c'4| 10 |5/4 c'4 c'4 c'4 c'4 c'4| 11 |5/4 c'4 c'4 c'4 c'2| 12 |5/4 c'4 c'2 c'2| 13 |5/4 c'4 c'2 c'4 c'4| 14 |5/4 c'4 c'2. c'4| 15 |5/4 c'4 c'1| Use for testing meter establishment. ''' from abjad.tools import scoretools # check input assert mathtools.is_positive_integer(grid_length) assert isinstance(rhythm_number, int) assert mathtools.is_positive_integer_power_of_two(denominator) # find count of all rhythms that fit grid length rhythm_count = 2 ** (grid_length - 1) # read rhythm number cyclically to allow large and # negative rhythm numbers rhythm_number = rhythm_number % rhythm_count # find binary representation of rhythm binary_representation = \ mathtools.integer_to_binary_string(rhythm_number) binary_representation = binary_representation.zfill(grid_length) # partition binary representation of rhythm parts = sequencetools.partition_sequence_by_value_of_elements( binary_representation) # find durations durations = [ durationtools.Duration(len(part), denominator) for part in parts ] # make notes notes = scoretools.make_notes([0], durations) # return notes return notes
def fill_measures_in_expr_with_minimal_number_of_notes( expr, decrease_durations_monotonically=True, iterctrl=None, ): '''Fills measures in `expr` with minimal number of notes that decrease durations monotonically: :: >>> measure = Measure((5, 18), [], implicit_scaling=True) :: >>> scoretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=True) .. doctest:: >>> print(format(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), []) >>> measure.implicit_scaling = True :: >>> scoretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=False) .. doctest:: >>> print(format(measure)) { \time 5/18 \scaleDurations #'(8 . 9) { c'16 ~ c'4 } } Returns none. ''' from abjad.tools import scoretools if iterctrl is None: iterctrl = lambda measure, i: True for i, measure in enumerate(iterate(expr).by_class(scoretools.Measure)): if iterctrl(measure, i): time_signature = measure.time_signature written_duration = time_signature.duration / time_signature.implied_prolation notes = scoretools.make_notes(0, written_duration, decrease_durations_monotonically= decrease_durations_monotonically) measure[:] = notes
def fill_measures_in_expr_with_minimal_number_of_notes(expr, decrease_durations_monotonically=True, iterctrl=None): """Fills measures in `expr` with minimal number of notes that decrease durations monotonically: :: >>> measure = Measure((5, 18), [], implicit_scaling=True) :: >>> scoretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=True) .. doctest:: >>> print(format(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), []) >>> measure.implicit_scaling = True :: >>> scoretools.fill_measures_in_expr_with_minimal_number_of_notes( ... measure, decrease_durations_monotonically=False) .. doctest:: >>> print(format(measure)) { \time 5/18 \scaleDurations #'(8 . 9) { c'16 ~ c'4 } } Returns none. """ from abjad.tools import scoretools if iterctrl is None: iterctrl = lambda measure, i: True for i, measure in enumerate(iterate(expr).by_class(scoretools.Measure)): if iterctrl(measure, i): time_signature = measure.time_signature written_duration = time_signature.duration / time_signature.implied_prolation notes = scoretools.make_notes( 0, written_duration, decrease_durations_monotonically=decrease_durations_monotonically ) measure[:] = notes
def to_tuplet( self, proportions, dotted=False, is_diminution=True, ): r'''Change logical tie to tuplet. .. container:: example **Example 1.** Change logical tie to diminished tuplet: :: >>> staff = Staff(r"c'8 ~ c'16 cqs''4") >>> crescendo = spannertools.Hairpin(descriptor='p < f') >>> attach(crescendo, staff[:]) >>> override(staff).dynamic_line_spanner.staff_padding = 3 >>> time_signature = TimeSignature((7, 16)) >>> attach(time_signature, staff) .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 c'8 ~ \< \p c'16 cqs''4 \f } :: >>> show(staff) # doctest: +SKIP :: >>> logical_tie = inspect_(staff[0]).get_logical_tie() >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=True) FixedDurationTuplet(Duration(3, 16), "c'8 c'16 c'16 c'16") .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 \tweak #'text #tuplet-number::calc-fraction-text \times 3/5 { c'8 \< \p c'16 c'16 c'16 } cqs''4 \f } :: >>> show(staff) # doctest: +SKIP .. container:: example **Example 2.** Change logical tie to augmented tuplet: :: >>> staff = Staff(r"c'8 ~ c'16 cqs''4") >>> crescendo = spannertools.Hairpin(descriptor='p < f') >>> attach(crescendo, staff[:]) >>> override(staff).dynamic_line_spanner.staff_padding = 3 >>> time_signature = TimeSignature((7, 16)) >>> attach(time_signature, staff) .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 c'8 ~ \< \p c'16 cqs''4 \f } :: >>> show(staff) # doctest: +SKIP :: >>> logical_tie = inspect_(staff[0]).get_logical_tie() >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=False) FixedDurationTuplet(Duration(3, 16), "c'16 c'32 c'32 c'32") .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 \tweak #'text #tuplet-number::calc-fraction-text \times 6/5 { c'16 \< \p c'32 c'32 c'32 } cqs''4 \f } :: >>> show(staff) # doctest: +SKIP Returns tuplet. ''' from abjad.tools import scoretools from abjad.tools import mathtools from abjad.tools import spannertools # coerce input proportions = mathtools.Ratio(proportions) # find target duration of fixed-duration tuplet target_duration = self._preprolated_duration # find duration of each note in tuplet prolated_duration = target_duration / sum(proportions) # find written duration of each notes in tuplet if is_diminution: if dotted: basic_written_duration = \ prolated_duration.equal_or_greater_assignable else: basic_written_duration = \ prolated_duration.equal_or_greater_power_of_two else: if dotted: basic_written_duration = \ prolated_duration.equal_or_lesser_assignable else: basic_written_duration = \ prolated_duration.equal_or_lesser_power_of_two # find written duration of each note in tuplet written_durations = [x * basic_written_duration for x in proportions] # make tuplet notes try: notes = [scoretools.Note(0, x) for x in written_durations] except AssignabilityError: denominator = target_duration._denominator note_durations = [durationtools.Duration(x, denominator) for x in proportions] notes = scoretools.make_notes(0, note_durations) # make tuplet tuplet = scoretools.FixedDurationTuplet(target_duration, notes) # replace logical tie with tuplet mutate(self).replace(tuplet) # untie tuplet for spanner in tuplet._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, tuplet) # return tuplet return tuplet
def make_notes(self, n, written_duration=None): r'''Makes first `n` notes in ascending diatonic scale according to `key_signature`. Set `written_duration` equal to `written_duration` or ``1/8``: :: >>> scale = tonalanalysistools.Scale('c', 'major') >>> notes = scale.make_notes(8) >>> staff = Staff(notes) .. doctest:: >>> print(format(staff)) \new Staff { c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8 } :: >>> show(staff) # doctest: +SKIP Allow nonassignable `written_duration`: :: >>> notes = scale.make_notes(4, Duration(5, 16)) >>> staff = Staff(notes) >>> time_signature = TimeSignature((5, 4)) >>> attach(time_signature, staff) .. doctest:: >>> print(format(staff)) \new Staff { \time 5/4 c'4 ~ c'16 d'4 ~ d'16 e'4 ~ e'16 f'4 ~ f'16 } :: >>> show(staff) # doctest: +SKIP Returns list of notes. ''' written_duration = written_duration or durationtools.Duration(1, 8) result = scoretools.make_notes(n * [0], [written_duration]) self._set_ascending_named_diatonic_pitches_on_logical_ties_in_expr( result) return result
def _make_gridded_test_rhythm(grid_length, rhythm_number, denominator=16): r'''Make test rhythm number `rhythm_number` that fits `grid_length`. Returns selection of one or more possibly tied notes. .. container:: example **Example 1.** The eight test rhythms that fit a length-``4`` grid: :: >>> from abjad.tools.metertools import Meter >>> for rhythm_number in range(8): ... notes = Meter._make_gridded_test_rhythm( ... 4, rhythm_number, denominator=4) ... measure = Measure((4, 4), notes) ... print('{}\t{}'.format(rhythm_number, str(measure))) ... 0 Measure((4, 4), "c'1") 1 Measure((4, 4), "c'2. c'4") 2 Measure((4, 4), "c'2 c'4 c'4") 3 Measure((4, 4), "c'2 c'2") 4 Measure((4, 4), "c'4 c'4 c'2") 5 Measure((4, 4), "c'4 c'4 c'4 c'4") 6 Measure((4, 4), "c'4 c'2 c'4") 7 Measure((4, 4), "c'4 c'2.") .. container:: example **Example 2.** The sixteenth test rhythms for that a length-``5`` grid: :: >>> for rhythm_number in range(16): ... notes = Meter._make_gridded_test_rhythm( ... 5, rhythm_number, denominator=4) ... measure = Measure((5, 4), notes) ... print('{}\t{}'.format(rhythm_number, str(measure))) ... 0 Measure((5, 4), "c'1 ~ c'4") 1 Measure((5, 4), "c'1 c'4") 2 Measure((5, 4), "c'2. c'4 c'4") 3 Measure((5, 4), "c'2. c'2") 4 Measure((5, 4), "c'2 c'4 c'2") 5 Measure((5, 4), "c'2 c'4 c'4 c'4") 6 Measure((5, 4), "c'2 c'2 c'4") 7 Measure((5, 4), "c'2 c'2.") 8 Measure((5, 4), "c'4 c'4 c'2.") 9 Measure((5, 4), "c'4 c'4 c'2 c'4") 10 Measure((5, 4), "c'4 c'4 c'4 c'4 c'4") 11 Measure((5, 4), "c'4 c'4 c'4 c'2") 12 Measure((5, 4), "c'4 c'2 c'2") 13 Measure((5, 4), "c'4 c'2 c'4 c'4") 14 Measure((5, 4), "c'4 c'2. c'4") 15 Measure((5, 4), "c'4 c'1") Use for testing meter establishment. ''' from abjad.tools import scoretools # check input assert mathtools.is_positive_integer(grid_length) assert isinstance(rhythm_number, int) assert mathtools.is_positive_integer_power_of_two(denominator) # find count of all rhythms that fit grid length rhythm_count = 2**(grid_length - 1) # read rhythm number cyclically to allow large and # negative rhythm numbers rhythm_number = rhythm_number % rhythm_count # find binary representation of rhythm binary_representation = \ mathtools.integer_to_binary_string(rhythm_number) binary_representation = binary_representation.zfill(grid_length) # partition binary representation of rhythm parts = sequencetools.partition_sequence_by_value_of_elements( binary_representation) # find durations durations = [ durationtools.Duration(len(part), denominator) for part in parts ] # make notes notes = scoretools.make_notes([0], durations) # return notes return notes
def make_notes(self, n=None, written_duration=None): r'''Make first `n` notes in pitch class segment. Set `n` equal to `n` or length of segment. Set `written_duration` equal to `written_duration` or ``1/8``: :: >>> pitch_class_segment = pitchtools.PitchClassSegment( ... [2, 4.5, 6, 11, 4.5, 10]) :: >>> notes = pitch_class_segment.make_notes() >>> staff = Staff(notes) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { d'8 eqs'8 fs'8 b'8 eqs'8 bf'8 } Allow nonassignable `written_duration`: :: >>> notes = pitch_class_segment.make_notes(4, Duration(5, 16)) >>> staff = Staff(notes) >>> time_signature = TimeSignature((5, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { \time 5/4 d'4 ~ d'16 eqs'4 ~ eqs'16 fs'4 ~ fs'16 b'4 ~ b'16 } Returns list of notes. ''' from abjad.tools import scoretools from abjad.tools import pitchtools n = n or len(self) written_duration = written_duration or durationtools.Duration(1, 8) result = scoretools.make_notes([0] * n, [written_duration]) for i, logical_tie in enumerate(iterate(result).by_logical_tie()): pitch_class = pitchtools.NamedPitchClass(self[i % len(self)]) pitch = pitchtools.NamedPitch(pitch_class, 4) for note in logical_tie: note.written_pitch = pitch return result
def make_notes(self, n=None, written_duration=None): r"""Make first `n` notes in pitch class segment. Set `n` equal to `n` or length of segment. Set `written_duration` equal to `written_duration` or ``1/8``: :: >>> pitch_class_segment = pitchtools.PitchClassSegment( ... [2, 4.5, 6, 11, 4.5, 10]) :: >>> notes = pitch_class_segment.make_notes() >>> staff = Staff(notes) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print format(staff) \new Staff { d'8 eqs'8 fs'8 b'8 eqs'8 bf'8 } Allow nonassignable `written_duration`: :: >>> notes = pitch_class_segment.make_notes(4, Duration(5, 16)) >>> staff = Staff(notes) >>> time_signature = TimeSignature((5, 4)) >>> attach(time_signature, staff) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print format(staff) \new Staff { \time 5/4 d'4 ~ d'16 eqs'4 ~ eqs'16 fs'4 ~ fs'16 b'4 ~ b'16 } Returns list of notes. """ from abjad.tools import scoretools from abjad.tools import pitchtools n = n or len(self) written_duration = written_duration or durationtools.Duration(1, 8) result = scoretools.make_notes([0] * n, [written_duration]) for i, logical_tie in enumerate(iterate(result).by_logical_tie()): pitch_class = pitchtools.NamedPitchClass(self[i % len(self)]) pitch = pitchtools.NamedPitch(pitch_class, 4) for note in logical_tie: note.written_pitch = pitch return result
def make_repeated_notes_with_shorter_notes_at_end( pitch, written_duration, total_duration, prolation=1, ): r'''Makes repeated notes with `pitch` and `written_duration` summing to `total_duration` under `prolation`. :: >>> args = [0, Duration(1, 16), Duration(1, 4)] >>> notes = scoretools.make_repeated_notes_with_shorter_notes_at_end(*args) >>> voice = Voice(notes) .. doctest:: >>> print(format(voice)) \new Voice { c'16 c'16 c'16 c'16 } Fill power-of-two remaining duration with power-of-two notes of lesser written duration: :: >>> args = [0, Duration(1, 16), Duration(9, 32)] >>> notes = scoretools.make_repeated_notes_with_shorter_notes_at_end(*args) >>> voice = Voice(notes) .. doctest:: >>> print(format(voice)) \new Voice { c'16 c'16 c'16 c'16 c'32 } Fill non-power-of-two remaining duration with ad hoc tuplet: :: >>> args = [0, Duration(1, 16), Duration(4, 10)] >>> notes = scoretools.make_repeated_notes_with_shorter_notes_at_end(*args) >>> voice = Voice(notes) .. doctest:: >>> print(format(voice)) \new Voice { c'16 c'16 c'16 c'16 c'16 c'16 \tweak #'edge-height #'(0.7 . 0) \times 4/5 { c'32 } } Set `prolation` when making notes in a measure with a non-power-of-two denominator. Returns list of components. ''' from abjad.tools import scoretools written_duration = durationtools.Duration(written_duration) total_duration = durationtools.Duration(total_duration) prolation = durationtools.Duration(prolation) prolation = fractions.Fraction(prolation) duration = prolation * written_duration current_duration = durationtools.Duration(0) result = [] while current_duration + duration <= total_duration: result.append(scoretools.Note(pitch, written_duration)) current_duration += duration remainder_duration = total_duration - current_duration if durationtools.Duration(0) < remainder_duration: multiplied_remainder = remainder_duration / prolation result.extend(scoretools.make_notes(pitch, [multiplied_remainder])) result = selectiontools.Selection(result) return result
def to_tuplet( self, proportions, dotted=False, is_diminution=True, ): r'''Change logical tie to tuplet. .. container:: example **Example 1.** Change logical tie to diminished tuplet: :: >>> staff = Staff(r"c'8 ~ c'16 cqs''4") >>> crescendo = spannertools.Hairpin(descriptor='p < f') >>> attach(crescendo, staff[:]) >>> override(staff).dynamic_line_spanner.staff_padding = 3 >>> time_signature = TimeSignature((7, 16)) >>> attach(time_signature, staff) .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 c'8 ~ \< \p c'16 cqs''4 \f } :: >>> show(staff) # doctest: +SKIP :: >>> logical_tie = inspect_(staff[0]).get_logical_tie() >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=True) FixedDurationTuplet(Duration(3, 16), "c'8 c'16 c'16 c'16") .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 \tweak #'text #tuplet-number::calc-fraction-text \times 3/5 { c'8 \< \p c'16 c'16 c'16 } cqs''4 \f } :: >>> show(staff) # doctest: +SKIP .. container:: example **Example 2.** Change logical tie to augmented tuplet: :: >>> staff = Staff(r"c'8 ~ c'16 cqs''4") >>> crescendo = spannertools.Hairpin(descriptor='p < f') >>> attach(crescendo, staff[:]) >>> override(staff).dynamic_line_spanner.staff_padding = 3 >>> time_signature = TimeSignature((7, 16)) >>> attach(time_signature, staff) .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 c'8 ~ \< \p c'16 cqs''4 \f } :: >>> show(staff) # doctest: +SKIP :: >>> logical_tie = inspect_(staff[0]).get_logical_tie() >>> logical_tie.to_tuplet([2, 1, 1, 1], is_diminution=False) FixedDurationTuplet(Duration(3, 16), "c'16 c'32 c'32 c'32") .. doctest:: >>> print(format(staff)) \new Staff \with { \override DynamicLineSpanner #'staff-padding = #3 } { \time 7/16 \tweak #'text #tuplet-number::calc-fraction-text \times 6/5 { c'16 \< \p c'32 c'32 c'32 } cqs''4 \f } :: >>> show(staff) # doctest: +SKIP Returns tuplet. ''' from abjad.tools import scoretools from abjad.tools import mathtools from abjad.tools import agenttools from abjad.tools import scoretools from abjad.tools import spannertools from abjad.tools import scoretools # coerce input proportions = mathtools.Ratio(proportions) # find target duration of fixed-duration tuplet target_duration = self._preprolated_duration # find duration of each note in tuplet prolated_duration = target_duration / sum(proportions) # find written duration of each notes in tuplet if is_diminution: if dotted: basic_written_duration = \ prolated_duration.equal_or_greater_assignable else: basic_written_duration = \ prolated_duration.equal_or_greater_power_of_two else: if dotted: basic_written_duration = \ prolated_duration.equal_or_lesser_assignable else: basic_written_duration = \ prolated_duration.equal_or_lesser_power_of_two # find written duration of each note in tuplet written_durations = [x * basic_written_duration for x in proportions] # make tuplet notes try: notes = [scoretools.Note(0, x) for x in written_durations] except AssignabilityError: denominator = target_duration._denominator note_durations = [durationtools.Duration(x, denominator) for x in proportions] notes = scoretools.make_notes(0, note_durations) # make tuplet tuplet = scoretools.FixedDurationTuplet(target_duration, notes) # replace logical tie with tuplet mutate(self).replace(tuplet) # untie tuplet for spanner in tuplet._get_spanners(spannertools.Tie): spanner._sever_all_components() #detach(spannertools.Tie, tuplet) # return tuplet return tuplet