Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# this covers the case in which a single voice was quantized, some notes overlapped so it had to be split in
# two, and the two voices were forced to share the same divisor. If this is one of those voices and it ended up
# empty for this beat, or with a note that spanned the whole beat, divisor should just be None
if all(note.pitch is None for note in beat_notes) or len(beat_notes) == 1:
divisor = None
else:
divisor = beat_quantization.divisor
if divisor is None:
# if there's no beat divisor, then it should just be a note or rest of the full length of the beat
assert len(beat_notes) == 1
pitch, length, properties = beat_notes[0].pitch, beat_notes[0].length, beat_notes[0].properties
if _is_single_note_length(length):
return [NoteLike(pitch, length, properties)]
else:
constituent_lengths = _length_to_undotted_constituents(length)
return [NoteLike(pitch, l, properties) for l in constituent_lengths]
# otherwise, if the divisor requires a tuplet, we construct it
tuplet = Tuplet.from_length_and_divisor(beat_quantization.length, divisor) if divisor is not None else None
dilation_factor = 1 if tuplet is None else tuplet.dilation_factor()
written_division_length = beat_quantization.length / divisor * dilation_factor
# these versions go from small to big prime factors and vice-versa
# so for one 6 is 3x2, for the other it's 2x3. We try both options in case one fits better
beat_division_hierarchy = _get_beat_division_hierarchy(beat_quantization.length, divisor)
beat_division_hierarchy2 = _get_beat_division_hierarchy(beat_quantization.length, divisor, False)
# if they're identical (e.g. if there's only one type of prime anyway) we only need to care about one version
written_length_components = [
(div_point - last_div_point) * written_division_length
for last_div_point, div_point in zip(division_points[:-1], division_points[1:])
]
note_parts = []
remainder = note
for segment_length in written_length_components:
split_note = remainder.split_at_beat(remainder.start_beat + segment_length / dilation_factor)
if len(split_note) > 1:
this_segment, remainder = split_note
else:
this_segment = split_note[0]
note_parts.append(NoteLike(this_segment.pitch, segment_length, this_segment.properties))
note_list.extend(note_parts)
return [tuplet] if tuplet is not None else note_list
def __init__(self, tuplet_divisions: int, normal_divisions: int, division_length: float,
contents: Sequence['NoteLike'] = None):
ScoreContainer.__init__(self, contents, "contents", NoteLike,
("tuplet_divisions", "normal_divisions", "division_length"))
self.tuplet_divisions = tuplet_divisions
self.normal_divisions = normal_divisions
self.division_length = division_length
# empty for this beat, or with a note that spanned the whole beat, divisor should just be None
if all(note.pitch is None for note in beat_notes) or len(beat_notes) == 1:
divisor = None
else:
divisor = beat_quantization.divisor
if divisor is None:
# if there's no beat divisor, then it should just be a note or rest of the full length of the beat
assert len(beat_notes) == 1
pitch, length, properties = beat_notes[0].pitch, beat_notes[0].length, beat_notes[0].properties
if _is_single_note_length(length):
return [NoteLike(pitch, length, properties)]
else:
constituent_lengths = _length_to_undotted_constituents(length)
return [NoteLike(pitch, l, properties) for l in constituent_lengths]
# otherwise, if the divisor requires a tuplet, we construct it
tuplet = Tuplet.from_length_and_divisor(beat_quantization.length, divisor) if divisor is not None else None
dilation_factor = 1 if tuplet is None else tuplet.dilation_factor()
written_division_length = beat_quantization.length / divisor * dilation_factor
# these versions go from small to big prime factors and vice-versa
# so for one 6 is 3x2, for the other it's 2x3. We try both options in case one fits better
beat_division_hierarchy = _get_beat_division_hierarchy(beat_quantization.length, divisor)
beat_division_hierarchy2 = _get_beat_division_hierarchy(beat_quantization.length, divisor, False)
# if they're identical (e.g. if there's only one type of prime anyway) we only need to care about one version
if beat_division_hierarchy == beat_division_hierarchy2:
beat_division_hierarchy2 = None
def iterate_notes(self, include_rests: bool = False) -> Iterator['NoteLike']:
"""
Iterate through the notes (and possibly rests) within this Voice
:param include_rests: Whether or not to include rests
"""
for note_or_tuplet in self.contents:
if isinstance(note_or_tuplet, NoteLike):
if include_rests or not note_or_tuplet.is_rest():
yield note_or_tuplet
else:
for note in note_or_tuplet.contents:
if include_rests or not note.is_rest():
yield note
def __init__(self, contents: Sequence[Union['Tuplet', 'NoteLike']], time_signature: TimeSignature):
ScoreContainer.__init__(self, contents, "contents", (Tuplet, NoteLike), ("time_signature", ))
self.time_signature = time_signature
def _attach_articulations_to_xml_note_group(self, xml_note_group):
if len(xml_note_group) > 1:
# there's a gliss, and xml_note_group contains the main note followed by grace notes
attack_notehead = xml_note_group[0] if not self.properties.ends_tie() else None
release_notehead = xml_note_group[-1] if not self.properties.starts_tie() else None
inner_noteheads = xml_note_group[1 if attack_notehead is not None else 0:
-1 if release_notehead is not None else None]
# only attach attack articulations to the main note
if attack_notehead is not None:
for articulation in self._get_attack_articulations():
NoteLike._attach_articulation_to_xml_note_or_chord(articulation, attack_notehead)
# attach inner articulations to inner grace notes
for articulation in self._get_inner_articulations():
for inner_grace_note in inner_noteheads:
NoteLike._attach_articulation_to_xml_note_or_chord(articulation, inner_grace_note)
# attach release articulations to the last grace note
if release_notehead is not None:
for articulation in self._get_release_articulations():
NoteLike._attach_articulation_to_xml_note_or_chord(articulation, release_notehead)
else:
# just a single notehead, so attach all articulations
for articulation in self.properties.articulations:
NoteLike._attach_articulation_to_xml_note_or_chord(articulation, xml_note_group[0])