コード例 #1
0
ファイル: meielement_test.py プロジェクト: lpugin/libmei
 def test_removechild(self):
     p = MeiElement("layer")
     el1 = MeiElement("note")
     el2 = MeiElement("note")
     
     p.addChild(el1)
     p.addChild(el2)
     
     self.assertEqual(2, len(p.children))
     p.removeChild(el1)
     self.assertEqual(1, len(p.children))
コード例 #2
0
ファイル: meielement_test.py プロジェクト: yrammos/libmei
    def test_removechild(self):
        p = MeiElement("layer")
        el1 = MeiElement("note")
        el2 = MeiElement("note")

        p.addChild(el1)
        p.addChild(el2)

        self.assertEqual(2, len(p.children))
        p.removeChild(el1)
        self.assertEqual(1, len(p.children))
コード例 #3
0
ファイル: meidocument_test.py プロジェクト: lpugin/libmei
    def test_flattenedtree(self):
        mei = MeiElement("mei")
        mus = MeiElement("music")
        body = MeiElement("body")
        staff = MeiElement("staff")
        staff2 = MeiElement("staff")
        n1 = MeiElement("note")
        n2 = MeiElement("note")
        n3 = MeiElement("note")

        doc = MeiDocument()

        mei.addChild(mus)

        doc.root = mei

        mus.addChild(body)
        body.addChild(staff)
        body.addChild(staff2)
        staff.addChild(n1)
        staff.addChild(n2)
        staff2.addChild(n3)

        doc.lookBack(n2, "mei")
        self.assertEqual(8, len(doc.getFlattenedTree()))

        staff.removeChild(n2)
        self.assertEqual(7, len(doc.getFlattenedTree()))

        self.assertEqual(staff2, doc.getFlattenedTree()[5])

        staff.removeChildrenWithName("note")
        self.assertEqual(6, len(doc.getFlattenedTree()))

        body.deleteAllChildren()
        self.assertEqual(3, len(doc.getFlattenedTree()))

        children = MeiElementList()
        staff3 = MeiElement("staff")
        staff4 = MeiElement("staff")
        children.append(staff3)
        children.append(staff4)

        body.children = children

        self.assertEqual(5, len(doc.getFlattenedTree()))

        elements = [mei, mus, body, staff3, staff4]

        for i,el in enumerate(doc.getFlattenedTree()):
            self.assertEqual(elements[i], doc.getFlattenedTree()[i])
コード例 #4
0
ファイル: meidocument_test.py プロジェクト: sunnylin0/libmei
    def test_flattenedtree(self):
        mei = MeiElement("mei")
        mus = MeiElement("music")
        body = MeiElement("body")
        staff = MeiElement("staff")
        staff2 = MeiElement("staff")
        n1 = MeiElement("note")
        n2 = MeiElement("note")
        n3 = MeiElement("note")

        doc = MeiDocument()

        mei.addChild(mus)

        doc.root = mei

        mus.addChild(body)
        body.addChild(staff)
        body.addChild(staff2)
        staff.addChild(n1)
        staff.addChild(n2)
        staff2.addChild(n3)

        doc.lookBack(n2, "mei")
        self.assertEqual(8, len(doc.getFlattenedTree()))

        staff.removeChild(n2)
        self.assertEqual(7, len(doc.getFlattenedTree()))

        self.assertEqual(staff2, doc.getFlattenedTree()[5])

        staff.removeChildrenWithName("note")
        self.assertEqual(6, len(doc.getFlattenedTree()))

        body.deleteAllChildren()
        self.assertEqual(3, len(doc.getFlattenedTree()))

        children = MeiElementList()
        staff3 = MeiElement("staff")
        staff4 = MeiElement("staff")
        children.append(staff3)
        children.append(staff4)

        body.children = children

        self.assertEqual(5, len(doc.getFlattenedTree()))

        elements = [mei, mus, body, staff3, staff4]

        for i, el in enumerate(doc.getFlattenedTree()):
            self.assertEqual(elements[i], doc.getFlattenedTree()[i])
コード例 #5
0
ファイル: meidocument_test.py プロジェクト: lpugin/libmei
    def test_elementbyid(self):
        mei = MeiElement("mei")
        mus = MeiElement("music")
        body = MeiElement("body")
        staff = MeiElement("staff")
        staff2 = MeiElement("staff")
        n1 = MeiElement("note")
        wantedId = n1.id
        n2 = MeiElement("note")
        n3 = MeiElement("note")
        n4 = MeiElement("note")

        mei.addChild(mus)
        mus.addChild(body)
        body.addChild(staff)
        body.addChild(staff2)
        staff.addChild(n1)
        staff.addChild(n2)
        staff.addChild(n3)
        staff2.addChild(n4)

        doc = MeiDocument()
        self.assertEqual(None, doc.getElementById(wantedId))

        doc.root = mei

        self.assertEqual(n1, doc.getElementById(wantedId))

        self.assertEqual(None, doc.getElementById("unknownID"))

        n5 = MeiElement("note")
        newid = n5.id
        staff2.addChild(n5)

        self.assertEqual(n5, doc.getElementById(newid))
        staff2.removeChild(n5)
        self.assertEqual(None, doc.getElementById(newid))
コード例 #6
0
ファイル: meidocument_test.py プロジェクト: sunnylin0/libmei
    def test_elementbyid(self):
        mei = MeiElement("mei")
        mus = MeiElement("music")
        body = MeiElement("body")
        staff = MeiElement("staff")
        staff2 = MeiElement("staff")
        n1 = MeiElement("note")
        wantedId = n1.id
        n2 = MeiElement("note")
        n3 = MeiElement("note")
        n4 = MeiElement("note")

        mei.addChild(mus)
        mus.addChild(body)
        body.addChild(staff)
        body.addChild(staff2)
        staff.addChild(n1)
        staff.addChild(n2)
        staff.addChild(n3)
        staff2.addChild(n4)

        doc = MeiDocument()
        self.assertEqual(None, doc.getElementById(wantedId))

        doc.root = mei

        self.assertEqual(n1, doc.getElementById(wantedId))

        self.assertEqual(None, doc.getElementById("unknownID"))

        n5 = MeiElement("note")
        newid = n5.id
        staff2.addChild(n5)

        self.assertEqual(n5, doc.getElementById(newid))
        staff2.removeChild(n5)
        self.assertEqual(None, doc.getElementById(newid))
コード例 #7
0
ファイル: AomrMeiOutput.py プロジェクト: agpar/Rodan
class AomrMeiOutput(object):
    # define the form of a neume.
    # form: [ num, interval_dir... ]
    # e.g., clivis: [2, 'd']
    # torculus: [3, 'u', 'd']
    NEUME_NOTES = {
        'punctum': [],
        'virga': [],
        'cephalicus': ['d'],
        'clivis': ['d'],
        'epiphonus': ['u'],
        'podatus': ['u'],
        'porrectus': ['d', 'u'],
        'salicus': ['u', 'u'],
        'scandicus': ['u', 'u'],
        'torculus': ['u', 'd'],
        'ancus': ['d', 'd'],  # See note 1 below
    }

    # given an alternate form, how many notes does it add to the neume?
    ADD_NOTES = {
        'flexus': ['d'],  # scandicus.flexus, porrectus.flexus
        'resupinus': ['u'],  # torculus.resupinus
    }

    SCALE = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

    def __init__(self, incoming_data, original_image, page_number=None):
        self._recognition_results = incoming_data
        # self.mei = mod.mei_()
        self.mei = MeiElement("mei")
        self.staff = None

        # Hack: I'm not sure what staff_num is. In any case it's strange to set it to None.
        # I therefore set it to 0 if page_number is None.
        if page_number is not None:
            self.staff_num = int(page_number)
        else:
            self.staff_num = 0
        self.glyph = None

        self._note_elements = None
        self._neume_pitches = []

        # set up a basic MEI document structure

        # header
        # self.meihead = mod.meiHead_()
        self.meihead = MeiElement("meiHead")
        # self.filedesc = mod.fileDesc_()
        self.filedesc = MeiElement("fileDesc")
        # self.titlestmt = mod.titleStmt_()
        self.titlestmt = MeiElement("titleStmt")
        # self.title = mod.title_()
        self.title = MeiElement("title")
        # self.pubstmt = mod.pubStmt_()
        self.pubstmt = MeiElement("pubStmt")

        self.titlestmt.addChild(self.title)

        self.filedesc.addChild(self.titlestmt)
        self.filedesc.addChild(self.pubstmt)

        self.meihead.addChild(self.filedesc)
        self.mei.addChild(self.meihead)

        # music
        # self.music = mod.music_()
        self.music = MeiElement("music")
        self.facsimile = self._create_facsimile_element()
        self.surface = self._create_surface_element()
        self.graphic = self._create_graphic_element(original_image)
        lg.debug("SELF GRAPHIC:{0}".format(
            XmlExport.meiElementToText(self.graphic)))

        self.surface.addChild(self.graphic)
        self.facsimile.addChild(self.surface)
        self.music.addChild(self.facsimile)

        self.layout = self._create_layout_element()
        self.pg = self._create_page_element()
        if page_number:
            # self.pg.attributes = {"n": page_number}
            self.pg.addAttribute("n", page_number)

        self.layout.addChild(self.pg)
        self.music.addChild(self.layout)

        # self.body = mod.body_()
        self.body = MeiElement("body")
        self.music.addChild(self.body)

        self.mdiv = MeiElement("mdiv")
        # self.mdiv = mod.mdiv_()
        self.mdiv.addAttribute("type", "solesmes")
        self.body.addChild(self.mdiv)

        # self.score = mod.score_()
        self.score = MeiElement("score")
        self.mdiv.addChild(self.score)

        # self.scoredef = mod.scoreDef_()
        self.scoredef = MeiElement("scoreDef")
        self.score.addChild(self.scoredef)

        # self.section = mod.section_()
        self.section = MeiElement("section")
        self.pagebreak = self._create_pb_element()
        # self.pagebreak.attributes = {"pageref": self.pg.id}
        self.pagebreak.addAttribute("pageref", self.pg.id)

        self.section.addChild(self.pagebreak)
        self.score.addChild(self.section)

        self.staffgrp = self._create_staffgrp_element()
        self.staffdef = self._create_staffdef_element()
        self.staffdef.addAttribute("n", str(self.staff_num))  # trouble

        self.staffgrp.addChild(self.staffdef)
        self.scoredef.addChild(self.staffgrp)

        self.layer = self._create_layer_element()
        self.layer.addAttribute("n", "1")

        self.staffel = self._create_staff_element()
        self.staffel.addAttribute("n", str(self.staff_num))  # trouble
        self.section.addChild(self.staffel)
        self.staffel.addChild(self.layer)

        for sysnum in sorted(self._recognition_results.keys()):
            syst = self._recognition_results[sysnum]
            lg.debug("sysnum:{0}".format(sysnum))
            self.system = syst
            self.systembreak = self._parse_system(sysnum, syst)
            # z = mod.zone_()
            z = MeiElement("zone")
            # z.id = self._idgen()
            # z.attributes = {'ulx': self.system['coord'][0], 'uly': self.system['coord'][1], \
            #                     'lrx': self.system['coord'][2], 'lry': self.system['coord'][3]}
            z.addAttribute("ulx", str(self.system['coord'][0]))
            z.addAttribute("uly", str(self.system['coord'][1]))
            z.addAttribute("lrx", str(self.system['coord'][2]))
            z.addAttribute("lry", str(self.system['coord'][3]))
            self.surface.addChild(z)
            # self.system.facs = z.id
            s = self._create_system_element()
            s.facs = z.id
            s.addAttribute("facs", s.facs)
            self.pg.addChild(s)
            self.systembreak.addAttribute("systemref", s.id)

        self.mei.addChild(self.music)

        # if not self.staffel.descendants_by_name('neume'):
        if not self.staffel.getDescendantsByName("neume"):
            self.staffgrp.removeChild(self.staffdef)
            self.section.removeChild(self.staffel)

        # self.md = MeiDocument.MeiDocument()
        # self.md.addelement(self.mei)
        self.md = MeiDocument()
        self.md.setRootElement(self.mei)
        print XmlExport.meiElementToText(
            self.md.getElementById(self.graphic.getId()))

    def _parse_system(self, sysnum, syst):
        sysbrk = self._create_sb_element()
        # sysbrk.attributes = {"n": sysnum + 1}
        sysnum = int(sysnum)
        sysbrk.addAttribute("n", "%d" % (sysnum + 1))
        self.layer.addChild(sysbrk)
        # staffel = self._create_staff_element()
        # staffel.addAttribute("n", stfnum)

        for c in self.system['content']:
            # parse the glyphs per staff.
            self.glyph = c
            if c['type'] == 'neume':
                if not self.glyph['form']:
                    lg.debug("Skipping glyph: {0}".format(self.glyph))
                    continue
                if self.glyph['form'][0] not in self.NEUME_NOTES.keys():
                    continue
                else:
                    self.layer.addChild(self._create_neume_element())

            elif c['type'] == 'clef':
                self.layer.addChild(self._create_clef_element())
            elif c['type'] == 'division':
                self.layer.addChild(self._create_division_element())
                if "final" in c['form']:
                    self.staff_num += 1
                    new_staff = self._create_staff_element()
                    new_staffdef = self._create_staffdef_element()
                    # new_staffdef.attributes = {'n': self.staff_num} TROUBLE
                    new_staffdef.addAttribute('n', str(self.staff_num))
                    # new_staff.attributes = {'n': self.staff_num} TROUBLE
                    new_staff.addAttribute('n', str(self.staff_num))
                    new_layer = self._create_layer_element()
                    # new_layer.attributes = {'n': 1} TROUBLE
                    new_layer.addAttribute('n', str(1))
                    self.layer = new_layer
                    self.staffel = new_staff
                    self.staffdef = new_staffdef
                    self.staffgrp.addChild(self.staffdef)
                    self.staffel.addChild(self.layer)
                    self.section.addChild(self.staffel)

            elif c['type'] == 'custos':
                self.layer.addChild(self._create_custos_element())

            elif c['type'] == "alteration":
                # staffel.addChild(self._create_alteration_element()) #GVM_OLD
                pass
        return sysbrk

    def _create_graphic_element(self, imgfile):
        graphic = MeiElement("graphic")
        # xlink = MeiNamespace("xlink", "http://www.w3.org/1999/xlink")
        # ns_attr = MeiAttribute("xlink")
        graphic.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
        graphic.addAttribute("xlink:href", imgfile)
        return graphic

    def _create_alteration_element(self):
        # accid = mod.accid_()
        accid = MeiElement("accid")
        accid.id = self._idgen()
        if self.glyph['form'] is "sharp":
            accid.addAttribute("accid", "s")
        elif self.glyph['form'] is "flat":
            accid.addAttribute("accid", "f")

        # zone = self._create_zone_element()
        # note.facs = zone.id
        return accid

    def _create_surface_element(self):
        # surface = mod.surface_()
        surface = MeiElement("surface")
        return surface

    def _create_facsimile_element(self):
        # facsimile = mod.facsimile_()
        facsimile = MeiElement("facsimile")
        # facsimile.id = self._idgen()
        return facsimile

    def _create_zone_element(self):
        zone = MeiElement("zone")
        # zone = mod.zone_()
        # zone.id = self._idgen()
        # zone.attributes = {'ulx': self.glyph['coord'][0], 'uly': self.glyph['coord'][1], \
        #                     'lrx': self.glyph['coord'][2], 'lry': self.glyph['coord'][3]}

        zone.addAttribute("ulx", str(self.glyph['coord'][0]))
        zone.addAttribute("uly", str(self.glyph['coord'][1]))
        zone.addAttribute("lrx", str(self.glyph['coord'][2]))
        zone.addAttribute("lry", str(self.glyph['coord'][3]))
        self.surface.addChild(zone)
        return zone

    def _create_layer_element(self):
        layer = MeiElement("layer")
        # layer = mod.layer_()
        # layer.id = self._idgen()
        lg.debug("layer:{0}".format(layer))
        return layer

    def _create_staffgrp_element(self):
        # stfgrp = mod.staffGrp_()
        stfgrp = MeiElement("staffGrp")
        # stfgrp.id = self._idgen()
        return stfgrp

    def _create_staffdef_element(self):
        stfdef = MeiElement("staffDef")
        # stfdef = mod.staffDef_()
        # stfdef.id = self._idgen()
        return stfdef

    def _create_staff_element(self):
        # staff = mod.staff_()
        staff = MeiElement("staff")
        # staff.id = self._idgen()
        return staff

    def _create_sb_element(self):
        sb = MeiElement("sb")
        # sb = mod.sb_()
        # sb.id = self._idgen()
        return sb

    def _create_pb_element(self):
        # pb = mod.pb_()
        pb = MeiElement("pb")
        # pb.id = self._idgen()
        return pb

    def _create_layout_element(self):
        layout = MeiElement("layout")  # GVM_FIXED
        return layout

    def _create_page_element(self):
        page = MeiElement("page")  # FIXED?
        # page = mod.page_()
        # page.id = self._idgen()
        return page

    def _create_system_element(self):
        system = MeiElement("system")  # FIXED?
        # system = mod.system_()
        # system.id = self._idgen()
        return system

    def _create_episema_element(self):
        epi = MeiElement("episema")
        # epi = mod.episema_()
        # epi.id = self._idgen()
        return epi

    def _create_neume_element(self):
        full_width_episema = False
        has_dot = False
        has_vertical_episema = False
        has_horizontal_episema = False
        has_quilisma = False
        this_neume_form = None
        local_horizontal_episema = None

        start_octave = self.glyph['octv']
        clef_pos = self.glyph['clef_pos']
        clef_type = self.glyph['clef'].split(".")[-1]  # f or c.

        # neume = mod.neume_()
        neume = MeiElement("neume")  # CHECK!
        # neume.id = self._idgen()
        zone = self._create_zone_element()
        neume.facs = zone.id
        neume.addAttribute("facs", neume.facs)

        # neumecomponent = mod.nc_()
        neumecomponent = MeiElement("nc")  # CHECK!
        # neumecomponent.id = self._idgen()
        neume.addChild(neumecomponent)
        if self.glyph['form'][0] == "he":
            full_width_episema = True
            del self.glyph['form'][0]

        # we've removed any global he's, so
        # any leftovers should be local.
        if 'he' in self.glyph['form']:
            has_horizontal_episema = True

        if 'dot' in self.glyph['form']:
            has_dot = True

        if 'q' in self.glyph['form']:
            has_quilisma = True

        if 've' in self.glyph['form']:
            has_vertical_episema = True

        if 'inclinatum' in self.glyph['form']:
            # neumecomponent.attributes = {'inclinatum': 'true'}
            neumecomponent.addAttribute("inclinatum", "true")

        # neume.attributes = {'name': self.glyph['form'][0]}
        neume.addAttribute("name", str(self.glyph['form'][0]))

        if 'compound' in self.glyph['form']:
            # do something and create a new set of pitch contours
            this_neume_form = [
                y for y in (self.__parse_contour(n)
                            for n in self.glyph['form']) if y
            ]
            self._note_elements = [
                y for y in (self.__parse_steps(n) for n in self.glyph['form'])
                if y
            ]
        else:
            this_neume_form = copy.deepcopy(
                self.NEUME_NOTES[self.glyph['form'][0]])
            self._note_elements = self.glyph['form'][1:]
        # get the form so we can find the number of notes we need to construct.

        num_notes = len(this_neume_form) + 1
        # we don't have an off-by-one problem here, since an added interval means an added note
        check_additional = [
            i for i in self.ADD_NOTES.keys() if i in self.glyph['form'][1:]
        ]
        if check_additional:
            for f in check_additional:
                this_neume_form.extend(self.ADD_NOTES[f])

                ## THIS SHOULD BE CHANGED. Otherwise we may end up with two attributes with the
                # same name.
                neume.addAttribute("variant", str(f))

            num_notes = num_notes + len(check_additional)

        self._neume_pitches = []
        # note elements are everything after the first form. This determines the shape a note takes.
        self._neume_pitches.append(self.glyph['strt_pitch'])
        nc = []
        note_octaves = [start_octave]
        if num_notes > 1:
            # we need to figure out the rest of the pitches in the neume.
            ivals = [int(d) for d in self._note_elements if d.isdigit()]
            idx = self.SCALE.index(self.glyph['strt_pitch'])

            if len(ivals) != (num_notes - 1):
                if 'scandicus' in self.glyph['form']:
                    diffr = abs(len(ivals) - (num_notes - 1))
                    num_notes = num_notes + diffr
                    this_neume_form.extend(diffr * 'u')
                else:
                    raise AomrMeiNoteIntervalMismatchError(
                        "There is a mismatch between the number of notes and number of intervals."
                    )

            # note elements = torculus.2.2.he.ve
            # ivals = [2,2]
            # torculus = ['u','d']
            this_pos = copy.deepcopy(self.glyph['strt_pos'])
            for n in xrange(len(ivals)):
                # get the direction
                dir = this_neume_form[n]
                iv = ivals[n]
                n_idx = idx
                if dir == "u":
                    n_idx = ((idx + iv) % len(self.SCALE)) - 1
                    this_pos -= (iv - 1)
                elif dir == "d":
                    n_idx = idx - (iv - 1)
                    this_pos += (iv - 1)
                    if n_idx < 0:
                        n_idx += len(self.SCALE)
                idx = n_idx
                self._neume_pitches.append(self.SCALE[n_idx])

                actual_line = 10 - (2 * (clef_pos - 1))

                if clef_type:
                    if this_pos <= actual_line:
                        note_octaves.append(4)
                    elif this_pos > actual_line + 7:
                        note_octaves.append(2)
                    else:
                        note_octaves.append(3)
                # elif clef_type == "f":
                #     if (actual_line + 3) >= this_pos > (actual_line - 3):
                #         note_octaves.append(3)
                #     elif this_pos < (actual_line - 3):
                #         note_octaves.append(4)
                #     elif this_pos > (actual_line + 3):
                #         note_octaves.append(2)

        if full_width_episema is True:
            epi = self._create_episema_element()
            # epi.attributes = {"form": "horizontal"} TROUBLE
            epi.addAttribute("form", "horizontal")
            self.layer.addChild(epi)

        qidxs = []
        if has_quilisma:
            self.__note_addition_figurer_outer("q", qidxs)

        dotidxs = []
        if has_dot:
            self.__note_addition_figurer_outer("dot", dotidxs)

        veidxs = []
        if has_vertical_episema:
            self.__note_addition_figurer_outer("ve", veidxs)

        heidxs = []
        if has_horizontal_episema:
            self.__note_addition_figurer_outer("he", heidxs)

        for n in xrange(num_notes):
            p = self._neume_pitches[n]
            o = note_octaves[n]
            # lg.debug("n:{0}, p:{1}, o:{2}".format(n, p, o))
            nt = self._create_note_element(p)
            nt.addAttribute("oct", str(o))
            # lg.debug("nt.pitchname:{0}".format(nt.pname))
            if n == 0 and full_width_episema is True:
                epi.addAttribute("startid", str(nt.id))
            elif n == num_notes and full_width_episema is True:
                epi.addAttribute("endid", str(nt.id))

            if has_quilisma:
                if n in qidxs:
                    neumecomponent.addAttribute("quilisma", "true")

            if has_dot:
                if n in dotidxs:
                    d = self._create_dot_element()
                    nt.addChild(d)

            if has_vertical_episema:
                if n in veidxs:
                    ep = self._create_episema_element()
                    ep.addAttribute("form", "vertical")
                    ep.addAttribute("startid", str(nt.id))
                    self.layer.addChild(ep)

            if has_horizontal_episema:
                if n in heidxs:
                    local_horizontal_episema = self._create_episema_element()
                    local_horizontal_episema.addAttribute("form", "horizontal")
                    local_horizontal_episema.addAttribute(
                        "startid", str(nt.id))
                    self.layer.addChild(local_horizontal_episema)

            if n == num_notes - 1 and local_horizontal_episema:
                # we've reached the end, and we have an HE we need to close up.
                local_horizontal_episema.addAttribute("endid", str(nt.id))

            nc.append(nt)

        for c in nc:
            neumecomponent.addChild(c)
        return neume

    def _create_note_element(self, pname=None):
        # note = mod.note_()
        note = MeiElement("note")
        # note.id = self._idgen()
        note.addAttribute("pname", str(pname))
        return note

    def _create_dot_element(self):
        # dot = mod.dot_()
        dot = MeiElement("dot")
        # dot.id = self._idgen()
        dot.addAttribute("form", "aug")
        return dot

    def _create_custos_element(self):
        custos = MeiElement("custos")
        # custos = mod.custos_()
        # custos.id = self._idgen()
        zone = self._create_zone_element()
        custos.facs = zone.id
        custos.addAttribute("pname", str(self.glyph['strt_pitch']))
        custos.addAttribute("oct", str(self.glyph['octv']))
        custos.addAttribute("facs", str(custos.facs))
        return custos

    def _create_clef_element(self):
        clef = MeiElement("clef")
        # clef = mod.clef_()
        # clef.id = self._idgen()
        zone = self._create_zone_element()
        clef.facs = zone.id
        clef.addAttribute("facs", str(clef.facs))

        # clef.attributes = {"line": self.glyph['strt_pos'], 'shape': self.glyph['form'][0].upper() }
        clef.addAttribute("line", str(self.glyph['strt_pos']))
        clef.addAttribute("shape", str(self.glyph['form'][0].upper()))
        lg.debug("clef:{0}".format(clef))
        return clef

    def _create_division_element(self):
        division = MeiElement("division")
        # division = mod.division_()
        # division.id = self._idgen()
        zone = self._create_zone_element()
        division.addAttribute("facs", str(zone.id))

        if self.glyph['form']:
            div = str(self.glyph['form'][0])
        else:
            div = "minor"

        division.addAttribute("form", div)
        return division

    def __parse_contour(self, form):
        # removes the contour indicator from the neume
        # and creates a neume form.
        if len(form) is 2 and (form.startswith("u") or form.startswith("d")):
            # do something
            return form[0]
        else:
            return None

    def __parse_steps(self, form):
        if len(form) is 2 and (form.startswith("u") or form.startswith("d")):
            return form[1]
        else:
            return None

    def __note_addition_figurer_outer(self, ntype, idxarray):
        for i, n in enumerate(self.glyph['form']):
            if n == ntype:
                j = copy.copy(i) - 1
                if j == 0:
                    idxarray.append(0)
                while j:
                    if self.__is_valid_note_indicator(self.glyph['form'][j]):
                        idxarray.append(j)
                        break
                    else:
                        j -= 1

    def __is_valid_note_indicator(self, form):
        # used to test if a form is a valid indicator of a note (and not a q, dot, or anything else)
        if form.isdigit():
            return True
        elif len(form) == 2 and form.startswith("u") or form.startswith("d"):
            return True
        else:
            return False
コード例 #8
0
ファイル: AomrMeiOutput.py プロジェクト: lexpar/Rodan
class AomrMeiOutput(object):
    # define the form of a neume.
    # form: [ num, interval_dir... ]
    # e.g., clivis: [2, 'd']
    # torculus: [3, 'u', 'd']
    NEUME_NOTES = {
        'punctum': [],
        'virga': [],
        'cephalicus': ['d'],
        'clivis': ['d'],
        'epiphonus': ['u'],
        'podatus': ['u'],
        'porrectus': ['d', 'u'],
        'salicus': ['u', 'u'],
        'scandicus': ['u', 'u'],
        'torculus': ['u', 'd'],
        'ancus': ['d', 'd'],  # See note 1 below
    }

    # given an alternate form, how many notes does it add to the neume?
    ADD_NOTES = {
        'flexus': ['d'],  # scandicus.flexus, porrectus.flexus
        'resupinus': ['u'],  # torculus.resupinus
    }

    SCALE = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

    def __init__(self, incoming_data, original_image, page_number=None):
        self._recognition_results = incoming_data
        # self.mei = mod.mei_()
        self.mei = MeiElement("mei")
        self.staff = None

        # Hack: I'm not sure what staff_num is. In any case it's strange to set it to None.
        # I therefore set it to 0 if page_number is None.
        if page_number is not None:
            self.staff_num = int(page_number)
        else:
            self.staff_num = 0
        self.glyph = None

        self._note_elements = None
        self._neume_pitches = []

        # set up a basic MEI document structure

        # header
        # self.meihead = mod.meiHead_()
        self.meihead = MeiElement("meiHead")
        # self.filedesc = mod.fileDesc_()
        self.filedesc = MeiElement("fileDesc")
        # self.titlestmt = mod.titleStmt_()
        self.titlestmt = MeiElement("titleStmt")
        # self.title = mod.title_()
        self.title = MeiElement("title")
        # self.pubstmt = mod.pubStmt_()
        self.pubstmt = MeiElement("pubStmt")

        self.titlestmt.addChild(self.title)

        self.filedesc.addChild(self.titlestmt)
        self.filedesc.addChild(self.pubstmt)

        self.meihead.addChild(self.filedesc)
        self.mei.addChild(self.meihead)

        # music
        # self.music = mod.music_()
        self.music = MeiElement("music")
        self.facsimile = self._create_facsimile_element()
        self.surface = self._create_surface_element()
        self.graphic = self._create_graphic_element(original_image)
        lg.debug("SELF GRAPHIC:{0}".format(XmlExport.meiElementToText(self.graphic)))

        self.surface.addChild(self.graphic)
        self.facsimile.addChild(self.surface)
        self.music.addChild(self.facsimile)

        self.layout = self._create_layout_element()
        self.pg = self._create_page_element()
        if page_number:
            # self.pg.attributes = {"n": page_number}
            self.pg.addAttribute("n", page_number)

        self.layout.addChild(self.pg)
        self.music.addChild(self.layout)

        # self.body = mod.body_()
        self.body = MeiElement("body")
        self.music.addChild(self.body)

        self.mdiv = MeiElement("mdiv")
        # self.mdiv = mod.mdiv_()
        self.mdiv.addAttribute("type", "solesmes")
        self.body.addChild(self.mdiv)

        # self.score = mod.score_()
        self.score = MeiElement("score")
        self.mdiv.addChild(self.score)

        # self.scoredef = mod.scoreDef_()
        self.scoredef = MeiElement("scoreDef")
        self.score.addChild(self.scoredef)

        # self.section = mod.section_()
        self.section = MeiElement("section")
        self.pagebreak = self._create_pb_element()
        # self.pagebreak.attributes = {"pageref": self.pg.id}
        self.pagebreak.addAttribute("pageref", self.pg.id)

        self.section.addChild(self.pagebreak)
        self.score.addChild(self.section)

        self.staffgrp = self._create_staffgrp_element()
        self.staffdef = self._create_staffdef_element()
        self.staffdef.addAttribute("n", str(self.staff_num))   # trouble

        self.staffgrp.addChild(self.staffdef)
        self.scoredef.addChild(self.staffgrp)

        self.layer = self._create_layer_element()
        self.layer.addAttribute("n", "1")

        self.staffel = self._create_staff_element()
        self.staffel.addAttribute("n", str(self.staff_num))   # trouble
        self.section.addChild(self.staffel)
        self.staffel.addChild(self.layer)

        for sysnum in sorted(self._recognition_results.keys()):
            syst = self._recognition_results[sysnum]
            lg.debug("sysnum:{0}".format(sysnum))
            self.system = syst
            self.systembreak = self._parse_system(sysnum, syst)
            # z = mod.zone_()
            z = MeiElement("zone")
            # z.id = self._idgen()
            # z.attributes = {'ulx': self.system['coord'][0], 'uly': self.system['coord'][1], \
            #                     'lrx': self.system['coord'][2], 'lry': self.system['coord'][3]}
            z.addAttribute("ulx", str(self.system['coord'][0]))
            z.addAttribute("uly", str(self.system['coord'][1]))
            z.addAttribute("lrx", str(self.system['coord'][2]))
            z.addAttribute("lry", str(self.system['coord'][3]))
            self.surface.addChild(z)
            # self.system.facs = z.id
            s = self._create_system_element()
            s.facs = z.id
            s.addAttribute("facs", s.facs)
            self.pg.addChild(s)
            self.systembreak.addAttribute("systemref", s.id)

        self.mei.addChild(self.music)

        # if not self.staffel.descendants_by_name('neume'):
        if not self.staffel.getDescendantsByName("neume"):
            self.staffgrp.removeChild(self.staffdef)
            self.section.removeChild(self.staffel)

        # self.md = MeiDocument.MeiDocument()
        # self.md.addelement(self.mei)
        self.md = MeiDocument()
        self.md.setRootElement(self.mei)
        print XmlExport.meiElementToText(self.md.getElementById(self.graphic.getId()))

    def _parse_system(self, sysnum, syst):
        sysbrk = self._create_sb_element()
        # sysbrk.attributes = {"n": sysnum + 1}
        sysnum = int(sysnum)
        sysbrk.addAttribute("n", "%d" % (sysnum+1))
        self.layer.addChild(sysbrk)
        # staffel = self._create_staff_element()
        # staffel.addAttribute("n", stfnum)

        for c in self.system['content']:
            # parse the glyphs per staff.
            self.glyph = c
            if c['type'] == 'neume':
                if not self.glyph['form']:
                    lg.debug("Skipping glyph: {0}".format(self.glyph))
                    continue
                if self.glyph['form'][0] not in self.NEUME_NOTES.keys():
                    continue
                else:
                    self.layer.addChild(self._create_neume_element())

            elif c['type'] == 'clef':
                self.layer.addChild(self._create_clef_element())
            elif c['type'] == 'division':
                self.layer.addChild(self._create_division_element())
                if "final" in c['form']:
                    self.staff_num += 1
                    new_staff = self._create_staff_element()
                    new_staffdef = self._create_staffdef_element()
                    # new_staffdef.attributes = {'n': self.staff_num} TROUBLE
                    new_staffdef.addAttribute('n', str(self.staff_num))
                    # new_staff.attributes = {'n': self.staff_num} TROUBLE
                    new_staff.addAttribute('n', str(self.staff_num))
                    new_layer = self._create_layer_element()
                    # new_layer.attributes = {'n': 1} TROUBLE
                    new_layer.addAttribute('n', str(1))
                    self.layer = new_layer
                    self.staffel = new_staff
                    self.staffdef = new_staffdef
                    self.staffgrp.addChild(self.staffdef)
                    self.staffel.addChild(self.layer)
                    self.section.addChild(self.staffel)

            elif c['type'] == 'custos':
                self.layer.addChild(self._create_custos_element())

            elif c['type'] == "alteration":
                # staffel.addChild(self._create_alteration_element()) #GVM_OLD
                pass
        return sysbrk

    def _create_graphic_element(self, imgfile):
        graphic = MeiElement("graphic")
        # xlink = MeiNamespace("xlink", "http://www.w3.org/1999/xlink")
        # ns_attr = MeiAttribute("xlink")
        graphic.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
        graphic.addAttribute("xlink:href", imgfile)
        return graphic

    def _create_alteration_element(self):
        # accid = mod.accid_()
        accid = MeiElement("accid")
        accid.id = self._idgen()
        if self.glyph['form'] is "sharp":
            accid.addAttribute("accid", "s")
        elif self.glyph['form'] is "flat":
            accid.addAttribute("accid", "f")

        # zone = self._create_zone_element()
        # note.facs = zone.id
        return accid

    def _create_surface_element(self):
        # surface = mod.surface_()
        surface = MeiElement("surface")
        return surface

    def _create_facsimile_element(self):
        # facsimile = mod.facsimile_()
        facsimile = MeiElement("facsimile")
        # facsimile.id = self._idgen()
        return facsimile

    def _create_zone_element(self):
        zone = MeiElement("zone")
        # zone = mod.zone_()
        # zone.id = self._idgen()
        # zone.attributes = {'ulx': self.glyph['coord'][0], 'uly': self.glyph['coord'][1], \
        #                     'lrx': self.glyph['coord'][2], 'lry': self.glyph['coord'][3]}

        zone.addAttribute("ulx", str(self.glyph['coord'][0]))
        zone.addAttribute("uly", str(self.glyph['coord'][1]))
        zone.addAttribute("lrx", str(self.glyph['coord'][2]))
        zone.addAttribute("lry", str(self.glyph['coord'][3]))
        self.surface.addChild(zone)
        return zone

    def _create_layer_element(self):
        layer = MeiElement("layer")
        # layer = mod.layer_()
        # layer.id = self._idgen()
        lg.debug("layer:{0}".format(layer))
        return layer

    def _create_staffgrp_element(self):
        # stfgrp = mod.staffGrp_()
        stfgrp = MeiElement("staffGrp")
        # stfgrp.id = self._idgen()
        return stfgrp

    def _create_staffdef_element(self):
        stfdef = MeiElement("staffDef")
        # stfdef = mod.staffDef_()
        # stfdef.id = self._idgen()
        return stfdef

    def _create_staff_element(self):
        # staff = mod.staff_()
        staff = MeiElement("staff")
        # staff.id = self._idgen()
        return staff

    def _create_sb_element(self):
        sb = MeiElement("sb")
        # sb = mod.sb_()
        # sb.id = self._idgen()
        return sb

    def _create_pb_element(self):
        # pb = mod.pb_()
        pb = MeiElement("pb")
        # pb.id = self._idgen()
        return pb

    def _create_layout_element(self):
        layout = MeiElement("layout")           # GVM_FIXED
        return layout

    def _create_page_element(self):
        page = MeiElement("page")               # FIXED?
        # page = mod.page_()
        # page.id = self._idgen()
        return page

    def _create_system_element(self):
        system = MeiElement("system")           # FIXED?
        # system = mod.system_()
        # system.id = self._idgen()
        return system

    def _create_episema_element(self):
        epi = MeiElement("episema")
        # epi = mod.episema_()
        # epi.id = self._idgen()
        return epi

    def _create_neume_element(self):
        full_width_episema = False
        has_dot = False
        has_vertical_episema = False
        has_horizontal_episema = False
        has_quilisma = False
        this_neume_form = None
        local_horizontal_episema = None

        start_octave = self.glyph['octv']
        clef_pos = self.glyph['clef_pos']
        clef_type = self.glyph['clef'].split(".")[-1]  # f or c.

        # neume = mod.neume_()
        neume = MeiElement("neume")                            # CHECK!
        # neume.id = self._idgen()
        zone = self._create_zone_element()
        neume.facs = zone.id
        neume.addAttribute("facs", neume.facs)

        # neumecomponent = mod.nc_()
        neumecomponent = MeiElement("nc")                      # CHECK!
        # neumecomponent.id = self._idgen()
        neume.addChild(neumecomponent)
        if self.glyph['form'][0] == "he":
            full_width_episema = True
            del self.glyph['form'][0]

        # we've removed any global he's, so
        # any leftovers should be local.
        if 'he' in self.glyph['form']:
            has_horizontal_episema = True

        if 'dot' in self.glyph['form']:
            has_dot = True

        if 'q' in self.glyph['form']:
            has_quilisma = True

        if 've' in self.glyph['form']:
            has_vertical_episema = True

        if 'inclinatum' in self.glyph['form']:
            # neumecomponent.attributes = {'inclinatum': 'true'}
            neumecomponent.addAttribute("inclinatum", "true")

        # neume.attributes = {'name': self.glyph['form'][0]}
        neume.addAttribute("name", str(self.glyph['form'][0]))

        if 'compound' in self.glyph['form']:
            # do something and create a new set of pitch contours
            this_neume_form = [y for y in (self.__parse_contour(n) for n in self.glyph['form']) if y]
            self._note_elements = [y for y in (self.__parse_steps(n) for n in self.glyph['form']) if y]
        else:
            this_neume_form = copy.deepcopy(self.NEUME_NOTES[self.glyph['form'][0]])
            self._note_elements = self.glyph['form'][1:]
        # get the form so we can find the number of notes we need to construct.

        num_notes = len(this_neume_form) + 1
        # we don't have an off-by-one problem here, since an added interval means an added note
        check_additional = [i for i in self.ADD_NOTES.keys() if i in self.glyph['form'][1:]]
        if check_additional:
            for f in check_additional:
                this_neume_form.extend(self.ADD_NOTES[f])

                ## THIS SHOULD BE CHANGED. Otherwise we may end up with two attributes with the
                # same name.
                neume.addAttribute("variant", str(f))

            num_notes = num_notes + len(check_additional)

        self._neume_pitches = []
        # note elements are everything after the first form. This determines the shape a note takes.
        self._neume_pitches.append(self.glyph['strt_pitch'])
        nc = []
        note_octaves = [start_octave]
        if num_notes > 1:
            # we need to figure out the rest of the pitches in the neume.
            ivals = [int(d) for d in self._note_elements if d.isdigit()]
            idx = self.SCALE.index(self.glyph['strt_pitch'])

            if len(ivals) != (num_notes - 1):
                if 'scandicus' in self.glyph['form']:
                    diffr = abs(len(ivals) - (num_notes - 1))
                    num_notes = num_notes + diffr
                    this_neume_form.extend(diffr * 'u')
                else:
                    raise AomrMeiNoteIntervalMismatchError("There is a mismatch between the number of notes and number of intervals.")

            # note elements = torculus.2.2.he.ve
            # ivals = [2,2]
            # torculus = ['u','d']
            this_pos = copy.deepcopy(self.glyph['strt_pos'])
            for n in xrange(len(ivals)):
                # get the direction
                dir = this_neume_form[n]
                iv = ivals[n]
                n_idx = idx
                if dir == "u":
                    n_idx = ((idx + iv) % len(self.SCALE)) - 1
                    this_pos -= (iv - 1)
                elif dir == "d":
                    n_idx = idx - (iv - 1)
                    this_pos += (iv - 1)
                    if n_idx < 0:
                        n_idx += len(self.SCALE)
                idx = n_idx
                self._neume_pitches.append(self.SCALE[n_idx])

                actual_line = 10 - (2*(clef_pos-1))

                if clef_type:
                    if this_pos <= actual_line:
                        note_octaves.append(4)
                    elif this_pos > actual_line + 7:
                        note_octaves.append(2)
                    else:
                        note_octaves.append(3)
                # elif clef_type == "f":
                #     if (actual_line + 3) >= this_pos > (actual_line - 3):
                #         note_octaves.append(3)
                #     elif this_pos < (actual_line - 3):
                #         note_octaves.append(4)
                #     elif this_pos > (actual_line + 3):
                #         note_octaves.append(2)

        if full_width_episema is True:
            epi = self._create_episema_element()
            # epi.attributes = {"form": "horizontal"} TROUBLE
            epi.addAttribute("form", "horizontal")
            self.layer.addChild(epi)

        qidxs = []
        if has_quilisma:
            self.__note_addition_figurer_outer("q", qidxs)

        dotidxs = []
        if has_dot:
            self.__note_addition_figurer_outer("dot", dotidxs)

        veidxs = []
        if has_vertical_episema:
            self.__note_addition_figurer_outer("ve", veidxs)

        heidxs = []
        if has_horizontal_episema:
            self.__note_addition_figurer_outer("he", heidxs)

        for n in xrange(num_notes):
            p = self._neume_pitches[n]
            o = note_octaves[n]
            # lg.debug("n:{0}, p:{1}, o:{2}".format(n, p, o))
            nt = self._create_note_element(p)
            nt.addAttribute("oct", str(o))
            # lg.debug("nt.pitchname:{0}".format(nt.pname))
            if n == 0 and full_width_episema is True:
                epi.addAttribute("startid", str(nt.id))
            elif n == num_notes and full_width_episema is True:
                epi.addAttribute("endid", str(nt.id))

            if has_quilisma:
                if n in qidxs:
                    neumecomponent.addAttribute("quilisma", "true")

            if has_dot:
                if n in dotidxs:
                    d = self._create_dot_element()
                    nt.addChild(d)

            if has_vertical_episema:
                if n in veidxs:
                    ep = self._create_episema_element()
                    ep.addAttribute("form", "vertical")
                    ep.addAttribute("startid", str(nt.id))
                    self.layer.addChild(ep)

            if has_horizontal_episema:
                if n in heidxs:
                    local_horizontal_episema = self._create_episema_element()
                    local_horizontal_episema.addAttribute("form", "horizontal")
                    local_horizontal_episema.addAttribute("startid", str(nt.id))
                    self.layer.addChild(local_horizontal_episema)

            if n == num_notes - 1 and local_horizontal_episema:
                # we've reached the end, and we have an HE we need to close up.
                local_horizontal_episema.addAttribute("endid", str(nt.id))

            nc.append(nt)

        for c in nc:
            neumecomponent.addChild(c)
        return neume

    def _create_note_element(self, pname=None):
        # note = mod.note_()
        note = MeiElement("note")
        # note.id = self._idgen()
        note.addAttribute("pname", str(pname))
        return note

    def _create_dot_element(self):
        # dot = mod.dot_()
        dot = MeiElement("dot")
        # dot.id = self._idgen()
        dot.addAttribute("form", "aug")
        return dot

    def _create_custos_element(self):
        custos = MeiElement("custos")
        # custos = mod.custos_()
        # custos.id = self._idgen()
        zone = self._create_zone_element()
        custos.facs = zone.id
        custos.addAttribute("pname", str(self.glyph['strt_pitch']))
        custos.addAttribute("oct", str(self.glyph['octv']))
        custos.addAttribute("facs", str(custos.facs))
        return custos

    def _create_clef_element(self):
        clef = MeiElement("clef")
        # clef = mod.clef_()
        # clef.id = self._idgen()
        zone = self._create_zone_element()
        clef.facs = zone.id
        clef.addAttribute("facs", str(clef.facs))

        # clef.attributes = {"line": self.glyph['strt_pos'], 'shape': self.glyph['form'][0].upper() }
        clef.addAttribute("line", str(self.glyph['strt_pos']))
        clef.addAttribute("shape", str(self.glyph['form'][0].upper()))
        lg.debug("clef:{0}".format(clef))
        return clef

    def _create_division_element(self):
        division = MeiElement("division")
        # division = mod.division_()
        # division.id = self._idgen()
        zone = self._create_zone_element()
        division.addAttribute("facs", str(zone.id))

        if self.glyph['form']:
            div = str(self.glyph['form'][0])
        else:
            div = "minor"

        division.addAttribute("form", div)
        return division

    def __parse_contour(self, form):
        # removes the contour indicator from the neume
        # and creates a neume form.
        if len(form) is 2 and (form.startswith("u") or form.startswith("d")):
            # do something
            return form[0]
        else:
            return None

    def __parse_steps(self, form):
        if len(form) is 2 and (form.startswith("u") or form.startswith("d")):
            return form[1]
        else:
            return None

    def __note_addition_figurer_outer(self, ntype, idxarray):
        for i,n in enumerate(self.glyph['form']):
            if n == ntype:
                j = copy.copy(i) - 1
                if j == 0:
                    idxarray.append(0)
                while j:
                    if self.__is_valid_note_indicator(self.glyph['form'][j]):
                        idxarray.append(j)
                        break
                    else:
                        j -= 1

    def __is_valid_note_indicator(self, form):
        # used to test if a form is a valid indicator of a note (and not a q, dot, or anything else)
        if form.isdigit():
            return True
        elif len(form) == 2 and form.startswith("u") or form.startswith("d"):
            return True
        else:
            return False