示例#1
0
def glyph_to_element(classifier, glyph, surface):
    '''
    Translates a glyph as output by the pitchfinder into an MEI element, registering bounding boxes
    in the given surface.

    Currently the assumption is that no MEI information in the given classifier is more than one
    level deep - that is, everything is either a single element (clef, custos) or the child of a
    single element (neumes).
    '''
    name = str(glyph['name'])
    try:
        xml = classifier[name]
    except KeyError:
        print('entry {} not found in classifier table!'.format(name))
        return None

    # remove everything up to the first dot in the name of the glyph
    try:
        name = name[:name.index('.')]
    except ValueError:
        pass

    # if this is an element with no children, then just apply a pitch and position to it
    if not list(xml):
        return create_primitive_element(xml, glyph, surface)

    # else, this element has at least one child (is a neume)
    ncs = list(xml)
    els = [create_primitive_element(nc, glyph, surface) for nc in ncs]
    parent = MeiElement(xml.tag)
    parent.setChildren(els)

    if len(els) < 2:
        return parent

    # if there's more than one element, must resolve intervals between ncs
    for i in range(1, len(els)):
        prev_nc = parent.children[i - 1]
        cur_nc = parent.children[i]
        new_pname, new_octave = resolve_interval(prev_nc, cur_nc)
        cur_nc.addAttribute('pname', new_pname)
        cur_nc.addAttribute('oct', new_octave)
        cur_nc.removeAttribute('intm')

    return parent
示例#2
0
    def neumify(self, ids, type_id, liquescence, head_shapes, ulx, uly, lrx, lry):
        '''
        Neumify a group of neumes (with provided ids)
        and give it the given neume name. Also update
        bounding box information.
        '''
        
        # get neume name and variant from type id
        type_split = type_id.split(".")
        if type_split[-1].isdigit():
             type_split.pop()

        if len(type_split) == 1:
            attrs = [MeiAttribute("name", type_split[0])]
        else:
            variant = " ".join(type_split[1:])
            attrs = [MeiAttribute("name", type_split[0]), MeiAttribute("variant", variant)]

        '''
        # need to determine how to encode these different types of liquescence in the MEI document
        if liquescence:
            if liquescence == "alt":
                attrs.append(MeiAttribute("variant", "liquescence"))
            elif liquescence == "aug":
                attrs.append(MeiAttribute("variant", "liquescence_aug"))
            elif liquescence == "dim":
                attrs.append(MeiAttribute("variant", "liquescence_dim"))
        '''

        new_neume = MeiElement("neume")
        new_neume.setAttributes(attrs)
        ncs = []
        cur_nc = None

        iNote = 0
        for id in ids:
            ref_neume = self.mei.getElementById(str(id))
            if ref_neume:
                # get underlying notes
                notes = ref_neume.getDescendantsByName("note")
                for n in notes:
                    head = str(head_shapes[iNote])
                    # check if a new nc must be opened
                    if head == 'punctum' and cur_nc != 'punctum':
                        ncs.append(MeiElement("nc"))
                        cur_nc = head
                    elif head == 'punctum_inclinatum' and cur_nc != 'punctum_inclinatum':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("inclinatum", "true")
                        ncs.append(new_nc)
                        cur_nc = head
                    elif head == 'punctum_inclinatum_parvum' and cur_nc != 'punctum_inclinatum_parvum':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("inclinatum", "true")
                        new_nc.addAttribute("deminutus", "true")
                        ncs.append(new_nc)
                        cur_nc = head 
                    elif head == 'quilisma' and cur_nc != 'quilisma':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("quilisma", "true")
                        ncs.append(new_nc)
                        cur_nc = head
                    elif cur_nc is None:
                        ncs.append(MeiElement("nc"))
                        cur_nc = 'punctum'

                    ncs[-1].addChild(n)
                    iNote += 1

        new_neume.setChildren(ncs)

        # insert the new neume
        before = self.mei.getElementById(ids[0])
        parent = before.getParent()

        if before and parent:
            parent.addChildBefore(before, new_neume)

        # remove the old neumes from the mei document
        for id in ids:
            neume = self.mei.getElementById(str(id))
            if neume:
                # remove facs data
                facs = neume.getAttribute("facs")
                if facs:
                    facsid = facs.value
                    # Remove the zone if it exists
                    zone = self.mei.getElementById(str(facsid))
                    if zone and zone.name == "zone":
                        zone.parent.removeChild(zone)

                # now remove the neume
                neume.parent.removeChild(neume)

        # update bounding box data
        self.update_or_add_zone(new_neume, ulx, uly, lrx, lry)

        result = {"id": new_neume.getId()}
        return result
示例#3
0
    def neumify(self, ids, type_id, head_shapes, ulx, uly, lrx, lry):
        '''
        Neumify a group of neumes (with provided ids)
        and give it the given neume name. Also update
        bounding box information.
        '''
        # get neume name and variant from type id
        type_split = type_id.split(".")
        if type_split[-1].isdigit():
            type_split.pop()
        if len(type_split) == 1:
            attrs = [MeiAttribute("name", type_split[0])]
        else:
            variant = " ".join(type_split[1:])
            attrs = [
                MeiAttribute("name", type_split[0]),
                MeiAttribute("variant", variant)
            ]

        new_neume = MeiElement("neume")
        new_neume.setAttributes(attrs)
        ncs = []
        cur_nc = None

        iNote = 0
        for id in ids:
            ref_neume = self.mei.getElementById(str(id))
            if ref_neume:
                # get underlying notes
                notes = ref_neume.getDescendantsByName("note")
                for n in notes:
                    head = str(head_shapes[iNote])
                    # check if a new nc must be opened
                    if head == 'punctum' and cur_nc != 'punctum':
                        ncs.append(MeiElement("nc"))
                        cur_nc = head
                    elif head == 'punctum_inclinatum' and cur_nc != 'punctum_inclinatum':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("inclinatum", "true")
                        ncs.append(new_nc)
                        cur_nc = head
                    elif head == 'punctum_inclinatum_parvum' and cur_nc != 'punctum_inclinatum_parvum':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("inclinatum", "true")
                        new_nc.addAttribute("deminutus", "true")
                        ncs.append(new_nc)
                        cur_nc = head
                    elif head == 'quilisma' and cur_nc != 'quilisma':
                        new_nc = MeiElement("nc")
                        new_nc.addAttribute("quilisma", "true")
                        ncs.append(new_nc)
                        cur_nc = head
                    elif cur_nc is None:
                        ncs.append(MeiElement("nc"))
                        cur_nc = 'punctum'

                    ncs[-1].addChild(n)
                    iNote += 1

        new_neume.setChildren(ncs)

        # insert the new neume
        before = self.mei.getElementById(ids[0])
        parent = before.getParent()

        if before and parent:
            parent.addChildBefore(before, new_neume)

        # remove the old neumes from the mei document
        for id in ids:
            neume = self.mei.getElementById(str(id))
            if neume:
                # remove facs data
                facs = neume.getAttribute("facs")
                if facs:
                    facsid = facs.value
                    # Remove the zone if it exists
                    zone = self.mei.getElementById(str(facsid))
                    if zone and zone.name == "zone":
                        zone.parent.removeChild(zone)

                # now remove the neume
                neume.parent.removeChild(neume)

        # update bounding box data
        self.update_or_add_zone(new_neume, ulx, uly, lrx, lry)

        result = {"id": new_neume.getId()}
        return result