-
Notifications
You must be signed in to change notification settings - Fork 4
Home
PYMEI IS DEPRECATED.
Use Libmei instead.
This is a Python library to read/write Music Encoding Initiative (MEI) files. While MEI is usually expressed in XML, this library abstracts the XML representation, parsing the MEI entities into Python objects. This is to allow for alternative representations to be output, e.g., a MEIXML file can be read in and converted to a JSON representation, or vice-versa.
The requirements for this library are straightforward. It requires Python 2.6 or later (not tested yet on Python 3.x, though) and the lxml XML processing library (Version 2.3). All other modules should be built in to Python.
As of now, this library has only been tested on OS X. There should be no reason, however, that it should not run on any other platform that supports Python 2.6+ and lxml.
Installing should be as easy as downloading the code, changing to the module directory and running:
sudo python setup.py install
If it isn’t, something has gone terribly wrong. You can test if it has installed correctly by opening the Python interpreter and running:
import pymei
No errors? Peachy.
For this library, if an element has not been assigned a unique id it will be given one when it is imported. This will be assigned as a UUID, a 32-character string that is almost certainly guaranteed to be unique. This will be assigned to the xml:id
attribute, unless one already exists.
For example, importing the following structure:
<foo>
<bar xml:id="d1n31">
</foo>
might yield:
<foo xml:id="fc7db31f-7c5e-4f18-aeea-86e0f27e3e8d">
<bar xml:id="d1n31">
</foo>
Here are some examples of how to use this library directly. Longer examples may be found in the Examples folder in the source.
This script finds all the notes in a piece and prints their pitches. The result is a list object with the pitch name as the first item in the list, and then any other accidentals on that note. If you just want the pitch name, you can change:
print note.pitch
to:
print note.pitchname
If you want the full representation of the note, you can print:
note.get_pitch_octave()
from pymei.Import import convert
meifile = convert("/Path/to/file.mei")
notes = meifile.search('note')
for note in notes:
print note.pitch
One thing to notice here is that all PyMEI object classes are lowercase an underscore (_) attached at the end. This is to avoid conflict with built-in Python libraries that might be named things like “string” or something like that. Other than that, they are named exactly the same as the tag name in the MEI spec. This library consciously breaks the CamelCase class naming convention in Python so that there is no ambiguity between the tag name and the object name.
from pymei.Components import Modules as mod
note = mod.note_()
note.attributes = {"pname": "a", "dur":"4", "stem.dir": "up"}
note.as_xml_string()
>>> '<note pname="a" dur="4" stem.dir="up"/>'
note.as_json()
>>> '{"note": [{"@a": {"stem.dir": "up", "dur": "4", "pname": "a"}}]}'
See also: Encoding MEI as JSON
from pymei.Export import meitoxml
from pymei.Components import MeiDocument
from pymei.Components import Modules as mod
doc = MeiDocument.MeiDocument()
root_el = mod.mei_()
mei_head = mod.meihead_()
file_desc = mod.filedesc_()
title_stmt = mod.titlestmt_()
title = mod.title_()
title_stmt.children = [title]
encoding_desc = mod.encodingdesc_()
file_desc.children = [title_stmt]
mei_head.children = [file_desc, encoding_desc]
music = mod.music_()
bd = mod.body_()
music.children = [bd]
root_el.children = [mei_head, music]
doc.addelement(root_el)
meitoxml.meitoxml(doc, "filename.mei")
This writes filename.mei to current directory, which should look something like
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<mei xmlns="https://www.music-encoding.org/ns/mei">
<meihead>
<filedesc>
<titlestmt>
<title/>
</titlestmt>
</filedesc>
<encodingdesc/>
</meihead>
<music>
<body/>
</music>
</mei>