After using LilyPond for some years and musicxml2ly for nearly as long, I felt
the need for a tool that would go beyond the latter and provide more options to
avoid too much hand editing of the LilyPond code produced.
In order to remain in the main stream with regards to LilyPond, I decided to go
for C++, which happens to be my language of choice. libxml2 turned out to be
too low level for the task at hand, and looking around, I discovered
libmusicxml2, designed and maintained by Grame’s Dominique Fober.
It is located at https://github.com/grame-cncm/libmusicxml .
libmusicxml2 is written in plain vanilla C++, and one only needs a compiler and
cmake to build it. As of version 2.1, it offers the following features:
- it can be built on Linux, Windows and Mac OS X;
- the >300 classes needed to describe the MusicXML markups are
automatically derived from the 3.0 DTD by a script, using templating;
- there are 4 base classes in complement to these classes to build an
mxml tree, i.e. a tree of so-called xmlelement’s representing the MusicXML data
as read from text input;
- a two-shot visitor pattern is used to traverse the mxml tree. For
example, when traversing a tree such as:
visitStart() will be executed for ‘a’ before visiting ‘b' et ‘c’, and
visitEnd() will be executed for ‘a’ after visiting them. This eases the
collection of information for the sub-trees, to be used at a higher level after
they have been visited;
- various tools are provided as examples of the use of the libmusicxml2
library. One of them is xml2guido, a 2-pass translator from MusicXML to the
Guido Music Notation, another one is RandomMusic, that generates an mxml tree
containing random music and then writes it as MusicXML text.
This is presented in
xml2ly is a new 5-pass translator from MusicXML to LilyPond, written in C++-11
(since it uses regular expressions):
- the design goal for it was to perform at least as well as musicxml2ly;
- it started as a clone of xml2guido in early 2016;
- it soon appeared that an internal representation of the whole score
would help, hence the 2- to 5-pass move;
- having more passes provides a cleaner separation of concerns in the
various translation activities, as well as ease of debugging and maintenance;
- xml2ly can be used in pipes, in shell scripts or behind a GUI;
- many options are provided to suit various needs, including a
comprehensive set of trace options that proved most useful for the tests.
The development is being done on a LilyDev 4 virtual machine (Debian 8), and
the source code is contributed back to Grame’s GIT repository at
The testing is done with my own unit tests, the Lily Unofficial Test Suite, and
the Recordare LLC samples. All of them are at
The architecture of libmusicxml2 v2.2 is shown in the attached image, also to
be found at
- MSR (Music Score Representation) is a representation of the structure
of a score in terms of part groups, parts, staves, voices, repeats, measures,
lyrics, notes and so on. Is is actually a semantic description of the score;
- LPSR (LilyPond Score Representation) is MSR augmented with
representations of LilyPond \header, \paper, \layout and \score blocks, among
The MIDI part of the depicted architecture has not yet been designed: it is
mentioned in the diagram to illustrate that libmusicxml2/MSR could become a
translation hub (airport analogy) for music scoring applications once this is
BUILD_README.txt at the top of the hierarchy shows how to build the library,
I’ve used musicxml2ly, MuseScore and Finale intensively for comparisons.
Couldn’t use Sibelius for that: it’s been dead software for me ever since I
changed machine two years ago the reloaded everything from backup ('license
already used' problem).
The results can be found in the attached ODS file, and show that MusicXML
import even by Finale is not perfect. MuseScore does a good job in my opinion.
You can compare the scores produced by musicxml2ly and xml2ly (attached) for
files such as gracenotes/LilyPondIssue34.xml and
UnofficialTestSuite/31a-Directions.xml to ge an idea of what xml2ly can do.
There’s also a ‘-jianpu’ option.
Uncompressing .mxl files and converting input data to UTF-8 has been disabled
for the time being, since that requires OS-dependent code.
Performance tests on large files show that xml2ly is slightly faster than
musicxml2ly with GCC’s full debug options, and roughly twice as fast with O3
and the trace options removed.
My questions are:
- do you think there might be an interest for xml2ly among the Lily
users community once it’s mature enough to be announced?
- if so, could it be incorporated to the Lily code base and distributed
with Lily on the three major OSes?
I won't announce xml2ly anyway until some pending problems I’m working on are
solved and all of the test files are translated successfully.
Thanks for your feedback!
lilypond-devel mailing list