Braille Music Compiler
C++ LilyPond C Python CMake Perl
Latest commit 02a572e Dec 22, 2016 @mlang Small clean up.
Failed to load latest commit information.
cmake Move test related files into test/ and remove unneeded cmake/FindICU.… Mar 7, 2016
doc Fix execuable name. Dec 27, 2014
doxygen Stop generating doxygen by default for now. Dec 10, 2014
include/bmc MSVC warns about these. Mar 16, 2016
lib Small clean up. Dec 21, 2016
python/bmc Remove import. Jan 5, 2015
sphinx Fix path to test input data. Apr 6, 2016
test Try to set UTF-8 encoding for MSVC by adding an UTF-8 BOM. Mar 17, 2016
ui Try to fix Qt build on Windows. Mar 17, 2016
xsdcxx-musicxml @ 58b031d Fix a signedness warning on MSVC. Mar 17, 2016
.gitignore initial commit Aug 21, 2013
.gitmodules Add xsdcxx-musicxml as a submodule. Dec 7, 2014
.travis.yml [TravisCI] Try to run with sudo: false. Mar 14, 2016
CMakeLists.txt Build XercesC statically and provide bmc.exe as an artifact. Mar 21, 2016
LICENSE.txt Explicitly declare our license Aug 11, 2011
README.rst Reorganize README.rst. Mar 18, 2016
appveyor.yml Build XercesC statically and provide bmc.exe as an artifact. Mar 21, 2016
appveyor_logs Mention artifacts download url after showing log. Mar 21, 2016
bmc.cpp Add the --locale option to bmc. Apr 6, 2016
bmcmdpp Edit links. Nov 4, 2013
cgi.cpp Fix compilation of bmc.cgi. Apr 22, 2015
fluidsynth.cpp Rename toplevel namespace from music to ::bmc. Dec 11, 2014
fluidsynth.hpp Rename toplevel namespace from music to ::bmc. Dec 11, 2014
main.cpp Rename toplevel namespace from music to ::bmc. Dec 11, 2014
midi.hpp Rename toplevel namespace from music to ::bmc. Dec 11, 2014
python.cpp lcm and gcd have been moved to boost::integer. Aug 19, 2015


BMC -- Braille Music Compiler

Travis CI build status (Linux and Mac OS X) AppVeyor CI build status (Windows)

BMC aims to become a system for parsing and generating braille music code.


A predecessor to this project is FreeDots, a Java-based program for converting MusicXML to Braille Music code, as well as offering playback and some interactive editing capabilities.

FreeDots has been very helpful in providing a general understanding of the various aspects of braille music code. However, it was only designed to cover one way of conversion, namely from some music notation source (like MusicXML) to braille music code. A full system for working with braille music code should eventually cover both directions.


Being a C++ program, BMC naturally uses the Standard Template Library (STL).

In addition to that some Boost C++ Libraries are employed.

The MusicXML backend makes use of CodeSynthesis XSD to generate C++ bindings for MusicXML documents.

The graphical user interface is implemented on top of Qt.

Installing dependencies on Debian

On Debian GNU/Linux systems, you will need to install the following dependencies:

sudo apt-get install cmake doxygen lib{boost-{program-options,test},fluidsynth,icu}-dev

Installing dependencies on Mac OS X

We assume you have Xcode installed. A nice package manager for Mac OS X is Homebrew. If you don't have it installed yet, here is how to do so:

ruby -e "$(curl -fsSL"

If you have the Homebrew package manager, run the following commands to get all dependencies required to build and run BMC:

xcode-select --install
brew install cmake lame pkg-config python3 qt5 timidity xerces-c xsd
pip3 install sphinx
brew install caskroom/cask/brew-cask
brew cask install lilypond
brew install boost --with-python
brew install boost-python

Getting the source

You need Git to retrieve the source repository.

git clone --quiet
git submodule --quiet update --init --recursive

Running CMake

You can now run CMake to generate a build system for your platform:

cd bmc
cmake .


UNIX and Mac OS X

To build BMC, run the following commands:


To execute the test-suite, run:

make check


After configuring via CMake, either open the Solution bmc in Visual Studio 14 (2015) or open a "MSBuild Command Prompt for VS2015" and run the following:

msbuild bmc.sln /t:bmc-ui /p:Configuration=Release


  • Port current codebase to Windows:
    • Figure out how to mimmick the FluidSynth functionality currently used under Linux under Windows. Ideally, create a common class for realtime MIDI playback which is platform independent, and implement FluidSynth (Linux) and Windows backends on top of that.
    • Investigate encoding compatibility: BMC tries to be Unicode-based internally. On UNIX, wchar_t is 32bit wide, which allos for full Unicode compatibility. On Windows, it is 16bit wide and implicitly UTF16 coded (that is my current understanding). Figure out what encodings we are to expect on Windows and deal with them in the most flexible way. Unicode is to be prefered internally, always. Is Unicode Braille supported on Windows in the command prompt? Currently unit test input data is all encoded with UTF-8. Figure out if this is a problem on Windows.
  • Improve error reporting during parsing: Some useful diagnostics are already printed, but in many other cases the parser does not produce helpful error messages. It can be quite hard to start a braille music piece from scratch if you have no idea why it is not accepted by BMC.
  • Implement Standard MIDI File (SMF) writing: In addition to real-time playback, musical scores should also be exportable to MIDI files on disk such that they can be played or imported with other programs. Note that the current playback code is only a proof of concept, and needs more work. Its probably best to write something that converts a bmc::midi::evenet_queue to a suitable on-disk representation so that common code between real-time playback and file export can be shared.
  • Handle tied-note playback correctly: As usual with prototypes, the playback code does take shortcuts currently. One typical problem when converting note material to performance data is the interpretation of (usually visual) cues on how to play the music. Articulations are one (more advanced) instance of this. A more fundamental one is the interpretation of ties. If a note is tied to another one, it is supposed to be played with both note durations added. Currently, the playback code ignores this and plays tied notes as if they are two separate notes. This needs to be fixed. Note that ties can cross measure boundaries: A note at the end of one measure can be tied to one of the first notes of the next measure.
  • Devise a method to specify subsets of the parsed note material for playback or export. For instance, the user might want to play starting from a certain measure, or only listen to a certain staff (hand) in multistaff music.
  • Design the necessary components to handle unrolling: Braille music code allows for specification of repeated note material in a much more fine-grained way as visual music notation allows for. Simile signs can be used to repeat complete measures, particular voices, or even parts of a voice. Braille repeats can be used to indicate repetition of an arbitrary range of measures of the current staff. This implies that we will have to deal with data in both representations somehow: There is a stage of processing where all these repetition instructions are present (once the parse stage succeds), and we will want to unroll the given abstract syntax tree such that we get a view of all the notes actually implied by these contractions. We obviously need an unrolled "view" for export to anything other then braille music code, since most other formats seem to lack these compression fascilities. For instance, when generating MIDI messages, we need to have all contractions expanded such that we know the notes we need to generate. However, LilyPond input data allows for a special kind of repeat which basically serves a similar purpose as in braille music, namely to reduce duplicated note material. If we ever get to the stage of LilyPond export, we might want to use some of the braille repeats as cues to generate more human readable LilyPond files.
  • Port Cococa Touch: iOS handles Unicode Braille just as expected. It is displayed on screen with an appropriate font and works together with external braille displays as well. Given that, a port to Cocoa Touch seem quite feasable.