Beispiel #1
0
def offset_increment(elt):
    if is_backup(elt):
        return -1
    elif is_forward(elt):
        return 1
    elif is_grace(elt):
        return 0
    elif is_note_or_chord(elt):
        return 1
    else:
        return None
Beispiel #2
0
def filter_by_voice_name(measure_list, voice_name):
    from copy import deepcopy
    from measure.measure import Measure
    result = []
    for measure in measure_list:
        elts = measure.elements
        new_measure = measure.copy()
        new_measure.elements = []
        for elt in elts:
            if is_note_or_chord(elt):
                if elt.lily_voice == voice_name:
                    new_measure.elements.append(elt)
            # else:
            #     new_measure.elements.append(elt)
        result.append(new_measure)
    voice = Voice(name=voice_name, measures=result)
    return voice
def associate_directions_with_note_events(measure_list):
    from copy import deepcopy
    from music_data.direction import DirectionsRegister

    # Every element in result which is not a top-level musicevent
    # (i.e. a Note or rest), needs to be attached/appended to a
    # top-level musicevent.
    new_measure_list = []
    # Pending Directions, such as Wedge, Words, Slide.

    for measure in measure_list:

        new_elements = []
        pre_note_directions = []
        last_note_event = None

        for elt in measure.elements:
            # If elt is a NoteElement, check if there are any pending
            # directions to collect
            if is_note_or_chord(elt) and not elt.is_non_printing_object:
                elt.directions = DirectionsRegister()
                last_note_event = elt
                # Attach Directions if their offset is greater than
                # the offset of the current element.
                if pre_note_directions:
                    insert, pre_note_directions = partition_by_offset(
                        pre_note_directions, elt.measure_offset)
                    elt.directions.extend(insert)
                new_elements.append(elt)

            elif is_direction(elt):
                pre_note_directions.append(elt)

            else:
                new_elements.append(elt)
        # At the end of the Measure, gather all pending Directions
        # and attach them to the last active NoteElement
        if pre_note_directions:
            if last_note_event:
                last_note_event.directions.extend(pre_note_directions)
            pre_note_directions = []

        measure.elements = new_elements
        new_measure_list.append(measure)

    return new_measure_list
def associate_directions_with_note_events(measure_list):
    from copy import deepcopy
    from music_data.direction import DirectionsRegister

    # Every element in result which is not a top-level musicevent
    # (i.e. a Note or rest), needs to be attached/appended to a
    # top-level musicevent.
    new_measure_list = []
    # Pending Directions, such as Wedge, Words, Slide.
     
    for measure in measure_list:

        new_elements = []
        pre_note_directions = []
        last_note_event = None

        for elt in measure.elements:
            # If elt is a NoteElement, check if there are any pending
            # directions to collect
            if is_note_or_chord(elt) and not elt.is_non_printing_object:
                elt.directions = DirectionsRegister()
                last_note_event = elt
                # Attach Directions if their offset is greater than
                # the offset of the current element. 
                if pre_note_directions:
                    insert, pre_note_directions = partition_by_offset(
                        pre_note_directions, elt.measure_offset)
                    elt.directions.extend(insert)
                new_elements.append(elt)

            elif is_direction(elt):
                pre_note_directions.append(elt)

            else:
                new_elements.append(elt)
        # At the end of the Measure, gather all pending Directions
        # and attach them to the last active NoteElement
        if pre_note_directions:
            if last_note_event:
                last_note_event.directions.extend(pre_note_directions)
            pre_note_directions = [] 

        measure.elements = new_elements
        new_measure_list.append(measure)

    return new_measure_list
Beispiel #5
0
def filter_by_voice_name(measure_list, voice_name):
    from copy import deepcopy
    from measure.measure import Measure
    result = []
    for measure in measure_list:
        elts = measure.elements
        new_measure = measure.copy()
        new_measure.elements = []
        for elt in elts:
            if is_note_or_chord(elt):
                if elt.lily_voice == voice_name:
                    new_measure.elements.append(elt)
            # else:
            #     new_measure.elements.append(elt)
        result.append(new_measure)
    voice = Voice(name=voice_name, measures=result)
    return voice
Beispiel #6
0
    def group_voices(self, measures):

        self.staff_type = get_staff_type(self)

        voice_numbers = []
        for measure in measures:
            for elt in measure.elements:
                if is_note_or_chord(elt):
                    voice = elt.lily_voice
                    if voice is not None and not voice in voice_numbers:
                        voice_numbers.append(voice)

        voices = []
        for voice_number in voice_numbers:
            voice = filter_by_voice_name(measures, voice_number)
            voice.part = self
            voices.append(voice)

        return voices
Beispiel #7
0
    def group_voices(self, measures):

        self.staff_type = get_staff_type(self)

        voice_numbers = []
        for measure in measures:
            for elt in measure.elements:
                if is_note_or_chord(elt):
                    voice = elt.lily_voice
                    if voice is not None and not voice in voice_numbers:
                        voice_numbers.append(voice)

        voices = []
        for voice_number in voice_numbers:
            voice = filter_by_voice_name(measures, voice_number)
            voice.part = self
            voices.append(voice)

        return voices
def add_skips_to_voice(voice):
    '''
    Loop through all measures in the measure_list of the current voice.
    We know the offsets of every durated element in this list and need
    to "fill the gaps" inbetween them with Skips to keep all the voices
    in sync. This is a potentially dangerous operation and a seemingly
    rich source of bugs -- be careful.
    '''

    new_measure_list = []
    curr_time_signature = None

    for measure in voice.measures:

        # 'offset' is a counter which keep track of the current
        # position in this measure. It is incremented by all elements
        # which have a 'duration' attribute, otherwise ignored.
        offset = 0
        new_elements = []

        # Keep track of current time signature. This is needed when an
        # empty measure is encountered, in which case we need to insert
        # a skip with the same length as the measure.
        if measure.time_signature is not None:
            curr_time_signature = measure.time_signature

        # CASE #1: Empty measure; no durated elements can be found.
        # Insert a skip of the same duration as the current time signature.
        if not measure.has_any_durated_element:

            # First, add all elements (Attributes etc.)...
            for elt in measure.elements:
                new_elements.append(elt)

            # ...then, append the Skip, filling the measure completely.
            skip = Skip(duration=curr_time_signature.duration_as_fraction)
            new_elements.append(skip)

        # CASE #2: There are one or more durated elements in this measure.
        else:

            for elt in measure.elements:

                # If we are dealing with a durated element (either a NoteElement,
                # BackupElement of ForwardElement), we now need to calculate the
                # difference between the current and previous offset. ('offset'
                # is set by the function xml2ly.part.set_measure_list_offsets --
                # if any weird behavior is encountered, please check that one as well.)
                if is_note_or_chord(elt):

                    diff = elt.measure_offset - offset
                    # Get the endpoint of this element by adding its duration
                    # to its offset. Multiply the duration with the element's
                    # time_modification to get the actual duration (this is necessary
                    # when dealing with tuplets and nested tuplets.
                    offset = elt.measure_offset + (
                        elt.duration_as_fraction / elt.time_modification_as_fraction)

                    # If the difference between this element's offset and the
                    # position in the measure which the counter is currently at,
                    # it probably means that we're dealing with a voice which doesn't
                    # start at the beginning of the piece. In this case, we need to
                    # add skips to keep up with the other voices in this staff, such
                    # that the different voices are perfectly 'aligned' at the end
                    # of every measure.
                    if diff > 0:
                        skip = Skip(duration=Fraction(diff))
                        new_elements.append(skip)
                    new_elements.append(elt)

                else:
                    new_elements.append(elt)

        # Copy the current measure, minus its elements...
        measure.elements = None
        new_measure = measure.copy()

        # ...and add the new elements.
        new_measure.elements = new_elements

        # Finally, append the result to the top-level variable 'new_measure_list',
        # which contains all measures in the current voice.
        new_measure_list.append(new_measure)

    return new_measure_list