def _make_ties_across_divisions(self, music): if not self.tie_across_divisions: return if self.tie_across_divisions == True: for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = next( iterate(division_one).by_class(prototype=scoretools.Leaf, reverse=True)) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf)) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) elif isinstance(self.tie_across_divisions, (tuple, list)): tie_across_divisions = datastructuretools.CyclicTuple( self.tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(music) for i, pair in enumerate(pairs): indicator = tie_across_divisions[i] if not bool(indicator): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) else: raise TypeError(self.tie_across_divisions)
def _make_ties_across_divisions(self, music): if not self.tie_across_divisions: return if self.tie_across_divisions == True: for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True)) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf)) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) elif isinstance(self.tie_across_divisions, (tuple, list)): tie_across_divisions = datastructuretools.CyclicTuple( self.tie_across_divisions ) pairs = sequencetools.iterate_sequence_nwise(music) for i, pair in enumerate(pairs): indicator = tie_across_divisions[i] if not bool(indicator): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie) else: raise TypeError(self.tie_across_divisions)
def _to_logical_measure_number( self, component, logical_measure_number_start_offsets, ): from abjad.tools import mathtools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ inspector = inspect_(component) component_start_offset = inspector.get_timespan().start_offset logical_measure_number_start_offsets = \ logical_measure_number_start_offsets[:] logical_measure_number_start_offsets.append(mathtools.Infinity()) pairs = sequencetools.iterate_sequence_nwise( logical_measure_number_start_offsets, n=2, ) for logical_measure_index, pair in enumerate(pairs): if pair[0] <= component_start_offset < pair[-1]: logical_measure_number = logical_measure_index + 1 return logical_measure_number message = 'can not find logical measure number: {!r}, {!r}.' message = message.format( component, logical_measure_number_start_offsets, ) raise ValueError(message)
def _find_divisible_leaf_indices_and_subdivisions(self, q_grid): # TODO: This should actually check for all QEvents which fall # within the leaf's duration, # including QEvents attached to the next leaf # It may be prudent to actually store QEvents in two lists: # before_offset and after_offset indices, subdivisions = [], [] leaves = list(q_grid.leaves) i = 0 for leaf_one, leaf_two in sequencetools.iterate_sequence_nwise(leaves): if leaf_one.is_divisible: succeeding_proxies = leaf_one.succeeding_q_event_proxies preceding_proxies = leaf_two.preceding_q_event_proxies if not preceding_proxies and \ all(proxy.offset == leaf_one.start_offset for proxy in succeeding_proxies): pass # proxies align perfectly with this leaf elif preceding_proxies or succeeding_proxies: parentage_ratios = leaf_one.parentage_ratios leaf_subdivisions = \ self._find_leaf_subdivisions(parentage_ratios) if leaf_subdivisions: indices.append(i) subdivisions.append(tuple(leaf_subdivisions)) i += 1 return indices, subdivisions
def _find_divisible_leaf_indices_and_subdivisions(self, q_grid): # TODO: This should actually check for all QEvents which fall # within the leaf's duration, # including QEvents attached to the next leaf # It may be prudent to actually store QEvents in two lists: # before_offset and after_offset indices, subdivisions = [], [] leaves = q_grid.leaves i = 0 for leaf_one, leaf_two in \ sequencetools.iterate_sequence_nwise(leaves): if (leaf_one.succeeding_q_event_proxies or leaf_two.preceding_q_event_proxies) and \ leaf_one.is_divisible: if len(leaf_one.q_event_proxies) == 1 and \ leaf_one.q_event_proxies[0].offset == \ leaf_one.start_offset: pass # perfect match, don't bother to continue subdivision else: parentage_ratios = leaf_one.parentage_ratios leaf_subdivisions = \ self._find_leaf_subdivisions(parentage_ratios) if leaf_subdivisions: indices.append(i) subdivisions.append(tuple(leaf_subdivisions)) i += 1 return indices, subdivisions
def _interleave_source_with_code_blocks(self, tmp_directory, lines, code_blocks, output_format): # print 'INTERLEAVE SOURCE WITH CODE BLOCKS' image_file_names = [ x for x in os.listdir(tmp_directory) if (x.endswith(output_format.image_format) and x.startswith(self.image_prefix)) ] image_dict = {} for image_file_name in image_file_names: suffix = os.path.splitext(image_file_name.partition("-")[2])[0] index, part, page = suffix.partition("-") index = int(index) if page: page = int(page.strip("page")) else: page = 0 if index not in image_dict: image_dict[index] = {} image_dict[index][page] = image_file_name interleaved = [] interleaved.append("\n".join(lines[: code_blocks[0].starting_line_number])) for pair in sequencetools.iterate_sequence_nwise(code_blocks): first_block, second_block = pair interleaved.extend(output_format(first_block, image_dict)) interleaved.append( "\n".join(lines[first_block.stopping_line_number + 1 : second_block.starting_line_number]) ) interleaved.extend(output_format(code_blocks[-1], image_dict)) interleaved.append("\n".join(lines[code_blocks[-1].stopping_line_number + 1 :])) return "\n".join(interleaved)
def are_stepwise_notes(self): r'''Is true when notes in selection are stepwise. :: >>> selection_1.are_stepwise_notes() True Otherwise false: :: >>> selection_2.are_stepwise_notes() False Returns true or false. ''' from abjad.tools import scoretools for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) hdi = pitchtools.NamedInterval.from_pitch_carriers( left, right) assert hdi.number <= 2 except AssertionError: return False return True
def _notate(self, grace_handler, attack_point_optimizer, attach_tempos): voice = scoretools.Voice() # generate the first beat = self.items[0] components = beat.q_grid(beat.beatspan) if attach_tempos: attachment_target = components[0] if isinstance(attachment_target, scoretools.Container): attachment_target = attachment_target.select_leaves()[0] tempo = copy.copy(beat.tempo) attach(tempo, attachment_target) voice.extend(components) # generate the rest pairwise, comparing tempi for beat_one, beat_two in \ sequencetools.iterate_sequence_nwise(self.items): components = beat_two.q_grid(beat_two.beatspan) if (beat_two.tempo != beat_one.tempo) and attach_tempos: attachment_target = components[0] if isinstance(attachment_target, scoretools.Container): attachment_target = attachment_target.select_leaves()[0] tempo = copy.copy(beat_two.tempo) attach(tempo, attachment_target) voice.extend(components) # apply logical ties, pitches, grace containers self._notate_leaves_pairwise(voice, grace_handler) # partition logical ties in voice attack_point_optimizer(voice) return voice
def are_scalar_notes(self): r'''Is true when notes in selection are scalar. :: >>> selection_1.are_scalar_notes() True Otherwise false: :: >>> selection_2.are_scalar_notes() False Returns true or false. ''' from abjad.tools import scoretools direction_string = None for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) mdi = pitchtools.NamedInterval.from_pitch_carriers( left, right) assert mdi.number <= 2 if direction_string is None: direction_string = mdi.direction_string assert direction_string == mdi.direction_string except AssertionError: return False return True
def list_nonspanning_subarrays(self): r'''Lists nonspanning subarrays of pitch array. .. container:: example **Example 1.** Lists three nonspanning subarrays: :: >>> array = pitchtools.PitchArray([ ... [2, 2, 3, 1], ... [1, 2, 1, 1, 2, 1], ... [1, 1, 1, 1, 1, 1, 1, 1]]) >>> print(array) [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] :: >>> subarrays = array.list_nonspanning_subarrays() >>> len(subarrays) 3 :: >>> print(subarrays[0]) [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] :: >>> print(subarrays[1]) [ ] [ ] [ ] [ ] [ ] [ ] :: >>> print(subarrays[2]) [ ] [ ] [ ] Returns list. ''' unspanned_indices = [] for i in range(self.width + 1): if not self.has_spanning_cell_over_index(i): unspanned_indices.append(i) array_depth = self.depth subarrays = [] for start_column, stop_column in \ sequencetools.iterate_sequence_nwise(unspanned_indices): upper_left_pair = (0, start_column) lower_right_pair = (array_depth, stop_column) subarray = self.copy_subarray(upper_left_pair, lower_right_pair) subarrays.append(subarray) return subarrays
def are_stepwise_notes(self): r'''Is true when notes in selection are stepwise. :: >>> selection_1.are_stepwise_notes() True Otherwise false: :: >>> selection_2.are_stepwise_notes() False Returns boolean. ''' from abjad.tools import scoretools for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) hdi = pitchtools.NamedInterval.from_pitch_carriers(left, right) assert hdi.number <= 2 except AssertionError: return False return True
def _to_logical_measure_number( self, component, logical_measure_number_start_offsets, ): from abjad.tools import mathtools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ inspector = inspect_(component) component_start_offset = inspector.get_timespan()._start_offset logical_measure_number_start_offsets = \ logical_measure_number_start_offsets[:] logical_measure_number_start_offsets.append(mathtools.Infinity()) pairs = sequencetools.iterate_sequence_nwise( logical_measure_number_start_offsets, n=2, ) for logical_measure_index, pair in enumerate(pairs): if pair[0] <= component_start_offset < pair[-1]: logical_measure_number = logical_measure_index + 1 return logical_measure_number message = 'can not find logical measure number: {!r}, {!r}.' message = message.format( component, logical_measure_number_start_offsets, ) raise ValueError(message)
def _score_pitch_set(pitch_set): buckets = {} for pitch in pitch_set: if pitch.diatonic_pitch_number not in buckets: buckets[pitch.diatonic_pitch_number] = set() buckets[pitch.diatonic_pitch_number].add(pitch) penalty = 0 for diatonic_pitch_number, bucket in sorted(buckets.items()): penalty = penalty + (len(bucket) - 1) for one, two in sequencetools.iterate_sequence_nwise( sorted(buckets.items())): number_1, bucket_1 = one number_2, bucket_2 = two if abs(number_1 - number_2) != 1: continue one_has_flats, one_has_sharps = False, False for pitch in bucket_1: if pitch.alteration_in_semitones > 0: one_has_sharps = True if pitch.alteration_in_semitones < 0: one_has_flats = True two_has_flats, two_has_sharps = False, False for pitch in bucket_2: if pitch.alteration_in_semitones > 0: two_has_sharps = True if pitch.alteration_in_semitones < 0: two_has_flats = True if one_has_flats and two_has_sharps: penalty += 1 if one_has_sharps and two_has_flats: penalty += 1 return penalty
def _shift_downbeat_q_events_to_next_q_grid(self): beats = self.beats for one, two in sequencetools.iterate_sequence_nwise(beats): one_q_events = one.q_grid.next_downbeat.q_event_proxies two_q_events = two.q_grid.leaves[0].q_event_proxies while one_q_events: two_q_events.append(one_q_events.pop())
def are_scalar_notes(self): r'''Is true when notes in selection are scalar. :: >>> selection_1.are_scalar_notes() True Otherwise false: :: >>> selection_2.are_scalar_notes() False Returns boolean. ''' from abjad.tools import scoretools direction_string = None for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) mdi = pitchtools.NamedInterval.from_pitch_carriers( left, right) assert mdi.number <= 2 if direction_string is None: direction_string = mdi.direction_string assert direction_string == mdi.direction_string except AssertionError: return False return True
def graph_order(self): r'''Graph order of tree node. Returns tuple. ''' from abjad.tools import sequencetools order = [] for parent, child in sequencetools.iterate_sequence_nwise( reversed(self.improper_parentage)): order.append(parent.index(child)) return tuple(order)
def prolations(self): r'''Prolations of rhythm tree node. Returns tuple. ''' prolations = [durationtools.Multiplier(1)] improper_parentage = self.improper_parentage for child, parent in \ sequencetools.iterate_sequence_nwise(improper_parentage): prolations.append(durationtools.Multiplier( parent.preprolated_duration, parent._contents_duration)) return tuple(prolations)
def has_voice_crossing(self): r'''Is true when pitch array column has voice crossing. Otherwise false. Returns boolean. ''' for upper, lower in \ sequencetools.iterate_sequence_nwise(self.cells): for lower_pitch in lower.pitches: for upper_pitch in upper.pitches: if upper_pitch.numbered_pitch < \ lower_pitch.numbered_pitch: return True return False
def _get_intervals_in_subrun(subrun_source): from abjad.tools import pitchtools subrun_source = list(subrun_source) result = [0] for first, second in sequencetools.iterate_sequence_nwise(subrun_source): first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first) second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second) interval = pitchtools.NumberedPitch(second_pitch).pitch_number - \ pitchtools.NumberedPitch(first_pitch).pitch_number result.append(interval + result[-1]) result.pop(0) return result
def _get_intervals_in_subrun(subrun_source): from abjad.tools import pitchtools subrun_source = list(subrun_source) result = [0] for first, second in sequencetools.iterate_sequence_nwise( subrun_source): first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first) second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second) interval = pitchtools.NumberedPitch(second_pitch).pitch_number - \ pitchtools.NumberedPitch(first_pitch).pitch_number result.append(interval + result[-1]) result.pop(0) return result
def _do_tie_across_divisions(self, divisions): from abjad.tools import rhythmmakertools if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, patterntools.Pattern): tie_across_divisions = patterntools.Pattern.from_vector( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def has_voice_crossing(self): r'''Is true when pitch array column has voice crossing. Otherwise false. Returns true or false. ''' pairs = sequencetools.iterate_sequence_nwise(self.cells) for upper, lower in pairs: lower_pitches = lower.pitches or () for lower_pitch in lower_pitches: upper_pitches = upper.pitches or () for upper_pitch in upper_pitches: if upper_pitch.numbered_pitch < lower_pitch.numbered_pitch: return True return False
def named_interval_class_segment(self): r'''Named interval class segment of scale. Returns interval-class segment. ''' dics = [] for left, right in \ sequencetools.iterate_sequence_nwise(self, wrapped=True): dic = left - right dics.append(dic) dicg = pitchtools.IntervalClassSegment( items=dics, item_class=pitchtools.NamedInversionEquivalentIntervalClass, ) return dicg
def cumulative_sums_pairwise(sequence): r'''Lists pairwise cumulative sums of `sequence` from ``0``. :: >>> mathtools.cumulative_sums_pairwise([1, 2, 3, 4, 5, 6]) [(0, 1), (1, 3), (3, 6), (6, 10), (10, 15), (15, 21)] Returns list of pairs. ''' from abjad.tools import mathtools from abjad.tools import sequencetools sums = mathtools.cumulative_sums(sequence) return list(sequencetools.iterate_sequence_nwise(sums))
def _do_tie_across_divisions(self, divisions): if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, patterntools.Pattern): tie_across_divisions = patterntools.Pattern.from_vector( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) rest_prototype = (scoretools.Rest, scoretools.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next( iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next( iterate(division_two).by_class(prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() if tie_spanner._attachment_test_all(combined_logical_tie): attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def __init__( self, items=None, item_class=None, ): from abjad.tools import pitchtools if isinstance(items, pitchtools.PitchSegment): intervals = [] for one, two in sequencetools.iterate_sequence_nwise(items): intervals.append(one - two) items = intervals Segment.__init__( self, items=items, item_class=item_class, )
def _get_logical_measure_start_offsets(self, component): from abjad.tools import durationtools from abjad.tools import indicatortools from abjad.tools import sequencetools from abjad.tools.topleveltools import inspect_ from abjad.tools.topleveltools import iterate expressions = [] prototype = indicatortools.TimeSignature components = self._iterate_entire_score(component) for component in components: expressions_ = component._get_indicators( prototype, unwrap=False, ) expressions.extend(expressions_) pairs = [] for expression in expressions: inspector = inspect_(expression.component) start_offset = inspector.get_timespan().start_offset time_signature = expression.indicator pair = start_offset, time_signature pairs.append(pair) offset_zero = durationtools.Offset(0) default_time_signature = indicatortools.TimeSignature((4, 4)) default_pair = (offset_zero, default_time_signature) if pairs and not pairs[0] == offset_zero: pairs.insert(0, default_pair) elif not pairs: pairs = [default_pair] pairs.sort(key=lambda x: x[0]) parentage = component._get_parentage() score_root = parentage.root inspector = inspect_(score_root) score_stop_offset = inspector.get_timespan().stop_offset dummy_last_pair = (score_stop_offset, None) pairs.append(dummy_last_pair) measure_start_offsets = [] pairs = sequencetools.iterate_sequence_nwise(pairs, n=2) for current_pair, next_pair in pairs: current_start_offset, current_time_signature = current_pair next_start_offset, next_time_signature = next_pair measure_start_offset = current_start_offset while measure_start_offset < next_start_offset: measure_start_offsets.append(measure_start_offset) measure_start_offset += current_time_signature.duration return measure_start_offsets
def _decode_parameters(value, index): from supriya.tools import synthdeftools sdd = SynthDefDecompiler parameter_values = [] parameter_count, index = sdd._decode_int_32bit(value, index) for _ in range(parameter_count): parameter_value, index = sdd._decode_float(value, index) parameter_values.append(parameter_value) parameter_count, index = sdd._decode_int_32bit(value, index) parameter_names = [] parameter_indices = [] for _ in range(parameter_count): parameter_name, index = sdd._decode_string(value, index) parameter_index, index = sdd._decode_int_32bit(value, index) parameter_names.append(parameter_name) parameter_indices.append(parameter_index) indexed_parameters = [] if parameter_count: pairs = tuple(zip(parameter_indices, parameter_names)) pairs = sorted(pairs, key=lambda x: x[0]) iterator = sequencetools.iterate_sequence_nwise(pairs) for (index_one, name_one), (index_two, name_two) in iterator: value = parameter_values[index_one:index_two] if len(value) == 1: value = value[0] parameter = synthdeftools.Parameter( name=name_one, value=value, ) indexed_parameters.append((index_one, parameter)) index_one, name_one = pairs[-1] value = parameter_values[index_one:] if len(value) == 1: value = value[0] parameter = synthdeftools.Parameter( name=name_one, value=value, ) indexed_parameters.append((index_one, parameter)) indexed_parameters.sort( key=lambda x: parameter_names.index(x[1].name), ) indexed_parameters = collections.OrderedDict(indexed_parameters) return indexed_parameters, index
def _notate( self, attach_tempos=True, attack_point_optimizer=None, grace_handler=None, ): voice = scoretools.Voice() # generate the first beat = self.items[0] components = beat.q_grid(beat.beatspan) if attach_tempos: attachment_target = components[0] leaves = select(attachment_target).by_leaf() if isinstance(attachment_target, scoretools.Container): attachment_target = leaves[0] tempo = copy.copy(beat.tempo) attach(tempo, attachment_target) voice.extend(components) # generate the rest pairwise, comparing tempi for beat_one, beat_two in \ sequencetools.iterate_sequence_nwise(self.items): components = beat_two.q_grid(beat_two.beatspan) if (beat_two.tempo != beat_one.tempo) and attach_tempos: attachment_target = components[0] leaves = select(attachment_target).by_leaf() if isinstance(attachment_target, scoretools.Container): attachment_target = leaves[0] tempo = copy.copy(beat_two.tempo) attach(tempo, attachment_target) voice.extend(components) # apply logical ties, pitches, grace containers self._notate_leaves( grace_handler=grace_handler, voice=voice, ) # partition logical ties in voice attack_point_optimizer(voice) return voice
def _attachment_test_all(self, component_expression): from abjad.tools import scoretools from abjad.tools import sequencetools #if not self._at_least_two_leaves(component_expression): # return False written_pitches = [] if isinstance(component_expression, scoretools.Component): component_expression = [component_expression] for component in component_expression: if isinstance(component, scoretools.Note): written_pitches.append(set([component.written_pitch])) elif isinstance(component, scoretools.Chord): written_pitches.append(set(component.written_pitches)) else: return False for pair in sequencetools.iterate_sequence_nwise(written_pitches): if not set.intersection(*pair): return False return True
def _interleave_source_with_code_blocks( self, tmp_directory, lines, code_blocks, output_format, ): #print 'INTERLEAVE SOURCE WITH CODE BLOCKS' image_file_names = [ x for x in os.listdir(tmp_directory) if (x.endswith(output_format.image_format) and x.startswith(self.image_prefix)) ] image_dict = {} for image_file_name in image_file_names: suffix = os.path.splitext(image_file_name.partition('-')[2])[0] index, part, page = suffix.partition('-') index = int(index) if page: page = int(page.strip('page')) else: page = 0 if index not in image_dict: image_dict[index] = {} image_dict[index][page] = image_file_name interleaved = [] interleaved.append('\n'.join( lines[:code_blocks[0].starting_line_number])) for pair in sequencetools.iterate_sequence_nwise(code_blocks): first_block, second_block = pair interleaved.extend(output_format(first_block, image_dict)) interleaved.append('\n'.join( lines[first_block.stopping_line_number + 1:second_block.starting_line_number])) interleaved.extend(output_format(code_blocks[-1], image_dict)) interleaved.append('\n'.join( lines[code_blocks[-1].stopping_line_number + 1:])) return '\n'.join(interleaved)
def _make_ties_across_divisions(self, divisions): from abjad.tools import rhythmmakertools if not self.tie_across_divisions: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, rhythmmakertools.BooleanPattern): tie_across_divisions = \ rhythmmakertools.BooleanPattern.from_sequence( tie_across_divisions) pairs = sequencetools.iterate_sequence_nwise(divisions) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, )) leaf_two = next(iterate(division_two).by_class( prototype=scoretools.Leaf, )) leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two tie_spanner = spannertools.Tie( use_messiaen_style_ties=self.use_messiaen_style_ties, ) tie_spanner._unconstrain_contiguity() attach(tie_spanner, combined_logical_tie) tie_spanner._constrain_contiguity()
def _notate( self, attach_tempos=True, attack_point_optimizer=None, grace_handler=None, ): voice = scoretools.Voice() # generate the first q_target_measure = self.items[0] measure = scoretools.Measure(q_target_measure.time_signature) for beat in q_target_measure.beats: measure.extend(beat.q_grid(beat.beatspan)) if attach_tempos: tempo = copy.copy(q_target_measure.tempo) attach(tempo, measure) voice.append(measure) # generate the rest pairwise, comparing tempi for q_target_measure_one, q_target_measure_two in \ sequencetools.iterate_sequence_nwise(self.items): measure = scoretools.Measure(q_target_measure_two.time_signature) for beat in q_target_measure_two.beats: measure.extend(beat.q_grid(beat.beatspan)) if (q_target_measure_two.tempo != q_target_measure_one.tempo) \ and attach_tempos: tempo = copy.copy(q_target_measure_two.tempo) attach(tempo, measure) voice.append(measure) # apply logical ties, pitches, grace containers self._notate_leaves( grace_handler=grace_handler, voice=voice, ) # partition logical ties in each measure for measure in voice: attack_point_optimizer(measure) return voice
def get_offsets_at_depth(depth): if depth < len(offset_inventory): return offset_inventory[depth] while len(offset_inventory) <= depth: new_offsets = [] old_offsets = offset_inventory[-1] for first, second in \ sequencetools.iterate_sequence_nwise(old_offsets): new_offsets.append(first) difference = second - first half = (first + second) / 2 if durationtools.Duration(1, 8) < difference: new_offsets.append(half) else: one_quarter = (first + half) / 2 three_quarters = (half + second) / 2 new_offsets.append(one_quarter) new_offsets.append(half) new_offsets.append(three_quarters) new_offsets.append(old_offsets[-1]) offset_inventory.append(tuple(new_offsets)) return offset_inventory[depth]
def is_repetition_free(self): '''Is true when sequence is repetition-free. .. container:: example Is true when sequence contains no repetitions: :: >>> Sequence((0, 1, 2, 6, 7, 8)).is_repetition_free() True Is true when sequence is empty: :: >>> Sequence().is_repetition_free() True .. container:: example Is false when sequence contains repetitions: :: >>> Sequence((0, 1, 2, 2, 7, 8)).is_repetition_free() False Returns true or false. ''' from abjad.tools import sequencetools try: pairs = sequencetools.iterate_sequence_nwise(self) for left, right in pairs: if left == right: return False return True except TypeError: return False
def _make_ties_across_divisions(music): for division_one, division_two in \ sequencetools.iterate_sequence_nwise(music): leaf_one = iterate(division_one).by_class( prototype=scoretools.Leaf, reverse=True, ).next() leaf_two = iterate(division_two).by_class( prototype=scoretools.Leaf, ).next() leaves = [leaf_one, leaf_two] prototype = (scoretools.Note, scoretools.Chord) if not all(isinstance(x, prototype) for x in leaves): continue logical_tie_one = inspect_(leaf_one).get_logical_tie() logical_tie_two = inspect_(leaf_two).get_logical_tie() for tie in inspect_(leaf_one).get_spanners(spannertools.Tie): detach(tie, leaf_one) for tie in inspect_(leaf_two).get_spanners(spannertools.Tie): detach(tie, leaf_two) combined_logical_tie = logical_tie_one + logical_tie_two attach(spannertools.Tie(), combined_logical_tie)
def are_stepwise_descending_notes(self): r'''Is true when notes in selection are stepwise descending. :: >>> selection_3 = tonalanalysistools.select(reversed(staff[:])) :: >>> selection_3.are_stepwise_descending_notes() True Otherwise false: :: >>> selection_1.are_stepwise_descending_notes() False :: >>> selection_2.are_stepwise_descending_notes() False Returns true or false. ''' from abjad.tools import scoretools for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) mdi = pitchtools.NamedInterval.from_pitch_carriers( left, right) assert mdi.number == -2 except AssertionError: return False return True
def are_stepwise_descending_notes(self): r'''Is true when notes in selection are stepwise descending. :: >>> selection_3 = tonalanalysistools.select(reversed(staff[:])) :: >>> selection_3.are_stepwise_descending_notes() True Otherwise false: :: >>> selection_1.are_stepwise_descending_notes() False :: >>> selection_2.are_stepwise_descending_notes() False Returns boolean. ''' from abjad.tools import scoretools for left, right in sequencetools.iterate_sequence_nwise( iterate(self._client).by_class(scoretools.Note)): try: assert not (left.written_pitch == right.written_pitch) mdi = pitchtools.NamedInterval.from_pitch_carriers( left, right) assert mdi.number == -2 except AssertionError: return False return True
def get_offsets_at_depth(depth, offset_inventory): r'''Gets offsets at `depth` in `offset_inventory`. ''' if depth < len(offset_inventory): return offset_inventory[depth] while len(offset_inventory) <= depth: new_offsets = [] old_offsets = offset_inventory[-1] for first, second in \ sequencetools.iterate_sequence_nwise(old_offsets): new_offsets.append(first) difference = second - first half = (first + second) / 2 if durationtools.Duration(1, 8) < difference: new_offsets.append(half) else: one_quarter = (first + half) / 2 three_quarters = (half + second) / 2 new_offsets.append(one_quarter) new_offsets.append(half) new_offsets.append(three_quarters) new_offsets.append(old_offsets[-1]) offset_inventory.append(tuple(new_offsets)) return offset_inventory[depth]
def __call__(self, logical_ties, timespan=None, offset=0): r'''Calls handler on `logical_ties` with `offset`. Returns none. ''' hairpin_tokens = datastructuretools.CyclicTuple(self.hairpin_tokens) logical_tie_groups = self._group_contiguous_logical_ties(logical_ties) for logical_tie_group in logical_tie_groups: pairs = sequencetools.iterate_sequence_nwise( logical_tie_group, n=2, ) for i, pair in enumerate(pairs): hairpin_token = hairpin_tokens[i] descriptor = ' '.join([_ for _ in hairpin_token if _]) hairpin = spannertools.Hairpin( descriptor=descriptor, include_rests=False, ) first_logical_tie, second_logical_tie = pair notes = [] notes.extend(first_logical_tie) notes.append(second_logical_tie.head) attach(hairpin, notes)
def __graph__(self, spanner=None, **kwargs): r'''Graphviz graph representation of container. Returns Graphviz graph. ''' def recurse(component, leaf_cluster): component_node = component._as_graphviz_node() node_mapping[component] = component_node node_order = [component_node.name] if isinstance(component, scoretools.Container): graph.append(component_node) this_leaf_cluster = documentationtools.GraphvizSubgraph( name=component_node.name, attributes={ 'color': 'grey75', 'penwidth': 2, }, ) all_are_leaves = True pending_node_order = [] for child in component: if not isinstance(child, scoretools.Leaf): all_are_leaves = False child_node, child_node_order = recurse( child, this_leaf_cluster) pending_node_order.extend(child_node_order) edge = documentationtools.GraphvizEdge() edge(component_node, child_node) if all_are_leaves: pending_node_order.reverse() node_order.extend(pending_node_order) if len(this_leaf_cluster): leaf_cluster.append(this_leaf_cluster) else: leaf_cluster.append(component_node) return component_node, node_order from abjad.tools import documentationtools from abjad.tools import scoretools node_order = [] node_mapping = {} graph = documentationtools.GraphvizGraph( name='G', attributes={ 'style': 'rounded', }, edge_attributes={ }, node_attributes={ 'fontname': 'Arial', 'shape': 'none', }, ) leaf_cluster = documentationtools.GraphvizSubgraph(name='leaves') component_node, node_order = recurse(self, leaf_cluster) if len(leaf_cluster) == 1: graph.append(leaf_cluster[0]) elif len(leaf_cluster): graph.append(leaf_cluster) graph._node_order = node_order if spanner: for component_one, component_two in \ sequencetools.iterate_sequence_nwise(spanner.components): node_one = node_mapping[component_one] node_two = node_mapping[component_two] edge = documentationtools.GraphvizEdge( attributes={ 'constraint': False, 'penwidth': 5, }, ) edge(node_one, node_two) for component in spanner.components: node = node_mapping[component] table = node[0] table.attributes['border'] = 4 table.attributes['bgcolor'] = 'grey80' if isinstance(component, Container): for child in iterate(component).depth_first(): if child is component: continue node = node_mapping[child] table = node[0] table.attributes['bgcolor'] = 'grey80' return graph
def __graph__(self, **kwargs): r'''Gets Graphviz format of meter. .. container:: example **Example 1.** Graphs ``7/4``: :: >>> meter = metertools.Meter((7, 4)) >>> meter_graph = meter.__graph__() >>> graph(meter_graph) # doctest: +SKIP .. doctest:: >>> print(str(meter_graph)) digraph G { graph [bgcolor=transparent, fontname=Arial, penwidth=2, truecolor=true]; node [fontname=Arial, fontsize=12, penwidth=2]; edge [penwidth=2]; node_0 [label="7/4", shape=triangle]; node_1 [label="3/4", shape=triangle]; node_2 [label="1/4", shape=box]; node_3 [label="1/4", shape=box]; node_4 [label="1/4", shape=box]; node_5 [label="2/4", shape=triangle]; node_6 [label="1/4", shape=box]; node_7 [label="1/4", shape=box]; node_8 [label="2/4", shape=triangle]; node_9 [label="1/4", shape=box]; node_10 [label="1/4", shape=box]; subgraph cluster_cluster_offsets { graph [style=rounded]; node_11_0 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 0 | <f_0_1> +++ }", shape=Mrecord, style=filled]; node_11_1 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 1/4 | <f_0_1> + }", shape=Mrecord, style=filled]; node_11_2 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 1/2 | <f_0_1> + }", shape=Mrecord, style=filled]; node_11_3 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 3/4 | <f_0_1> ++ }", shape=Mrecord, style=filled]; node_11_4 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 1 | <f_0_1> + }", shape=Mrecord, style=filled]; node_11_5 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 5/4 | <f_0_1> ++ }", shape=Mrecord, style=filled]; node_11_6 [color=white, fillcolor=black, fontcolor=white, fontname="Arial bold", label="{ <f_0_0> 3/2 | <f_0_1> + }", shape=Mrecord, style=filled]; node_11_7 [label="{ <f_0_0> 7/4 | <f_0_1> +++ }", shape=Mrecord]; } node_0 -> node_1; node_0 -> node_5; node_0 -> node_8; node_1 -> node_2; node_1 -> node_3; node_1 -> node_4; node_2 -> node_11_0 [style=dotted]; node_2 -> node_11_1 [style=dotted]; node_3 -> node_11_1 [style=dotted]; node_3 -> node_11_2 [style=dotted]; node_4 -> node_11_2 [style=dotted]; node_4 -> node_11_3 [style=dotted]; node_5 -> node_6; node_5 -> node_7; node_6 -> node_11_3 [style=dotted]; node_6 -> node_11_4 [style=dotted]; node_7 -> node_11_4 [style=dotted]; node_7 -> node_11_5 [style=dotted]; node_8 -> node_9; node_8 -> node_10; node_9 -> node_11_5 [style=dotted]; node_9 -> node_11_6 [style=dotted]; node_10 -> node_11_6 [style=dotted]; node_10 -> node_11_7 [style=dotted]; } Returns Graphviz graph. ''' def make_offset_node( offset, leaf_one=None, leaf_two=None, is_last=False, ): if not is_last: offset_node = documentationtools.GraphvizNode( attributes={ 'shape': 'Mrecord', 'style': 'filled', 'color': 'white', 'fontname': 'Arial bold', 'fontcolor': 'white', 'fillcolor': 'black', }, ) else: offset_node = documentationtools.GraphvizNode( attributes={ 'shape': 'Mrecord', }, ) offset_field = documentationtools.GraphvizField( label=str(offset), ) weight_field = documentationtools.GraphvizField( label='+' * offsets[offset], ) group = documentationtools.GraphvizGroup() group.extend([offset_field, weight_field]) offset_node.append(group) offset_subgraph.append(offset_node) leaf_one_node = node_mapping[leaf_one] edge = documentationtools.GraphvizEdge( attributes={'style': 'dotted'}, ) edge.attach(leaf_one_node, offset_node) if leaf_two: leaf_two_node = node_mapping[leaf_two] edge = documentationtools.GraphvizEdge( attributes={'style': 'dotted'}, ) edge.attach(leaf_two_node, offset_node) from abjad.tools import metertools offsets = metertools.MetricAccentKernel.count_offsets_in_expr( sequencetools.flatten_sequence(self.depthwise_offset_inventory)) graph = documentationtools.GraphvizGraph( name='G', attributes={ 'bgcolor': 'transparent', 'fontname': 'Arial', 'penwidth': 2, 'truecolor': True, }, edge_attributes={ 'penwidth': 2, }, node_attributes={ 'fontname': 'Arial', 'fontsize': 12, 'penwidth': 2, }, ) node_mapping = {} for node in self._root_node.nodes: graphviz_node = documentationtools.GraphvizNode() graphviz_node.attributes['label'] = str(node.preprolated_duration) if isinstance(node, rhythmtreetools.RhythmTreeContainer): graphviz_node.attributes['shape'] = 'triangle' else: graphviz_node.attributes['shape'] = 'box' graph.append(graphviz_node) node_mapping[node] = graphviz_node if node.parent is not None: documentationtools.GraphvizEdge().attach( node_mapping[node.parent], node_mapping[node], ) leaves = self._root_node.leaves offset = leaves[0].start_offset offset_subgraph = documentationtools.GraphvizSubgraph( name='cluster_offsets', attributes={ 'style': 'rounded', }, ) graph.append(offset_subgraph) make_offset_node(offset, leaves[0]) for one, two in sequencetools.iterate_sequence_nwise(leaves): offset = one.stop_offset make_offset_node(offset, one, two) offset = leaves[-1].stop_offset make_offset_node(offset, leaves[-1], is_last=True) return graph
def _split( self, durations, cyclic=False, fracture_spanners=False, tie_split_notes=True, use_messiaen_style_ties=False, ): from abjad.tools import pitchtools from abjad.tools import selectiontools from abjad.tools import scoretools from abjad.tools import spannertools durations = [durationtools.Duration(x) for x in durations] if cyclic: durations = sequencetools.repeat_sequence_to_weight( durations, self._get_duration()) durations = [durationtools.Duration(x) for x in durations] if sum(durations) < self._get_duration(): last_duration = self._get_duration() - sum(durations) durations.append(last_duration) sequencetools.truncate_sequence( durations, weight=self._get_duration(), ) result = [] leaf_prolation = self._get_parentage(include_self=False).prolation timespan = self._get_timespan() start_offset = timespan.start_offset for duration in durations: new_leaf = copy.copy(self) preprolated_duration = duration / leaf_prolation shard = new_leaf._set_duration( preprolated_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) for x in shard: if isinstance(x, scoretools.Leaf): x_duration = x.written_duration * leaf_prolation else: x_duration = x.multiplied_duration * leaf_prolation stop_offset = x_duration + start_offset x._start_offset = start_offset x._stop_offset = stop_offset x._timespan = timespantools.Timespan( start_offset=start_offset, stop_offset=stop_offset, ) start_offset = stop_offset shard = [x._get_parentage().root for x in shard] result.append(shard) flattened_result = sequencetools.flatten_sequence(result) flattened_result = selectiontools.SliceSelection(flattened_result) prototype = (spannertools.Tie,) parentage = self._get_parentage() if parentage._get_spanners(prototype=prototype): selection = select(flattened_result) for component in selection: # TODO: make top-level detach() work here for spanner in component._get_spanners(prototype): spanner._sever_all_components() #detach(prototype, component) # replace leaf with flattened result selection = selectiontools.SliceSelection(self) parent, start, stop = selection._get_parent_and_start_stop_indices() if parent: parent.__setitem__(slice(start, stop + 1), flattened_result) else: selection._give_dominant_spanners(flattened_result) selection._withdraw_from_crossing_spanners() # fracture spanners if fracture_spanners: first_shard = result[0] for spanner in first_shard[-1]._get_spanners(): index = spanner._index(first_shard[-1]) spanner._fracture(index, direction=Right) last_shard = result[-1] for spanner in last_shard[0]._get_spanners(): index = spanner._index(last_shard[0]) spanner._fracture(index, direction=Left) for middle_shard in result[1:-1]: for spanner in middle_shard[0]._get_spanners(): index = spanner._index(middle_shard[0]) spanner._fracture(index, direction=Left) for spanner in middle_shard[-1]._get_spanners(): index = spanner._index(middle_shard[-1]) spanner._fracture(index, direction=Right) # adjust first leaf first_leaf = flattened_result[0] self._detach_grace_containers(kind='after') # adjust any middle leaves for middle_leaf in flattened_result[1:-1]: middle_leaf._detach_grace_containers(kind='grace') self._detach_grace_containers(kind='after') detach(object, middle_leaf) # adjust last leaf last_leaf = flattened_result[-1] last_leaf._detach_grace_containers(kind='grace') detach(object, last_leaf) # tie split notes, rests and chords as specified if pitchtools.Pitch.is_pitch_carrier(self) and tie_split_notes: flattened_result_leaves = iterate(flattened_result).by_class( scoretools.Leaf) # TODO: implement SliceSelection._attach_tie_spanner_to_leaves() for leaf_pair in sequencetools.iterate_sequence_nwise( flattened_result_leaves): selection = selectiontools.ContiguousSelection(leaf_pair) selection._attach_tie_spanner_to_leaf_pair( use_messiaen_style_ties=use_messiaen_style_ties, ) # return result return result
def list_numbered_interval_numbers_pairwise(pitch_carriers, wrap=False): r'''Lists numbered interval numbers pairwise between `pitch_carriers`. :: >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8") .. doctest:: >>> f(staff) \new Staff { c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8 } :: >>> pitchtools.list_numbered_interval_numbers_pairwise(staff[:]) [2, 2, 1, 2, 2, 2, 1] :: >>> pitchtools.list_numbered_interval_numbers_pairwise( ... staff[:], wrap=True) [2, 2, 1, 2, 2, 2, 1, -12] :: >>> notes = [ ... Note("c'8"), Note("d'8"), Note("e'8"), Note("f'8"), ... Note("g'8"), Note("a'8"), Note("b'8"), Note("c''8"), ... ] :: >>> notes.reverse() :: >>> pitchtools.list_numbered_interval_numbers_pairwise(notes) [-1, -2, -2, -2, -1, -2, -2] :: >>> pitchtools.list_numbered_interval_numbers_pairwise( ... notes, wrap=True) [-1, -2, -2, -2, -1, -2, -2, 12] When ``wrap = False`` do not return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series. When ``wrap = True`` do return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series. Returns list. ''' from abjad.tools import pitchtools result = [] if len(pitch_carriers) == 0: return result elif len(pitch_carriers) == 1: if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]): return result else: message = 'must be pitch, not, note-head or chord.' raise TypeError(message) pairs = sequencetools.iterate_sequence_nwise(pitch_carriers, wrapped=wrap) pairs = list(pairs) for first_carrier, second_carrier in pairs: first_pitch = pitchtools.NamedPitch.from_pitch_carrier(first_carrier) second_pitch = pitchtools.NamedPitch.from_pitch_carrier(second_carrier) signed_interval = \ pitchtools.NumberedPitch(second_pitch).pitch_number - \ pitchtools.NumberedPitch(first_pitch).pitch_number result.append(signed_interval) return result
def _apply_spanners(self, leaves): spanner_references = { spannertools.Beam: None, spannertools.Slur: None, } first_leaf = leaves[0] for leaf, next_leaf in \ sequencetools.iterate_sequence_nwise(leaves, wrapped=True): span_events = self._get_span_events(leaf) for current_class, directions in span_events.items(): starting, stopping = [], [] for direction in directions: if direction == Left: starting.append(Left) else: stopping.append(Right) # apply undirected events immediately, # and do not maintain a reference to them if current_class is spannertools.Tie: if next_leaf is first_leaf: message = 'unterminated {} at {}.' message = message.format(current_class.__name__, leaf) raise Exception(message) previous_tie = [ x for x in leaf._get_spanners() if isinstance(x, spannertools.Tie) ] if previous_tie: previous_tie[0]._append(next_leaf) else: tie = spannertools.Tie() attach(tie, (leaf, next_leaf)) elif current_class is spannertools.Beam: # A beam may begin and end on the same leaf # but only one beam spanner may cover any given leaf, # and starting events are processed before ending ones for _ in starting: if spanner_references[current_class] is not None: message = 'already have beam.' raise Exception(message) else: spanner_references[current_class] = current_class() for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None elif current_class is spannertools.Slur: # Slurs process stop events before start events, # they must contain more than one leaf, # but they can stop on a leaf and start on the same leaf. for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None else: message = 'can not end: {}.' message = message.format(current_class.__name) raise Exception(message) for _ in starting: if spanner_references[current_class] is None: spanner_references[current_class] = current_class() else: message = 'already have: {}.' message = message.format(current_class.__name) raise Exception(message) # append leaf to all tracked spanners, for current_class, instance in spanner_references.items(): if instance is not None: instance._append(leaf) # check for unterminated spanners for current_class, instance in spanner_references.items(): if instance is not None: message = 'unterminated {}.' message = message.format(current_class.__name__) raise Exception(message)