Skip to content
Laurent Pugin edited this page Nov 29, 2023 · 60 revisions

Building instruction memo

git clone -b master https://github.com/rism-digital/MuseScore
cd MuseScore
mkdir applebuild
cd applebuild
cmake .. -GXcode -DMUE_COMPILE_BUILD_MACOS_APPLE_SILICON=1
open mscore.xcodeproj

Select "Manually Manage Schemes"

image

Select "mscore" (the only one needed)

image

Build and run with Command-R

General code organization

The code organization for the MEI exporter and importer follows the code organization of other import/export implementations in MuseScore, such as MusicXML or Braille. Most of the code is in the ./src/importexport/mei directory.

The MEI exporter and importer uses the LibMEI code generator integrated in Verovio. LibMEI generates C++ code for elements, attribute classes and data types directly from the MEI Schema.

The code for the MuseScore MEI exporter and importer code is based on a reduced set of MEI elements and attributes, the MEI Basic customization. It is in ./src/importexport/mei/libmei.

Re-generating the LibMEI code

The LibMEI code for the MEI import/export is in the MuseScore repository and does not have to be generated. However, if there are some changes that have been made to MEI Basic and for which the LibMEI code needs to be adjusted, it should not be edited by hand. The code should be re-generated with the new version of MEI Basic.

[TODO] Add documentation for the code generation

Code structure

The code is organized around three main C++ classes. The MeiExporter and MeiImporter classes, to which constructor the mu::engraving::Score is passed, and the MeiConverter class.

In addition to these classes, there are also the MeiWriter and MeiReader classes inheriting from the mu::project::INotationWriter and mu::project::INotationReader respectively. Theses two classes simply create one instance of an MeiExporter or MeiImporter and call the write() and read() methods with the appropriate file name to write or read.

The MeiExporter class is where the mu::engraving::Score object is parsed and where corresponding libmei objects are created and added to the tree. The MeiImporter is the mirror of it. It parses the MEI tree and create MuseScore object and builds the mu::engraving::Score. In other words, these classes focus on the high level structural aspect of the export and the import. They perform essentially looping and mapping tasks. For example, going through the list of measures in the score, or generating the MEI scoreDef structure from the MuseScore parts and the opposite.

Element-level conversion is regrouped in the MeiConverter class with mirroring reading and writing methods. For example, converting a clef from and to MEI will look like:

static engraving::ClefType clefFromMEI(const libmei::Clef &meiClef, bool &warning);
static libmei::Clef clefToMEI(engraving::ClefType clef);

With this approach, atomic writing and reading conversion step can be kept side-by-side, making it much easier to verify and to maintain full round-tripping. That is, to ensure that a file exported to MEI from MuseScore can be re-imported, but also that the same MEI output will be obtained if the file is re-exported again.

Clone this wiki locally