Document object model for the MNX music interchange format. It is compatible with the C++17 standard.
- compatible with the C++17 standard and higher. (Currently tested with C++23.)
- uses nlohmann_json as its JSON parser.
- allows structured access to MNX objects, without the need of quoted strings.
- validates against the MNX schema using json-schema-validator.
- no class serialization beyond nlohmann.
- every MNX class is a wrapper around the root JSON object and a pointer to the location of the instance.
Here is a simple example of code that creates the Hello World MNX JSON file.
// create new document
auto doc = mnx::Document(); // automatically creates required child nodes
// global
auto globalMeasure = doc.global().measures().append();
// required fields are supplied when objects are created
globalMeasure.create_barline(mnx::BarlineType::Regular);
globalMeasure.create_time(4, mnx::TimeSignatureUnit::Quarter);
// parts
auto part = doc.parts().append();
auto measure = part.create_measures().append();
measure.create_clefs().append(mnx::ClefSign::GClef, -2, std::nullopt);
auto event = measure.sequences()
.append()
.content()
.append<mnx::sequence::Event>(mnx::NoteValueBase::Whole);
event.create_notes().append(mnx::sequence::Pitch::make(mnx::NoteStep::C, 4));
// save to file
doc.save("hello-world.json", 4); // indent with 4 spacesNote that this code never uses references. Since every MNX class in the model is a lightweight wrapper around a root JSON object and a pointer to its location, copying them is extremely cheap. The class instance returned by any method is a temporary instance. Using references on return values can result in undefined behavior.
Include the top header in your source file.
#include "mnxdom.h"Add the libary to your project with FetchContent:
include(FetchContent)
FetchContent_Declare(
musx
GIT_REPOSITORY https://github.com/rpatters1/mnxdom
GIT_TAG main # Replace with the desired commit hash, tag, or branch
)
FetchContent_MakeAvailable(musx)
# Also add somewhere:
target_link_libraries(project PRIVATE mnxdom) # replace "project" with your actual project nameInstall the library using:
sudo cmake --install build
This should install:
- Headers in
/usr/local/include/mnxdom pkg-configfile in/usr/local/lib/pkgconfig/mnxdom.pc
If you use cmake in your project, and assuming pkg-config on your system is configured to look for files in /usr/local/lib/pkgconfig too, you can use:
find_package(PkgConfig REQUIRED)
pkg_check_modules(mnxdom REQUIRED IMPORTED_TARGET mnxdom)
target_link_libraries(project PRIVATE PkgConfig::mnxdom)And include the top header in your source file with:
#include <mnxdom/mnxdom.h>The dependencies pboettch/json-schema-validator and nlohmann/json are required by mnxdom. If you wish mnxdom to use the system versions of either of these dependencies, configure mnxdom with the following CMake flags:
-DUSE_SYSTEM_NLOHMANN_JSON=ON
-DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ONmnxdom vendors the W3C MNX schema and example JSON files in third_party/w3c-mnx. These files are not fetched during the build. To update them from the current main branch of the W3C MNX repository, run:
scripts/update-w3c-mnx.shTo update to a specific upstream commit or ref of the w3c repository, pass it as an argument. The resolved commit is recorded in third_party/w3c-mnx/UPSTREAM_COMMIT.
Package creators should configure mnxdom so that the build does not download dependencies from the internet. Use system-provided copies of nlohmann/json and json-schema-validator:
cmake -S . -B build \
-DUSE_SYSTEM_NLOHMANN_JSON=ON \
-DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ON \
-Dmnxdom_BUILD_TESTING=OFFIf package builds run the test suite, also use a system-provided GoogleTest:
cmake -S . -B build \
-DUSE_SYSTEM_NLOHMANN_JSON=ON \
-DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ON \
-DUSE_SYSTEM_GOOGLETEST=ONThe W3C MNX schema and examples are vendored in third_party/w3c-mnx, so CMake does not fetch them. Do not run scripts/update-w3c-mnx.sh during a package build; that script is for maintainers updating the vendored snapshot before a release.
mnxdom records its own version and, when available, its source commit in generated MNX provenance. When building from a source tree without .git, whoever builds mnxdom may provide the source revision explicitly. This includes package creators and client projects that vendor mnxdom or bring it in with CMake FetchContent:
-DMNXDOM_GIT_COMMIT=<mnxdom-commit>If MNXDOM_GIT_COMMIT is not supplied and .git is unavailable, the commit field is omitted from the provenance rather than filled with a placeholder.
Package builds may also provide a package or build identifier for mnxdom itself:
-DMNXDOM_BUILD_ID=<mnxdom-build-id>This value is recorded as mnxdom.build in provenance. Client application build metadata should be recorded separately in the client provenance fields.
You need cmake to build and run the tests. From the directory containing this repository, configure the build directory:
cmake -S . buildTo build the tests:
cmake --build buildTo run the tests:
ctest --test-dir buildYou need Doxygen to create the documentation. You can download and run the installer from the Doxygen site. Package managers can also install it. Once you have Doxygen you can build the documentation as follows.
cd docs
doxygen DoxyfileYou will then find an html website in ./docs/generated/html. Use a web browser to view the site from your hard drive. Opening any of the .html pages gives you access to the entire site.