File size: 1,435 Bytes
c42fe7e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# inference/mei_parser.py
from lxml import etree

def parse_mei(mei_path, tempo=120):
    tree = etree.parse(str(mei_path))
    ns = {"mei": "http://www.music-encoding.org/ns/mei"}

    staff_defs = tree.xpath("//mei:staffDef", namespaces=ns)
    if len(staff_defs) != 1:
        raise ValueError(f"Expected exactly one staffDef (monophonic input), found {len(staff_defs)}.")

    notes = []
    syllables = []
    durations = []
    is_slur_seq = []

    quarter_duration = 60 / tempo

    for note in tree.xpath("//mei:staff//mei:note", namespaces=ns):
        pname = note.get("pname")
        octv = note.get("oct")
        dur = note.get("dur")
        syl_elem = note.find(".//mei:syl", namespaces=ns)

        if not pname or not octv or not dur:
            continue

        # Note name
        pitch = pname.upper() + octv
        notes.append(pitch)

        # Duration in seconds
        dur_val = int(dur)
        sec = 4 / dur_val * quarter_duration
        durations.append(round(sec, 6))

        # Syllable text
        if syl_elem is not None and syl_elem.text:
            syllables.append(syl_elem.text.strip())
            is_slur_seq.append(1 if syl_elem.get("con") == "d" else 0)
        else:
            syllables.append("a")
            is_slur_seq.append(0)

    return {
        "notes": notes,
        "durations": durations,
        "lyrics": " ".join(syllables),
        "is_slur_seq": is_slur_seq
    }