def __init__(self, *args): from abjad.tools import indicatortools if len(args) == 1 and isinstance(args[0], type(self)): self._tempo_indication = args[0].tempo_indication self._proportional_notation_duration = \ args[0].proportional_notation_duration elif len(args) == 2: tempo = args[0] if isinstance(tempo, tuple): tempo = indicatortools.Tempo(*tempo) tempo_indication = tempo proportional_notation_duration = durationtools.Duration(args[1]) self._tempo_indication = tempo_indication self._proportional_notation_duration = \ proportional_notation_duration elif len(args) == 0: tempo = indicatortools.Tempo() proportional_notation_duration = durationtools.Duration(1, 68) self._tempo_indication = tempo self._proportional_notation_duration = \ proportional_notation_duration else: message = 'can not initialize spacing indication from {!r}' message = message.format(args) raise ValueError(message)
def quarters_per_minute(self): r'''Quarters per minute of tempo. :: >>> tempo = Tempo(Duration(1, 8), 52) >>> tempo.quarters_per_minute Fraction(104, 1) Returns tuple when tempo `units_per_minute` is a range. Returns none when tempo is imprecise. Returns fraction otherwise. ''' if self.is_imprecise: return None if isinstance(self.units_per_minute, tuple): low = durationtools.Duration(1, 4) / self.duration * \ self.units_per_minute[0] high = durationtools.Duration(1, 4) / self.duration * \ self.units_per_minute[1] return (low, high) result = durationtools.Duration(1, 4) / self.duration * \ self.units_per_minute return fractions.Fraction(result)
def make_skips( written_duration, multiplied_durations, ): '''Make `written_duration` skips with `multiplied_durations`: :: >>> scoretools.make_skips( ... Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]) Selection(Skip('s4 * 2'), Skip('s4 * 4/3'), Skip('s4 * 1'), Skip('s4 * 4/5')) Useful for making invisible layout voices. Returns selection. ''' from abjad.tools import scoretools # initialize skips and written duration skips = [] written_duration = durationtools.Duration(written_duration) # make skips for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) skip = scoretools.Skip(written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, skip) skips.append(skip) # return skips skips = selectiontools.Selection(skips) return skips
def duration_to_milliseconds(self, duration): r'''Gets millisecond value of `duration` under a given tempo. .. container:: example :: >>> duration = (1, 4) >>> tempo = Tempo((1, 4), 60) >>> tempo.duration_to_milliseconds(duration) Duration(1000, 1) Returns duration. ''' duration = durationtools.Duration(duration) # TODO: rewrite formula without line breaks; # use two or three temporary variables instead. whole_note_duration = 1000 \ * durationtools.Multiplier( self.duration.denominator, self.duration.numerator, ) \ * durationtools.Multiplier( 60, self.units_per_minute, ) return durationtools.Duration(duration * whole_note_duration)
def __init__( self, beatspan=None, offset_in_ms=None, search_tree=None, tempo=None, ): from abjad.tools import quantizationtools beatspan = beatspan or durationtools.Duration(0) beatspan = durationtools.Duration(beatspan) offset_in_ms = offset_in_ms or durationtools.Duration(0) offset_in_ms = durationtools.Offset(offset_in_ms) if search_tree is None: search_tree = quantizationtools.UnweightedSearchTree() assert isinstance(search_tree, quantizationtools.SearchTree) tempo = tempo or indicatortools.Tempo(durationtools.Duration(1, 4), 60) #tempo = indicatortools.Tempo(tempo) if isinstance(tempo, tuple): tempo = indicatortools.Tempo(*tempo) assert not tempo.is_imprecise q_events = [] q_grids = [] self._beatspan = beatspan self._distances = {} self._offset_in_ms = offset_in_ms self._q_events = q_events self._q_grid = None self._q_grids = q_grids self._search_tree = search_tree self._tempo = tempo
def __init__( self, minimum_duration=None, maximum_duration=None, minimum_written_pitch=None, maximum_written_pitch=None, ): if minimum_duration is None: self._minimum_duration = minimum_duration else: self._minimum_duration = durationtools.Duration(minimum_duration) if maximum_duration is None: self._maximum_duration = maximum_duration else: self._maximum_duration = durationtools.Duration(maximum_duration) if minimum_written_pitch is None: self._minimum_written_pitch = minimum_written_pitch else: self._minimum_written_pitch = \ pitchtools.NamedPitch(minimum_written_pitch) if maximum_written_pitch is None: self._maximum_written_pitch = maximum_written_pitch else: self._maximum_written_pitch = \ pitchtools.NamedPitch(maximum_written_pitch)
def apply_expressive_marks(score): r'''Applies expressive marks to score. ''' voice = score['First Violin Voice'] markup = markuptools.Markup(r'\left-column { div. \line { con sord. } }', Up) attach(markup, voice[6][1]) markup = markuptools.Markup('sim.', Up) attach(markup, voice[8][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[58][3]) markup = markuptools.Markup('div.', Up) attach(markup, voice[59][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[63][3]) voice = score['Second Violin Voice'] markup = markuptools.Markup('div.', Up) attach(markup, voice[7][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[66][1]) markup = markuptools.Markup('div.', Up) attach(markup, voice[67][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[74][0]) voice = score['Viola Voice'] markup = markuptools.Markup('sole', Up) attach(markup, voice[8][0]) voice = score['Cello Voice'] markup = markuptools.Markup('div.', Up) attach(markup, voice[10][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[74][0]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[84][1]) markup = markuptools.Markup(r'\italic { espr. }', Down) attach(markup, voice[86][0]) markup = markuptools.Markup(r'\italic { molto espr. }', Down) attach(markup, voice[88][1]) voice = score['Bass Voice'] markup = markuptools.Markup('div.', Up) attach(markup, voice[14][0]) markup = markuptools.Markup(r'\italic { espr. }', Down) attach(markup, voice[86][0]) mutate(voice[88][:]).split( [durationtools.Duration(1, 1), durationtools.Duration(1, 2)]) markup = markuptools.Markup(r'\italic { molto espr. }', Down) attach(markup, voice[88][1]) markup = markuptools.Markup('uniti', Up) attach(markup, voice[99][1]) strings_staff_group = score['Strings Staff Group'] for voice in iterate(strings_staff_group).by_class(scoretools.Voice): markup = markuptools.Markup(r'\italic { (non dim.) }', Down) attach(markup, voice[102][0])
def make_notes_with_multiplied_durations( pitch, written_duration, multiplied_durations, ): '''Make `written_duration` notes with `pitch` and `multiplied_durations`: :: >>> args = [0, Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]] >>> scoretools.make_notes_with_multiplied_durations(*args) Selection(Note("c'4 * 2"), Note("c'4 * 4/3"), Note("c'4 * 1"), Note("c'4 * 4/5")) Useful for making spatially positioned notes. Returns list of notes. ''' from abjad.tools import scoretools from abjad.tools import selectiontools # initialize input written_duration = durationtools.Duration(written_duration) # make notes notes = [] for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) note = scoretools.Note(pitch, written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, note) notes.append(note) # return notes notes = selectiontools.Selection(notes) return notes
def make_windungen_score( bandwidth=3, compress_reflections=True, leaf_duration=durationtools.Duration(1, 16), length=32, pitches=('c', 'd', 'e'), staff_count=12, ): from experimental.demos.windungen.WindungenScoreTemplate import WindungenScoreTemplate bandwidth = int(bandwidth) compress_reflections = bool(compress_reflections) leaf_duration = durationtools.Duration(leaf_duration) length = int(length) pitches = [pitchtools.NamedPitch(x) for x in pitches] staff_count = int(staff_count) assert 0 < bandwidth assert 0 < leaf_duration assert 0 < length assert 0 < len(pitches) assert 0 < staff_count score_template = WindungenScoreTemplate(staff_count=staff_count) score = score_template() all_pitches = sequencetools.repeat_sequence_to_length(length) matrix = make_cyclic_matrix_for_rotation_by_bandwidth()
def _contents_duration(self): if self.is_simultaneous: return max([durationtools.Duration(0)] + [x._preprolated_duration for x in self]) else: duration = durationtools.Duration(0) for x in self: duration += x._preprolated_duration return duration
def _duration_in_seconds(self): from abjad.tools import scoretools if self.is_simultaneous: return max([durationtools.Duration(0)] + [x._get_duration(in_seconds=True) for x in self]) else: duration = durationtools.Duration(0) for leaf in iterate(self).by_class(scoretools.Leaf): duration += leaf._get_duration(in_seconds=True) return duration
def __init__( self, duration=durationtools.Duration(1, 4), parts=Exact, ): self._duration = durationtools.Duration(duration) if not isinstance(parts, collections.Sequence): parts = (parts, ) assert all(_ in (None, Exact, More, Less) for _ in parts) self._parts = parts
def _remove_and_shrink_durated_parent_containers(self): from abjad.tools import indicatortools from abjad.tools import scoretools prolated_leaf_duration = self._get_duration() parentage = self._get_parentage(include_self=False) prolations = parentage._prolations current_prolation, i = durationtools.Duration(1), 0 parent = self._parent while parent is not None and not parent.is_simultaneous: current_prolation *= prolations[i] if isinstance(parent, scoretools.FixedDurationTuplet): candidate_new_parent_dur = ( parent.target_duration - current_prolation * self.written_duration) if durationtools.Duration(0) < candidate_new_parent_dur: parent.target_duration = candidate_new_parent_dur elif isinstance(parent, scoretools.Measure): indicator = parent._get_indicator(indicatortools.TimeSignature) parent_time_signature = indicator old_prolation = parent_time_signature.implied_prolation naive_time_signature = (parent_time_signature.duration - prolated_leaf_duration) better_time_signature = mathtools.NonreducedFraction( naive_time_signature) better_time_signature = better_time_signature.with_denominator( parent_time_signature.denominator) better_time_signature = indicatortools.TimeSignature( better_time_signature) detach(indicatortools.TimeSignature, parent) attach(better_time_signature, parent) indicator = parent._get_indicator(indicatortools.TimeSignature) parent_time_signature = indicator new_prolation = parent_time_signature.implied_prolation adjusted_prolation = old_prolation / new_prolation for x in parent: if isinstance(x, scoretools.FixedDurationTuplet): x.target_duration *= adjusted_prolation else: if adjusted_prolation != 1: new_target = \ x._preprolated_duration * adjusted_prolation scoretools.FixedDurationTuplet(new_target, [x]) parent = parent._parent i += 1 parentage = self._get_parentage(include_self=False) parent = self._parent if parent: index = parent.index(self) del (parent[index]) for x in parentage: if not len(x): x._extract() else: break
def make_score(self): r'''Make MIDI playback score from scale: :: >>> scale = tonalanalysistools.Scale('E', 'major') >>> score = scale.make_score() .. doctest:: >>> print(format(score)) \new Score \with { tempoWholesPerMinute = #(ly:make-moment 30 1) } << \new Staff { \key e \major e'8 fs'8 gs'8 a'8 b'8 cs''8 ds''8 e''8 ds''8 cs''8 b'8 a'8 gs'8 fs'8 e'4 } >> :: >>> show(score) # doctest: +SKIP Returns score. ''' ascending_notes = self.make_notes(8, durationtools.Duration(1, 8)) descending_notes = copy.deepcopy(ascending_notes[:-1]) descending_notes = list(descending_notes) descending_notes.reverse() descending_notes = selectiontools.Selection(descending_notes) notes = ascending_notes + descending_notes notes[-1].written_duration = durationtools.Duration(1, 4) staff = scoretools.Staff(notes) key_signature = copy.copy(self.key_signature) attach(key_signature, staff) score = scoretools.Score([staff]) set_(score).tempo_wholes_per_minute = schemetools.SchemeMoment(30) return score
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 make_multiplied_quarter_notes( pitches, multiplied_durations, ): r'''Make quarter notes with `pitches` and `multiplied_durations`: :: >>> args = [[0, 2, 4, 5], [(1, 4), (1, 5), (1, 6), (1, 7)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 1"), Note("d'4 * 4/5"), Note("e'4 * 2/3"), Note("f'4 * 4/7")) Read `pitches` cyclically where the length of `pitches` is less than the length of `multiplied_durations`: :: >>> args = [[0], [(1, 4), (1, 5), (1, 6), (1, 7)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 1"), Note("c'4 * 4/5"), Note("c'4 * 2/3"), Note("c'4 * 4/7")) Read `multiplied_durations` cyclically where the length of `multiplied_durations` is less than the length of `pitches`: :: >>> args = [[0, 2, 4, 5], [(1, 5)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 4/5"), Note("d'4 * 4/5"), Note("e'4 * 4/5"), Note("f'4 * 4/5")) Returns list of zero or more newly constructed notes. ''' from abjad.tools import scoretools multiplied_durations = [ durationtools.Duration(x) for x in multiplied_durations ] quarter_notes = [] sequences = [pitches, multiplied_durations] for pitch, duration in sequencetools.zip_sequences(sequences, cyclic=True): quarter_note = scoretools.Note(pitch, durationtools.Duration(1, 4)) duration = durationtools.Duration(duration) multiplier = durationtools.Multiplier(duration / durationtools.Duration(1, 4)) attach(multiplier, quarter_note) quarter_notes.append(quarter_note) quarter_notes = selectiontools.Selection(quarter_notes) return quarter_notes
def set_line_breaks_by_line_duration( expr, line_duration, line_break_class=None, kind='prolated', add_empty_bars=False, ): r'''Iterate `line_break_class` instances in `expr` and accumulate `kind` duration. Add line break after every total less than or equal to `line_duration`. Set `line_break_class` to measure when `line_break_class` is none. ''' if line_break_class is None: line_break_class = scoretools.Measure previous = None cumulative_duration = durationtools.Duration(0) for current in iterate(expr).by_class(line_break_class): # TODO: compress these 4 lines to only the 4th line # after duration migration if kind == 'seconds': current_duration = current._get_duration(in_seconds=True) elif kind == 'prolated': current_duration = current._get_duration() elif kind == 'preprolated': current_duration = current._preprolated_duration else: current_duration = getattr(current._get_duration(), kind) candidate_duration = cumulative_duration + current_duration if candidate_duration < line_duration: cumulative_duration += current_duration elif candidate_duration == line_duration: command = indicatortools.LilyPondCommand('break', 'closing') attach(command, current) if add_empty_bars: if current.bar_line.kind is None: current.bar_line.kind = '' cumulative_duration = durationtools.Duration(0) else: if previous is not None: command = indicatortools.LilyPondCommand('break', 'closing') attach(command, previous) if add_empty_bars: if current.bar_line.kind is None: current.bar_line.kind = '' cumulative_duration = current_duration previous = current
def t_DURATION(self, t): r'-?[1-9]\d*(/[1-9]\d*)?' parts = t.value.partition('/') if not parts[2]: t.value = durationtools.Duration(int(parts[0])) else: numerator, denominator = int(parts[0]), int(parts[2]) fraction = mathtools.NonreducedFraction(numerator, denominator) preprolated_duration = durationtools.Duration(fraction) if fraction.numerator == preprolated_duration.numerator: t.value = preprolated_duration else: t.value = fraction return t
def _get_timespan(self, in_seconds=False): from abjad.tools import durationtools if len(self): start_offset = \ self[0]._get_timespan(in_seconds=in_seconds)._start_offset stop_offset = \ self[-1]._get_timespan(in_seconds=in_seconds)._stop_offset else: start_offset = durationtools.Duration(0) stop_offset = durationtools.Duration(0) return timespantools.Timespan( start_offset=start_offset, stop_offset=stop_offset, )
def __init__(self, *args, **kwargs): if len(args) == 1 and durationtools.Duration.is_token(args[0]): args = durationtools.Duration(args[0]) elif len(args) == 1 and isinstance(args[0], type(self)): args = args[0].duration elif len(args) == 2 and \ isinstance(args[0], int) and isinstance(args[1], int): args = durationtools.Duration(args) elif len(args) == 0: args = durationtools.Duration((1, 4)) else: message = 'can not intialize {}: {!r}.' message = message.format(type(self).__name__, args) raise TypeError(message) Scheme.__init__(self, args, **kwargs)
def test_systemtools_StorageFormatAgent_get_import_statements_04(): subject = rhythmmakertools.IncisedRhythmMaker( incise_specifier=rhythmmakertools.InciseSpecifier( prefix_talea=(1, ), prefix_counts=(0, ), suffix_talea=(1, ), suffix_counts=(1, ), talea_denominator=16, body_ratio=mathtools.Ratio((1, )), outer_divisions_only=True, ), beam_specifier=rhythmmakertools.BeamSpecifier( beam_each_division=False, beam_divisions_together=False, ), duration_spelling_specifier=rhythmmakertools.DurationSpellingSpecifier( decrease_durations_monotonically=True, forbidden_written_duration=durationtools.Duration(1, 2), ), tuplet_spelling_specifier=rhythmmakertools.TupletSpellingSpecifier( avoid_dots=True, is_diminution=True, simplify_redundant_tuplets=True, ), ) agent = systemtools.StorageFormatAgent(subject) assert agent.get_import_statements() == ( 'from abjad.tools import durationtools', 'from abjad.tools import mathtools', 'from abjad.tools import rhythmmakertools', )
def written_duration(self, expr): rational = durationtools.Duration(expr) if not rational.is_assignable: message = 'not assignable duration: {!r}.' message = message.format(rational) raise AssignabilityError(message) self._written_duration = rational
def implied_prolation(self): '''Gets implied prolation of time signature. .. container:: example **Example 1.** Implied prolation of time signature with power-of-two denominator: :: >>> TimeSignature((3, 8)).implied_prolation Multiplier(1, 1) .. container:: example **Example 2.** Implied prolation of time signature with non-power-of-two denominator: :: >>> TimeSignature((7, 12)).implied_prolation Multiplier(2, 3) Returns multiplier. ''' dummy_duration = durationtools.Duration(1, self.denominator) return dummy_duration.implied_prolation
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 _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 _rewrite_meter_( selections, meters, reference_meters=None, rewrite_tuplets=False, use_messiaen_style_ties=False, ): from abjad.tools import metertools from abjad.tools import scoretools from abjad.tools.topleveltools import mutate meters = [metertools.Meter(_) for _ in meters] durations = [durationtools.Duration(_) for _ in meters] reference_meters = reference_meters or () selections = DurationSpellingSpecifier._split_at_measure_boundaries( selections, meters, use_messiaen_style_ties=use_messiaen_style_ties, ) measures = scoretools.make_spacer_skip_measures(durations) staff = scoretools.Staff(measures) mutate(staff).replace_measure_contents(selections) for measure, meter in zip(staff, meters): for reference_meter in reference_meters: if str(reference_meter) == str(meter): meter = reference_meter break mutate(measure[:]).rewrite_meter( meter, rewrite_tuplets=rewrite_tuplets, use_messiaen_style_ties=use_messiaen_style_ties, ) selections = [] for measure in staff: selections.append(measure[:]) return selections
def __init__( self, decrease_durations_monotonically=True, forbid_meter_rewriting=None, forbidden_written_duration=None, rewrite_meter=None, spell_metrically=None, ): from abjad.tools import rhythmmakertools assert isinstance(decrease_durations_monotonically, bool) if forbidden_written_duration is not None: forbidden_written_duration = durationtools.Duration( forbidden_written_duration) self._decrease_durations_monotonically = \ decrease_durations_monotonically self._forbidden_written_duration = forbidden_written_duration assert isinstance(rewrite_meter, (bool, type(None))) self._rewrite_meter = rewrite_meter assert (spell_metrically is None or isinstance(spell_metrically, bool) or spell_metrically == 'unassignable' or isinstance( spell_metrically, rhythmmakertools.PartitionTable)) self._spell_metrically = spell_metrically if forbid_meter_rewriting is not None: forbid_meter_rewriting = bool(forbid_meter_rewriting) self._forbid_meter_rewriting = forbid_meter_rewriting
def __init__( self, compound_meter_multiplier=durationtools.Multiplier(1), cyclic=True, durations=(), pattern_rotation_index=0, remainder=Right, remainder_fuse_threshold=None, ): compound_meter_multiplier = durationtools.Multiplier( compound_meter_multiplier) self._compound_meter_multiplier = compound_meter_multiplier assert isinstance(cyclic, bool), repr(cyclic) self._cyclic = cyclic durations = durations or () pattern_ = [] for division in durations: division = mathtools.NonreducedFraction(division) pattern_.append(division) durations = tuple(pattern_) self._pattern = durations assert remainder in (Left, Right), repr(remainder) self._remainder = remainder assert isinstance(pattern_rotation_index, int) self._pattern_rotation_index = pattern_rotation_index if remainder_fuse_threshold is not None: remainder_fuse_threshold = durationtools.Duration( remainder_fuse_threshold, ) self._remainder_fuse_threshold = remainder_fuse_threshold self._callbacks = ()
def _make_numeric_map_part( self, numerator, prefix, suffix, is_note_filled=True, ): prefix_weight = mathtools.weight(prefix) suffix_weight = mathtools.weight(suffix) middle = numerator - prefix_weight - suffix_weight if numerator < prefix_weight: weights = [numerator] prefix = sequencetools.split_sequence(prefix, weights, cyclic=False, overhang=False)[0] middle = self._make_middle_of_numeric_map_part(middle) suffix_space = numerator - prefix_weight if suffix_space <= 0: suffix = () elif suffix_space < suffix_weight: weights = [suffix_space] suffix = sequencetools.split_sequence( suffix, weights, cyclic=False, overhang=False, )[0] numeric_map_part = prefix + middle + suffix return [durationtools.Duration(x) for x in numeric_map_part]
def __init__( self, durations=None, include_long_duration_notes=False, include_long_duration_rests=False, isolated_nib_direction=None, use_stemlets=False, vertical_direction=None, ): Spanner.__init__( self, ) if durations: durations = tuple(durationtools.Duration(x) for x in durations) self._durations = durations self._include_long_duration_notes = bool(include_long_duration_notes) self._include_long_duration_rests = bool(include_long_duration_rests) assert isolated_nib_direction in (Left, Right, None) self._isolated_nib_direction = isolated_nib_direction if self._durations is not None: self._span_points = mathtools.cumulative_sums(self.durations)[1:] else: self._span_points = [self._get_duration()] self._use_stemlets = bool(use_stemlets) assert vertical_direction in (Up, Down, Center, None) self._vertical_direction = vertical_direction