def all_are_positive_integer_powers_of_two(expr): '''Is true when `expr` is a sequence and all elements in `expr` are positive integer powers of two. :: >>> mathtools.all_are_nonnegative_integer_powers_of_two([1, 1, 1, 2, 4, 32, 32]) True Is true when `expr` is an empty sequence: :: >>> mathtools.all_are_nonnegative_integer_powers_of_two([]) True Otherwise false: :: >>> mathtools.all_are_nonnegative_integer_powers_of_two(17) False Returns true or false. ''' from abjad.tools import mathtools try: return all( mathtools.is_positive_integer_power_of_two(x) for x in expr ) except TypeError: return False
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 _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 all_are_positive_integer_powers_of_two(expr): '''Is true when `expr` is a sequence and all elements in `expr` are positive integer powers of two. :: >>> mathtools.all_are_nonnegative_integer_powers_of_two([1, 1, 1, 2, 4, 32, 32]) True Is true when `expr` is an empty sequence: :: >>> mathtools.all_are_nonnegative_integer_powers_of_two([]) True Otherwise false: :: >>> mathtools.all_are_nonnegative_integer_powers_of_two(17) False Returns true or false. ''' from abjad.tools import mathtools try: return all(mathtools.is_positive_integer_power_of_two(x) for x in expr) except TypeError: return False
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_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 generate_offset_kernel_to_denominator( self, denominator, normalize=True, ): r'''Generate a dictionary of all offsets in a meter up to `denominator`, where the keys are the offsets and the values are the normalized weights of those offsets: :: >>> meter = \ ... metertools.Meter((4, 4)) >>> kernel = \ ... meter.generate_offset_kernel_to_denominator(8) >>> for offset, weight in sorted(kernel.kernel.iteritems()): ... print '{!s}\t{!s}'.format(offset, weight) ... 0 3/16 1/8 1/16 1/4 1/8 3/8 1/16 1/2 1/8 5/8 1/16 3/4 1/8 7/8 1/16 1 3/16 This is useful for testing how strongly a collection of offsets responds to a given meter. Returns dictionary. ''' from abjad.tools import metertools assert mathtools.is_positive_integer_power_of_two( denominator / self.denominator) inventory = list(self.depthwise_offset_inventory) old_flag_count = durationtools.Duration(1, self.denominator).flag_count new_flag_count = durationtools.Duration(1, denominator).flag_count extra_depth = new_flag_count - old_flag_count for _ in range(extra_depth): old_offsets = inventory[-1] new_offsets = [] for first, second in \ sequencetools.iterate_sequence_pairwise_strict(old_offsets): new_offsets.append(first) new_offsets.append((first + second) / 2) new_offsets.append(old_offsets[-1]) inventory.append(tuple(new_offsets)) total = 0 kernel = {} for offsets in inventory: for offset in offsets: if offset not in kernel: kernel[offset] = 0 kernel[offset] += 1 total += 1 if normalize: for offset, response in kernel.iteritems(): kernel[offset] = durationtools.Multiplier(response, total) return metertools.MetricAccentKernel(kernel)
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 _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 generate_offset_kernel_to_denominator( self, denominator, normalize=True, ): r'''Generates a dictionary of all offsets in a meter up to `denominator`. Keys are the offsets and the values are the normalized weights of those offsets. .. container:: example :: >>> meter = metertools.Meter((4, 4)) >>> kernel = meter.generate_offset_kernel_to_denominator(8) >>> for offset, weight in sorted(kernel.kernel.items()): ... print('{!s}\t{!s}'.format(offset, weight)) ... 0 3/16 1/8 1/16 1/4 1/8 3/8 1/16 1/2 1/8 5/8 1/16 3/4 1/8 7/8 1/16 1 3/16 This is useful for testing how strongly a collection of offsets responds to a given meter. Returns dictionary. ''' from abjad.tools import metertools assert mathtools.is_positive_integer_power_of_two(denominator // self.denominator) inventory = list(self.depthwise_offset_inventory) old_flag_count = durationtools.Duration(1, self.denominator).flag_count new_flag_count = durationtools.Duration(1, denominator).flag_count extra_depth = new_flag_count - old_flag_count for _ in range(extra_depth): old_offsets = inventory[-1] new_offsets = [] for first, second in \ sequencetools.iterate_sequence_nwise(old_offsets): new_offsets.append(first) new_offsets.append((first + second) / 2) new_offsets.append(old_offsets[-1]) inventory.append(tuple(new_offsets)) total = 0 kernel = {} for offsets in inventory: for offset in offsets: if offset not in kernel: kernel[offset] = 0 kernel[offset] += 1 total += 1 if normalize: for offset, response in kernel.items(): kernel[offset] = durationtools.Multiplier(response, total) return metertools.MetricAccentKernel(kernel)