├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE.txt ├── README.rst ├── appveyor.yml ├── appveyor_logs ├── bmc.cpp ├── bmcmdpp ├── cgi.cpp ├── cmake ├── FindLilypond.cmake └── FindSphinxBuild.cmake ├── config.hpp ├── doc ├── blog │ ├── 20131014_weekend_hackaton_summary.mdwn │ ├── 20131023_recent_changes.mdwn │ ├── 20131027_recent_changes.mdwn │ ├── BMC_found_its_first_print_error.mdwn │ ├── The_new_CGI_interface.mdwn │ └── Yet_another_transcriber_error_cought.mdwn ├── bugs.mdwn ├── bugs │ └── done.mdwn ├── codingstyle.mdwn ├── goldberg.mdwn ├── index.mdwn ├── news.mdwn ├── news │ └── Documentation_Wiki_started.mdwn ├── output │ ├── bwv988-v01.midi │ ├── bwv988-v01.pdf │ ├── bwv988-v02.midi │ ├── bwv988-v02.pdf │ ├── bwv988-v03.midi │ ├── bwv988-v03.pdf │ ├── bwv988-v04.midi │ ├── bwv988-v04.pdf │ ├── bwv988-v05.midi │ ├── bwv988-v05.pdf │ ├── bwv988-v06.midi │ ├── bwv988-v06.pdf │ ├── bwv988-v07.midi │ ├── bwv988-v07.pdf │ ├── bwv988-v08.midi │ ├── bwv988-v08.pdf │ ├── bwv988-v09.midi │ ├── bwv988-v09.pdf │ ├── bwv988-v10.midi │ ├── bwv988-v10.pdf │ ├── bwv988-v11.midi │ ├── bwv988-v11.pdf │ ├── bwv988-v12.midi │ ├── bwv988-v12.pdf │ ├── bwv988-v13.midi │ ├── bwv988-v13.pdf │ ├── bwv988-v14.midi │ ├── bwv988-v14.pdf │ ├── bwv988-v15.midi │ ├── bwv988-v15.pdf │ ├── bwv988-v16.midi │ ├── bwv988-v16.pdf │ ├── bwv988-v17.midi │ ├── bwv988-v17.pdf │ ├── bwv988-v18.midi │ ├── bwv988-v18.pdf │ ├── bwv988-v19.midi │ ├── bwv988-v19.pdf │ ├── bwv988-v30.midi │ └── bwv988-v30.pdf ├── source.mdwn ├── tutorial.mdwn └── tutorial │ ├── a1.svg │ ├── a2.svg │ ├── a4.svg │ ├── a8.svg │ ├── b1.svg │ ├── b2.svg │ ├── b4.svg │ ├── b8.svg │ ├── c1.svg │ ├── c2.svg │ ├── c4.svg │ ├── c8.svg │ ├── d1.svg │ ├── d2.svg │ ├── d4.svg │ ├── d8.svg │ ├── e1.svg │ ├── e2.svg │ ├── e4.svg │ ├── e8.svg │ ├── f1.svg │ ├── f2.svg │ ├── f4.svg │ ├── f8.svg │ ├── g1.svg │ ├── g2.svg │ ├── g4.svg │ ├── g8.svg │ ├── index.mdwn.in │ ├── r1.svg │ ├── r2.svg │ ├── r4.svg │ ├── r8.svg │ ├── snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.ly │ ├── snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.midi │ ├── snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.mp3 │ ├── snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.svg │ ├── snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.ly │ ├── snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.midi │ ├── snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.mp3 │ ├── snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.svg │ ├── snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.ly │ ├── snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.midi │ ├── snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.mp3 │ ├── snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.svg │ ├── snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.ly │ ├── snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.midi │ ├── snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.mp3 │ ├── snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.svg │ ├── snippet_3f68e0222f816f35c97900b69f9b1b081540788e.ly │ ├── snippet_3f68e0222f816f35c97900b69f9b1b081540788e.midi │ ├── snippet_3f68e0222f816f35c97900b69f9b1b081540788e.mp3 │ ├── snippet_3f68e0222f816f35c97900b69f9b1b081540788e.svg │ ├── snippet_4f88d827469b646785a22e91d4fd3e8981101fad.ly │ ├── snippet_4f88d827469b646785a22e91d4fd3e8981101fad.midi │ ├── snippet_4f88d827469b646785a22e91d4fd3e8981101fad.mp3 │ ├── snippet_4f88d827469b646785a22e91d4fd3e8981101fad.svg │ ├── snippet_62639a3f85da78f4be7b92367333ca0570057d1f.ly │ ├── snippet_62639a3f85da78f4be7b92367333ca0570057d1f.midi │ ├── snippet_62639a3f85da78f4be7b92367333ca0570057d1f.mp3 │ ├── snippet_62639a3f85da78f4be7b92367333ca0570057d1f.svg │ ├── snippet_95147d3db25b99789406d175cbe66a271c1678e9.ly │ ├── snippet_95147d3db25b99789406d175cbe66a271c1678e9.midi │ ├── snippet_95147d3db25b99789406d175cbe66a271c1678e9.mp3 │ ├── snippet_95147d3db25b99789406d175cbe66a271c1678e9.svg │ ├── snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.ly │ ├── snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.midi │ ├── snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.mp3 │ ├── snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.svg │ ├── snippet_a534c14987afc4508effaccb7f8588071299d286.ly │ ├── snippet_a534c14987afc4508effaccb7f8588071299d286.midi │ ├── snippet_a534c14987afc4508effaccb7f8588071299d286.mp3 │ ├── snippet_a534c14987afc4508effaccb7f8588071299d286.svg │ ├── snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.ly │ ├── snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.midi │ ├── snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.mp3 │ ├── snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.svg │ ├── snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.ly │ ├── snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.midi │ ├── snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.mp3 │ ├── snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.svg │ ├── snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.ly │ ├── snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.midi │ ├── snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.mp3 │ ├── snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.svg │ ├── snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.ly │ ├── snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.midi │ ├── snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.mp3 │ ├── snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.svg │ ├── snippet_c1dae73a06fc54c80b53e57d3842fb2de1ab54f1.ly │ ├── snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.ly │ ├── snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.midi │ ├── snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.mp3 │ ├── snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.svg │ ├── snippet_cec08a48509e49a2972a365617373114b21976f6.ly │ ├── snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.ly │ ├── snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.midi │ ├── snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.mp3 │ ├── snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.svg │ ├── snippet_da06795ce64673da4bb1171f13e119bb271763e5.ly │ ├── snippet_da06795ce64673da4bb1171f13e119bb271763e5.midi │ ├── snippet_da06795ce64673da4bb1171f13e119bb271763e5.mp3 │ ├── snippet_da06795ce64673da4bb1171f13e119bb271763e5.svg │ ├── snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.ly │ ├── snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.midi │ ├── snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.mp3 │ ├── snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.svg │ ├── snippet_db593fd6120808f1ad00aeef540c460ba2710513.ly │ ├── snippet_db593fd6120808f1ad00aeef540c460ba2710513.midi │ ├── snippet_db593fd6120808f1ad00aeef540c460ba2710513.mp3 │ ├── snippet_db593fd6120808f1ad00aeef540c460ba2710513.svg │ ├── snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.ly │ ├── snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.midi │ ├── snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.mp3 │ ├── snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.svg │ ├── snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.ly │ ├── snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.midi │ ├── snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.mp3 │ ├── snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.svg │ ├── snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.ly │ ├── snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.midi │ ├── snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.mp3 │ ├── snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.svg │ ├── snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.ly │ ├── snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.midi │ ├── snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.mp3 │ ├── snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.svg │ ├── snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.ly │ ├── snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.midi │ ├── snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.mp3 │ └── snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.svg ├── doxygen ├── CMakeLists.txt ├── Doxyfile.in ├── layout.xml └── main.doxygen ├── fluidsynth.cpp ├── fluidsynth.hpp ├── include └── bmc │ ├── braille │ ├── ast.hpp │ ├── ast │ │ ├── ast.hpp │ │ ├── duration.hpp │ │ ├── fusion_adapt.hpp │ │ ├── visitor.hpp │ │ └── visitors.hpp │ ├── linebreaking.hpp │ ├── parsing │ │ ├── annotation.hpp │ │ ├── error_handler.hpp │ │ ├── grammar │ │ │ ├── key_signature.hpp │ │ │ ├── measure.hpp │ │ │ ├── numbers.hpp │ │ │ ├── partial_voice_sign.hpp │ │ │ ├── score.hpp │ │ │ ├── simile.hpp │ │ │ ├── time_signature.hpp │ │ │ └── tuplet_start.hpp │ │ └── qi │ │ │ └── primitive │ │ │ └── brl.hpp │ ├── reformat.hpp │ ├── semantic_analysis.hpp │ ├── semantic_analysis │ │ ├── alteration_calculator.hpp │ │ ├── compiler_pass.hpp │ │ ├── doubling_decoder.hpp │ │ ├── location_calculator.hpp │ │ ├── octave_calculator.hpp │ │ ├── value_disambiguation.hpp │ │ └── value_disambiguator.hpp │ └── text2braille.hpp │ ├── braille_music.hpp │ ├── lilypond.hpp │ ├── math.hpp │ ├── music.hpp │ ├── musicxml.hpp │ └── output_format.hpp ├── lib ├── CMakeLists.txt ├── ast.cpp ├── brlsym.cpp ├── brlsym.hpp ├── key_signature.cpp ├── key_signature_def.hpp ├── lilypond.cpp ├── linebreaking.cpp ├── measure.cpp ├── measure_def.hpp ├── music.cpp ├── musicxml.cpp ├── numbers.cpp ├── numbers_def.hpp ├── partial_voice_sign.cpp ├── partial_voice_sign_def.hpp ├── reformat.cpp ├── score.cpp ├── score_def.hpp ├── simile.cpp ├── simile_def.hpp ├── spirit │ └── detail │ │ └── info_wchar_t_io.hpp ├── tables │ ├── brf.cpp │ ├── de.cpp │ ├── en_CA.cpp │ ├── en_GB.cpp │ ├── en_US.cpp │ ├── es.cpp │ ├── fr_CA.cpp │ └── fr_FR.cpp ├── text2braille.cpp ├── time_signature.cpp ├── time_signature_def.hpp ├── tuplet_start.cpp ├── tuplet_start_def.hpp ├── value_disambiguation.cpp └── value_disambiguator.cpp ├── main.cpp ├── midi.hpp ├── python.cpp ├── python └── bmc │ ├── __init__.py │ ├── rst.py │ └── sphinx.py ├── sphinx ├── .gitignore ├── CClef.svg ├── CMakeLists.txt ├── FClef.svg ├── GClef.svg ├── bmc.rst ├── chords-lh.bmc ├── conf.py.in ├── goldberg.rst ├── index.rst ├── intervals-lh.bmc ├── intervals-rh.bmc └── tutorial.rst ├── test ├── CMakeLists.txt ├── input │ ├── bwv988-aria.bmc │ ├── bwv988-v01.bmc │ ├── bwv988-v02.bmc │ ├── bwv988-v03.bmc │ ├── bwv988-v04.bmc │ ├── bwv988-v05.bmc │ ├── bwv988-v06.bmc │ ├── bwv988-v07.bmc │ ├── bwv988-v08.bmc │ ├── bwv988-v09.bmc │ ├── bwv988-v10.bmc │ ├── bwv988-v11.bmc │ ├── bwv988-v12.bmc │ ├── bwv988-v13.bmc │ ├── bwv988-v13.de.bmc │ ├── bwv988-v14.bmc │ ├── bwv988-v15.bmc │ ├── bwv988-v16.bmc │ ├── bwv988-v17.bmc │ ├── bwv988-v18.bmc │ ├── bwv988-v19.bmc │ ├── bwv988-v22.bmc │ └── bwv988-v30.bmc ├── m21.py ├── m21.sh ├── output │ ├── bwv988-v01.ly │ ├── bwv988-v01.ly.locations.expected │ ├── bwv988-v01.xml │ ├── bwv988-v02.ly │ ├── bwv988-v02.xml │ ├── bwv988-v03.ly │ ├── bwv988-v03.xml │ ├── bwv988-v04.ly │ ├── bwv988-v04.xml │ ├── bwv988-v05.ly │ ├── bwv988-v05.xml │ ├── bwv988-v06.ly │ ├── bwv988-v06.xml │ ├── bwv988-v07.ly │ ├── bwv988-v07.xml │ ├── bwv988-v08.ly │ ├── bwv988-v08.xml │ ├── bwv988-v09.ly │ ├── bwv988-v09.xml │ ├── bwv988-v10.ly │ ├── bwv988-v10.xml │ ├── bwv988-v11.ly │ ├── bwv988-v11.xml │ ├── bwv988-v12.ly │ ├── bwv988-v12.xml │ ├── bwv988-v13.ly │ ├── bwv988-v13.xml │ ├── bwv988-v14.ly │ ├── bwv988-v14.xml │ ├── bwv988-v15.ly │ ├── bwv988-v15.xml │ ├── bwv988-v16.ly │ ├── bwv988-v16.xml │ ├── bwv988-v17.ly │ ├── bwv988-v17.xml │ ├── bwv988-v18.ly │ ├── bwv988-v18.xml │ ├── bwv988-v19.ly │ ├── bwv988-v19.xml │ ├── bwv988-v22.ly │ ├── bwv988-v22.xml │ ├── bwv988-v30.ly │ ├── bwv988-v30.xml │ ├── score_tuplet_test4.ly │ └── score_tuplet_test8.ly └── test.cpp └── ui ├── CMakeLists.txt ├── gtk ├── BrailleMusicEditor.h ├── CMakeLists.txt ├── color.c ├── color.h ├── color_test ├── compile.c ├── compile.h ├── edit.c ├── edit.h ├── errors.c ├── errors.h ├── goto.c ├── goto.h ├── main.c ├── menubar.c ├── menubar.h ├── new.c ├── new.h ├── open.c ├── open.h ├── player.c ├── player.h ├── save.c ├── save.h ├── scoreviewer.c ├── scoreviewer.h ├── toolbar.c ├── toolbar.h ├── tops.c ├── tops.h ├── window.c └── window.h └── qt ├── .gitignore ├── CMakeLists.txt ├── app.cpp ├── app.qrc ├── config.h.in ├── images └── empty.svg ├── lilypondsvgcontainer.h ├── lilypondsvgwidget.cpp ├── lilypondsvgwidget.h ├── mainwindow.cpp ├── mainwindow.h ├── optionsdialog.cpp ├── optionsdialog.h └── sounds ├── fail.wav └── ok.wav /.gitignore: -------------------------------------------------------------------------------- 1 | /.ikiwiki 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "xsdcxx-musicxml"] 2 | path = xsdcxx-musicxml 3 | url = ../xsdcxx-musicxml.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: cpp 3 | 4 | matrix: 5 | include: 6 | - os: osx 7 | env: COMPILER=clang++ 8 | osx_image: xcode7 9 | - os: linux 10 | env: COMPILER=clang++-3.6 BOOST_VERSION=1.58.0 11 | addons: 12 | apt: 13 | packages: ["clang-3.6", "libxerces-c-dev"] 14 | sources: 15 | - ubuntu-toolchain-r-test 16 | - llvm-toolchain-precise-3.6 17 | - llvm-toolchain-precise-3.7 18 | - llvm-toolchain-precise 19 | - os: linux 20 | env: COMPILER=clang++-3.6 BOOST_VERSION=1.59.0 21 | addons: 22 | apt: 23 | packages: ["clang-3.6", "libxerces-c-dev"] 24 | sources: 25 | - ubuntu-toolchain-r-test 26 | - llvm-toolchain-precise-3.6 27 | - llvm-toolchain-precise-3.7 28 | - llvm-toolchain-precise 29 | 30 | before install: 31 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then; brew update; fi 32 | 33 | install: 34 | - | 35 | if [[ "$TRAVIS_OS_NAME" == "osx" ]] 36 | then brew install boost qt5 xerces-c xsd 37 | fi 38 | - | 39 | if [[ "$TRAVIS_OS_NAME" == "linux" ]] 40 | then cd .. 41 | wget --no-check-certificate --quiet -O - http://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz | tar -xz 42 | wget --no-check-certificate --quiet -O - http://www.codesynthesis.com/download/xsd/4.0/linux-gnu/x86_64/xsd-4.0.0-x86_64-linux-gnu.tar.bz2 | tar -jx 43 | cd ${TRAVIS_BUILD_DIR} 44 | elif [[ "$TRAVIS_OS_NAME" == "osx" ]] 45 | then cd .. 46 | wget --no-check-certificate --quiet -O - http://cmake.org/files/v3.4/cmake-3.4.3-Darwin-x86_64.tar.gz | tar -xz 47 | cd ${TRAVIS_BUILD_DIR} 48 | fi 49 | - | 50 | if [[ "$TRAVIS_OS_NAME" == "linux" ]] 51 | then cd .. 52 | mkdir boost 53 | wget --no-check-certificate --quiet -O - http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION//./_}.tar.bz2/download | tar jx --strip-components=1 -C boost 54 | cd boost 55 | ./bootstrap.sh --with-toolset=clang --with-libraries=program_options 56 | ./b2 headers 57 | ./b2 58 | cd ${TRAVIS_BUILD_DIR} 59 | fi 60 | 61 | script: 62 | - set -e 63 | - git submodule --quiet update --init --recursive 64 | - mkdir build 65 | - cd build 66 | - | 67 | if [[ "$TRAVIS_OS_NAME" == "linux" ]] 68 | then XSDDIR=${TRAVIS_BUILD_DIR}/../xsd-4.0.0-x86_64-linux-gnu ${TRAVIS_BUILD_DIR}/../cmake-3.4.3-Linux-x86_64/bin/cmake -Dbmc_USE_PYTHON=OFF -DBOOST_ROOT=${TRAVIS_BUILD_DIR}/../boost -DCMAKE_CXX_COMPILER=$COMPILER .. 69 | elif [[ "$TRAVIS_OS_NAME" == "osx" ]] 70 | then ${TRAVIS_BUILD_DIR}/../cmake-3.4.3-Darwin-x86_64/CMake.app/Contents/bin/cmake -Dbmc_USE_PYTHON=OFF -DCMAKE_CXX_COMPILER=$COMPILER .. 71 | fi 72 | - make check 73 | 74 | notifications: 75 | recipients: 76 | - mlang@blind.guru 77 | email: 78 | on_success: change 79 | on_failure: always 80 | 81 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | build: 3 | verbosity: minimal 4 | project: bmc.sln 5 | 6 | configuration: Release 7 | 8 | environment: 9 | BOOST_ROOT: 'c:\Libraries\boost_1_59_0' 10 | QTDIR: 'C:\Qt\5.5\msvc2013' 11 | XSDDIR: 'C:\Program Files (x86)\CodeSynthesis XSD 4.0' 12 | 13 | install: 14 | - git submodule --quiet update --init --recursive 15 | - curl.exe -s -o xsd-4.0.msi https://www.codesynthesis.com/download/xsd/4.0/windows/i686/xsd-4.0.msi 16 | - msiexec.exe /i xsd-4.0.msi /quiet /qn /norestart /log install.log 17 | 18 | before_build: 19 | - cd %XSDDIR%\xerces-c-3.1.1\projects\Win32\VC10\xerces-all 20 | - msbuild xerces-all.sln /t:XercesLib /p:PlatformToolset=v140 /P:Configuration="Static Release" 21 | - cd %BOOST_ROOT% 22 | - bootstrap.bat --with-libraries=program_options 23 | - b2.exe --build-type=complete --with-program_options stage 24 | - cd c:\projects\bmc 25 | - set PATH=%QTDIR%\bin;%XSDDIR%\bin;%PATH% 26 | - set CMAKE_PREFIX_PATH=%QTDIR%;%CMAKE_PREFIX_PATH% 27 | - cmake -G "Visual Studio 14 2015" -Dbmc_USE_PYTHON=OFF -DXercesC_INCLUDE_DIR="%XSDDIR%\include" -DXercesC_LIBRARY_DEBUG="%XSDDIR%\lib\vc-12.0\xerces-c_3D.lib" -DXercesC_LIBRARY_RELEASE="%XSDDIR%\xerces-c-3.1.1\Build\Win32\VC10\Static Release\xerces-c_static_3.lib" . 28 | 29 | build_script: 30 | - msbuild bmc.sln /t:bmc,bmc-ui,bmc_test /p:Configuration=Release 31 | - cd c:\projects\bmc\test 32 | - Release\bmc_test.exe 33 | 34 | artifacts: 35 | - path: Release/bmc.exe 36 | -------------------------------------------------------------------------------- /appveyor_logs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # A simple helper script to retrieve AppVeyor logs from the command line. 3 | # 4 | # Set the following git config variables: 5 | # $ git config appveyor.token 'Your AppVeyor Toekn' 6 | # $ git config appveyor.slug = 'user/project' 7 | # 8 | from urllib.request import Request, urlopen 9 | import json 10 | from subprocess import check_output 11 | 12 | def git_config(key): 13 | return check_output(['git', 'config', key]).decode('UTF-8').strip() 14 | 15 | def slug(): 16 | return git_config('appveyor.slug') 17 | 18 | def token(): 19 | return git_config('appveyor.token') 20 | 21 | api = 'https://ci.appveyor.com/api/' 22 | 23 | if __name__ == '__main__': 24 | req = Request(api + 'projects/' + slug()) 25 | req.add_header('Authorization', 'Bearer ' + token()) 26 | with urlopen(req) as api_resp: 27 | info = json.loads(api_resp.read().decode('UTF-8')) 28 | jobId = info['build']['jobs'][0]['jobId'] 29 | with urlopen(api + 'buildjobs/' + jobId + '/log') as log: 30 | print(log.read().decode('UTF-8')) 31 | print(api + 'projects/' + slug() + '/artifacts/Release/bmc.exe') 32 | 33 | 34 | -------------------------------------------------------------------------------- /bmcmdpp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | ############################################################################### 3 | # BMC MarkDown PreProcessor # 4 | ############################################################################### 5 | 6 | use strict; 7 | use warnings; 8 | use Digest::SHA qw(sha1_hex); 9 | use Getopt::Declare; 10 | use URI::Escape; 11 | my $args = Getopt::Declare->new(<<'EOARGS'); 12 | --bmc2ly Path to bmc2ly [required] 13 | EOARGS 14 | die "bmc2ly not executable" unless -x $args->{'--bmc2ly'}; 15 | 16 | sub munge($); 17 | 18 | print < 20 | .snippet-div { 21 | text-align: center; 22 | } 23 | .snippet-span { 24 | border: solid 1px; 25 | text-align: center; 26 | display: inline-block; 27 | padding: 10px; 28 | } 29 | .brailled pre { 30 | font-family: serif; 31 | } 32 | 33 | EOF 34 | 35 | # Read MarkDown from STDIN 36 | my $in_group = 0; 37 | my $text = ''; 38 | while (<>) { 39 | if (/^begin{(.*)}$/) { $in_group = 1; next; } 40 | if (/^end{(.*)}$/) { munge($text); $in_group = 0; $text = ''; next; } 41 | $text = $text . $_ if $in_group eq 1; 42 | print $_ if $in_group eq 0; 43 | } 44 | 45 | exit 0; 46 | 47 | sub munge($) { 48 | my $text = shift; 49 | my $out = "snippet_".sha1_hex($text); 50 | unlink "$out.svg", "$out.midi", "$out.mp3"; 51 | open FILE, "|$args->{'--bmc2ly'} --no-tagline - >$out.ly" 52 | or die "Unable to run bmc2ly"; 53 | print FILE $text; 54 | close(FILE) or die "Error running bmc2ly: $!"; 55 | system("lilypond", "-d", "backend=svg", "-d", "preview", "-d", "no-print-pages", "-lWARNING", "$out.ly") == 0 56 | or die "LilyPond failed"; 57 | die "No output from LilyPond" if ! -r "$out.preview.svg" or ! -r "$out.midi"; 58 | system("mv", "$out.preview.svg", "$out.svg") == 0 59 | or die "Failed to rename SVG"; 60 | system("timidity", "-idqq", "-Ow", "$out.midi") == 0 61 | or die "Timidity++ failed"; 62 | system("lame", "--silent", "-b", "64", "$out.wav", "$out.mp3") == 0 63 | or die "Lame failed"; 64 | unlink "$out.wav" or warn "Could not unlink $out.wav: $!"; 65 | my $encoded = uri_escape($text); 66 | print "
\n"; 67 | print " \n"; 68 | print "
";
69 |   my $brl;
70 |   open FILE, "|brltty-trtxt -6 -i de -o unicode -";
71 |   print FILE $text;
72 |   close(FILE) or die "Error during brltty-trtxt execution: $!";
73 |   print "
\n"; 74 | print < 76 | 77 | LilyPond 78 | 79 |
80 | MIDI | MP3 81 | | Edit 82 | 83 | 84 | EOHTML 85 | } 86 | 87 | -------------------------------------------------------------------------------- /cmake/FindLilypond.cmake: -------------------------------------------------------------------------------- 1 | # CMake find_package() Module for Lilypond music engraver 2 | # http://lilypond.org/ 3 | # 4 | # Example usage: 5 | # 6 | # find_package(Lilypond) 7 | # 8 | # If successful the following variables will be defined 9 | # LILYPOND_FOUND 10 | # LILYPOND_EXECUTABLE 11 | 12 | set(CMAKE_FIND_APPBUNDLE LAST) 13 | find_program(LILYPOND_EXECUTABLE 14 | NAMES lilypond 15 | PATH_SUFFIXES lilypond.app/Contents/Resources/bin 16 | DOC "Path to lilypond executable" 17 | ) 18 | 19 | # Handle REQUIRED and QUIET arguments 20 | # this will also set LILYPOND_FOUND to true if LILYPOND_EXECUTABLE exists 21 | include(FindPackageHandleStandardArgs) 22 | find_package_handle_standard_args(Lilypond 23 | "Failed to locate lilypond executable" LILYPOND_EXECUTABLE 24 | ) 25 | -------------------------------------------------------------------------------- /cmake/FindSphinxBuild.cmake: -------------------------------------------------------------------------------- 1 | # CMake find_package() Module for Sphinx documentation generator 2 | # http://sphinx-doc.org/ 3 | # 4 | # Example usage: 5 | # 6 | # find_package(SphinxBuild) 7 | # 8 | # If successful the following variables will be defined 9 | # SPHINX_BUILD_FOUND 10 | # SPHINX_BUILD_EXECUTABLE 11 | 12 | find_program(SPHINX_BUILD_EXECUTABLE 13 | NAMES sphinx-build sphinx-build2 14 | DOC "Path to sphinx-build executable" 15 | ) 16 | 17 | # Handle REQUIRED and QUIET arguments 18 | # this will also set SPHINX_BUILD_FOUND to true if SPHINX_BUILD_EXECUTABLE exists 19 | include(FindPackageHandleStandardArgs) 20 | find_package_handle_standard_args(SphinxBuild 21 | "Failed to locate sphinx-build executable" SPHINX_BUILD_EXECUTABLE 22 | ) 23 | -------------------------------------------------------------------------------- /config.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_CONFIG_HPP 8 | #define BMC_CONFIG_HPP 9 | 10 | #include 11 | 12 | #define BOOST_CONTROL_RATIONAL_HAS_GCD 0 13 | #define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT 14 | #define BOOST_SPIRIT_USE_PHOENIX_V3 15 | #define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 16 | 17 | #if defined(_MSC_VER) && _MSC_VER <= 1900 18 | #define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES 19 | #endif 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /doc/blog/20131014_weekend_hackaton_summary.mdwn: -------------------------------------------------------------------------------- 1 | This weekend ended up being quite productive. It actually already started during 2 | the past week by an exercise in learning about [music21](http://web.mit.edu/music21/). 3 | After I found (and filed) a few bugs related to music21's braille transcription 4 | abilities, I began work on enabling BMC to parse at least a bit of what 5 | music21 can generate. There is still work to do regarding the section 6 | formatting that music21 uses, but short excerpts of braille music can 7 | now be generated by music21 and parsed and validated by BMC. This might end 8 | up being an interesting tools for developers working on braille transcription 9 | software, since BMC can now be used as a sort of proof-reader. 10 | 11 | This whole new realm of possibilities is now being explored in an optional testsuite for BMC, which is being run when music21 is installed. 12 | It currently contains just three little melodies, but it can easily 13 | grow, and will be extended in the future. 14 | 15 | During evaluation of the result of one of these test melodies, I realized 16 | (late, but still) that we should really map notegroups to beaming. 17 | After a bit of thinking, it turned out to be lots easier then anticipated. 18 | Apparently, some parts of BMC are really well designed, that was made 19 | apparent by the ease of this addition. 20 | 21 | BMC's LilyPond output now places beams over notegroups in the braille input. 22 | This is an important improvement, as it links up two aspects 23 | of tactile and visual notation, that are quite different in how they 24 | are implemented in both worlds, but still do express a fundamentally equal concept. 25 | 26 | I also took a bit of time to rework test.cpp such that it doesn't do things unnecessarily twice. 27 | We have a bit more strict testing now, and the testsuite runtime dropped about 25%. 28 | This refactoring was long in order. 29 | 30 | All in all, this was a wonderful weekend for BMC development. 31 | -------------------------------------------------------------------------------- /doc/blog/20131023_recent_changes.mdwn: -------------------------------------------------------------------------------- 1 | A number of BMC improvements have been developed since the last post. 2 | 3 | * Measure range specifications (used to state what measure nubmers are part of a particular section) can now include alternative endings. 4 | * A few more test cases based on goldberg variations (var. 14 through 18) have been entered. 5 | * The goldberg variations currently parsed successfully by BMC are now available [here](/goldberg/). 6 | * Doubled slurs and staccato signs are now correctly translated to LilyPond. 7 | * bmc2ly has gained a true command-line option parser and now supports setting the default MIDI instrument for LilyPond exports. 8 | 9 | Plus the usual array of occasional cleanups. 10 | 11 | -------------------------------------------------------------------------------- /doc/blog/20131027_recent_changes.mdwn: -------------------------------------------------------------------------------- 1 | Fortunately I happened to have enough free time on my hand to make this weekend 2 | yet another BMC hackaton. 3 | 4 | It all started on last saturday when I finally worked on a rather old idea. 5 | I wanted to have the ability to write braille music code inline in some sort of 6 | document format (in our current case, that is MarkDown). This opens a few 7 | abilities: The braille music code can be verified using BMC. It can 8 | automatically be transcribed to visual notation using LilyPond. And 9 | as a by-product, we even get a aural rendition via LilyPond's MIDI output. 10 | After a bit of reactivating my Perl-Fu, I wrote 11 | [bmcmdpp](https://github.com/mlang/bmc/blob/master/bmcmdpp) which allows 12 | preprocessing of a MarkDown file to insert images and links to the aural 13 | rendition into the actual MarkDown file. This is definitely not 14 | ideal since it requires manual preprocessing. It would be nice 15 | to transform this functionality into an ikiwiki plugin compatible with 16 | branchable.com hosting. 17 | But that is a project for later on. Much more importan for now is the fact 18 | that we can now generate multi-modal examples for the web. 19 | 20 | As a result of this tool working as expected, I started to expand the 21 | [tutorial](../tutorial/) started last weekend. Have a look, it is already 22 | quite extensive and described and demonstrates many braille music code features 23 | already supported. 24 | 25 | As a side effect of working on the tutorial, I ended up implementing 26 | support for clef signs and proper handling of single and doubled slurs 27 | in BMC. The slur handling code is basically just a refactoring of work 28 | begun a few days ago. Turns out that we can do more with less code... 29 | Support for clefs is something that wasn't particularily hard, but also 30 | important since it was missing completely for really no good reason. 31 | There is still work to be done regarding interval direction detection, but 32 | that is something left for later on. 33 | 34 | -------------------------------------------------------------------------------- /doc/blog/BMC_found_its_first_print_error.mdwn: -------------------------------------------------------------------------------- 1 | Today, BMC found its first real error in a book of braille music. 2 | I am anticipating this event since at least a year, when I first started to realize the potential of automated validation of braille music code. 3 | However, its something different when you finally see it really happening! 4 | 5 | Consider the following measure of music, in 4/4 time (in G, one sharp): 6 | 7 | ((>h_eaflg{gh(il<+w"cj"ctsarq 8 | 9 | At first, when BMC refused to accept this, I was already searching for a programming error. 10 | Until I realized that the measure given is really invalid. 11 | 12 | In print, the first two beats are beamed 16th notes. The transcriber 13 | used a notegroup for the 16th notes on the second beat. But they apparently 14 | forgot to put dots 3 and 6 on the first 16th G. 15 | 16 | The correct measure is: 17 | 18 | ((>{_eaflg{gh(il<+w"cj"ctsarq 19 | 20 | Now that the first notegroup is correct, BMC can infer that all note durations 21 | match up with a time signature of 4/4. 22 | 23 | -------------------------------------------------------------------------------- /doc/blog/The_new_CGI_interface.mdwn: -------------------------------------------------------------------------------- 1 | We have a very rudimentary, but probably quite useful, web interface to BMC now. 2 | That means, you can enter braille music code in your web browser and have it processed 3 | by BMC to produce visual and aural renditions of your braille music. 4 | 5 | This is a first step to get the features we support already out to users. 6 | While BMC is quite easy to compile and install on Linux and probably Mac OS X, 7 | we haven't really amanged to make any progress on a Windows or iOS/Android port 8 | recently. So while I actually envisage even more fine-grained interactive 9 | features in the future, a web service is actually a useful start to bridge 10 | the cross-platform divide. 11 | 12 | You can find the current version of bmc.cgi [here](http://bmc.delysid.org/). 13 | 14 | Additionally, links have been placed in the [tutorial](../tutorial/) which allow to 15 | expand on the provided examples using this new web service. 16 | 17 | Concerning the backend, I have made BMC compliant with another braille 18 | music rule. A note group can never span across a music hyphen. Since music 19 | hyphens were previously parsed, but ignored in the AST, this had to be changed. 20 | A Music hyphen is now saved in the internal AST, and can be queried to 21 | stop note group search. 22 | 23 | -------------------------------------------------------------------------------- /doc/blog/Yet_another_transcriber_error_cought.mdwn: -------------------------------------------------------------------------------- 1 | While working with bwv988 variation 16, BMC just found yet another error 2 | in the original transcription to braille. Consider the following measure, in 3/8 time (G, one sharp): 3 | 4 | ⠨⠺⠄⠈⠉⠣⠜⠐⠺⠩⠙⠩⠑⠋⠁⠛⠇⠑⠃ 5 | 6 | Once alerted to it by BMC's value disambiguation algorithm, this one is actually 7 | easy to spot and fix. There is just one dot missing. Can you see which one it is? 8 | 9 | The first voice is rather clear, it consists of a dotted quarter note, which means it matches 3/8 time signature. 10 | If we follow whats written in braille, the second voice consists of either 11 | 6 64th notes, or a 64th note followed by 5 8th notes. Both possibilities make 12 | no sense, and do not match the length of the other voice. 13 | So BMC rightly barfs and reports this as a measure with no possible interpretations. 14 | 15 | The fix is, as already said, rather simple: 16 | 17 | ⠨⠺⠄⠈⠉⠣⠜⠐⠾⠩⠙⠩⠑⠋⠁⠛⠇⠑⠃ 18 | 19 | Now the second voice is a notegroup of 6 16th notes, which makes sense, and parses fine as unambiguous. 20 | 21 | BMC found actually *two* outright errors in the original transcription of this variation already. 22 | This is a rather nice demonstration that BMC can be very helpful as a proof-reading tool for transcribers, humans and computers, alike. 23 | 24 | -------------------------------------------------------------------------------- /doc/bugs.mdwn: -------------------------------------------------------------------------------- 1 | This is BMC's bug list. Link bugs to [[bugs/done]] when done. 2 | 3 | [[!inline pages="./bugs/* and !./bugs/done and !link(done) and !*/Discussion" 4 | actions=yes postform=yes show=0]] 5 | -------------------------------------------------------------------------------- /doc/bugs/done.mdwn: -------------------------------------------------------------------------------- 1 | recently fixed [[bugs]] 2 | 3 | [[!inline pages="./* and link(./done) and !*/Discussion" sort=mtime show=10]] 4 | -------------------------------------------------------------------------------- /doc/index.mdwn: -------------------------------------------------------------------------------- 1 | BMC stands for Braille Music Compiler. It aims to become a universal 2 | translator between various visual music notation formats and braille music code. 3 | A sort of bridge between visual and tactile music notation. 4 | At the moment, it can convert certain braille music code to LilyPond, which 5 | can later be converted (using LilyPond) to PDF and/or MIDI. 6 | BMC is currently being developed as a spare-time project by Mario Lang. 7 | 8 | This is a list of braille music code features that BMC already supports: 9 | 10 | * Full and partial measure in-accord. 11 | * Ambiguity resolution (automatic value deduction including support for value distinction signs). 12 | * Note grouping (decoded and emitted as beams in visual notation). 13 | * Tuplets. 14 | * Anacrusis. 15 | * Repeat barlines and alternative endings. 16 | * Section-by-section solo and keyboard music (parts with one or two staves). 17 | * Partial support for simile signs (full and partial measure repetition). 18 | 19 | The following is a list of braille music code features which are currently not yet supported by BMC: 20 | 21 | * Doubling. 22 | * Repeated ranges of measures. 23 | * Polymetric music (music on staves with different time signatures). 24 | * Bar-over-bar format. 25 | 26 | BMC can already be used to read braille music code of substantial complexity. Have a look at the [goldberg variations](goldberg) to see a few examples of BMC in action. 27 | 28 | For braille music beginners, we are developing a small [[tutorial]]. 29 | 30 | A web frontend to BMC can be found [here](http://bmc.delysid.org/). 31 | 32 | ## See also 33 | * [[News]] 34 | * [[Source]] 35 | * [[Bugs]] 36 | * [[CodingStyle]] 37 | * [[Contact]] 38 | 39 | # Development blog 40 | 41 | [[!inline pages="./blog/* and !*/Discussion" actions=yes show=5]] 42 | -------------------------------------------------------------------------------- /doc/news.mdwn: -------------------------------------------------------------------------------- 1 | This is where announcements of new releases, features, and other news is 2 | posted. BMC users are recommended to subscribe to this page's RSS 3 | feed. 4 | 5 | 6 | [[!inline pages="./news/* and !*/Discussion" show="30"]] 7 | -------------------------------------------------------------------------------- /doc/news/Documentation_Wiki_started.mdwn: -------------------------------------------------------------------------------- 1 | To give it more exposure, we are just about to create documentation for BMC on this brand new site. 2 | 3 | Please excuse the empty site for now, we are working on making it useful. 4 | -------------------------------------------------------------------------------- /doc/output/bwv988-v01.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v01.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v01.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v01.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v02.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v02.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v02.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v03.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v03.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v03.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v04.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v04.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v04.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v04.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v05.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v05.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v05.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v05.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v06.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v06.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v06.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v06.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v07.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v07.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v07.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v07.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v08.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v08.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v08.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v08.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v09.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v09.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v09.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v09.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v10.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v10.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v10.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v11.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v11.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v11.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v11.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v12.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v12.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v12.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v12.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v13.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v13.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v13.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v13.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v14.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v14.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v14.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v14.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v15.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v15.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v15.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v15.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v16.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v16.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v16.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v16.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v17.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v17.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v17.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v17.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v18.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v18.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v18.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v18.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v19.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v19.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v19.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v19.pdf -------------------------------------------------------------------------------- /doc/output/bwv988-v30.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v30.midi -------------------------------------------------------------------------------- /doc/output/bwv988-v30.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/output/bwv988-v30.pdf -------------------------------------------------------------------------------- /doc/source.mdwn: -------------------------------------------------------------------------------- 1 | This is how to compile BMC from source. 2 | 3 | $ git clone git://bmc.branchable.com/ bmc 4 | $ mkdir -p build/bmc 5 | $ cd build/bmc 6 | $ cmake ../../bmc 7 | $ make 8 | 9 | Run the test suite like this: 10 | 11 | $ make check 12 | 13 | To install the binary programs and libraries onto your system, run: 14 | 15 | $ make install 16 | 17 | bmc should be installed in /usr/local/bin now. 18 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \key f \major 11 | \time 6/8 12 | f'8 f' a' c''8. a'16 c''8 | % 1 13 | f,8 g, a, bes,4. | % 2 14 | } 15 | >> 16 | 17 | \score { 18 | \music 19 | \layout { } 20 | } 21 | \score { 22 | \unfoldRepeats \articulate \music 23 | \midi { } 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1197f47ddb2f34c591fc67d863f129fdd1650d61.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | c''4 \times 2/3 { e''8 f'' g'' } \times 2/3 { f'' \times 2/3 { e''16 f'' e'' } d''8 } c''4 | % 1 11 | } 12 | >> 13 | 14 | \score { 15 | \music 16 | \layout { } 17 | } 18 | \score { 19 | \unfoldRepeats \articulate \music 20 | \midi { } 21 | } 22 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1246eb55d4edcfd00bd9caeee58e9b994c4b3421.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \clef G 4 8 4 8 r | % 1 11 | } 12 | >> 13 | 14 | \score { 15 | \music 16 | \layout { } 17 | } 18 | \score { 19 | \unfoldRepeats \articulate \music 20 | \midi { } 21 | } 22 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_1ace53b3a95407d4abd234a7b6c17ece47c2651c.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 6/8 11 | b'8 b' b' b' b' b' | % 1 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_206d45bafb0b7299536ba1d0873ef47d041178ab.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_3f68e0222f816f35c97900b69f9b1b081540788e.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | 4 | % 1 12 | 2. | % 2 13 | } 14 | >> 15 | 16 | \score { 17 | \music 18 | \layout { } 19 | } 20 | \score { 21 | \unfoldRepeats \articulate \music 22 | \midi { } 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_3f68e0222f816f35c97900b69f9b1b081540788e.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_3f68e0222f816f35c97900b69f9b1b081540788e.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_3f68e0222f816f35c97900b69f9b1b081540788e.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_3f68e0222f816f35c97900b69f9b1b081540788e.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_4f88d827469b646785a22e91d4fd3e8981101fad.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | r8 g'( e') r r c''( | % 1 12 | bes'8 a') r f''( d'' b' | % 2 13 | c''4) r2 | % 3 14 | } 15 | >> 16 | 17 | \score { 18 | \music 19 | \layout { } 20 | } 21 | \score { 22 | \unfoldRepeats \articulate \music 23 | \midi { } 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_4f88d827469b646785a22e91d4fd3e8981101fad.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_4f88d827469b646785a22e91d4fd3e8981101fad.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_4f88d827469b646785a22e91d4fd3e8981101fad.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_4f88d827469b646785a22e91d4fd3e8981101fad.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_62639a3f85da78f4be7b92367333ca0570057d1f.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 6/8 11 | c'8 e' g' a'4 c''8 | % 1 12 | d''8 f'' a'' b'' d''' f''' | % 2 13 | e'''8 g''' b''' c'''' a''' f''' | % 3 14 | d'''8 b'' g'' f'' d'' b' | % 4 15 | g'4 f'8 d'4 e'8 | % 5 16 | c'2. | % 6 17 | } 18 | >> 19 | 20 | \score { 21 | \music 22 | \layout { } 23 | } 24 | \score { 25 | \unfoldRepeats \articulate \music 26 | \midi { } 27 | } 28 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_62639a3f85da78f4be7b92367333ca0570057d1f.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_62639a3f85da78f4be7b92367333ca0570057d1f.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_62639a3f85da78f4be7b92367333ca0570057d1f.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_62639a3f85da78f4be7b92367333ca0570057d1f.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_95147d3db25b99789406d175cbe66a271c1678e9.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \partial 16 11 | g16 | % 0 12 | c'8 r b r c' r d' r | % 1 13 | e'8 r f' r d'2 | % 2 14 | } 15 | >> 16 | 17 | \score { 18 | \music 19 | \layout { } 20 | } 21 | \score { 22 | \unfoldRepeats \articulate \music 23 | \midi { } 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_95147d3db25b99789406d175cbe66a271c1678e9.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_95147d3db25b99789406d175cbe66a271c1678e9.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_95147d3db25b99789406d175cbe66a271c1678e9.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_95147d3db25b99789406d175cbe66a271c1678e9.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 1/4 11 | c,,4 | % 1 12 | c,4 | % 2 13 | c4 | % 3 14 | c'4 | % 4 15 | c''4 | % 5 16 | c'''4 | % 6 17 | c''''4 | % 7 18 | } 19 | >> 20 | 21 | \score { 22 | \music 23 | \layout { } 24 | } 25 | \score { 26 | \unfoldRepeats \articulate \music 27 | \midi { } 28 | } 29 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_a51a86e58e705729afeff9bcb6ccfc8f04691ec6.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_a534c14987afc4508effaccb7f8588071299d286.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | r16[ e' f' g'] r[ f' g' a'] r[ g' a' b'] | % 1 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_a534c14987afc4508effaccb7f8588071299d286.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_a534c14987afc4508effaccb7f8588071299d286.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_a534c14987afc4508effaccb7f8588071299d286.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_a534c14987afc4508effaccb7f8588071299d286.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | g'4 g'8 c'' << {f''2}\\{c''4 b'8 a'} >> | % 1 11 | 2. r4 | % 2 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_ae2a42ef8b85f66338667a864d9a5997a68256d0.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 2/4 11 | g'4( a'8 b' | % 1 12 | c''4 d''8 e'' | % 2 13 | f''4 e''8 d'' | % 3 14 | e''4 c''8) r | % 4 15 | } 16 | >> 17 | 18 | \score { 19 | \music 20 | \layout { } 21 | } 22 | \score { 23 | \unfoldRepeats \articulate \music 24 | \midi { } 25 | } 26 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b77e1bce61b64430cd0ef0ab5357862ab368b797.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | << {c''1}\\{e'4 d' e' f'} >> | % 1 11 | << {b'1}\\{g'4 f' e' d'} >> | % 2 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b8028b0a870cafb04fb2160ddf4eaf7e5f859d2f.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | e''2 d''4 c'' | % 1 11 | a'4 d''2 c''4 | % 2 12 | b'4 e''2 d''4 | % 3 13 | c''2 f''4 e'' | % 4 14 | d''4 g''2 f''4 | % 5 15 | e''4 c'' a'' c'' | % 6 16 | b'8 c'' d'' e'' f'' g'' a'' b'' | % 7 17 | c'''2 r | % 8 18 | } 19 | >> 20 | 21 | \score { 22 | \music 23 | \layout { } 24 | } 25 | \score { 26 | \unfoldRepeats \articulate \music 27 | \midi { } 28 | } 29 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_b9cf4d2c86f86eca81856501b1eaffab5faabbc0.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_c1dae73a06fc54c80b53e57d3842fb2de1ab54f1.ly: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_c1dae73a06fc54c80b53e57d3842fb2de1ab54f1.ly -------------------------------------------------------------------------------- /doc/tutorial/snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 4/4 11 | c'16[ d' e' f'] g'[ a' b' c''] d''[ c'' b' a'] g'[ f' e' d'] | % 1 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_c66de7c4c7212e188bc110c8a1f6213150bcc4d5.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_cec08a48509e49a2972a365617373114b21976f6.ly: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_cec08a48509e49a2972a365617373114b21976f6.ly -------------------------------------------------------------------------------- /doc/tutorial/snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \key f \major 11 | \time 6/8 12 | f'8 f' a' c''8. a'16 c''8 | % 1 13 | \clef F f,8 g, a, bes,4. | % 2 14 | } 15 | >> 16 | 17 | \score { 18 | \music 19 | \layout { } 20 | } 21 | \score { 22 | \unfoldRepeats \articulate \music 23 | \midi { } 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_d3f57fa0ada3287616707b7b6788de68d9f4fc89.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_da06795ce64673da4bb1171f13e119bb271763e5.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new PianoStaff << 10 | \new Staff = "RH" { 11 | \clef "treble" 12 | \time 4/4 13 | r1 | % 1 14 | r1 | % 2 15 | r1 | % 3 16 | r1 | % 4 17 | r1 | % 5 18 | r1 | % 6 19 | r1 | % 7 20 | } 21 | \new Staff = "LH" { 22 | \clef "bass" 23 | \time 4/4 24 | 1 | % 1 25 | 1 | % 2 26 | 1 | % 3 27 | 1 | % 4 28 | 1 | % 5 29 | 1 | % 6 30 | 1 | % 7 31 | } 32 | >> 33 | >> 34 | 35 | \score { 36 | \music 37 | \layout { } 38 | } 39 | \score { 40 | \unfoldRepeats \articulate \music 41 | \midi { } 42 | } 43 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_da06795ce64673da4bb1171f13e119bb271763e5.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_da06795ce64673da4bb1171f13e119bb271763e5.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_da06795ce64673da4bb1171f13e119bb271763e5.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_da06795ce64673da4bb1171f13e119bb271763e5.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | c'8 d' e' c' f' c' | % 1 12 | g'8 c' a'2 | % 2 13 | } 14 | >> 15 | 16 | \score { 17 | \music 18 | \layout { } 19 | } 20 | \score { 21 | \unfoldRepeats \articulate \music 22 | \midi { } 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_dafedf9c6fb3ad06d5df1abbabf9f89c4502ee68.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_db593fd6120808f1ad00aeef540c460ba2710513.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new PianoStaff << 10 | \new Staff = "RH" { 11 | \clef "treble" 12 | \time 4/4 13 | 1 | % 1 14 | 1 | % 2 15 | 1 | % 3 16 | 1 | % 4 17 | 1 | % 5 18 | 1 | % 6 19 | 1 | % 7 20 | } 21 | \new Staff = "LH" { 22 | \clef "bass" 23 | \time 4/4 24 | r1 | % 1 25 | r1 | % 2 26 | r1 | % 3 27 | r1 | % 4 28 | r1 | % 5 29 | r1 | % 6 30 | r1 | % 7 31 | } 32 | >> 33 | >> 34 | 35 | \score { 36 | \music 37 | \layout { } 38 | } 39 | \score { 40 | \unfoldRepeats \articulate \music 41 | \midi { } 42 | } 43 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_db593fd6120808f1ad00aeef540c460ba2710513.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_db593fd6120808f1ad00aeef540c460ba2710513.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_db593fd6120808f1ad00aeef540c460ba2710513.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_db593fd6120808f1ad00aeef540c460ba2710513.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 6/8 11 | c'8 e' g' a' c' a' | % 1 12 | c'8 bes' c' a' c' a' | % 2 13 | g'2. | % 3 14 | } 15 | >> 16 | 17 | \score { 18 | \music 19 | \layout { } 20 | } 21 | \score { 22 | \unfoldRepeats \articulate \music 23 | \midi { } 24 | } 25 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_dd8a73cbd5e4fe4b8aed61f902afdf653aecac45.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | << {g'8 e' << {a'8. g'16 f'8 e'16 f' g'[ f' e' d']}\\{c'8 a d'8. c'16 b8 a16 b} >>}\\{g1} >> | % 1 11 | } 12 | >> 13 | 14 | \score { 15 | \music 16 | \layout { } 17 | } 18 | \score { 19 | \unfoldRepeats \articulate \music 20 | \midi { } 21 | } 22 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_e30483dd2d16f8ba7ac0e92caa5206f4e692889b.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | g'8 a' b' g' c'' g' | % 1 12 | d''8 g' e''2 | % 2 13 | } 14 | >> 15 | 16 | \score { 17 | \music 18 | \layout { } 19 | } 20 | \score { 21 | \unfoldRepeats \articulate \music 22 | \midi { } 23 | } 24 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_ee1c1d5a7eca5a3dcee24a61ae3812993e32fefe.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new Staff { 10 | \time 3/4 11 | c''2 c''32 d'' e'' f'' g''8 | % 1 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_f68f805f8aa758a5c6ac4090adbc5855a1124f7a.mp3 -------------------------------------------------------------------------------- /doc/tutorial/snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | \header { 5 | tagline = "" 6 | } 7 | music = 8 | << 9 | \new PianoStaff << 10 | \new Staff = "RH" { 11 | \clef "treble" 12 | \key d \major 13 | \time 4/4 14 | r1 | % 1 15 | } 16 | \new Staff = "LH" { 17 | \clef "bass" 18 | \key d \major 19 | \time 4/4 20 | 4 8. 16 4 r | % 1 21 | } 22 | >> 23 | >> 24 | 25 | \score { 26 | \music 27 | \layout { } 28 | } 29 | \score { 30 | \unfoldRepeats \articulate \music 31 | \midi { } 32 | } 33 | -------------------------------------------------------------------------------- /doc/tutorial/snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.midi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.midi -------------------------------------------------------------------------------- /doc/tutorial/snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/doc/tutorial/snippet_f8f302c38d883acc4f69bd6256755e03769c1c25.mp3 -------------------------------------------------------------------------------- /doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Doxygen REQUIRED) 2 | include(FindLATEX) 3 | configure_file(Doxyfile.in Doxyfile) 4 | add_custom_target(doxygen) 5 | if(DOXYGEN_FOUND) 6 | add_custom_command(TARGET doxygen 7 | COMMAND ${DOXYGEN_EXECUTABLE} 8 | ) 9 | add_custom_command(TARGET doxygen 10 | COMMAND ${PDFLATEX_COMPILER} refman.tex 11 | WORKING_DIRECTORY latex 12 | ) 13 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.pdf 14 | DESTINATION share/doc/${CMAKE_PROJECT_NAME} 15 | ) 16 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc/${CMAKE_PROJECT_NAME}) 17 | endif() 18 | -------------------------------------------------------------------------------- /doxygen/main.doxygen: -------------------------------------------------------------------------------- 1 | /** \mainpage Overview 2 | 3 | \section intro Introduction 4 | 5 | \subsection whatis What is Braille Music? 6 | 7 | \defgroup music music 8 | \defgroup braille braille 9 | \ingroup music 10 | \defgroup compilation compilation 11 | \ingroup braille 12 | \defgroup grammar grammar 13 | \ingroup braille 14 | */ 15 | -------------------------------------------------------------------------------- /fluidsynth.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include "bmc/braille/ast.hpp" 9 | #include "midi.hpp" 10 | 11 | namespace bmc { 12 | 13 | class fluidsynth 14 | : public boost::static_visitor 15 | { 16 | fluid_settings_t *settings; 17 | fluid_synth_t *synth; 18 | fluid_audio_driver_t *audio_driver; 19 | midi::event_queue queue; 20 | unsigned int ppq, bpm; 21 | rational current_position; 22 | public: 23 | fluidsynth(std::string const& soundfont); 24 | fluidsynth(fluidsynth const&) = delete; 25 | fluidsynth& operator=(fluidsynth const&) = delete; 26 | fluidsynth(fluidsynth&&); 27 | ~fluidsynth(); 28 | 29 | void operator()(midi::note_on const&); 30 | void operator()(midi::note_off const&); 31 | 32 | void operator()(braille::ast::score const&); 33 | void operator()(braille::ast::measure const&); 34 | result_type operator()(braille::ast::key_and_time_signature const&) {}; 35 | private: 36 | void play(); 37 | }; 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /include/bmc/braille/ast.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_AST_HPP 8 | #define BMC_AST_HPP 9 | 10 | #include "bmc/braille/ast/ast.hpp" 11 | #include "bmc/braille/ast/visitors.hpp" 12 | #include "bmc/braille/ast/duration.hpp" 13 | #include "bmc/braille/ast/fusion_adapt.hpp" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/bmc/braille/ast/fusion_adapt.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BMC_AST_FUSION_ADAPT_HPP 2 | #define BMC_AST_FUSION_ADAPT_HPP 3 | 4 | #include "bmc/braille/ast/ast.hpp" 5 | #include 6 | #include 7 | 8 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::clef, 9 | sign, line, other_staff 10 | ) 11 | 12 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::slur, 13 | value 14 | ) 15 | 16 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::tie, 17 | value 18 | ) 19 | 20 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::hand_sign, 21 | value 22 | ) 23 | 24 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::rest, 25 | by_transcriber, ambiguous_value, dots 26 | ) 27 | 28 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::stem, 29 | type, dots, tied 30 | ) 31 | 32 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::note, 33 | articulations, acc, octave_spec, step, ambiguous_value, dots, slurs, fingers, 34 | tie, extra_stems 35 | ) 36 | 37 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::interval, 38 | acc, octave_spec, steps, fingers, tie 39 | ) 40 | 41 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::chord, 42 | base, intervals, all_tied 43 | ) 44 | 45 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::moving_note, 46 | base, intervals 47 | ) 48 | 49 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::value_prefix, 50 | value 51 | ) 52 | 53 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::simile, 54 | octave_spec, count 55 | ) 56 | 57 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::measure, 58 | ending, voices 59 | ) 60 | 61 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::key_and_time_signature, 62 | key, time 63 | ) 64 | 65 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::measure_specification, 66 | number, alternative 67 | ) 68 | 69 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::measure_range, 70 | first, last 71 | ) 72 | 73 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::section, 74 | key_and_time_sig, number, range, paragraphs 75 | ) 76 | 77 | BOOST_FUSION_ADAPT_STRUCT(::bmc::braille::ast::score, 78 | key_sig, time_sigs, parts 79 | ) 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /include/bmc/braille/linebreaking.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_BRAILLE_LINEBREAKING_HPP_INCLUDED 8 | #define BMC_BRAILLE_LINEBREAKING_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace bmc { namespace braille { namespace linebreaking { 16 | 17 | struct object { 18 | virtual ~object() {} 19 | }; 20 | 21 | struct box: public object { 22 | virtual int width() const = 0; 23 | virtual bool is_guide() const = 0; 24 | }; 25 | 26 | struct glue: public object { 27 | virtual int width() const = 0; 28 | }; 29 | 30 | int const infinity = std::numeric_limits::max() - 1; 31 | 32 | struct penalty: public object { 33 | virtual int width() const = 0; 34 | virtual int value() const = 0; 35 | }; 36 | 37 | using objects = std::vector>; 38 | 39 | std::deque 40 | breakpoints(objects const &objs, std::vector const &line_lengths); 41 | 42 | }}} 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/annotation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #if !defined(BMC_ANNOTATIONS_HPP) 8 | #define BMC_ANNOTATIONS_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include "bmc/braille/ast.hpp" 14 | 15 | namespace bmc { namespace braille { 16 | 17 | template 18 | struct annotation 19 | { 20 | template 21 | struct result { typedef void type; }; 22 | 23 | std::vector>& ranges; 24 | annotation(std::vector>& ranges) 25 | : ranges(ranges) 26 | { 27 | } 28 | 29 | void operator()( ast::locatable& ast 30 | , Iterator begin, Iterator end 31 | ) const 32 | { 33 | std::size_t id = ranges.size(); 34 | ranges.emplace_back(begin, end); 35 | ast.id = id; 36 | } 37 | }; 38 | 39 | }} 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/key_signature.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_KEY_SIGNATURE_HPP 8 | #define BMC_KEY_SIGNATURE_HPP 9 | 10 | #include "config.hpp" 11 | #include "bmc/music.hpp" 12 | #include "bmc/braille/parsing/grammar/numbers.hpp" 13 | #include 14 | 15 | namespace bmc { namespace braille { 16 | 17 | /** 18 | * \brief A grammar for parsing a braille key signature. 19 | * 20 | * \ingroup grammar 21 | */ 22 | template 23 | struct key_signature_grammar : boost::spirit::qi::grammar 24 | { 25 | key_signature_grammar(); 26 | 27 | boost::spirit::qi::rule start; 28 | boost::spirit::qi::rule flat_sign, sharp_sign; 29 | upper_number_grammar upper_number; 30 | }; 31 | 32 | }} 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/measure.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_MEASURE_HPP 8 | #define BMC_MEASURE_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include "bmc/braille/ast/ast.hpp" 13 | #include "bmc/braille/parsing/grammar/numbers.hpp" 14 | #include "bmc/braille/parsing/grammar/partial_voice_sign.hpp" 15 | #include "bmc/braille/parsing/error_handler.hpp" 16 | 17 | namespace bmc { namespace braille { 18 | 19 | /** 20 | * \brief A grammar for parsing a single braille music measure. 21 | * 22 | * \ingroup grammar 23 | */ 24 | template 25 | struct measure_grammar : boost::spirit::qi::grammar 26 | { 27 | measure_grammar(error_handler&); 28 | 29 | boost::spirit::qi::rule start; 30 | boost::spirit::qi::rule voice; 31 | boost::spirit::qi::rule partial_measure; 32 | boost::spirit::qi::rule partial_voice; 33 | partial_voice_sign_grammar partial_voice_sign; 34 | boost::spirit::qi::rule 35 | full_measure_in_accord, partial_measure_sign, partial_measure_in_accord, 36 | optional_dot; 37 | upper_number_grammar upper_number; 38 | lower_number_grammar lower_number; 39 | boost::spirit::qi::rule ending; 40 | }; 41 | 42 | }} 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/numbers.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #if !defined(BMC_NUMBERS_HPP) 8 | #define BMC_NUMBERS_HPP 9 | 10 | #include "config.hpp" 11 | #include "bmc/music.hpp" 12 | #include 13 | 14 | namespace bmc { namespace braille { 15 | 16 | /** 17 | * \brief A grammar for parsing a sequence of braille digits written in the 18 | * upper part (dots 1 2 4 5) of a 6-dot braille cell as a (unsigned) number. 19 | * 20 | * \ingroup grammar 21 | * \see lower_number_grammar 22 | */ 23 | template 24 | struct upper_number_grammar : boost::spirit::qi::grammar 25 | { 26 | upper_number_grammar(); 27 | 28 | boost::spirit::qi::rule start; 29 | }; 30 | 31 | /** 32 | * \brief A grammar for parsing a sequence of braille digits written in the 33 | * lower part (dots 2 3 5 6) of a 6-dot braille cell as a (unsigned) number. 34 | * 35 | * \ingroup grammar 36 | * \see upper_number_grammar 37 | */ 38 | template 39 | struct lower_number_grammar : boost::spirit::qi::grammar 40 | { 41 | lower_number_grammar(); 42 | 43 | boost::spirit::qi::rule start; 44 | }; 45 | 46 | }} 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/partial_voice_sign.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_PARTIAL_VOICE_SIGN_HPP 8 | #define BMC_PARTIAL_VOICE_SIGN_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include "bmc/braille/ast/ast.hpp" 13 | #include "bmc/braille/parsing/grammar/numbers.hpp" 14 | #include "bmc/braille/parsing/grammar/simile.hpp" 15 | #include "bmc/braille/parsing/grammar/tuplet_start.hpp" 16 | #include "bmc/braille/parsing/error_handler.hpp" 17 | 18 | namespace bmc { namespace braille { 19 | 20 | /** 21 | * \brief A grammar for parsing a single braille music measure. 22 | * 23 | * \ingroup grammar 24 | */ 25 | template 26 | struct partial_voice_sign_grammar : boost::spirit::qi::grammar 27 | { 28 | partial_voice_sign_grammar(error_handler&); 29 | 30 | boost::spirit::qi::rule start; 31 | boost::spirit::qi::rule note; 32 | boost::spirit::qi::rule stem; 33 | boost::spirit::qi::rule added_by_transcriber; 34 | boost::spirit::qi::rule rest; 35 | boost::spirit::qi::rule chord; 36 | boost::spirit::qi::rule moving_note; 37 | boost::spirit::qi::rule()> moving_intervals; 38 | boost::spirit::qi::rule interval; 39 | boost::spirit::qi::rule finger_sign; 40 | boost::spirit::qi::rule finger_change; 41 | boost::spirit::qi::rule fingering; 42 | tuplet_start_grammar tuplet_start; 43 | boost::spirit::qi::rule hand_sign; 44 | boost::spirit::qi::rule clef; 45 | simile_grammar simile; 46 | boost::spirit::qi::rule dots; 47 | boost::spirit::qi::rule slur; 48 | boost::spirit::qi::rule tie, simple_tie; 49 | boost::spirit::qi::rule chord_tied_sign; 50 | boost::spirit::qi::rule value_prefix; 51 | boost::spirit::qi::rule hyphen; 52 | boost::spirit::qi::rule optional_dot; 53 | }; 54 | 55 | }} 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/score.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_SCORE_HPP 8 | #define BMC_SCORE_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include "bmc/braille/ast/ast.hpp" 13 | #include "bmc/braille/parsing/error_handler.hpp" 14 | #include "bmc/braille/parsing/grammar/measure.hpp" 15 | #include "bmc/braille/parsing/grammar/key_signature.hpp" 16 | #include "bmc/braille/parsing/grammar/time_signature.hpp" 17 | 18 | namespace bmc { namespace braille { 19 | 20 | /** 21 | * \brief Top-level grammar for parsing braille music scores. 22 | * 23 | * \ingroup grammar 24 | */ 25 | template 26 | struct score_grammar : boost::spirit::qi::grammar 27 | { 28 | score_grammar(error_handler&); 29 | 30 | boost::spirit::qi::rule start; 31 | boost::spirit::qi::rule solo_part, keyboard_part; 32 | boost::spirit::qi::rule keyboard_section, last_keyboard_section; 33 | boost::spirit::qi::rule solo_section, last_solo_section; 34 | boost::spirit::qi::rule paragraph; 35 | boost::spirit::qi::rule section_number; 36 | boost::spirit::qi::rule measure_range; 37 | boost::spirit::qi::rule measure_specification; 38 | measure_grammar measure; 39 | time_signature_grammar time_signature; 40 | key_signature_grammar key_signature; 41 | upper_number_grammar upper_number; 42 | lower_number_grammar lower_number; 43 | boost::spirit::qi::rule key_and_time_signature; 44 | boost::spirit::qi::rule right_hand_sign, left_hand_sign; 45 | boost::spirit::qi::rule eom; 46 | boost::spirit::qi::rule optional_dot, whitespace, indent; 47 | }; 48 | 49 | }} 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/simile.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_SIMILE_HPP 8 | #define BMC_SIMILE_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include "bmc/braille/ast/ast.hpp" 13 | #include "bmc/braille/parsing/grammar/numbers.hpp" 14 | #include "bmc/braille/parsing/grammar/simile.hpp" 15 | #include "bmc/braille/parsing/error_handler.hpp" 16 | 17 | namespace bmc { namespace braille { 18 | 19 | /** 20 | * \brief A grammar for parsing a single braille music measure. 21 | * 22 | * \ingroup grammar 23 | */ 24 | template 25 | struct simile_grammar : boost::spirit::qi::grammar> 26 | { 27 | simile_grammar(error_handler&); 28 | 29 | boost::spirit::qi::rule> start; 30 | upper_number_grammar upper_number; 31 | }; 32 | 33 | }} 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/time_signature.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #if !defined(BMC_TIME_SIGNATURE_HPP) 8 | #define BMC_TIME_SIGNATURE_HPP 9 | 10 | #include "config.hpp" 11 | #include "bmc/music.hpp" 12 | #include "bmc/braille/parsing/grammar/numbers.hpp" 13 | #include 14 | 15 | namespace bmc { namespace braille { 16 | 17 | /** 18 | * \brief A grammar for parsing a braille time signature. 19 | * 20 | * \ingroup grammar 21 | */ 22 | template 23 | struct time_signature_grammar 24 | : boost::spirit::qi::grammar< Iterator 25 | , ::bmc::time_signature() 26 | , boost::spirit::qi::locals 27 | > 28 | { 29 | time_signature_grammar(); 30 | 31 | boost::spirit::qi::rule< Iterator 32 | , ::bmc::time_signature() 33 | , boost::spirit::qi::locals 34 | > start; 35 | upper_number_grammar upper_number; 36 | lower_number_grammar lower_number; 37 | }; 38 | 39 | }} 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /include/bmc/braille/parsing/grammar/tuplet_start.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_TUPLET_START_HPP 8 | #define BMC_TUPLET_START_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include "bmc/braille/ast/ast.hpp" 13 | #include "bmc/braille/parsing/grammar/numbers.hpp" 14 | #include "bmc/braille/parsing/error_handler.hpp" 15 | 16 | namespace bmc { namespace braille { 17 | 18 | /** 19 | * \brief A grammar for parsing a single braille music measure. 20 | * 21 | * \ingroup grammar 22 | */ 23 | template 24 | struct tuplet_start_grammar : boost::spirit::qi::grammar> 25 | { 26 | tuplet_start_grammar(error_handler&); 27 | 28 | boost::spirit::qi::rule> start; 29 | lower_number_grammar lower_number; 30 | }; 31 | 32 | }} 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/bmc/braille/reformat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_BRAILLE_REFORMAT_HPP_INCLUDED 8 | #define BMC_BRAILLE_REFORMAT_HPP_INCLUDED 9 | 10 | #include "bmc/braille/ast.hpp" 11 | 12 | #include 13 | 14 | namespace bmc { namespace braille { 15 | 16 | struct format_style { 17 | unsigned columns = 40; 18 | }; 19 | 20 | struct output { 21 | struct fragment { 22 | std::u32string unicode; 23 | std::string description; 24 | bool needs_guide_dot; 25 | fragment(std::u32string const &unicode, std::string const &description, bool needs_guide_dot = false) 26 | : unicode{unicode}, description{description}, needs_guide_dot{needs_guide_dot} {} 27 | }; 28 | std::vector fragments; 29 | }; 30 | 31 | output reformat(ast::score const &, format_style const &style = format_style()); 32 | 33 | std::ostream &operator<<(std::ostream &, output const &); 34 | 35 | }} 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/bmc/braille/semantic_analysis/compiler_pass.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2012 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_COMPILER_PASS_HPP 8 | #define BMC_COMPILER_PASS_HPP 9 | 10 | #include 11 | 12 | namespace bmc { namespace braille { 13 | 14 | class compiler_pass 15 | { 16 | protected: 17 | typedef std::function report_error_type; 18 | report_error_type const report_error; 19 | 20 | compiler_pass(report_error_type const& report_error) 21 | : report_error(report_error) 22 | {} 23 | }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/bmc/braille/semantic_analysis/location_calculator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2012 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_LOCATION_CALCULATOR_HPP 8 | #define BMC_LOCATION_CALCULATOR_HPP 9 | 10 | #include 11 | #include 12 | #include "bmc/braille/ast.hpp" 13 | #include "bmc/braille/ast/visitor.hpp" 14 | #include "compiler_pass.hpp" 15 | #include "bmc/braille/parsing/error_handler.hpp" 16 | 17 | namespace bmc { namespace braille { 18 | 19 | /** 20 | * \brief Set line and column numbers for all locatable objects. 21 | * 22 | * \ingroup compilation 23 | */ 24 | template 25 | class location_calculator 26 | : public ast::visitor> 27 | , public compiler_pass 28 | { 29 | ErrorHandler const& handler; 30 | public: 31 | location_calculator( report_error_type const& report_error 32 | , ErrorHandler const& handler 33 | ) 34 | : compiler_pass(report_error) 35 | , handler(handler) 36 | {} 37 | 38 | void operator()(ast::measure& measure) { 39 | bool const ok = this->traverse_measure(measure); 40 | BOOST_ASSERT(ok); 41 | } 42 | void operator()(ast::key_and_time_signature &kt) { 43 | bool const ok = this->traverse_key_and_time_signature(kt); 44 | BOOST_ASSERT(ok); 45 | } 46 | 47 | bool visit_locatable(ast::locatable& lexeme) { 48 | typedef typename ErrorHandler::iterator_type iterator_type; 49 | if (lexeme.id >= 0) { 50 | BOOST_ASSERT(lexeme.id < handler.ranges.size()); 51 | iterator_type const begin_line_start(handler.get_pos(handler.ranges[lexeme.id].begin(), lexeme.begin_line)); 52 | lexeme.begin_column = std::distance(begin_line_start, handler.ranges[lexeme.id].begin()) + 1; 53 | 54 | iterator_type const end_line_start(handler.get_pos(handler.ranges[lexeme.id].end(), lexeme.end_line)); 55 | lexeme.end_column = std::distance(end_line_start, handler.ranges[lexeme.id].end()) + 1; 56 | } 57 | 58 | return true; 59 | } 60 | }; 61 | 62 | }} 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /include/bmc/braille/semantic_analysis/value_disambiguator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_VALUE_DISAMBIGUATOR_HPP 8 | #define BMC_VALUE_DISAMBIGUATOR_HPP 9 | 10 | #include "bmc/braille/ast.hpp" 11 | #include 12 | #include "compiler_pass.hpp" 13 | 14 | namespace bmc { namespace braille { 15 | 16 | /** 17 | * \brief Calcualte the duration (value) of all notes and rests in a measure. 18 | * 19 | * When braille music was invented, 6 dot braille was dominant. The number of 20 | * possible signs was therefore limited to 63 combinations (minus the empty 21 | * cell). Since steps and values are encoded into a single cell, this led to 22 | * the necessity to overload braille patterns because it would have been 23 | * impossible to represent whole to 128th notes without exceeding the possible 24 | * combinations (7*8 + 8 is already 64). A trick had to be invented to allow 25 | * the representation of all these values. Therefore, every value in braille 26 | * music can have two possible meanings. The sign for a whole note C either 27 | * represents a whole note C or a 16th note C. The sign for a half note D 28 | * either represents a half note D or a 32th note D. The reader of braille music 29 | * is assumed to disambiguate the meanings of each sign from the context. 30 | * Context is mostly the time signature and a bit of musical understanding. 31 | * 32 | * This compiler pass (the most complicated of all passes we have) tries to 33 | * find the one and only possiblle interpretation of all notes and rests in 34 | * a single measure given the current time signature. 35 | * 36 | * As a special case, it handles music with upbeat (anacrusis) as well. 37 | * If a measure appears short relative to the current time signature, its 38 | * interpretation is delayed until another short measure appears. Once a second 39 | * measure with duration less then the current time signature is found the 40 | * two measures are combined, and if they add up to a duration which equals to 41 | * the current time signature, both measures are disambiguated correctly. 42 | * 43 | * \ingroup compilation 44 | */ 45 | class value_disambiguator: public compiler_pass 46 | { 47 | ::bmc::time_signature time_signature; 48 | rational prev_duration; 49 | value_disambiguation::measure_doubled_tuplet_info prev_doubled_tuplets; 50 | boost::optional anacrusis; 51 | 52 | public: 53 | typedef bool result_type; 54 | value_disambiguator(report_error_type const& report_error); 55 | 56 | void set(::bmc::time_signature const& time_sig) 57 | { time_signature = time_sig; } 58 | 59 | result_type operator()(ast::measure& measure); 60 | 61 | bool end_of_staff() const; 62 | }; 63 | 64 | }} 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /include/bmc/braille/text2braille.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BMC_BRAILLE_TEXT2BRAILLE_HPP_INCLUDED 2 | #define BMC_BRAILLE_TEXT2BRAILLE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace bmc { namespace braille { 8 | 9 | extern std::string default_table; 10 | 11 | void set_default_table_from_locale (); 12 | uint8_t get_dots_for_character(char32_t c, std::string const &table = default_table); 13 | 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/bmc/braille_music.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2012 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_BRAILLE_MUSIC_HPP 8 | #define BMC_BRAILLE_MUSIC_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace bmc { namespace braille { 14 | 15 | enum class interval_direction 16 | { down 17 | , up 18 | }; 19 | 20 | typedef std::pair finger_change; 21 | typedef boost::variant fingering; 22 | typedef std::vector fingering_list; 23 | 24 | }} 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/bmc/music.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_MUSIC_HPP 8 | #define BMC_MUSIC_HPP 9 | 10 | #include 11 | #include 12 | #include "bmc/math.hpp" 13 | 14 | namespace bmc { 15 | 16 | typedef boost::rational rational; 17 | 18 | rational const zero = rational(); 19 | 20 | inline rational augmentation_dots_factor(unsigned dots) 21 | { return dots ? rational{(1 << (dots + 1)) - 1, 1 << dots} : rational{1}; } 22 | 23 | inline rational tuplet_number_to_ratio(unsigned number) 24 | { 25 | BOOST_ASSERT(number > 0); 26 | rational factor{1}; 27 | if (number > 2) 28 | factor.assign(number - 1, number); 29 | else if (number == 2) // duplet 30 | factor.assign(number + 1, number); 31 | return factor; 32 | } 33 | 34 | /** 35 | * \brief Represents a time signature with numerator and denominator. 36 | * 37 | * Arithmetic with time signatures is useful, so derive from rational. 38 | * However, care has to be taken to avoid the implicit simplification of 39 | * boost::rational. 40 | */ 41 | class time_signature: public rational { 42 | /** 43 | * \brief boost::rational simplifies during construction, so we 44 | * need to preserve the original numerator and denominator. 45 | */ 46 | int_type d_num, d_den; 47 | public: 48 | time_signature(int_type n = 4, int_type d = 4) 49 | : rational(n, d), d_num(n), d_den(d) {} 50 | using rational::operator==; bool operator==(time_signature const&) const; 51 | int_type numerator() const { return d_num; } 52 | int_type denominator() const { return d_den; } 53 | 54 | friend 55 | std::ostream &operator<< ( std::ostream &os 56 | , time_signature const &signature 57 | ) 58 | { return os << signature.numerator() << '/' << signature.denominator(); } 59 | }; 60 | 61 | enum diatonic_step { C = 0, D, E, F, G, A, B }; 62 | unsigned BOOST_CONSTEXPR_OR_CONST steps_per_octave = B + 1; 63 | enum accidental { 64 | natural, flat, double_flat, triple_flat, 65 | sharp, double_sharp, triple_sharp 66 | }; 67 | 68 | typedef signed short key_signature; 69 | 70 | enum articulation { 71 | appoggiatura, short_appoggiatura, 72 | short_trill, extended_short_trill, 73 | turn_between_notes, turn_above_or_below_note, 74 | inverted_turn_between_notes, inverted_turn_above_or_below_note, 75 | staccato, staccatissimo, mezzo_staccato, 76 | agogic_accent, accent, 77 | mordent, extended_mordent, 78 | arpeggio_up, arpeggio_up_multi_staff, 79 | arpeggio_down, arpeggio_down_multi_staff 80 | }; 81 | 82 | enum interval { 83 | unison = 0, 84 | second = 1, 85 | third = 2, 86 | fourth = 3, 87 | fifth = 4, 88 | sixth = 5, 89 | seventh = 6, 90 | octave = 7 91 | }; 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /include/bmc/musicxml.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_MUSICXML_HPP_INCLUDED 8 | #define BMC_MUSICXML_HPP_INCLUDED 9 | 10 | #include "bmc/braille/ast.hpp" 11 | 12 | #include 13 | 14 | namespace bmc { 15 | 16 | void musicxml(std::ostream &, braille::ast::score const &); 17 | 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(braillemusic SHARED 2 | text2braille.cpp 3 | brlsym.cpp music.cpp ast.cpp 4 | numbers.cpp key_signature.cpp time_signature.cpp 5 | partial_voice_sign.cpp simile.cpp tuplet_start.cpp 6 | measure.cpp score.cpp 7 | value_disambiguation.cpp value_disambiguator.cpp 8 | lilypond.cpp musicxml.cpp linebreaking.cpp reformat.cpp 9 | ) 10 | set_target_properties(braillemusic 11 | PROPERTIES 12 | VERSION ${bmc_VERSION} 13 | SOVERSION ${bmc_VERSION_MAJOR}.${bmc_VERSION_MINOR} 14 | ) 15 | target_link_libraries(braillemusic xsdcxx-musicxml Threads::Threads) 16 | target_compile_features(braillemusic PRIVATE cxx_range_for cxx_final) 17 | add_library(braillemusic-static STATIC 18 | text2braille.cpp 19 | brlsym.cpp music.cpp ast.cpp 20 | numbers.cpp key_signature.cpp time_signature.cpp 21 | partial_voice_sign.cpp simile.cpp tuplet_start.cpp 22 | measure.cpp score.cpp 23 | value_disambiguation.cpp value_disambiguator.cpp 24 | lilypond.cpp musicxml.cpp linebreaking.cpp reformat.cpp 25 | ) 26 | target_include_directories(braillemusic-static PUBLIC ${Boost_INCLUDE_DIRS}) 27 | target_include_directories(braillemusic PUBLIC ${Boost_INCLUDE_DIRS}) 28 | target_link_libraries(braillemusic-static 29 | xsdcxx-musicxml-static Threads::Threads 30 | ) 31 | target_compile_features(braillemusic-static PRIVATE cxx_final) 32 | 33 | install(TARGETS braillemusic braillemusic-static 34 | ARCHIVE DESTINATION lib COMPONENT Development 35 | LIBRARY DESTINATION lib COMPONENT Development 36 | ) 37 | install(DIRECTORY ${bmc_SOURCE_DIR}/include/bmc DESTINATION include) 38 | 39 | 40 | -------------------------------------------------------------------------------- /lib/ast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace bmc { namespace braille { namespace ast { 4 | 5 | rhythmic::~rhythmic() = default; 6 | note::~note() = default; 7 | rest::~rest() = default; 8 | stem::~stem() = default; 9 | chord::~chord() = default; 10 | moving_note::~moving_note() = default; 11 | 12 | }}} 13 | -------------------------------------------------------------------------------- /lib/brlsym.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_BRLSYM_HPP 8 | #define BMC_BRLSYM_HPP 9 | 10 | #include "config.hpp" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace bmc { namespace braille { 16 | 17 | // A special version of qi::symbols<> which transparently translates its input 18 | // to Unicode braille. 19 | 20 | struct tst_braillify { 21 | template 22 | Char operator()(Char ch) const { 23 | return ch < 0X20? ch: 0X2800 | (get_dots_for_character(ch)&0X3F); 24 | } 25 | }; 26 | 27 | template 28 | struct brl_symbols : boost::spirit::qi::symbols, tst_braillify> 29 | {}; 30 | 31 | // A number of generally useful symbol tables for parsing braille music code 32 | 33 | #define BMC_DEFINE_SYMBOL_TABLE(Return, Type, Name) \ 34 | struct Type : brl_symbols { Type(); }; \ 35 | extern Type Name; 36 | 37 | BMC_DEFINE_SYMBOL_TABLE(unsigned, upper_digit_symbols, upper_digit_sign) 38 | BMC_DEFINE_SYMBOL_TABLE(unsigned, lower_digit_symbols, lower_digit_sign) 39 | BMC_DEFINE_SYMBOL_TABLE(boost::spirit::unused_type, dots_123_symbols, dots_123) 40 | BMC_DEFINE_SYMBOL_TABLE(accidental, accidental_symbols, accidental_sign) 41 | BMC_DEFINE_SYMBOL_TABLE(unsigned, octave_symbols, octave_sign) 42 | typedef std::pair step_and_value; 43 | BMC_DEFINE_SYMBOL_TABLE(step_and_value, 44 | step_and_value_symbols, step_and_value_sign) 45 | BMC_DEFINE_SYMBOL_TABLE(ast::value, rest_symbols, rest_sign) 46 | BMC_DEFINE_SYMBOL_TABLE(interval, interval_symbols, interval_sign) 47 | BMC_DEFINE_SYMBOL_TABLE(ast::slur::type, slur_symbols, slur_sign) 48 | BMC_DEFINE_SYMBOL_TABLE(ast::tie::type, tie_symbols, tie_sign) 49 | BMC_DEFINE_SYMBOL_TABLE(ast::hand_sign::type, hand_symbols, hand_sign) 50 | BMC_DEFINE_SYMBOL_TABLE(::bmc::articulation, articulation_symbols, articulation_sign) 51 | BMC_DEFINE_SYMBOL_TABLE(ast::barline, barline_symbols, barline_sign) 52 | BMC_DEFINE_SYMBOL_TABLE(::bmc::rational, stem_symbols, stem_sign) 53 | 54 | #undef BMC_DEFINE_SYMBOL_TABLE 55 | }} 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lib/key_signature.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "key_signature_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct key_signature_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/key_signature_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "brlsym.hpp" 15 | #include 16 | 17 | namespace bmc { namespace braille { 18 | 19 | template 20 | key_signature_grammar::key_signature_grammar() 21 | : key_signature_grammar::base_type(start) 22 | { 23 | boost::spirit::qi::_pass_type _pass; 24 | boost::spirit::qi::_val_type _val; 25 | boost::spirit::qi::_1_type _1; 26 | boost::spirit::qi::eps_type eps; 27 | boost::spirit::qi::attr_type attr; 28 | boost::spirit::qi::repeat_type repeat; 29 | using boost::phoenix::size; 30 | brl_type brl; 31 | 32 | start = repeat(1, 3)[sharp_sign] [_val = size(_1)] 33 | | brl(3456) >> upper_number[_pass = _1 > unsigned(2), 34 | _val = _1] >> sharp_sign 35 | | repeat(1, 3)[flat_sign] [_val = -size(_1)] 36 | | brl(3456) >> upper_number[_pass = _1 > unsigned(2), 37 | _val = -_1] >> flat_sign 38 | | eps [_val = 0] 39 | ; 40 | 41 | flat_sign = brl(126) >> attr(-1); 42 | sharp_sign = brl(146) >> attr(1); 43 | } 44 | 45 | }} 46 | -------------------------------------------------------------------------------- /lib/measure.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "measure_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct measure_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/measure_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_MEASURE_DEF_HPP 8 | #define BMC_MEASURE_DEF_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include "brlsym.hpp" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace bmc { namespace braille { 29 | 30 | template 31 | measure_grammar::measure_grammar(error_handler& error_handler) 32 | : measure_grammar::base_type(start, "measure") 33 | , partial_voice_sign(error_handler) 34 | { 35 | typedef boost::phoenix::function< annotation > 36 | annotation_function; 37 | 38 | ::bmc::braille::brl_type brl; 39 | 40 | start = -ending >> (voice % full_measure_in_accord); 41 | 42 | voice = partial_measure % partial_measure_sign; 43 | partial_measure = partial_voice % partial_measure_in_accord; 44 | partial_voice = +partial_voice_sign; 45 | 46 | boost::spirit::_val_type _val; 47 | boost::spirit::_1_type _1; 48 | boost::spirit::_3_type _3; 49 | boost::spirit::repeat_type repeat; 50 | using boost::phoenix::at_c; 51 | boost::spirit::eol_type eol; 52 | 53 | full_measure_in_accord = brl(126) >> brl(345) >> *eol; 54 | partial_measure_sign = brl(46) >> brl(13) >> *eol; 55 | partial_measure_in_accord = brl(5) >> brl(2) >> *eol; 56 | 57 | optional_dot = (!dots_123) | (&(brl(3) >> dots_123) > brl(3)); 58 | ending = (brl(3456) >> lower_digit_sign) > optional_dot; 59 | 60 | #define BMC_LOCATABLE_SET_ID(rule) \ 61 | boost::spirit::qi::on_success(rule,\ 62 | annotation_function(error_handler.ranges)\ 63 | (_val, _1, _3)) 64 | BMC_LOCATABLE_SET_ID(start); 65 | BMC_LOCATABLE_SET_ID(voice); 66 | BMC_LOCATABLE_SET_ID(partial_measure); 67 | BMC_LOCATABLE_SET_ID(partial_voice); 68 | #undef BMC_LOCATABLE_SET_ID 69 | 70 | optional_dot.name("."); 71 | } 72 | 73 | }} 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /lib/music.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "bmc/music.hpp" 8 | 9 | namespace bmc { 10 | 11 | bool time_signature::operator==(time_signature const& rhs) const { 12 | return d_num == rhs.d_num && d_den == rhs.d_den; 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /lib/numbers.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "numbers_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct upper_number_grammar; 13 | template struct lower_number_grammar; 14 | 15 | }} 16 | -------------------------------------------------------------------------------- /lib/numbers_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "brlsym.hpp" 14 | #include 15 | 16 | namespace bmc { namespace braille { 17 | 18 | template 19 | upper_number_grammar::upper_number_grammar() 20 | : upper_number_grammar::base_type(start) 21 | { 22 | boost::spirit::qi::eps_type eps; 23 | boost::spirit::qi::_1_type _1; 24 | boost::spirit::qi::_val_type _val; 25 | 26 | start = eps[_val = 0] >> +upper_digit_sign[_val = _val * 10 + _1]; 27 | } 28 | 29 | template 30 | lower_number_grammar::lower_number_grammar() 31 | : lower_number_grammar::base_type(start) 32 | { 33 | boost::spirit::qi::eps_type eps; 34 | boost::spirit::qi::_1_type _1; 35 | boost::spirit::qi::_val_type _val; 36 | 37 | start = eps[_val = 0] >> +lower_digit_sign[_val = _val * 10 + _1]; 38 | } 39 | 40 | }} 41 | -------------------------------------------------------------------------------- /lib/partial_voice_sign.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "partial_voice_sign_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct partial_voice_sign_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/score.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "score_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct score_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/simile.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "simile_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct simile_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/simile_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_SIMILE_DEF_HPP 8 | #define BMC_SIMILE_DEF_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include "brlsym.hpp" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace bmc { namespace braille { 26 | 27 | template 28 | simile_grammar::simile_grammar(error_handler& error_handler) 29 | : simile_grammar::base_type(start, "partial_voice_sign") 30 | { 31 | typedef boost::phoenix::function< annotation > 32 | annotation_function; 33 | 34 | ::bmc::braille::brl_type brl; 35 | boost::spirit::qi::_a_type _a; 36 | boost::spirit::_1_type _1; 37 | boost::spirit::_3_type _3; 38 | boost::spirit::_val_type _val; 39 | using boost::phoenix::at_c; 40 | 41 | boost::spirit::eps_type eps; 42 | start = eps[_a = 0] 43 | >> (-octave_sign)[at_c<0>(_val) = _1] 44 | >> +(brl(2356)[_a += 1]) 45 | >> -(brl(3456) >> upper_number[_a = _1]) 46 | >> eps[at_c<1>(_val) = _a] 47 | ; 48 | 49 | #define BMC_LOCATABLE_SET_ID(rule) \ 50 | boost::spirit::qi::on_success(rule,\ 51 | annotation_function(error_handler.ranges)\ 52 | (_val, _1, _3)) 53 | BMC_LOCATABLE_SET_ID(start); 54 | #undef BMC_LOCATABLE_SET_ID 55 | } 56 | 57 | }} 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /lib/spirit/detail/info_wchar_t_io.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include 9 | 10 | namespace boost { namespace spirit { 11 | 12 | /** 13 | * \brief Template specialisation to enable printing of Spirit info to 14 | * std::wostream. 15 | * \see https://svn.boost.org/trac/boost/ticket/5716 16 | */ 17 | template<> 18 | struct simple_printer 19 | { 20 | typedef utf8_string string; 21 | 22 | simple_printer(std::wostream& out) : out(out) {} 23 | 24 | void element(string const& tag, string const& value, int /*depth*/) const 25 | { 26 | typedef std::wostream::char_type char_type; 27 | if (value == "") 28 | out << char_type('<') 29 | << locale::conv::utf_to_utf(tag) 30 | << char_type('>'); 31 | else 32 | out << char_type('"') 33 | << locale::conv::utf_to_utf(value) 34 | << char_type('"'); 35 | } 36 | 37 | std::wostream& out; 38 | }; 39 | 40 | }} 41 | -------------------------------------------------------------------------------- /lib/time_signature.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "time_signature_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct time_signature_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/time_signature_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "brlsym.hpp" 13 | #include 14 | 15 | namespace bmc { namespace braille { 16 | 17 | template 18 | time_signature_grammar::time_signature_grammar() 19 | : time_signature_grammar::base_type(start) 20 | { 21 | boost::spirit::qi::_1_type _1; 22 | boost::spirit::qi::_a_type _a; 23 | boost::spirit::qi::_val_type _val; 24 | ::bmc::braille::brl_type brl; 25 | using boost::phoenix::construct; 26 | start = brl(3456) 27 | >> upper_number[_a = _1] 28 | >> lower_number[_val = construct<::bmc::time_signature>(_a, _1)] 29 | | brl(46) 30 | >> brl(14)[_val = construct<::bmc::time_signature>(4, 4)] 31 | | brl(456) 32 | >> brl(14)[_val = construct<::bmc::time_signature>(4, 4)] 33 | ; 34 | } 35 | 36 | }} 37 | -------------------------------------------------------------------------------- /lib/tuplet_start.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include "tuplet_start_def.hpp" 8 | 9 | namespace bmc { namespace braille { 10 | 11 | typedef std::wstring::const_iterator iterator_type; 12 | template struct tuplet_start_grammar; 13 | 14 | }} 15 | -------------------------------------------------------------------------------- /lib/tuplet_start_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #ifndef BMC_TUPLET_START_DEF_HPP 8 | #define BMC_TUPLET_START_DEF_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include "brlsym.hpp" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace bmc { namespace braille { 23 | 24 | template 25 | tuplet_start_grammar::tuplet_start_grammar(error_handler& error_handler) 26 | : tuplet_start_grammar::base_type(start, "measure") 27 | { 28 | typedef boost::phoenix::function< annotation > 29 | annotation_function; 30 | 31 | ::bmc::braille::brl_type brl; 32 | boost::spirit::qi::_a_type _a; 33 | boost::spirit::_1_type _1; 34 | boost::spirit::_3_type _3; 35 | boost::spirit::_val_type _val; 36 | boost::spirit::qi::_pass_type _pass; 37 | using boost::phoenix::construct; 38 | 39 | start = brl(23) >> brl(23)[_val = construct(true)] 40 | | brl(23)[_val = construct(false)] 41 | | brl(456) >> lower_number[_a = _1] 42 | >> brl(456) >> lower_number[_pass = _a == _1] 43 | >> brl(3)[_val = construct(_a, true)] 44 | | brl(456) >> lower_number[_a = _1] 45 | >> brl(3)[_val = construct(_a, false)] 46 | ; 47 | 48 | #define BMC_LOCATABLE_SET_ID(rule) \ 49 | boost::spirit::qi::on_success(rule,\ 50 | annotation_function(error_handler.ranges)\ 51 | (_val, _1, _3)) 52 | BMC_LOCATABLE_SET_ID(start); 53 | #undef BMC_LOCATABLE_SET_ID 54 | } 55 | 56 | }} 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lib/value_disambiguator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2012 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | #include "bmc/braille/semantic_analysis/value_disambiguator.hpp" 9 | #include "bmc/braille/semantic_analysis/value_disambiguation.hpp" 10 | 11 | namespace bmc { namespace braille { 12 | 13 | value_disambiguator::value_disambiguator(report_error_type const& report_error) 14 | : compiler_pass(report_error) 15 | , time_signature(4, 4) 16 | , prev_duration(0) 17 | {} 18 | 19 | value_disambiguator::result_type 20 | value_disambiguator::operator()(ast::measure& measure) 21 | { 22 | value_disambiguation::measure_interpretations 23 | interpretations(measure, time_signature, prev_duration, prev_doubled_tuplets); 24 | 25 | if (!interpretations.contains_complete_measure() && !interpretations.empty()) { 26 | if (!anacrusis) { 27 | anacrusis = interpretations; 28 | prev_duration = 0; 29 | prev_doubled_tuplets.clear(); 30 | return true; 31 | } 32 | 33 | if (anacrusis->completes_uniquely(interpretations)) { 34 | for (auto& lhs: *anacrusis) { 35 | for (auto& rhs: interpretations) { 36 | if (duration(lhs) + duration(rhs) == time_signature) { 37 | lhs.accept(), rhs.accept(); 38 | prev_duration = duration(rhs); 39 | prev_doubled_tuplets = rhs.get_doubled_tuplets(); 40 | anacrusis.reset(); 41 | return true; 42 | } 43 | } 44 | } 45 | } 46 | } 47 | 48 | if (interpretations.size() == 1) { 49 | auto &proxied_measure = interpretations.front(); 50 | proxied_measure.accept(); 51 | prev_duration = duration(proxied_measure); 52 | prev_doubled_tuplets = proxied_measure.get_doubled_tuplets(); 53 | return true; 54 | } 55 | 56 | if (interpretations.empty()) { 57 | report_error(measure.id, L"No possible interpretations"); 58 | } else { 59 | std::wstringstream s; 60 | s << interpretations.size() << L" possible interpretations:"; 61 | for (auto& interpretation: interpretations) { 62 | rational const score(interpretation.harmonic_mean()); 63 | s << std::endl 64 | << boost::rational_cast(score) << L": " << interpretation; 65 | } 66 | report_error(measure.id, s.str()); 67 | } 68 | return false; 69 | } 70 | 71 | bool 72 | value_disambiguator::end_of_staff() const { 73 | if (anacrusis && anacrusis->size() > 1) { 74 | std::wstringstream msg; 75 | msg << "Unterminated anacrusis ("; 76 | msg << anacrusis->size() << ")"; 77 | report_error(anacrusis->get_measure_id(), msg.str()); 78 | return false; 79 | } 80 | if (anacrusis && !anacrusis->empty()) anacrusis->front().accept(); 81 | return true; 82 | } 83 | 84 | }} 85 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Mario Lang 2 | // 3 | // Distributed under the terms of the GNU General Public License version 3. 4 | // (see accompanying file LICENSE.txt or copy at 5 | // http://www.gnu.org/licenses/gpl-3.0-standalone.html) 6 | 7 | #include 8 | 9 | #include "config.hpp" 10 | #include 11 | #include "bmc/braille/parsing/grammar/score.hpp" 12 | #include "bmc/braille/semantic_analysis.hpp" 13 | 14 | #include "fluidsynth.hpp" 15 | #include "bmc/lilypond.hpp" 16 | 17 | #include 18 | 19 | int 20 | main(int argc, char const *argv[]) 21 | { 22 | std::locale::global(std::locale("")); 23 | 24 | { 25 | char *localeTable = selectTextTable(TABLES_DIRECTORY); 26 | if (localeTable) { 27 | replaceTextTable(TABLES_DIRECTORY, localeTable); 28 | free(localeTable); 29 | } 30 | } 31 | 32 | std::istreambuf_iterator wcin_begin(std::wcin.rdbuf()), wcin_end; 33 | std::wstring source(wcin_begin, wcin_end); 34 | typedef std::wstring::const_iterator iterator_type; 35 | 36 | iterator_type iter = source.begin(); 37 | iterator_type const end = source.end(); 38 | typedef ::bmc::braille::error_handler error_handler_type; 39 | error_handler_type error_handler(iter, end); 40 | typedef ::bmc::braille::score_grammar parser_type; 41 | parser_type parser(error_handler); 42 | boost::spirit::traits::attribute_of::type score; 43 | 44 | bool const success = parse(iter, end, parser, score); 45 | 46 | if (success and iter == end) { 47 | ::bmc::braille::compiler compile(error_handler); 48 | if (compile(score)) { 49 | std::thread player; 50 | 51 | if (argc == 2 and strcmp(argv[1], "-p") == 0) 52 | player = std::thread(::bmc::fluidsynth(SOUNDFONT_PATH), score); 53 | 54 | ::bmc::lilypond_output_format(std::cout); 55 | //::bmc::include_locations_for_lilypond(std::cout); 56 | std::cout << score; 57 | 58 | if (player.joinable()) player.join(); 59 | 60 | return EXIT_SUCCESS; 61 | } 62 | } 63 | 64 | return EXIT_FAILURE; 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /python/bmc/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sphinx/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeFiles/ 2 | Makefile 3 | cmake_install.cmake 4 | conf.py 5 | html/ 6 | man/ 7 | -------------------------------------------------------------------------------- /sphinx/CClef.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 12 | 14 | 18 | 22 | 23 | 27 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /sphinx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 2 | find_package(SphinxBuild REQUIRED) 3 | find_package(Lilypond REQUIRED) 4 | configure_file(conf.py.in conf.py @ONLY) 5 | add_custom_command( 6 | OUTPUT man/bmc.1 man/braille_music.7 7 | COMMAND ${SPHINX_BUILD_EXECUTABLE} -q -b man -c ${CMAKE_CURRENT_BINARY_DIR} 8 | ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/man 9 | DEPENDS bmc.rst tutorial.rst ${CMAKE_SOURCE_DIR}/python/bmc/sphinx.py 10 | ${CMAKE_BINARY_DIR}/bmc 11 | ) 12 | add_custom_target(man ALL 13 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/man/bmc.1 14 | ${CMAKE_CURRENT_BINARY_DIR}/man/braille_music.7 15 | ) 16 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/bmc.1 DESTINATION share/man/man1) 17 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/braille_music.7 DESTINATION share/man/man7) 18 | set_property(DIRECTORY APPEND 19 | PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/man" 20 | ) 21 | 22 | add_custom_command( 23 | OUTPUT html/index.html html/tutorial.html 24 | COMMAND ${SPHINX_BUILD_EXECUTABLE} -q -b html -c ${CMAKE_CURRENT_BINARY_DIR} 25 | ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/html 26 | DEPENDS index.rst goldberg.rst tutorial.rst ${CMAKE_SOURCE_DIR}/python/bmc/sphinx.py 27 | ) 28 | add_custom_target(html ALL 29 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html 30 | ) 31 | set_property(DIRECTORY APPEND 32 | PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/html" 33 | ) 34 | 35 | add_custom_target(linkcheck 36 | COMMAND ${SPHINX_BUILD_EXECUTABLE} -q -b linkcheck -c ${CMAKE_CURRENT_BINARY_DIR} 37 | ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/linkcheck 38 | ) 39 | set_property(DIRECTORY APPEND 40 | PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/linkcheck" 41 | ) 42 | -------------------------------------------------------------------------------- /sphinx/GClef.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sphinx/bmc.rst: -------------------------------------------------------------------------------- 1 | bmc manual page 2 | =============== 3 | 4 | Synopsis 5 | -------- 6 | 7 | **bmc** [*options*] <*source-file* | *-*> 8 | 9 | Description 10 | ----------- 11 | 12 | BMC parses braille music code and converts it to digital music notation formats 13 | suitable for exchange with users of typical visual music notation. 14 | 15 | Options 16 | ------- 17 | 18 | --lilypond Convert to LilyPond music engraver format. 19 | --musicxml Convert to MusicXML. 20 | 21 | See also 22 | -------- 23 | 24 | :manpage:`braille_music(7)` 25 | 26 | -------------------------------------------------------------------------------- /sphinx/chords-lh.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠩⠀⠼⠙⠲ 2 | ⠨⠜⠄⠍⠣⠅ 3 | ⠸⠜⠸⠱⠬⠔⠤⠘⠑⠄⠤⠵⠤⠱⠤⠧⠣⠅ 4 | -------------------------------------------------------------------------------- /sphinx/goldberg.rst: -------------------------------------------------------------------------------- 1 | Goldberg Variations 2 | =================== 3 | 4 | As a demonstration of all the braille music features implemented by the Braille 5 | Music Compiler so far, a number of significant pieces by Johann Sebastian Bach are 6 | used to test the implementation. 7 | 8 | Variation 1 9 | ----------- 10 | 11 | .. braille-music:: ../test/input/bwv988-v01.bmc 12 | 13 | Variation 2 14 | ----------- 15 | 16 | .. braille-music:: ../test/input/bwv988-v02.bmc 17 | 18 | Variation 3 19 | ----------- 20 | 21 | .. braille-music:: ../test/input/bwv988-v03.bmc 22 | 23 | Variation 4 24 | ----------- 25 | 26 | .. braille-music:: ../test/input/bwv988-v04.bmc 27 | 28 | Variation 5 29 | ----------- 30 | 31 | .. braille-music:: ../test/input/bwv988-v05.bmc 32 | 33 | Variation 6 34 | ----------- 35 | 36 | .. braille-music:: ../test/input/bwv988-v06.bmc 37 | 38 | Variation 7 39 | ----------- 40 | 41 | .. braille-music:: ../test/input/bwv988-v07.bmc 42 | 43 | Variation 8 44 | ----------- 45 | 46 | .. braille-music:: ../test/input/bwv988-v08.bmc 47 | 48 | Variation 9 49 | ----------- 50 | 51 | .. braille-music:: ../test/input/bwv988-v09.bmc 52 | 53 | Variation 10 54 | ------------ 55 | 56 | .. braille-music:: ../test/input/bwv988-v10.bmc 57 | 58 | Variation 11 59 | ------------ 60 | 61 | .. braille-music:: ../test/input/bwv988-v11.bmc 62 | 63 | Variation 12 64 | ------------ 65 | 66 | .. braille-music:: ../test/input/bwv988-v12.bmc 67 | 68 | Variation 13 69 | ------------ 70 | 71 | .. braille-music:: ../test/input/bwv988-v13.bmc 72 | 73 | Variation 14 74 | ------------ 75 | 76 | .. braille-music:: ../test/input/bwv988-v14.bmc 77 | 78 | Variation 15 79 | ------------ 80 | 81 | .. braille-music:: ../test/input/bwv988-v15.bmc 82 | 83 | Variation 16 84 | ------------ 85 | 86 | .. braille-music:: ../test/input/bwv988-v16.bmc 87 | 88 | Variation 17 89 | ------------ 90 | 91 | .. braille-music:: ../test/input/bwv988-v17.bmc 92 | 93 | Variation 18 94 | ------------ 95 | 96 | .. braille-music:: ../test/input/bwv988-v18.bmc 97 | 98 | Variation 19 99 | ------------ 100 | 101 | .. braille-music:: ../test/input/bwv988-v19.bmc 102 | 103 | Variation 22 104 | ------------ 105 | 106 | .. braille-music:: ../test/input/bwv988-v22.bmc 107 | 108 | Variation 30 109 | ------------ 110 | 111 | .. braille-music:: ../test/input/bwv988-v30.bmc 112 | 113 | -------------------------------------------------------------------------------- /sphinx/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to BMC, the Braille Music Compiler 2 | ========================================== 3 | 4 | BMC parses braille music code and transcribes it to several digital music 5 | notations formats. Currently, export to LilyPond and MusicXML 6 | is implemented. 7 | 8 | Contents: 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | 13 | tutorial 14 | goldberg 15 | 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | 23 | -------------------------------------------------------------------------------- /sphinx/intervals-lh.bmc: -------------------------------------------------------------------------------- 1 | ⠀ ⠼⠙⠲ 2 | ⠨⠜⠄⠍⠀⠍⠀⠍⠀⠍⠀⠍⠀⠍⠀⠍⠣⠅ 3 | ⠸⠜⠸⠽⠌⠀⠽⠬⠀⠽⠼⠀⠽⠔⠀⠽⠴⠀⠽⠒⠀⠽⠤⠣⠅ 4 | -------------------------------------------------------------------------------- /sphinx/intervals-rh.bmc: -------------------------------------------------------------------------------- 1 | ⠀ ⠼⠙⠲ 2 | ⠀⠀⠨⠜⠨⠽⠌⠀⠽⠬⠀⠽⠼⠀⠽⠔⠀⠽⠴⠀⠽⠒⠀⠽⠤⠣⠅ 3 | ⠸⠜⠄⠍⠀⠍⠀⠍⠀⠍⠀⠍⠀⠍⠀⠍⠣⠅ 4 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(bmc_test test.cpp) 2 | target_compile_features(bmc_test PRIVATE cxx_range_for cxx_auto_type) 3 | target_link_libraries(bmc_test braillemusic-static) 4 | find_package(Boost QUIET COMPONENTS unit_test_framework) 5 | if(Boost_UNIT_TEST_FRAMEWORK_FOUND) 6 | get_target_property(bmc_test_cflags bmc_test COMPILE_DEFINITIONS) 7 | set_target_properties(bmc_test 8 | PROPERTIES COMPILE_DEFINITIONS "${bmc_test_cflags}; BOOST_TEST_DYN_LINK") 9 | target_link_libraries(bmc_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) 10 | else(Boost_UNIT_TEST_FRAMEWORK_FOUND) 11 | message(STATUS "Boost unit test framework library not available") 12 | endif(Boost_UNIT_TEST_FRAMEWORK_FOUND) 13 | enable_testing() 14 | set(BMC_TEST_NAMES 15 | time_signature_grammar_test_1 16 | key_signature_grammar_test_1 key_signature_grammar_test_2 17 | key_signature_grammar_test_3 18 | brl_parser_test 19 | measure_test1 measure_test2 20 | measure_interpretations_test1 measure_interpretations_test2 21 | notegroup_test1 22 | compiler_test1 23 | score_solo_test1 score_solo_test2 24 | score_tuplet_test1 score_tuplet_test2 score_tuplet_test3 score_tuplet_test4 25 | score_tuplet_test5 score_tuplet_test6 score_tuplet_test7 score_tuplet_test8 26 | slur_test1 27 | score_multiple_time_sigs 28 | common_factor 29 | bwv988_v01 30 | bwv988_v02 31 | bwv988_v03 32 | bwv988_v04 33 | bwv988_v05 34 | bwv988_v06 35 | bwv988_v07 36 | bwv988_v08 37 | bwv988_v09 38 | bwv988_v10 39 | bwv988_v11 40 | bwv988_v12 41 | bwv988_v13 42 | bwv988_v13_de 43 | bwv988_v14 44 | bwv988_v15 45 | bwv988_v16 46 | bwv988_v17 47 | bwv988_v18 48 | bwv988_v19 49 | bwv988_v22 50 | bwv988_v30 51 | ) 52 | foreach(test_name ${BMC_TEST_NAMES}) 53 | add_test(NAME bmc_${test_name} 54 | COMMAND bmc_test --run_test=${test_name}) 55 | set_tests_properties(bmc_${test_name} PROPERTIES 56 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 57 | ) 58 | endforeach(test_name) 59 | # A kludge to workaround cmake's inability to add dependencies to the test target 60 | add_custom_target(check 61 | COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure 62 | DEPENDS bmc_test bmc 63 | ) 64 | 65 | if(PYTHONINTERP_FOUND) 66 | execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import music21;" 67 | RESULT_VARIABLE music21_NOTFOUND ERROR_QUIET) 68 | if(NOT music21_NOTFOUND) 69 | message(STATUS "Found music21") 70 | add_test(NAME music21 COMMAND ${CMAKE_SOURCE_DIR}/m21.sh ${CMAKE_SOURCE_DIR}/m21.py ${CMAKE_BINARY_DIR}/bmc2ly) 71 | else() 72 | message(STATUS "music21 not found") 73 | endif() 74 | endif(PYTHONINTERP_FOUND) 75 | -------------------------------------------------------------------------------- /test/input/bwv988-aria.bmc: -------------------------------------------------------------------------------- 1 | 3 #c/ 2 | #a #,-/ ⠨⠜⠨⠳⠃⠳⠁⠉⠐⠖⠇⠊⠄⠾⠀⠊⠐⠢⠷⠉⠛⠇⠐⠢⠯⠉⠕⠀⠐⠖⠇⠐⠳⠇⠠⠲⠇⠰⠖⠳⠄⠿⠷⠀⠎⠉⠗⠉⠿⠗⠉⠟⠉⠯⠐⠢⠋⠃⠉⠕ 3 | ⠸⠜⠸⠗⠄⠇⠣⠜⠧⠨⠅⠸⠞⠐⠂⠧⠐⠱⠀⠸⠟⠄⠣⠜⠧⠨⠅⠸⠎⠐⠂⠧⠐⠱⠀⠸⠏⠄⠅⠉⠂⠣⠜⠧⠨⠅⠸⠗⠐⠂⠧⠩⠐⠹⠀⠸⠕⠈⠉⠑⠙⠂⠣⠜⠧⠨⠅⠸⠟⠃⠐⠂⠧⠸⠪ 4 | #b #?-( ⠨⠜⠨⠱⠃⠱⠁⠉⠐⠖⠇⠋⠄⠡⠿⠀⠋⠐⠢⠵⠉⠙⠇⠐⠢⠾⠉⠪⠄⠠⠲⠩⠨⠛⠀⠗⠂⠉⠿⠄⠎⠉⠷⠄⠟⠉⠯⠄⠕⠉⠽⠄⠃⠐⠢⠽⠁⠉⠨⠊⠄⠨⠽ 5 | ⠞⠇⠉⠷⠄⠛⠇⠐⠢⠛⠃⠉⠐⠖⠇⠗ 6 | ⠸⠜⠘⠞⠄⠣⠜⠧⠨⠅⠸⠕⠐⠂⠧⠸⠳⠀⠸⠝⠂⠉⠅⠈⠉⠙⠑⠣⠜⠧⠸⠫⠪⠀⠸⠋⠙⠕⠂⠉⠅⠣⠜⠭⠐⠙⠈⠉⠙⠾⠮⠷⠁⠛⠋⠛⠀⠘⠳⠄⠸⠑⠂⠋⠄⠿⠣⠜⠸⠓⠊⠞ 7 | ⠨⠜⠐⠺⠃⠺⠁⠉⠐⠖⠇⠩⠙⠄⠵⠀⠵⠂⠩⠙⠚⠊⠈⠉⠨⠕⠼⠀⠜⠅⠳⠬⠴⠤⠠⠲⠰⠖⠳⠄⠂⠇⠉⠿⠷⠀⠓⠂⠐⠢⠿⠉⠋⠐⠢⠵⠉⠩⠹⠄⠃⠋⠇ 8 | ⠮⠉⠉⠷⠿⠉⠯⠑⠐⠪⠃⠈⠉⠎⠞⠡⠽ ⠾⠮⠷⠿⠃⠋⠐⠢⠨⠵⠉⠩⠹⠇⠈⠉⠝⠕⠯⠀⠵⠉⠉⠩⠽⠾⠉⠮⠨⠓⠐⠺⠃⠉⠇⠙⠀⠐⠢⠩⠽⠇⠉⠑⠈⠉⠕⠏⠕⠩⠝⠐⠢⠙⠂⠉⠕⠣⠜⠐⠳⠟⠃⠣⠆ 9 | ⠸⠜⠸⠗⠄⠁⠉⠇⠈⠉⠣⠜⠧⠨⠅⠸⠞⠐⠂⠧⠐⠫⠀⠸⠳⠌⠰⠖⠛⠋⠛⠚⠀⠫⠄⠋⠛⠓⠅⠣⠜⠭⠸⠚⠐⠫⠄⠑⠀⠸⠪⠄⠂⠚⠊⠓⠣⠜⠩⠐⠙⠇⠑⠏ 10 | ⠸⠟⠄⠂⠣⠜⠧⠨⠅⠸⠎⠐⠂⠧⠐⠱⠀⠸⠗⠄⠅⠣⠜⠧⠸⠺⠐⠫⠀⠸⠎⠄⠅⠉⠃⠣⠜⠐⠻⠃⠋⠄⠁⠿⠃⠨⠜⠐⠳⠁⠈⠉⠀⠸⠕⠄⠣⠜⠸⠜⠄⠧⠭⠸⠊⠐⠱⠣⠆ 11 | ⠨⠜⠄⠣⠶⠐⠖⠐⠪⠇⠠⠲⠰⠖⠪⠈⠉⠮⠎⠁⠉⠉⠞⠡⠝⠕⠉⠯⠀⠐⠢⠯⠂⠉⠑⠐⠢⠽⠉⠚⠐⠢⠮⠃⠉⠳⠄⠨⠓ 12 | ⠐⠢⠿⠉⠋⠄⠟⠩⠕⠐⠢⠵⠇⠉⠫⠄⠁⠎⠚⠊⠓⠀⠐⠢⠓⠂⠉⠊⠄⠿⠐⠢⠋⠁⠉⠩⠱⠄⠇⠚ 13 | ⠸⠜⠄⠣⠶⠐⠕⠇⠹⠣⠜⠭⠐⠋⠟⠀⠸⠺⠄⠅⠉⠂⠊⠺⠣⠜⠭⠐⠙⠕⠀⠐⠹⠄⠚⠪⠣⠜⠭⠐⠋⠃⠳⠐⠖⠛⠋⠁⠀⠸⠺⠄⠊⠂⠐⠖⠓⠛⠂⠣⠜⠩⠐⠑⠇⠋⠟ 14 | #e #;,-;/ ⠨⠜⠨⠓⠄⠿⠐⠢⠛⠇⠉⠫⠈⠉⠯⠐⠾⠝⠂⠉⠉⠚⠊⠉⠚⠁⠀⠨⠗⠉⠯⠄⠟⠉⠩⠵⠄⠐⠢⠑⠂⠉⠫⠈⠉⠯⠐⠓⠛⠃⠋ 15 | ⠛⠄⠃⠉⠁⠨⠯⠐⠢⠋⠇⠉⠩⠑⠊⠓⠛⠇⠣⠜⠐⠻⠄⠨⠙⠚⠊⠈⠉⠀⠐⠢⠨⠿⠂⠉⠋⠿⠩⠵⠐⠢⠑⠇⠉⠏⠣⠜⠐⠪⠗ 16 | ⠸⠜⠸⠏⠅⠉⠂⠱⠅⠉⠂⠣⠜⠭⠸⠊⠐⠖⠓⠛⠳⠁⠀⠸⠝⠺⠣⠜⠭⠸⠊⠰⠖⠓⠛⠓⠚⠀⠘⠊⠙⠚⠊⠺⠣⠜⠧⠧⠭⠩⠸⠑⠃⠀⠸⠋⠸⠁⠘⠚⠋⠚⠸⠋⠡⠑⠇ 17 | ⠨⠜⠨⠋⠅⠐⠢⠡⠵⠉⠙⠐⠢⠾⠉⠪⠄⠾⠽⠀⠕⠉⠝⠉⠾⠝⠉⠞⠉⠮⠐⠢⠊⠃⠉⠳⠄⠮⠾⠀⠽⠑⠙⠚⠽⠊⠋⠸⠃⠊⠃⠨⠅⠨⠹⠈⠉⠐⠂⠐⠯⠚⠊⠁⠓⠃ 18 | ⠨⠽⠑⠙⠚⠽⠊⠛⠁⠊⠽⠋⠑⠙⠣⠜⠐⠻⠭⠻⠄⠀⠐⠾⠙⠚⠊⠾⠂⠓⠑⠓⠾⠓⠁⠨⠙⠃⠑⠣⠜⠐⠓⠭⠭⠑⠄⠓⠄⠈⠉⠀⠨⠯⠡⠛⠋⠑⠯⠙⠐⠓⠨⠙⠯⠙⠁⠩⠛⠇⠓⠣⠜⠐⠳⠄⠓⠄⠨⠙⠄ 19 | ⠨⠮⠨⠙⠚⠃⠊⠾⠇⠙⠑⠐⠓⠾⠇⠊⠓⠛⠂⠀⠳⠈⠉⠷⠵⠷⠿⠇⠐⠢⠛⠂⠉⠳⠣⠜⠍⠐⠙⠁⠚⠃⠊⠞⠃⠉⠁⠣⠆⠣⠅ 20 | ⠸⠜⠸⠝⠄⠣⠜⠧⠨⠅⠸⠏⠐⠂⠧⠸⠪⠈⠉⠀⠘⠞⠄⠅⠉⠂⠣⠜⠸⠊⠛⠐⠢⠯⠁⠉⠑⠂⠯⠿⠷⠿⠓⠈⠉⠀⠘⠪⠄⠓⠂⠛⠇⠋⠣⠜⠸⠓⠋⠊⠭⠧⠘⠑⠊⠸⠑⠙⠚⠊ 21 | ⠓⠸⠑⠓⠡⠛⠋⠑⠀⠙⠓⠐⠙⠚⠊⠁⠓⠀⠛⠑⠓⠇⠚⠑⠸⠑⠀⠳⠄⠁⠑⠃⠘⠳⠣⠆⠣⠅ 22 | -------------------------------------------------------------------------------- /test/input/bwv988-v01.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠲ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠲⠀⠨⠜⠐⠷⠂⠿⠓⠈⠉⠷⠑⠋⠛⠷⠁⠊⠚⠩⠙⠀⠵⠩⠽⠇⠑⠈⠉⠵⠐⠊⠚⠙⠵⠁⠋⠛⠑⠀⠷⠿⠓⠈⠉⠷⠛⠋⠑⠩⠽⠇⠋⠐⠊⠃⠓⠀⠿⠇⠋⠑⠩⠙⠃⠵⠛⠸⠊⠓⠇⠿⠮⠑ 3 | ⠀⠀⠸⠜⠘⠓⠸⠾⠃⠮⠚⠓⠁⠘⠓⠸⠓⠀⠘⠛⠸⠿⠃⠯⠛⠑⠁⠘⠛⠂⠸⠑⠀⠘⠋⠸⠯⠁⠵⠇⠋⠃⠓⠘⠊⠩⠐⠙⠁⠀⠸⠑⠿⠃⠯⠛⠑⠁⠘⠑⠍⠡⠸⠽⠃ 4 | ⠀⠀⠼⠃⠀⠼⠢⠤⠦⠀⠨⠜⠄⠭⠨⠵⠅⠡⠽⠑⠐⠓⠃⠸⠚⠨⠑⠀⠭⠯⠅⠵⠋⠐⠊⠐⠙⠨⠋⠀⠭⠿⠂⠯⠛⠑⠊⠨⠙⠁⠈⠉⠀⠙⠚⠍⠓⠚⠑⠷⠑⠁⠓⠇⠊ 5 | ⠀⠀⠸⠜⠘⠾⠮⠚⠈⠉⠾⠑⠋⠂⠛⠷⠊⠚⠃⠓⠁⠀⠽⠂⠾⠙⠈⠉⠽⠋⠁⠛⠂⠓⠮⠚⠙⠃⠊⠁⠀⠵⠂⠩⠽⠑⠈⠉⠵⠊⠚⠡⠙⠵⠋⠛⠑⠀⠷⠛⠓⠑⠾⠑⠁⠸⠓⠇⠚⠸⠵⠓⠁⠘⠚⠂⠑ 6 | ⠀⠀⠼⠉⠀⠼⠔⠤⠂⠆⠀⠨⠜⠄⠾⠓⠂⠑⠚⠷⠃⠚⠁⠑⠓⠾⠓⠇⠛⠋⠀⠮⠅⠋⠩⠙⠊⠿⠊⠁⠙⠋⠮⠛⠋⠑⠀⠷⠑⠚⠓⠯⠓⠚⠑⠷⠛⠇⠋⠑⠀⠩⠽⠂⠐⠓⠋⠩⠙⠂⠮⠙⠋⠁⠓⠨⠽⠋⠑⠙ 7 | ⠀⠀⠸⠜⠘⠓⠸⠓⠚⠃⠓⠁⠘⠓⠸⠓⠀⠘⠛⠸⠛⠊⠛⠘⠛⠸⠛⠀⠘⠋⠸⠋⠓⠋⠘⠋⠸⠓⠀⠘⠊⠸⠋⠓⠋⠘⠊⠸⠓ 8 | ⠀⠀⠼⠙⠀⠼⠂⠒⠤⠂⠖⠀⠨⠜⠨⠑⠸⠛⠃⠛⠐⠊⠁⠨⠑⠃⠛⠀⠐⠚⠸⠓⠓⠐⠚⠁⠨⠋⠇⠓⠀⠩⠽⠃⠋⠐⠊⠓⠇⠿⠊⠁⠨⠑⠛⠷⠋⠑⠁⠙⠃⠀⠿⠅⠑⠁⠩⠙⠂⠚⠮⠓⠛⠋⠱⠣⠆ 9 | ⠀⠀⠸⠜⠸⠿⠂⠊⠐⠑⠛⠇⠮⠃⠛⠑⠁⠸⠊⠿⠊⠑⠛⠂⠀⠷⠅⠚⠑⠓⠾⠃⠓⠁⠑⠚⠷⠚⠁⠋⠓⠂⠀⠊⠩⠙⠃⠵⠸⠮⠿⠵⠊⠘⠊⠃⠀⠵⠸⠑⠋⠂⠛⠷⠊⠚⠩⠙⠱⠣⠆ 10 | ⠀⠀⠼⠑⠀⠼⠂⠶⠤⠆⠂⠀⠨⠜⠄⠣⠶⠨⠿⠃⠷⠊⠈⠉⠮⠚⠊⠓⠿⠋⠑⠂⠙⠀⠾⠽⠑⠈⠉⠵⠋⠑⠙⠾⠊⠓⠇⠛⠀⠯⠩⠓⠊⠚⠮⠋⠊⠃⠚⠽⠊⠁⠩⠨⠑⠇⠋⠀⠿⠋⠩⠑⠩⠙⠞⠈⠉ 11 | ⠾⠩⠵⠂⠋⠈⠉⠯⠩⠐⠵⠃⠋⠈⠉⠯⠩⠸⠵⠃⠋ 12 | ⠀⠀⠸⠜⠄⠣⠶⠘⠑⠸⠿⠃⠯⠛⠑⠁⠘⠑⠸⠛⠁⠀⠘⠓⠸⠾⠮⠚⠓⠘⠓⠸⠚⠀⠸⠙⠐⠽⠁⠾⠙⠸⠛⠂⠊⠙⠀⠊⠛⠇⠩⠵⠂⠚⠑⠇⠛⠾⠩⠑⠇⠛⠊⠀⠓⠄⠿⠓⠄⠸⠿⠃⠓⠄⠘⠾⠅ 13 | ⠀⠀⠼⠋⠀⠼⠆⠆⠤⠆⠖⠀⠨⠜⠄⠍⠩⠨⠷⠂⠊⠈⠉⠮⠩⠐⠷⠃⠊⠈⠉⠮⠩⠸⠷⠃⠊⠁⠈⠉⠀⠮⠚⠙⠛⠸⠾⠩⠑⠋⠓⠿⠂⠋⠑⠊⠀⠷⠛⠋⠁⠩⠑⠃⠯⠇⠓⠸⠚⠊⠇⠷⠾⠋⠀⠭⠨⠋⠇⠙⠃⠋⠊⠐⠊ 14 | ⠭⠨⠑⠚⠑⠓⠐⠓ 15 | ⠀⠀⠸⠜⠸⠙⠄⠐⠾⠃⠙⠄⠸⠾⠃⠙⠄⠸⠯⠂⠀⠩⠑⠊⠃⠓⠁⠩⠘⠊⠂⠚⠅⠸⠛⠃⠀⠋⠷⠿⠇⠓⠋⠁⠘⠋⠍⠡⠸⠵⠇⠀⠽⠋⠊⠙⠇⠯⠃⠙⠊⠁⠋⠃⠽⠋⠑⠙⠀⠾⠑⠓⠚⠵⠚⠓⠑⠾⠑⠃⠙⠚ 16 | ⠀⠀⠼⠛⠀⠼⠆⠶⠤⠒⠆⠀⠨⠜⠨⠽⠅⠊⠋⠙⠮⠃⠙⠁⠋⠊⠽⠊⠁⠙⠃⠋⠀⠿⠙⠊⠛⠇⠵⠃⠛⠊⠁⠙⠿⠙⠁⠛⠃⠊⠀⠾⠓⠂⠑⠚⠷⠃⠚⠁⠑⠓⠾⠡⠛⠁⠚⠇⠑ 17 | ⠨⠯⠰⠑⠙⠨⠋⠁⠵⠃⠰⠙⠚⠨⠑⠽⠃⠋⠁⠩⠛⠇⠓⠀⠮⠨⠙⠚⠃⠊⠾⠇⠑⠚⠓⠨⠽⠊⠓⠛⠃⠀⠾⠓⠁⠛⠂⠋⠵⠙⠚⠊⠳⠣⠆⠣⠅ 18 | ⠀⠀⠸⠜⠘⠊⠙⠋⠓⠛⠇⠋⠀⠑⠛⠊⠙⠚⠇⠊⠀⠓⠚⠑⠡⠛⠋⠑⠀⠙⠋⠂⠩⠛⠩⠓⠊⠡⠓⠀⠛⠑⠓⠁⠸⠓⠐⠑⠁⠸⠑⠀⠷⠘⠓⠊⠚⠽⠑⠋⠛⠳⠣⠆⠣⠅ 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v02.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠃⠲ 2 | ⠨⠜⠐⠺⠁⠐⠖⠇⠨⠫⠇⠈⠉⠀⠋⠵⠽⠵⠇⠙⠚⠊⠃⠀⠨⠳⠅⠉⠁⠐⠖⠇⠰⠹⠂⠇⠅⠈⠉⠣⠜⠐⠳⠭⠨⠊⠀⠰⠙⠾⠮⠾⠊⠓⠁⠛⠂⠣⠜⠨⠛⠑⠧ ⠨⠳⠈⠉⠷⠡⠛⠋⠑⠣⠜ 3 | ⠍⠨⠵⠃⠽⠯⠑⠚⠈⠉⠀⠨⠫⠅⠈⠉⠯⠑⠙⠅⠚⠣⠜⠐⠾⠮⠃⠷⠾⠊⠓⠈⠉⠀⠐⠪⠇⠉⠂⠈⠉⠮⠙⠚⠊⠣⠜⠐⠷⠛⠋⠓⠻ ⠐⠾⠂⠨⠓⠛⠇⠊⠷⠛⠋⠑⠣⠜⠐⠓⠁⠭⠧ 4 | ⠸⠜⠸⠓⠛⠓⠋⠀⠛⠋⠛⠑⠀⠋⠁⠑⠋⠙⠀⠑⠁⠘⠑⠸⠵⠙⠚⠊⠀⠚⠊⠚⠓⠀⠸⠙⠚⠙⠊⠀⠸⠑⠙⠑⠘⠑⠀⠓⠇⠸⠓⠚⠇⠑ 5 | ⠨⠜⠰⠙⠉⠚⠧⠣⠜⠸⠜⠐⠷⠇⠉⠮⠉⠾⠨⠜⠨⠵⠫⠈⠉⠀⠍⠣⠜⠨⠯⠑⠩⠙⠇⠋⠵⠙⠚⠊⠀⠐⠾⠃⠉⠩⠑⠉⠋⠁⠓⠺⠈⠉⠣⠜⠸⠜⠐⠳⠁⠭⠨⠜⠨⠓ 6 | ⠨⠾⠊⠓⠚⠮⠓⠛⠋⠣⠜⠨⠋⠃⠩⠙⠧⠀⠨⠱⠅⠈⠉⠵⠡⠙⠚⠊⠣⠜⠍⠐⠮⠷⠾⠊⠛⠁⠈⠉⠀⠐⠺⠅⠈⠉⠾⠊⠓⠅⠛⠣⠜⠐⠿⠯⠵⠿⠋⠑⠈⠉ ⠐⠫⠇⠉⠂⠈⠉⠯⠓⠛⠋⠣⠜ 7 | ⠐⠵⠩⠙⠚⠑⠹⠀⠼⠂⠐⠑⠐⠤⠭⠧⠣⠆⠀⠼⠆⠐⠱⠐⠤⠧ 8 | ⠸⠜⠐⠓⠇⠛⠂⠓⠁⠋⠇⠀⠛⠋⠛⠑⠀⠋⠇⠡⠑⠋⠸⠚⠀⠩⠙⠯⠁⠵⠽⠚⠊⠁⠓⠀⠛⠋⠛⠑⠀⠓⠛⠓⠋⠀⠊⠓⠊⠘⠊⠀⠼⠂⠸⠑⠐⠵⠡⠽⠇⠵⠙⠁⠚⠊⠣⠆⠀⠼⠆⠸⠑⠘⠊⠱ 9 | ⠨⠜⠄⠣⠶⠐⠪⠨⠪⠈⠉⠣⠜⠍⠨⠛⠇⠋⠓⠿⠋⠑⠩⠙⠃⠀⠨⠮⠓⠛⠊⠷⠛⠋⠅⠩⠑⠣⠜⠨⠱⠭⠚⠁⠀⠨⠫⠅⠭⠛⠣⠜⠐⠓⠃⠋⠪⠃⠈⠉ ⠩⠨⠑⠂⠚⠅⠧⠣⠜ 10 | ⠐⠮⠓⠛⠃⠊⠷⠛⠋⠩⠑⠀⠨⠫⠈⠉⠯⠑⠙⠚⠣⠜⠐⠯⠾⠃⠮⠽⠚⠓⠈⠉⠀⠨⠹⠅⠈⠉⠽⠚⠊⠅⠓⠣⠜⠐⠷⠿⠯⠷⠛⠋⠈⠉ ⠐⠻⠇⠉⠂⠈⠉⠿⠊⠓⠛⠣⠜⠐⠯⠩⠑⠃⠩⠙⠋⠱ 11 | ⠸⠜⠄⠣⠶⠐⠑⠩⠙⠑⠸⠊⠀⠚⠊⠚⠓⠀⠐⠽⠁⠸⠙⠅⠚⠂⠑⠽⠚⠊⠙⠀⠾⠸⠚⠊⠂⠙⠾⠁⠊⠓⠛⠀⠓⠛⠓⠋⠀⠊⠓⠊⠛⠀⠚⠩⠊⠚⠘⠚⠃ 12 | ⠨⠜⠐⠳⠧⠣⠜⠐⠫⠺⠅⠈⠉⠀⠐⠫⠪⠈⠉⠣⠜⠐⠾⠊⠓⠚⠮⠓⠁⠛⠇⠋⠀⠐⠮⠓⠛⠊⠅⠷⠛⠋⠁⠑⠃⠣⠜⠐⠱⠳⠈⠉⠀⠐⠹⠨⠹⠈⠉⠣⠜⠐⠷⠛⠋⠓⠇⠿⠋⠑⠃⠙ 13 | ⠨⠽⠚⠊⠙⠾⠊⠓⠁⠛⠃⠣⠜⠐⠱⠃⠉⠁⠧ 14 | ⠸⠜⠘⠯⠸⠋⠩⠑⠂⠛⠯⠁⠡⠑⠙⠚⠀⠙⠚⠙⠸⠊⠀⠘⠚⠂⠊⠚⠸⠓⠀⠘⠊⠂⠓⠊⠸⠓⠀⠿⠑⠙⠋⠵⠁⠙⠚⠊ 15 | ⠨⠜⠐⠚⠂⠓⠁⠚⠃⠑⠁⠣⠜⠨⠱⠅⠉⠂⠡⠻⠅⠉⠇⠈⠉⠀⠨⠳⠂⠉⠇⠰⠹⠈⠉⠣⠜⠡⠨⠿⠋⠑⠛⠃⠯⠓⠩⠛⠓⠁⠀⠰⠽⠚⠊⠙⠾⠊⠇⠓⠅⠛⠣⠜⠨⠊⠇⠑⠵⠙⠚⠃⠊ 16 | ⠼⠂⠨⠳⠴⠧⠣⠆⠀⠼⠆⠨⠳⠴⠧⠣⠅ 17 | ⠸⠜⠘⠷⠸⠓⠡⠛⠂⠊⠷⠁⠛⠋⠑⠀⠽⠐⠙⠚⠂⠑⠽⠁⠚⠊⠓⠁⠀⠿⠷⠿⠮⠘⠚⠂⠑⠀⠼⠂⠘⠓⠸⠷⠿⠷⠊⠂⠚⠙⠣⠆⠀⠼⠆⠸⠓⠑⠘⠳⠣⠅ 18 | -------------------------------------------------------------------------------- /test/input/bwv988-v03.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠁⠃⠦ 2 | ⠨⠜⠐⠺⠄⠃⠈⠉⠾⠙⠑⠙⠑⠋⠐⠪⠄⠈⠉⠮⠚⠙⠚⠙⠑ ⠐⠳⠄⠨⠳⠄⠈⠉⠓⠅⠉⠂⠮⠷⠿⠷⠊⠭⠭⠣⠜⠐⠺⠄⠃⠈⠉⠾⠙⠁⠑⠇⠙⠑⠋⠐⠪⠄⠈⠉⠮⠚⠙⠚⠙⠑ 3 | ⠭⠨⠵⠅⠽⠾⠮⠚⠁⠽⠇⠾⠮⠾⠓⠨⠋⠇⠑⠁⠉⠃⠙⠛⠊⠣⠜⠐⠳⠄⠨⠳⠄⠅⠈⠉⠓⠅⠉⠂⠮⠷⠿⠇⠷⠊⠭⠭ 4 | ⠸⠜⠘⠓⠚⠑⠓⠚⠃⠋⠅⠘⠛⠂⠊⠸⠑⠛⠃⠊⠑ ⠘⠋⠅⠓⠚⠸⠋⠘⠚⠇⠩⠙⠘⠑⠛⠊⠸⠑⠛⠃⠘⠊ ⠾⠇⠮⠾⠽⠑⠈⠉⠵⠘⠓⠊⠚⠙⠑⠯⠃⠑⠁⠙⠚⠙⠋⠘⠿⠂⠊⠁⠓⠛⠋⠑ 5 | ⠨⠜⠐⠺⠁⠨⠓⠳⠛⠭⠭⠚⠪⠂⠉⠅⠑⠃⠈⠉⠣⠜⠭⠨⠵⠂⠽⠾⠮⠚⠽⠁⠾⠃⠮⠾⠓⠨⠋⠇⠑⠃⠙⠛⠂⠊⠅ ⠨⠵⠯⠂⠵⠽⠚⠨⠋⠐⠚⠑⠃⠉⠁⠩⠙⠑⠋⠃⠉⠁⠈⠉⠋⠙⠃⠊⠣⠜ 6 | ⠐⠺⠨⠓⠳⠛⠭⠭⠚⠪⠂⠉⠅⠑⠈⠉ ⠭⠭⠨⠑⠂⠐⠳⠄⠈⠉⠓⠛⠁⠓⠁⠉⠃⠋⠮⠷⠿⠃⠯⠣⠜⠨⠵⠯⠵⠡⠽⠁⠚⠨⠋⠐⠚⠑⠂⠩⠙⠑⠋⠈⠉⠋⠙⠊⠇ 7 | ⠸⠜⠘⠷⠛⠓⠊⠚⠂⠙⠵⠋⠘⠊⠂⠚⠙⠊⠾⠮⠁⠷⠿⠓⠈⠉⠷⠛⠋⠑⠋⠛ ⠷⠛⠓⠊⠓⠛⠯⠛⠓⠋⠛⠓⠮⠓⠂⠊⠚⠊⠓⠿⠸⠛⠓⠃⠛⠁⠋⠛ 8 | ⠘⠾⠇⠊⠚⠡⠙⠑⠚⠂⠩⠽⠑⠋⠑⠙⠚⠮⠸⠋⠑⠙⠑⠚⠽⠊⠚⠙⠑⠋ 9 | ⠨⠜⠐⠑⠃⠯⠁⠿⠷⠁⠮⠚⠑⠩⠙⠱⠄⠈⠉⠑⠙⠭⠣⠜⠭⠭⠨⠑⠐⠳⠄⠈⠉⠓⠛⠓⠃⠋⠮⠷⠿⠇⠯ ⠨⠱⠄⠈⠉⠵⠐⠊⠁⠓⠃⠛⠓⠃⠋⠟⠄⠣⠜ 10 | ⠐⠑⠯⠿⠷⠁⠮⠚⠑⠅⠩⠙⠂⠕⠄⠣⠆ 11 | ⠸⠜⠸⠿⠃⠘⠚⠩⠙⠑⠋⠁⠛⠇⠷⠛⠋⠁⠑⠋⠩⠘⠊⠂⠾⠙⠑⠙⠚⠁⠡⠊⠷⠛⠓⠚⠊⠓ ⠿⠮⠁⠷⠿⠯⠵⠓⠋⠊⠵⠛⠊⠸⠑⠘⠊⠛⠱⠄⠣⠆ 12 | ⠨⠜⠄⠣⠶⠧⠄⠨⠪⠄⠃⠈⠉⠮⠚⠙⠊⠚⠙⠾⠊⠓⠛⠂⠋⠩⠑⠣⠜⠍ ⠨⠋⠁⠛⠇⠓⠈⠉⠓⠛⠋⠩⠱⠄⠁⠈⠉⠱⠭⠣⠜⠧⠄⠨⠪⠄⠈⠉⠮⠚⠂⠙⠊⠃⠚⠙⠾⠅⠊⠓⠛⠋⠩⠑⠃ 13 | ⠧⠄⠐⠪⠄⠈⠉⠊⠾⠇⠮⠷⠿⠷⠁⠊⠚⠓⠊⠚⠣⠜⠨⠋⠛⠓⠈⠉⠓⠛⠋⠅⠩⠱⠄⠂⠉⠅⠈⠉⠱⠭ ⠐⠋⠿⠷⠁⠮⠇⠾⠙⠐⠋⠩⠑⠫⠄⠧⠄⠣⠜ 14 | ⠧⠄⠐⠪⠄⠈⠉⠊⠾⠅⠮⠷⠿⠷⠁⠊⠚⠓⠊⠚ 15 | ⠸⠜⠄⠣⠶⠸⠑⠛⠊⠐⠑⠽⠾⠮⠁⠷⠛⠊⠑⠓⠊⠚⠇ ⠽⠡⠑⠙⠚⠊⠁⠓⠿⠯⠿⠷⠮⠿⠚⠛⠂⠓⠮⠙⠚⠊⠁⠓⠛ ⠷⠊⠓⠛⠋⠁⠑⠽⠚⠊⠚⠙⠊⠣⠂⠚⠸⠛⠚⠈⠉⠚⠓⠇⠋ 16 | ⠐⠽⠑⠃⠙⠚⠊⠁⠓⠿⠋⠛⠚⠊⠚⠣⠂⠋⠓⠚⠐⠋⠸⠋⠇⠑ 17 | ⠨⠜⠨⠫⠄⠈⠉⠯⠛⠂⠓⠋⠛⠓⠽⠡⠑⠋⠙⠑⠂⠋⠐⠮⠚⠙⠊⠚⠙⠣⠜⠐⠋⠿⠷⠁⠮⠾⠁⠙⠸⠜⠐⠋⠩⠑⠫⠄⠧⠄ ⠨⠜⠐⠾⠙⠑⠚⠙⠑⠐⠳⠄⠈⠉⠓⠨⠳⠈⠉⠓⠩⠛⠊⠈⠉⠣⠜ 18 | ⠨⠫⠄⠈⠉⠯⠩⠛⠂⠓⠋⠛⠓⠽⠑⠋⠙⠑⠋⠐⠮⠚⠙⠇⠊⠚⠃⠙⠁ ⠨⠊⠓⠂⠡⠛⠅⠯⠑⠙⠋⠅⠑⠙⠺⠃⠉⠁⠨⠚⠪⠙⠣⠜⠐⠾⠙⠁⠑⠃⠚⠙⠑⠐ 19 | ⠐⠳⠄⠈⠉⠓⠨⠳⠅⠉⠇⠈⠉⠓⠩⠛⠊⠇⠈⠉ ⠨⠺⠑⠨⠓⠊⠩⠛⠂⠗⠄⠣⠜⠨⠊⠓⠁⠡⠛⠃⠯⠑⠃⠙⠋⠑⠁⠙⠞⠄⠣⠆⠣⠅ 20 | ⠸⠜⠸⠙⠐⠙⠚⠇⠪⠄⠈⠉⠊⠙⠊⠇⠛⠑⠡⠐⠑ ⠸⠷⠇⠮⠷⠁⠡⠿⠯⠵⠙⠋⠁⠙⠃⠮⠾⠽⠮⠾⠽⠑⠘⠑⠩⠸⠛⠂ ⠷⠮⠾⠷⠅⠮⠾⠙⠋⠸⠊⠐⠵⠙⠚⠑⠁⠙⠚⠽⠚⠊⠁⠓⠛⠊ 21 | ⠷⠿⠯⠁⠵⠽⠾⠙⠊⠸⠑⠘⠷⠚⠑⠓⠑⠚⠳⠄⠣⠆⠣⠅ 22 | -------------------------------------------------------------------------------- /test/input/bwv988-v04.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠦ 2 | ⠀⠀⠨⠜⠄⠭⠐⠚⠃⠓⠀⠨⠑⠇⠐⠊⠨⠑⠣⠜⠭⡸⠜⠐⠑⠃⠛⠁⠀⠨⠳⠄⠈⠉⠣⠜⡸⠜⡸⠚⠃⠨⠜⠐⠓⠁⠨⠙⠇⠀⠨⠓⠛⠭⠣⠜⠐⠾⠷⠊⠭⠀⠍⠣⠜⠍⠀⠍⠣⠜⠭⠐⠙⠇⠋ 3 | ⠭⠐⠊⠇⠙⠈⠉⠣⠜⡸⠊⠃⠐⠱⠈⠉⠀⠨⠽⠮⠚⠭⠣⠜⠐⠑⠓⠭ 4 | ⠀⠀⡸⠜⡸⠳⠄⠁⠀⠻⠄⠅⠉⠂⠀⠫⠄⠣⠜⠭⡸⠚⠁⠓⠀⠭⡸⠑⠂⠛⠣⠜⠐⠱⠭⠀⠘⠺⠄⠣⠜⠭⡸⠓⠚⠀⡸⠹⠄⠂⠉⠅⠣⠜⡸⠋⠊⠓⠃⠉⠁⠈⠉⠀⡸⠱⠄⠣⠜⡸⠓⠿⠯⠛ 5 | ⠭⠘⠚⠂⠑⠁⠣⠜⡸⠓⠑⠭ 6 | ⠀⠀⠨⠜⠄⠭⠨⠋⠇⠓⠣⠜⠍⠀⠩⠨⠙⠨⠪⠣⠜⠠⠍⠀⠨⠑⠁⠳⠈⠉⠣⠜⠭⠩⠨⠙⠋⠀⠨⠓⠛⠋⠅⠈⠉⠣⠜⠐⠪⠓⠈⠉⠀⠨⠋⠴⠑⠂⠴⠡⠙⠅⠈⠉⠬⠃⠀⠙⠒⠺⠅⠔⠃⠠⠬⠇ 7 | ⠊⠂⠩⠴⠨⠑⠼⠇⠩⠙⠼⠨⠉⠀⠼⠂⠄⠩⠨⠙⠑⠭⠣⠜⠐⠷⠯⠛⠭⠣⠆⠀⠼⠆⠄⠩⠨⠙⠑⠭⠣⠜⠐⠷⠯⠛⠭⠣⠅⠄ 8 | ⠀⠀⡸⠜⠘⠓⡸⠳⠁⠉⠂⠈⠉⠣⠜⠠⠍⠀⡸⠓⠻⠈⠉⠣⠜⠭⠐⠑⠃⠛⠀⡸⠛⠂⠋⠓⠣⠜⡸⠚⠃⠐⠋⠭⠀⠩⡸⠙⡸⠊⠂⠩⠙⠣⠜⠠⠭⠩⠐⠙⠋⠀⡸⠻⠄⠅⠬⠇⠈⠉⠀⠓⠘⠳⠈⠉⠣⠜ 9 | ⡸⠊⠓⠨⠜⡸⠚⠀⡸⠜⠘⠓⠴⠛⠂⠤⠊⠃⠔⠀⠼⠂⠘⠑⠄⡸⠵⠂⠯⠿⠣⠜⡸⠱⠭⠣⠆⠀⠼⠆⠘⠑⠄⡸⠮⠂⠾⠩⠽⠣⠜⡸⠱⠭⠣⠅⠄ 10 | ⠀⠀⠨⠜⠄⠣⠶⠭⠨⠛⠑⠣⠜⠠⠍⠀⠨⠓⠺⠈⠉⠣⠜⠭⠨⠑⠚⠀⠨⠚⠮⠂⠷⠅⠿⠯⠅⠣⠜⡸⠜⠐⠓⠨⠜⠐⠊⠙⠀⠩⠨⠵⠇⠯⠻⠈⠉⠣⠜⠐⠻⠭⠀⠨⠛⠋⠂⠓⠣⠜⠭⠐⠚⠓ 11 | ⠩⠨⠙⠇⠴⠩⠑⠴⠋⠈⠉⠴⠀⠋⠩⠵⠩⠽⠾⠅⠮⠣⠜⠐⠻⠄⠀⠐⠖⠐⠷⠿⠋⠭⠣⠜⠐⠫⠭ 12 | ⠀⠀⡸⠜⠄⠣⠶⠐⠱⠡⠙⠇⠣⠜⠠⠍⠀⡸⠺⠓⠣⠜⠭⠐⠑⠓⠀⠐⠙⠇⡸⠛⠅⠊⠣⠜⠐⠋⠹⠁⠈⠉⠀⡸⠚⠩⡸⠑⠚⠣⠜⠐⠙⠾⠃⠮⠁⠷⠿⠀⡸⠋⠂⠓⠋⠣⠜⡸⠷⠁⠮⠃⠺⠈⠉ 13 | ⡸⠊⠌⠛⠬⠋⠔⠀⠊⠇⠬⠃⠚⠁⡸⠁⠈⠉⠘⠚⠀⡸⠫⠇⠔⠠⠬⠑⠴ 14 | ⠀⠀⠨⠜⠄⠭⠨⠙⠬⠋⠬⠂⠀⠐⠊⠇⠬⠚⠑⠀⠐⠓⠇⠨⠹⠂⠈⠉⠀⠙⠬⠑⠴⠙⠬⠈⠉⠀⠾⠽⠱⠈⠉⠣⠜⠐⠊⠓⠚⠀⠨⠵⠙⠑⠙⠚⠊⠣⠜⠐⠫⠄⠀⠨⠑⠐⠓⠅⠛⠂⠈⠉⠣⠜ 15 | ⡸⠜⡸⠊⠃⠨⠜⠐⠑⠁⠙⠃⠈⠉⠀⠼⠂⠐⠛⠓⠭⠣⠜⠐⠽⠮⠚⠭⠣⠆⠀⠼⠆⠐⠛⠓⠭⠣⠜⠐⠽⠮⠚⠭⠣⠅ 16 | ⠀⠀⡸⠜⡸⠹⠄⠈⠉⠣⠜⡸⠋⠮⠷⠿⠷⠁⠀⡸⠙⠅⠉⠇⠺⠈⠉⠣⠜⠨⠜⠐⠱⠄⠀⠘⠚⠊⠙⠂⠣⠜⠨⠜⠐⠙⡸⠜⡸⠛⠃⠊⠀⠘⠛⠇⠑⠛⠂⠣⠜⡸⠱⠄⠈⠉⠀⠘⠓⠅⠚⠓⠣⠜⡸⠱⠓⠈⠉ 17 | ⡸⠹⠄⠇⠉⠅⠈⠉⠣⠜⡸⠓⠊⠃⠙⠀⡸⠙⠼⠚⠴⠁⠑⠃⠔⠀⠼⠂⠘⠓⠄⡸⠮⠂⠾⠽⠣⠜⡸⠳⠭⠣⠆⠀⠼⠆⠘⠳⠭⠣⠜⡸⠳⠠⠭⠣⠅ 18 | 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v05.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠲ 2 | ⠀⠀⠨⠜⠄⠍⠐⠑⠁⠋⠛⠷⠛⠓⠁⠊⠾⠊⠓⠚⠀⠮⠓⠛⠇⠋⠵⠋⠛⠓⠮⠛⠋⠑⠀⠷⠛⠋⠑⠩⠽⠑⠁⠋⠛⠷⠁⠚⠊⠓⠀⠿⠇⠋⠑⠩⠙⠃⠵⠸⠊⠐⠑⠃⠋⠿⠑⠁⠛⠊ 3 | ⠨⠵⠚⠊⠚⠷⠚⠂⠊⠚⠐⠵⠓⠅⠛⠓⠀⠯⠓⠑⠓⠽⠓⠸⠚⠐⠓⠸⠮⠐⠓⠸⠚⠐⠓⠀⠽⠃⠓⠸⠚⠐⠓⠽⠁⠛⠂⠋⠛⠵⠛⠙⠛⠀⠸⠾⠐⠓⠛⠋⠵⠽⠾⠇⠮⠓⠭ 4 | ⠀⠀⠸⠜⠸⠓⠅⠭⠐⠚⠃⠭⠸⠳⠇⠀⠛⠭⠐⠊⠃⠭⠸⠻⠇⠀⠋⠭⠐⠓⠃⠭⠸⠫⠂⠀⠑⠭⠐⠛⠃⠭⠸⠑⠇⠡⠙⠀⠚⠭⠨⠑⠭⠘⠺⠂⠀⠙⠭⠨⠋⠭⠸⠹⠀⠑⠭⠐⠊⠭⠸⠱⠃ 5 | ⠘⠓⠭⠐⠺⠈⠉⠾⠊⠓⠛ 6 | ⠀⠀⠨⠜⠨⠚⠅⠭⠐⠓⠃⠭⠨⠺⠀⠊⠭⠐⠛⠃⠭⠨⠪⠂⠀⠷⠛⠋⠩⠑⠃⠯⠓⠡⠑⠁⠓⠩⠽⠓⠐⠚⠨⠓⠀⠩⠽⠷⠯⠷⠐⠊⠨⠓⠇⠛⠠⠲⠓⠀⠊⠐⠋⠃⠛⠨⠛⠃⠓⠊⠀⠚⠐⠛⠇⠋⠨⠓⠇⠊⠚ 7 | ⠋⠐⠓⠅⠸⠊⠐⠋⠂⠩⠙⠊⠀⠑⠃⠐⠑⠛⠃⠊⠨⠱⠣⠆ 8 | ⠀⠀⠸⠜⠐⠷⠚⠩⠙⠇⠑⠯⠛⠃⠋⠁⠑⠽⠚⠁⠊⠓⠀⠿⠊⠚⠩⠙⠇⠵⠋⠑⠙⠾⠁⠊⠓⠛⠀⠋⠛⠓⠚⠐⠖⠇⠨⠫⠃⠈⠉⠀⠋⠑⠩⠽⠋⠐⠚⠨⠋⠁⠐⠮⠂⠨⠋⠐⠓⠨⠋ 9 | ⠐⠿⠨⠋⠑⠩⠙⠵⠁⠐⠊⠑⠨⠑⠐⠯⠅⠨⠑⠐⠛⠨⠑⠀⠐⠷⠅⠨⠋⠑⠩⠙⠵⠁⠚⠋⠨⠑⠐⠿⠨⠑⠐⠓⠅⠨⠑⠀⠐⠮⠨⠑⠩⠙⠚⠽⠋⠐⠊⠇⠙⠐⠯⠓⠃⠛⠋⠀⠿⠊⠑⠛⠃⠸⠮⠐⠑⠁⠸⠛⠊⠱⠣⠆ 10 | ⠀⠀⠨⠜⠄⠣⠶⠨⠛⠂⠭⠐⠑⠃⠭⠰⠖⠇⠨⠻⠀⠓⠵⠷⠇⠊⠵⠮⠚⠉⠓⠀⠋⠁⠉⠙⠇⠊⠃⠉⠨⠓⠟⠏⠩⠵⠋⠈⠉⠀⠋⠐⠖⠩⠑⠭⠸⠊⠂⠐⠖⠓⠛⠀⠋⠭⠨⠋⠅⠭⠰⠖⠇⠸⠱ 11 | ⠙⠭⠨⠋⠭⠰⠖⠇⠘⠪⠀⠚⠭⠨⠓⠅⠛⠋⠩⠑⠀⠋⠭⠸⠫⠅⠈⠉⠯⠡⠑⠙⠚ 12 | ⠀⠀⠸⠜⠄⠣⠶⠍⠨⠑⠙⠚⠮⠁⠓⠛⠋⠵⠨⠙⠚⠊⠀⠾⠁⠓⠃⠛⠋⠵⠁⠙⠚⠊⠷⠐⠓⠊⠇⠚⠀⠽⠑⠇⠋⠑⠽⠁⠚⠊⠓⠮⠚⠙⠊⠀⠾⠁⠊⠚⠛⠃⠸⠾⠩⠙⠩⠑⠋⠁⠿⠇⠓⠊⠛⠂ 13 | ⠷⠚⠓⠋⠶⠶⠀⠐⠮⠙⠊⠋⠷⠨⠙⠐⠓⠋⠿⠨⠙⠐⠛⠋⠀⠷⠚⠓⠃⠋⠇⠸⠾⠐⠚⠊⠚⠷⠚⠛⠚⠀⠷⠋⠓⠂⠚⠨⠯⠐⠾⠷⠾⠋⠭ 14 | ⠀⠀⠨⠜⠸⠽⠁⠋⠑⠋⠮⠋⠑⠋⠁⠐⠽⠊⠇⠓⠊⠁⠀⠐⠿⠸⠊⠓⠃⠊⠁⠐⠷⠑⠇⠙⠑⠁⠐⠾⠓⠛⠓⠁⠀⠨⠯⠑⠙⠁⠑⠿⠑⠙⠑⠷⠑⠙⠑⠀⠮⠑⠙⠚⠇⠽⠚⠊⠓⠿⠨⠊⠅⠓⠛ 15 | ⠓⠐⠚⠭⠡⠸⠛⠂⠋⠑⠀⠽⠐⠙⠚⠇⠙⠵⠙⠁⠋⠙⠿⠙⠓⠙⠀⠐⠮⠐⠽⠾⠇⠮⠚⠨⠑⠸⠑⠃⠨⠙⠅⠀⠾⠓⠑⠓⠾⠓⠁⠨⠑⠚⠨⠳⠣⠆⠣⠅ 16 | ⠀⠀⠸⠜⠐⠋⠭⠸⠙⠭⠐⠫⠀⠑⠭⠘⠚⠭⠐⠱⠀⠙⠚⠊⠁⠓⠛⠋⠀⠛⠷⠮⠱⠈⠉⠵⠐⠙⠚⠊⠀⠾⠁⠓⠇⠛⠓⠮⠓⠚⠓⠅⠐⠽⠸⠓⠐⠑⠸⠓ 17 | ⠐⠋⠸⠓⠭⠚⠃⠊⠓⠀⠿⠐⠑⠃⠋⠛⠃⠷⠑⠚⠓⠮⠙⠓⠛⠇⠀⠓⠸⠓⠁⠑⠚⠳⠣⠆⠣⠅ 18 | 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v06.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠦ 2 | ⠀⠀⠨⠜⠨⠳⠄⠂⠈⠉⠀⠣⠶⠨⠪⠄⠈⠉⠣⠜⠨⠓⠿⠯⠵⠽⠃⠀⠨⠊⠷⠿⠯⠅⠵⠣⠜⠐⠺⠄⠈⠉⠀⠨⠹⠄⠇⠉⠅⠈⠉⠣⠜⠐⠚⠮⠃⠷⠿⠇⠯⠀⠨⠙⠾⠂⠮⠅⠷⠿⠣⠜⠐⠱⠄⠈⠉ 3 | ⠐⠫⠄⠃⠉⠅⠈⠉⠣⠜⠐⠑⠽⠃⠾⠮⠃⠷⠀⠐⠋⠵⠽⠅⠾⠮⠇⠣⠜⠸⠪⠄⠈⠉⠀⠸⠺⠄⠈⠉⠣⠜⠸⠮⠓⠁⠚⠅⠊⠓⠛ 4 | ⠀⠀⠸⠜⠘⠷⠇⠛⠓⠊⠚⠓⠅⠀⠣⠶⠸⠵⠃⠙⠑⠋⠛⠃⠑⠀⠷⠛⠋⠛⠓⠋⠂⠀⠮⠓⠛⠓⠊⠛⠂⠀⠾⠊⠓⠊⠚⠓⠂⠀⠐⠽⠚⠊⠓⠁⠛⠋⠀⠿⠋⠛⠑⠋⠛⠀⠷⠋⠑⠁⠙⠚⠊ 5 | ⠀⠀⠨⠜⠸⠾⠊⠁⠙⠃⠚⠊⠃⠓⠣⠜⠸⠓⠇⠐⠳⠈⠉⠀⠸⠊⠃⠉⠁⠐⠪⠈⠉⠣⠜⠐⠓⠅⠉⠂⠿⠯⠵⠡⠽⠃⠀⠐⠊⠷⠇⠿⠯⠵⠃⠣⠜⠸⠾⠵⠃⠷⠇⠮⠣⠚⠈⠉ 6 | ⠩⠐⠽⠯⠃⠮⠇⠡⠾⠡⠙⠈⠉⠣⠜⠣⠐⠚⠮⠇⠷⠿⠯⠃⠀⠨⠙⠾⠂⠮⠅⠷⠿⠣⠜⠐⠱⠄⠈⠉⠀⠐⠫⠄⠅⠈⠉⠣⠜⠐⠵⠩⠙⠇⠚⠑⠙⠚⠀⠐⠯⠑⠩⠙⠋⠅⠑⠅⠙⠂⠣⠜ 7 | ⠩⠐⠽⠚⠊⠓⠁⠛⠃⠋⠀⠼⠂⠐⠵⠡⠽⠾⠮⠷⠸⠜⠸⠿⠁⠐⠉⠣⠜⠨⠜⠸⠛⠭⠭⠀⠨⠜⠨⠳⠄⠂⠈⠉⠣⠆⠀⠼⠆⠐⠱⠄⠴⠀⠨⠪⠄⠂⠈⠉⠣⠅⠄ 8 | ⠀⠀⠸⠜⠘⠷⠸⠛⠃⠋⠁⠑⠙⠚⠀⠩⠽⠊⠸⠑⠋⠛⠃⠑⠀⠷⠛⠋⠛⠓⠋⠂⠀⠮⠓⠛⠓⠊⠛⠂⠀⠾⠊⠓⠊⠚⠊⠀⠩⠓⠁⠩⠘⠓⠭⠀⠊⠈⠊⠭⠀⠼⠂⠘⠑⠸⠵⠽⠾⠮⠂ 9 | ⠷⠛⠂⠓⠊⠚⠓⠣⠜⠸⠓⠭⠭⠣⠆⠀⠼⠆⠘⠑⠅⠛⠊⠀⠸⠵⠩⠙⠇⠑⠋⠛⠃⠑⠣⠅⠄ 10 | ⠀⠀⠨⠜⠄⠣⠶⠨⠺⠄⠈⠉⠣⠜⠈⠉⠨⠊⠷⠿⠯⠵⠃⠀⠨⠚⠮⠷⠅⠿⠯⠅⠣⠜⠩⠨⠙⠡⠹⠈⠉⠀⠩⠨⠑⠡⠱⠅⠈⠉⠣⠜⠨⠙⠾⠃⠮⠩⠷⠇⠿⠀⠨⠑⠽⠂⠾⠅⠮⠷⠅⠣⠜⠐⠫⠄⠈⠉ 11 | ⠐⠻⠄⠂⠉⠅⠈⠉⠣⠜⠐⠯⠩⠑⠇⠩⠙⠋⠑⠙⠀⠐⠿⠩⠬⠯⠩⠬⠵⠬⠿⠡⠴⠯⠴⠵⠇⠴⠀⠯⠅⠡⠑⠙⠚⠊⠩⠓⠃⠣⠜⠡⠸⠓⠁⠭⠭ 12 | ⠀⠀⠸⠜⠄⠣⠶⠸⠷⠛⠋⠛⠓⠋⠅⠀⠮⠓⠛⠓⠊⠛⠂⠀⠾⠊⠩⠓⠊⠚⠓⠂⠀⠐⠽⠚⠊⠚⠙⠚⠀⠩⠊⠁⠩⠘⠊⠭⠀⠚⠈⠚⠭⠀⠘⠋⠸⠯⠵⠽⠾ 13 | ⠀⠀⠨⠜⠸⠊⠁⠭⠭⠣⠜⠐⠹⠄⠂⠈⠉⠀⠐⠱⠄⠈⠉⠣⠜⠐⠽⠊⠃⠚⠓⠚⠃⠑⠀⠐⠵⠚⠙⠊⠙⠃⠋⠣⠜⠐⠫⠄⠈⠉⠀⠐⠻⠄⠈⠉⠣⠜⠐⠯⠩⠙⠑⠚⠑⠃⠛⠀⠐⠿⠩⠑⠋⠙⠋⠃⠓⠣⠜ 14 | ⠐⠳⠄⠈⠉⠀⠐⠪⠄⠈⠉⠣⠜⠐⠷⠛⠋⠓⠛⠋⠀⠐⠮⠬⠓⠬⠛⠬⠊⠴⠃⠓⠴⠛⠇⠴⠀⠼⠂⠐⠷⠅⠿⠯⠵⠽⠸⠜⠸⠾⠐⠉⠣⠜⠨⠜⠸⠓⠭⠭⠀⠨⠜⠨⠪⠄⠂⠈⠉⠣⠆ 15 | ⠼⠆⠐⠳⠄⠴⠣⠅ 16 | ⠀⠀⠸⠜⠘⠮⠙⠋⠓⠛⠋⠀⠛⠘⠓⠭⠀⠸⠓⠘⠊⠭⠀⠸⠊⠘⠚⠭⠀⠸⠚⠸⠙⠭⠀⠩⠙⠩⠘⠙⠸⠙⠃⠀⠑⠘⠑⠸⠑⠀⠼⠂⠘⠓⠸⠷⠿⠇⠯⠷⠃⠀⠿⠋⠑⠋⠛⠑⠣⠜⠸⠊⠭⠭⠣⠆ 17 | ⠼⠆⠘⠓⠸⠑⠋⠣⠅ 18 | 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v07.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠋⠦ 2 | ⠀⠀⠨⠜⠐⠚⠄⠂⠮⠚⠐⠑⠄⠷⠚⠀⠐⠖⠊⠄⠷⠊⠁⠨⠱⠄⠀⠐⠖⠇⠓⠄⠂⠿⠓⠅⠐⠊⠄⠨⠯⠓⠀⠐⠖⠛⠄⠯⠛⠱⠄⠈⠉⠀⠱⠏⠁⠉⠉⠟⠗⠎⠉⠚⠄⠷⠑ 3 | ⠫⠟⠉⠉⠗⠁⠎⠞⠉⠙⠄⠮⠋⠀⠛⠄⠂⠵⠓⠐⠊⠄⠾⠙⠀⠐⠢⠙⠂⠺⠄⠈⠉⠚⠄⠮⠷⠿⠃ 4 | ⠀⠀⠸⠜⠐⠖⠇⠸⠳⠘⠓⠐⠖⠇⠸⠳⠄⠈⠉⠀⠳⠄⠐⠖⠛⠄⠯⠑⠅⠀⠫⠐⠑⠩⠹⠇⠊⠀⠐⠱⠄⠈⠉⠑⠄⠯⠙⠀⠚⠄⠽⠁⠊⠂⠓⠄⠮⠚⠀⠙⠄⠵⠚⠊⠄⠾⠙⠀⠑⠄⠽⠚⠹⠑ 5 | ⠸⠓⠄⠃⠿⠓⠑⠄⠮⠙ 6 | ⠀⠀⠨⠜⠐⠳⠇⠨⠑⠁⠐⠖⠇⠳⠄⠈⠉⠀⠓⠮⠷⠿⠯⠐⠖⠇⠻⠄⠈⠉⠀⠛⠄⠷⠛⠋⠄⠁⠩⠽⠃⠑⠀⠐⠖⠩⠙⠄⠵⠋⠐⠪⠄⠈⠉⠀⠪⠞⠁⠉⠉⠩⠝⠕⠏⠉⠛⠄⠵⠐⠊ 7 | ⠺⠩⠝⠉⠉⠕⠁⠏⠟⠉⠓⠄⠯⠐⠚⠀⠐⠢⠚⠃⠩⠙⠄⠮⠨⠊⠑⠄⠁⠯⠂⠙⠀⠐⠢⠩⠙⠱⠄⠈⠉⠱⠄⠣⠆ 8 | ⠀⠀⠸⠜⠐⠖⠸⠚⠄⠮⠚⠋⠄⠾⠑⠀⠐⠖⠩⠙⠄⠾⠊⠐⠑⠄⠽⠑⠀⠸⠓⠄⠅⠾⠂⠑⠳⠄⠁⠉⠃⠈⠉⠀⠓⠮⠷⠿⠯⠛⠄⠷⠨⠜⠐⠊⠃⠀⠸⠜⠐⠑⠄⠁⠸⠮⠃⠛⠑⠄⠯⠛ 9 | ⠓⠄⠮⠛⠋⠄⠿⠓⠀⠊⠄⠷⠛⠚⠄⠷⠊⠀⠑⠄⠿⠊⠐⠱⠄⠣⠆ 10 | ⠀⠀⠨⠜⠄⠣⠶⠨⠛⠄⠂⠯⠛⠐⠊⠄⠨⠵⠛⠀⠓⠄⠿⠃⠓⠺⠄⠀⠫⠟⠉⠉⠗⠁⠎⠞⠉⠽⠚⠊⠓⠛⠃⠋⠀⠐⠖⠩⠑⠄⠩⠽⠑⠺⠄⠈⠉⠀⠚⠄⠨⠾⠛⠇⠓⠄⠩⠵⠋ 11 | ⠙⠄⠯⠃⠩⠓⠇⠪⠞⠉⠉⠎⠡⠗⠩⠟⠉⠀⠓⠄⠮⠚⠋⠄⠿⠂⠩⠑⠀⠋⠄⠐⠾⠓⠃⠫⠚ 12 | ⠀⠀⠸⠜⠄⠣⠶⠐⠱⠸⠑⠐⠱⠙⠀⠐⠖⠚⠄⠮⠚⠓⠄⠮⠚⠀⠙⠄⠵⠚⠊⠄⠾⠙⠀⠺⠁⠘⠚⠸⠚⠄⠮⠚⠀⠳⠎⠉⠉⠞⠩⠝⠇⠩⠕⠉⠋⠄⠸⠾⠃⠓⠀⠪⠞⠉⠉⠝⠕⠇⠏⠉⠡⠛⠄⠯⠩⠑ 13 | ⠫⠁⠸⠓⠐⠙⠄⠁⠮⠚⠀⠫⠄⠈⠉⠋⠄⠐⠯⠑ 14 | ⠀⠀⠨⠜⠐⠚⠄⠂⠩⠷⠊⠁⠨⠑⠂⠯⠵⠽⠾⠀⠙⠄⠁⠯⠑⠋⠄⠁⠷⠛⠀⠓⠮⠷⠿⠯⠊⠄⠾⠓⠀⠐⠖⠛⠄⠯⠛⠇⠱⠄⠁⠉⠃⠈⠉⠀⠱⠏⠁⠉⠉⠟⠗⠎⠉⠚⠄⠷⠑ 15 | ⠫⠟⠉⠉⠗⠁⠎⠞⠉⠙⠄⠮⠋⠀⠛⠄⠵⠰⠑⠨⠓⠄⠁⠮⠂⠛⠀⠳⠄⠈⠉⠳⠄⠣⠆⠣⠅ 16 | ⠀⠀⠸⠜⠐⠖⠐⠙⠄⠾⠙⠁⠩⠸⠓⠄⠇⠾⠋⠀⠊⠄⠽⠚⠙⠄⠾⠇⠊⠀⠚⠄⠐⠯⠑⠐⠖⠩⠙⠄⠾⠙⠀⠱⠄⠈⠉⠑⠄⠯⠙⠀⠚⠄⠽⠁⠊⠂⠓⠄⠮⠚⠀⠙⠄⠵⠚⠊⠄⠾⠙ 17 | ⠑⠄⠽⠚⠐⠋⠄⠽⠇⠑⠀⠸⠓⠄⠁⠵⠚⠳⠄⠣⠆⠣⠅ 18 | -------------------------------------------------------------------------------- /test/input/bwv988-v08.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠲ 2 | ⠨⠜⠐⠵⠁⠓⠃⠚⠊⠷⠁⠚⠃⠑⠙⠾⠁⠵⠷⠍ ⠐⠵⠛⠃⠊⠓⠿⠊⠇⠙⠚⠮⠁⠨⠵⠿⠍ ⠸⠾⠑⠃⠓⠛⠯⠁⠓⠚⠊⠷⠁⠩⠨⠽⠯⠍ ⠸⠮⠐⠑⠛⠋⠵⠁⠛⠊⠓⠿⠮⠨⠑⠈⠉ 3 | ⠵⠚⠇⠓⠊⠂⠾⠓⠑⠋⠇⠡⠿⠵⠾⠍ ⠨⠯⠅⠙⠊⠚⠽⠊⠋⠩⠛⠷⠯⠽⠍ ⠨⠮⠛⠑⠋⠇⠿⠑⠐⠊⠚⠂⠽⠊⠛⠨⠙ ⠾⠓⠑⠛⠂⠷⠑⠚⠙⠇⠵⠚⠓⠊ 4 | ⠸⠜⠸⠓⠑⠚⠓⠍⠸⠓⠛⠋ ⠛⠑⠁⠘⠊⠛⠍⠸⠛⠃⠋⠑ ⠋⠁⠘⠚⠓⠋⠍⠸⠋⠑⠩⠙ ⠑⠘⠊⠛⠑⠍⠡⠸⠙⠇⠚⠊ ⠚⠑⠓⠚⠃⠍⠷⠁⠡⠿⠇⠷⠃ ⠙⠅⠋⠊⠁⠙⠃⠍⠊⠓⠊ 5 | ⠑⠛⠊⠐⠑⠍⠸⠑⠙⠑ ⠘⠓⠸⠓⠘⠚⠑⠘⠓⠭ 6 | ⠨⠜⠸⠚⠨⠾⠅⠮⠷⠛⠋⠑⠇⠩⠽⠋⠑⠋ ⠐⠊⠨⠮⠷⠿⠋⠑⠩⠙⠇⠾⠑⠙⠑ ⠐⠓⠨⠷⠿⠯⠑⠁⠩⠙⠇⠚⠮⠙⠚⠑ ⠩⠽⠋⠐⠊⠚⠇⠽⠊⠋⠛⠂⠷⠋⠩⠙⠋ ⠑⠁⠛⠊⠨⠑⠍⠡⠙⠅⠊⠛⠃ 7 | ⠓⠇⠚⠅⠑⠃⠓⠍⠓⠛⠓ ⠐⠊⠩⠙⠋⠓⠍⠓⠂⠊⠨⠙ ⠵⠁⠛⠊⠇⠩⠙⠵⠝⠞⠎⠗⠟⠏⠱⠣⠆ 8 | ⠸⠜⠸⠷⠅⠚⠑⠙⠇⠾⠑⠓⠛⠇⠯⠷⠾⠍ ⠸⠿⠅⠊⠩⠙⠃⠚⠮⠙⠛⠁⠋⠇⠵⠿⠮⠍ ⠸⠯⠅⠓⠚⠊⠇⠷⠚⠐⠋⠑⠇⠩⠽⠋⠓⠛⠇ ⠯⠓⠩⠨⠙⠁⠚⠇⠮⠙⠋⠑⠇⠽⠋⠊⠓ 9 | ⠿⠊⠑⠂⠋⠿⠃⠑⠇⠐⠊⠚⠇⠡⠽⠊⠛⠊⠇ ⠾⠑⠐⠓⠊⠾⠁⠓⠃⠋⠛⠷⠁⠋⠸⠚⠑ ⠩⠽⠋⠁⠸⠊⠂⠚⠽⠊⠁⠋⠇⠛⠷⠋⠩⠙⠅⠋ ⠿⠊⠑⠂⠋⠿⠑⠅⠛⠊⠐⠱⠣⠆ 10 | ⠨⠜⠄⠣⠶⠐⠮⠨⠑⠛⠋⠵⠁⠛⠊⠓⠿⠮⠡⠽⠍ ⠐⠵⠓⠚⠊⠷⠁⠚⠑⠙⠾⠁⠵⠇⠡⠿⠍ ⠯⠙⠊⠁⠚⠂⠽⠊⠩⠛⠃⠓⠮⠛⠩⠑⠋⠇ ⠿⠩⠑⠚⠩⠙⠂⠩⠵⠚⠛⠁⠓⠇⠮⠛⠩⠑⠛ 11 | ⠷⠁⠚⠃⠐⠋⠩⠑⠯⠁⠓⠚⠊⠷⠁⠾⠨⠯⠍ ⠐⠯⠊⠃⠙⠚⠮⠙⠋⠑⠽⠯⠮⠍ ⠍⠨⠙⠚⠨⠛⠂⠷⠩⠑⠋⠐⠓⠿⠃⠨⠋⠑⠃⠊ ⠐⠖⠷⠿⠋⠍⠐⠊⠂⠓⠛⠐ 12 | ⠐⠢⠛⠫⠈⠉ 13 | ⠸⠜⠄⠣⠶⠐⠑⠸⠊⠛⠑⠍⠡⠐⠙⠁⠚⠊ ⠓⠁⠑⠚⠓⠍⠡⠸⠛⠃⠋⠑ ⠽⠋⠊⠓⠇⠩⠿⠊⠙⠚⠇⠮⠡⠙⠩⠑⠁⠩⠙⠇ ⠾⠩⠑⠛⠁⠋⠇⠵⠛⠊⠓⠇⠿⠊⠙⠊⠃ 14 | ⠾⠓⠃⠋⠛⠷⠃⠋⠇⠸⠚⠩⠑⠯⠁⠸⠚⠓⠚ ⠽⠁⠊⠋⠩⠓⠮⠁⠋⠃⠙⠑⠯⠁⠙⠃⠊⠙ ⠩⠘⠑⠩⠸⠑⠃⠋⠙⠃⠊⠇⠚ ⠋⠓⠚⠸⠋⠍⠑⠇⠙⠚ 15 | ⠨⠜⠈⠉⠐⠋⠨⠯⠵⠽⠚⠊⠓⠃⠿⠩⠊⠩⠙⠋ ⠵⠐⠛⠁⠨⠑⠂⠡⠙⠾⠊⠩⠓⠇⠛⠯⠓⠚⠑ ⠽⠐⠋⠨⠙⠚⠮⠁⠙⠋⠑⠽⠁⠋⠊⠓⠇ ⠿⠊⠙⠚⠮⠓⠁⠛⠇⠋⠵⠛⠊⠙ 16 | ⠾⠑⠨⠓⠃⠊⠾⠓⠑⠋⠇⠡⠿⠑⠚⠑ ⠯⠓⠙⠑⠇⠯⠙⠊⠚⠂⠽⠊⠋⠓ ⠿⠊⠑⠋⠇⠿⠑⠸⠊⠚⠂⠽⠊⠛⠊⠇ ⠾⠑⠸⠓⠃⠊⠾⠓⠚⠂⠑⠁⠳⠣⠆⠣⠅ 17 | ⠸⠜⠸⠽⠋⠓⠡⠛⠇⠯⠓⠐⠙⠚⠇⠩⠮⠩⠽⠩⠿⠍ ⠘⠾⠅⠑⠛⠃⠋⠵⠛⠚⠊⠇⠩⠷⠾⠐⠯⠍ ⠘⠮⠙⠋⠑⠽⠊⠙⠋⠮⠃⠙⠸⠛⠓ ⠮⠛⠑⠋⠇⠿⠑⠁⠘⠊⠇⠚⠽⠊⠛⠑ 18 | ⠓⠚⠁⠑⠃⠡⠛⠍⠛⠃⠋⠑ ⠙⠋⠓⠁⠐⠙⠃⠍⠙⠁⠚⠙ ⠸⠑⠛⠊⠙⠍⠙⠑⠸⠛⠂ ⠷⠅⠚⠂⠑⠇⠛⠃⠷⠟⠏⠕⠁⠝⠞⠎⠳⠣⠆⠣⠅ 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v09.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠨⠉ 2 | ⠀⠀⠨⠜⠐⠚⠃⠊⠚⠙⠑⠐⠊⠨⠑⠙⠣⠜⠍⠀⠐⠚⠑⠇⠳⠈⠉⠓⠅⠉⠂⠮⠷⠻⠇⠣⠜⠐⠓⠛⠓⠊⠃⠚⠁⠸⠜⠐⠛⠨⠜⠐⠚⠁⠸⠜⠐⠊⠁⠀⠨⠓⠛⠃⠓⠊⠚⠛⠇⠚⠊⠣⠜ 3 | ⠸⠜⠐⠓⠚⠨⠜⠨⠫⠈⠉⠋⠿⠇⠯⠱ 4 | ⠀⠀⠸⠜⠘⠳⠸⠳⠈⠉⠓⠿⠯⠛⠑⠀⠓⠊⠂⠚⠙⠱⠄⠁⠉⠅⠩⠑⠂⠀⠫⠭⠙⠇⠸⠓⠐⠑⠓⠮⠇⠾ 5 | ⠀⠀⠨⠜⠨⠓⠇⠮⠾⠹⠂⠈⠉⠙⠾⠅⠮⠚⠐⠚⠣⠜⠨⠋⠃⠑⠋⠛⠃⠓⠃⠑⠓⠛⠃⠉⠂⠀⠩⠨⠙⠚⠙⠃⠩⠑⠁⠋⠐⠚⠨⠋⠡⠑⠃⠉⠂⠣⠜⠨⠋⠅⠿⠇⠷⠪⠈⠉⠊⠷⠿⠓⠅⠐⠓ 6 | ⠨⠙⠵⠅⠯⠂⠡⠻⠈⠉⠛⠯⠵⠯⠅⠩⠿⠂⠓⠈⠉⠣⠜⠐⠊⠓⠊⠃⠚⠁⠙⠐⠓⠨⠙⠃⠚⠁⠉⠃⠀⠨⠓⠻⠋⠃⠛⠡⠓⠊⠓⠣⠜⠐⠊⠾⠩⠽⠱⠁⠈⠉⠑⠽⠃⠾⠽⠵⠁⠋⠈⠉ 7 | ⠨⠻⠇⠉⠅⠫⠕⠣⠜⠨⠋⠱⠩⠙⠕⠣⠆ 8 | ⠀⠀⠸⠜⠨⠙⠚⠊⠨⠑⠐⠗⠈⠉⠀⠓⠸⠳⠇⠛⠋⠐⠯⠩⠵⠫⠈⠉⠀⠋⠸⠫⠇⠑⠙⠐⠽⠾⠂⠽⠑⠋⠑⠀⠩⠽⠊⠐⠑⠙⠾⠁⠊⠇⠚⠩⠓⠮⠚⠊⠁⠡⠓⠿⠋⠁⠑⠩⠙ 9 | ⠵⠩⠙⠚⠁⠊⠷⠯⠊⠑⠿⠮⠸⠱⠣⠆ 10 | ⠀⠀⠨⠜⠄⠣⠶⠨⠛⠇⠑⠋⠛⠓⠑⠓⠇⠊⠣⠜⠍⠀⠨⠚⠋⠇⠪⠈⠉⠊⠷⠂⠿⠓⠭⠣⠜⠨⠑⠃⠚⠩⠙⠩⠑⠋⠇⠐⠚⠨⠋⠛⠀⠭⠨⠫⠂⠵⠡⠽⠾⠊⠃⠓⠩⠛⠷⠊⠚⠓⠃⠣⠜ 11 | ⠨⠓⠅⠩⠙⠡⠻⠈⠉⠛⠯⠂⠩⠵⠋⠅⠭ 12 | ⠀⠀⠸⠜⠄⠣⠶⠸⠑⠐⠱⠡⠙⠾⠊⠚⠙⠾⠁⠊⠓⠛⠀⠓⠐⠳⠛⠯⠩⠑⠋⠛⠯⠁⠡⠑⠡⠙⠚⠀⠩⠮⠅⠐⠯⠁⠿⠇⠷⠡⠊⠡⠸⠊⠂⠷⠊⠇⠚⠁⠓⠃⠯⠛⠓⠋ 13 | ⠀⠀⠨⠜⠐⠢⠐⠿⠋⠄⠿⠩⠱⠋⠭⠺⠈⠉⠣⠜⠭⠨⠙⠈⠉⠰⠖⠙⠾⠅⠮⠷⠛⠋⠩⠑⠯⠛⠓⠋⠃⠀⠐⠚⠪⠩⠓⠇⠊⠽⠾⠇⠽⠋⠑⠙⠅⠣⠜⠐⠢⠐⠵⠙⠄⠵⠐⠖⠺⠙⠭⠡⠳⠈⠉ 14 | ⠐⠺⠇⠩⠹⠕⠈⠉⠣⠜⠐⠓⠻⠃⠋⠛⠮⠷⠁⠮⠡⠙⠚⠊ ⠨⠑⠓⠛⠋⠑⠷⠿⠃⠷⠮⠚⠣⠜⠐⠳⠪⠞⠈⠉⠀⠨⠋⠊⠰⠖⠛⠄⠷⠗⠅⠣⠜⠐⠚⠨⠋⠑⠙⠞⠣⠆⠣⠅ 15 | ⠀⠀⠸⠜⠐⠙⠊⠚⠘⠚⠃⠫⠭⠸⠋⠃⠈⠉⠀⠋⠙⠑⠋⠘⠊⠸⠊⠯⠇⠑⠋⠛⠀⠷⠊⠃⠚⠓⠮⠛⠓⠊⠁⠵⠋⠛⠓⠁⠿⠋⠑⠁⠙⠀⠾⠓⠊⠚⠽⠑⠋⠇⠛⠷⠊⠇⠚⠊⠷⠁⠛⠋⠑⠁ 16 | ⠽⠾⠽⠮⠸⠑⠘⠑⠓⠇⠉⠅⠾⠵⠳⠣⠆⠣⠅ 17 | -------------------------------------------------------------------------------- /test/input/bwv988-v10.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠸⠉ 2 | ⠀⠀⠨⠜⠄⠍⠣⠜⠍⠣⠜⠍⠀⠶⠼⠉⠀⠍⠣⠜⠍⠣⠜⠐⠖⠇⠐⠕⠇⠰⠖⠱⠄⠽⠵⠀⠍⠣⠜⠍⠣⠜⠐⠫⠹⠪⠹⠂⠀⠍⠣⠜⠍⠣⠜⠸⠪⠐⠱⠸⠱⠐⠹⠀⠍⠣⠜⠍⠣⠜ 3 | ⠰⠖⠸⠺⠊⠚⠓⠸⠜⠸⠚⠊⠃⠙⠐⠉ 4 | ⠀⠀⠸⠜⠐⠖⠇⠸⠗⠃⠰⠖⠳⠄⠿⠷⠀⠪⠻⠱⠻⠃⠀⠫⠪⠘⠪⠸⠳⠁⠀⠰⠖⠻⠋⠛⠑⠋⠁⠙⠑⠀⠚⠑⠋⠛⠃⠳⠘⠺⠀⠝⠧⠪⠃⠀⠟⠧⠱ 5 | ⠳⠇⠸⠱⠺⠅⠱⠅ 6 | ⠀⠀⠨⠜⠐⠖⠇⠨⠗⠇⠰⠖⠳⠄⠿⠷⠣⠜⠠⠍⠀⠨⠪⠻⠱⠻⠂⠣⠜⠶⠀⠐⠺⠨⠫⠅⠐⠫⠨⠱⠂⠣⠜⠶⠀⠰⠖⠩⠨⠹⠚⠙⠊⠚⠙⠊⠣⠜⠍⠀⠨⠱⠅⠐⠱⠨⠕⠈⠉⠣⠜⠐⠎⠃⠰⠖⠪⠄⠷⠮ 7 | ⠨⠱⠐⠱⠨⠕⠈⠉⠣⠜⠐⠺⠳⠫⠳⠀⠨⠕⠩⠝⠣⠜⠐⠫⠪⠃⠸⠜⠸⠪⠨⠜⠐⠳⠁⠀⠨⠵⠣⠜⠰⠖⠐⠻⠋⠛⠕⠣⠆ 8 | ⠀⠀⠸⠜⠸⠗⠂⠧⠫⠣⠜⠸⠚⠃⠊⠺⠐⠏⠈⠉⠀⠸⠟⠧⠱⠣⠜⠐⠫⠸⠪⠐⠕⠈⠉⠀⠸⠗⠧⠫⠣⠜⠐⠱⠺⠨⠜⠐⠏⠈⠉⠀⠸⠎⠇⠉⠂⠧⠳⠅⠣⠜⠨⠜⠐⠫⠸⠜⠐⠱⠩⠹⠫ 9 | ⠸⠟⠂⠧⠱⠇⠣⠜⠸⠊⠚⠊⠓⠁⠟⠀⠘⠳⠺⠃⠳⠫⠣⠜⠸⠗⠥⠀⠘⠎⠇⠉⠅⠧⠪⠣⠜⠧⠸⠫⠎⠈⠉⠀⠸⠵⠇⠉⠅⠣⠜⠸⠊⠊⠓⠊⠟⠣⠆ 10 | ⠀⠀⠨⠜⠄⠣⠶⠐⠖⠇⠨⠟⠇⠰⠖⠻⠄⠯⠿⠣⠜⠠⠍⠀⠨⠳⠅⠱⠺⠱⠇⠣⠜⠶⠀⠨⠹⠡⠻⠡⠐⠻⠨⠫⠂⠣⠜⠶⠀⠰⠖⠩⠨⠱⠩⠙⠑⠚⠙⠑⠚⠣⠜⠶⠀⠨⠫⠅⠐⠫⠨⠏⠈⠉⠣⠜ 11 | ⠐⠞⠃⠰⠖⠺⠄⠮⠾⠀⠨⠫⠐⠫⠨⠏⠈⠉⠣⠜⠨⠹⠪⠻⠁⠪⠀⠨⠏⠩⠕⠣⠜⠐⠻⠺⠸⠜⠸⠺⠨⠜⠐⠪⠃⠀⠨⠏⠈⠉⠋⠑⠅⠩⠙⠚⠣⠜⠰⠖⠐⠳⠛⠃⠓⠃⠏⠈⠉ 12 | ⠀⠀⠸⠜⠄⠣⠶⠸⠑⠋⠛⠓⠪⠸⠹⠂⠣⠜⠠⠍⠀⠘⠚⠑⠂⠋⠛⠓⠊⠃⠺⠈⠉⠣⠜⠶⠀⠸⠺⠊⠩⠓⠎⠈⠉⠣⠜⠶⠀⠸⠪⠩⠻⠺⠪⠣⠜⠶⠀⠸⠓⠊⠚⠊⠓⠛⠓⠋⠣⠜⠶ 13 | ⠸⠊⠚⠙⠃⠚⠁⠊⠓⠊⠛⠣⠜⠶⠀⠸⠚⠊⠓⠊⠚⠊⠚⠘⠚⠣⠜⠶⠀⠸⠋⠁⠘⠚⠃⠊⠚⠁⠓⠇⠛⠓⠋⠣⠜⠶ 14 | ⠀⠀⠨⠜⠐⠪⠨⠗⠡⠛⠋⠣⠜⠈⠉⠐⠫⠧⠎⠈⠉⠀⠡⠨⠟⠄⠅⠋⠑⠣⠜⠐⠪⠨⠱⠺⠳⠈⠉⠀⠨⠏⠄⠅⠩⠛⠂⠓⠣⠜⠐⠳⠨⠙⠚⠝⠁⠈⠉⠀⠨⠊⠂⠚⠓⠊⠻⠪⠅⠈⠉⠣⠜⠨⠝⠄⠹⠃ 15 | ⠨⠪⠓⠛⠳⠅⠐⠺⠂⠈⠉⠣⠜⠐⠞⠧⠳⠀⠐⠺⠊⠚⠝⠈⠉⠣⠜⠐⠏⠄⠊⠂⠓⠀⠨⠹⠔⠺⠂⠬⠁⠈⠉⠎⠅⠌⠠⠬⠇⠀⠷⠣⠜⠐⠓⠑⠙⠑⠞⠣⠆⠣⠅ 16 | ⠀⠀⠸⠜⠄⠩⠸⠝⠰⠖⠹⠄⠾⠽⠣⠜⠠⠍⠀⠸⠱⠺⠳⠺⠣⠜⠶⠀⠸⠹⠫⠘⠪⠅⠸⠳⠣⠜⠶⠀⠰⠖⠸⠻⠋⠛⠑⠋⠛⠑⠣⠜⠶⠀⠸⠳⠅⠪⠺⠳⠣⠜⠐⠕⠰⠖⠱⠄⠽⠵⠁ 17 | ⠸⠝⠧⠸⠪⠃⠣⠜⠨⠜⠐⠫⠸⠜⠐⠹⠪⠇⠹⠀⠸⠕⠧⠱⠣⠜⠸⠪⠐⠱⠸⠱⠐⠹⠀⠸⠗⠂⠘⠗⠣⠜⠰⠖⠸⠺⠊⠚⠗⠣⠆⠣⠅ 18 | -------------------------------------------------------------------------------- /test/input/bwv988-v11.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠁⠃⠂⠖ 2 | ⠀⠀⠨⠜⠐⠾⠇⠊⠓⠿⠇⠯⠵⠩⠙⠄⠃⠈⠉⠙⠯⠀⠮⠓⠛⠯⠵⠩⠽⠇⠚⠄⠈⠉⠚⠐⠮⠀⠷⠛⠋⠵⠩⠽⠇⠾⠊⠽⠃⠋⠷⠀⠿⠇⠋⠑⠩⠽⠂⠚⠊⠷⠛⠇⠋⠵⠋⠇⠡⠙ 3 | ⠾⠃⠑⠓⠁⠾⠑⠓⠵⠚⠓⠡⠿⠇⠋⠑⠀⠩⠽⠋⠓⠁⠣⠾⠐⠋⠓⠯⠸⠚⠊⠷⠇⠩⠛⠋⠀⠵⠃⠓⠂⠡⠚⠁⠵⠃⠓⠚⠮⠛⠑⠽⠂⠚⠊⠀⠷⠚⠑⠷⠁⠾⠵⠓⠵⠚⠁⠿⠃ 4 | ⠀⠀⠸⠜⠸⠓⠄⠈⠉⠓⠾⠐⠯⠑⠩⠙⠾⠁⠊⠓⠀⠛⠄⠈⠉⠛⠐⠯⠵⠩⠙⠚⠁⠮⠓⠛⠀⠋⠷⠂⠚⠵⠩⠽⠚⠊⠁⠷⠛⠋⠀⠵⠋⠛⠷⠊⠚⠂⠩⠽⠑⠋⠿⠇⠓⠊⠀⠰⠖⠳⠄⠈⠉⠓⠸⠾⠑⠂⠷⠃ 5 | ⠰⠖⠳⠄⠈⠉⠓⠩⠽⠋⠷⠃⠀⠰⠖⠳⠄⠈⠉⠷⠇⠊⠙⠐⠿⠊⠙⠀⠚⠄⠈⠉⠾⠓⠁⠑⠃⠾⠓⠚⠵⠓⠊⠇ 6 | ⠀⠀⠨⠜⠐⠓⠄⠇⠈⠉⠓⠾⠃⠨⠯⠅⠑⠩⠙⠾⠊⠓⠇⠀⠛⠄⠈⠉⠛⠨⠯⠵⠩⠙⠚⠮⠓⠂⠛⠀⠋⠄⠈⠉⠯⠛⠓⠩⠽⠁⠐⠚⠊⠷⠊⠚⠀⠯⠁⠨⠑⠩⠙⠇⠾⠁⠙⠑⠽⠋⠇⠛⠷⠛⠋ 7 | ⠰⠖⠱⠄⠈⠉⠑⠐⠿⠁⠊⠨⠵⠀⠰⠖⠱⠄⠈⠉⠑⠩⠐⠷⠚⠵⠀⠰⠖⠱⠄⠈⠉⠵⠋⠓⠩⠽⠃⠋⠓⠀⠛⠄⠈⠉⠿⠑⠐⠊⠿⠃⠑⠛⠮⠇⠩⠙⠑⠣⠆ 8 | ⠀⠀⠸⠜⠐⠾⠃⠊⠓⠁⠿⠯⠵⠩⠙⠄⠈⠉⠙⠯⠀⠮⠓⠛⠯⠁⠑⠇⠩⠙⠚⠄⠈⠉⠚⠐⠮⠀⠷⠛⠋⠁⠵⠇⠩⠙⠚⠐⠯⠃⠑⠁⠙⠾⠊⠓⠀⠩⠐⠽⠚⠁⠊⠷⠛⠋⠮⠁⠓⠛⠯⠛⠓ 9 | ⠿⠊⠐⠑⠿⠊⠨⠑⠐⠮⠛⠑⠁⠡⠽⠚⠊⠀⠩⠷⠚⠑⠡⠿⠚⠃⠑⠾⠛⠂⠋⠁⠵⠩⠙⠚⠀⠮⠐⠑⠇⠩⠛⠮⠨⠑⠇⠛⠯⠁⠩⠙⠊⠂⠷⠁⠛⠋⠀⠵⠁⠸⠊⠛⠵⠘⠊⠛⠵⠿⠮⠸⠑⠄⠣⠆ 10 | ⠀⠀⠨⠜⠄⠣⠶⠧⠄⠨⠮⠅⠓⠛⠯⠑⠙⠂⠀⠾⠊⠓⠭⠄⠰⠵⠙⠚⠮⠓⠡⠛⠂⠀⠯⠑⠙⠾⠇⠮⠷⠩⠛⠩⠨⠵⠂⠋⠩⠐⠮⠃⠀⠚⠩⠐⠵⠁⠛⠮⠡⠽⠚⠊⠷⠁⠊⠅⠛ 11 | ⠯⠓⠚⠁⠨⠯⠓⠚⠷⠋⠐⠚⠷⠇⠛⠋⠀⠡⠿⠊⠙⠁⠡⠿⠊⠙⠮⠛⠙⠮⠂⠓⠩⠛⠀⠷⠁⠚⠨⠋⠷⠋⠁⠡⠰⠙⠂⠾⠊⠓⠿⠂⠋⠩⠑⠀⠯⠓⠋⠂⠐⠾⠓⠛⠃⠷⠋⠓⠃⠾⠨⠋⠩⠑ 12 | ⠀⠀⠸⠜⠄⠣⠶⠸⠵⠋⠛⠷⠊⠚⠃⠡⠽⠸⠑⠐⠙⠈⠉⠽⠚⠇⠊⠀⠷⠊⠚⠽⠑⠋⠡⠿⠸⠓⠐⠛⠈⠉⠿⠋⠃⠑⠀⠙⠄⠈⠉⠽⠋⠓⠨⠽⠃⠚⠊⠁⠷⠩⠛⠋⠁ 13 | ⠩⠵⠩⠙⠚⠁⠮⠓⠛⠯⠁⠩⠑⠩⠙⠾⠁⠡⠙⠃⠊⠀⠓⠄⠈⠉⠷⠚⠸⠋⠷⠾⠇⠩⠵⠋⠘⠷⠅⠀⠊⠄⠂⠉⠅⠈⠉⠮⠙⠡⠛⠮⠽⠇⠩⠵⠋⠩⠘⠮⠂⠀⠚⠄⠈⠉⠾⠩⠙⠇⠩⠑⠯⠛⠂⠓⠮⠓⠛ 14 | ⠷⠋⠓⠂⠾⠐⠋⠩⠑⠇⠯⠓⠋⠸⠾⠓⠚⠁ 15 | ⠀⠀⠨⠜⠨⠯⠡⠑⠙⠾⠮⠷⠇⠛⠄⠈⠉⠛⠮⠇⠀⠨⠵⠙⠚⠮⠷⠿⠇⠋⠄⠈⠉⠋⠨⠵⠀⠽⠚⠊⠷⠛⠃⠋⠿⠇⠋⠑⠩⠽⠃⠑⠋⠀⠿⠨⠋⠑⠡⠽⠚⠊⠃⠾⠊⠓⠿⠃⠓⠊ 16 | ⠾⠅⠊⠓⠡⠿⠋⠑⠃⠯⠑⠙⠾⠃⠙⠑⠀⠯⠅⠙⠋⠁⠷⠐⠙⠋⠽⠊⠙⠁⠯⠊⠙⠀⠐⠿⠇⠑⠃⠛⠮⠁⠨⠑⠛⠵⠐⠊⠨⠑⠿⠇⠊⠙⠀⠾⠓⠑⠾⠃⠓⠛⠃⠷⠁⠾⠵⠓⠄⠣⠆⠣⠅ 17 | ⠀⠀⠸⠜⠸⠙⠄⠈⠉⠙⠐⠯⠅⠮⠃⠓⠛⠯⠁⠑⠙⠀⠚⠄⠈⠉⠚⠐⠮⠁⠷⠛⠋⠁⠵⠙⠚⠀⠊⠄⠈⠉⠮⠚⠙⠵⠋⠛⠇⠷⠛⠋⠀⠑⠄⠈⠉⠵⠋⠛⠷⠊⠚⠇⠽⠚⠊ 18 | ⠓⠄⠈⠉⠷⠊⠚⠽⠑⠋⠃⠡⠿⠋⠑⠀⠙⠄⠈⠉⠽⠋⠃⠙⠇⠮⠁⠋⠙⠮⠙⠋⠀⠮⠙⠃⠊⠇⠿⠂⠑⠁⠸⠊⠿⠑⠛⠮⠙⠸⠛⠂⠀⠷⠅⠚⠑⠷⠚⠂⠑⠷⠵⠾⠓⠄⠣⠆⠣⠅ 19 | -------------------------------------------------------------------------------- /test/input/bwv988-v12.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠲ 2 | ⠨⠜⠄⠭⠐⠷⠇⠿⠓⠁⠮⠾⠽⠚⠊⠓ ⠨⠵⠐⠊⠚⠩⠙⠵⠁⠯⠿⠷⠊⠭ ⠭⠷⠿⠯⠑⠩⠙⠂⠚⠮⠓⠛⠃⠓ ⠓⠂⠉⠐⠖⠿⠯⠑⠭⠧ 3 | ⠸⠜⠸⠳⠂⠳⠳ ⠻⠻⠻⠣⠜⠭⠐⠵⠃⠯⠑⠡⠽⠁⠾⠇⠮⠂⠚⠙⠑ ⠸⠫⠫⠫⠣⠜⠸⠷⠂⠐⠙⠚⠊⠁⠷⠿⠯⠁⠵⠇⠩⠙⠭ ⠸⠵⠘⠵⠸⠑⠭⠽⠇⠾⠊⠙⠣⠜ 4 | ⠭⠸⠵⠯⠇⠿⠷⠨⠜⠸⠮⠃⠾⠽⠁⠑⠋⠑⠐⠉ 5 | ⠨⠜⠄⠍⠨⠑⠄⠈⠉⠵⠚⠊⠓⠡⠿⠇⠋⠑⠛⠣⠜⠐⠑⠁⠉⠯⠁⠩⠿⠓⠁⠭⠧ ⠐⠯⠷⠁⠨⠽⠇⠵⠋⠐⠪⠅⠊⠂⠈⠉⠣⠜⠍⠸⠜⠸⠓⠄⠃⠈⠉⠷⠾⠨⠜⠐⠽⠁⠵⠯⠁⠛⠓⠋ 6 | ⠐⠮⠚⠛⠓⠁⠮⠇⠓⠛⠁⠨⠋⠵⠙⠚⠊⠣⠜⠐⠿⠵⠸⠜⠸⠮⠷⠛⠐⠹⠙⠈⠉ ⠐⠳⠂⠧⠧⠣⠜⠸⠜⠐⠽⠨⠜⠸⠾⠐⠯⠃⠵⠽⠇⠑⠋⠸⠛⠃⠷⠁⠊⠚⠙ 7 | ⠸⠜⠘⠺⠺⠺⠂ ⠹⠅⠹⠹ ⠱⠱⠱ ⠓⠄⠘⠾⠸⠯⠃⠑⠙⠋⠵⠁⠙⠚⠊ 8 | ⠨⠜⠄⠍⠐⠛⠃⠓⠊⠾⠁⠩⠙⠑⠛⠯⠑⠁⠙⠇⠚⠣⠜⠐⠱⠁⠧⠧ ⠐⠮⠷⠂⠿⠯⠃⠑⠁⠉⠅⠭⠧⠣⠜⠍⠐⠯⠵⠸⠜⠄⠩⠐⠽⠃⠾⠁⠨⠜⠸⠮⠷⠯⠃⠿⠓⠁⠊⠚ 9 | ⠭⠩⠨⠙⠈⠉⠽⠚⠇⠊⠚⠽⠑⠁⠋⠇⠛⠣⠜⠩⠐⠽⠵⠁⠯⠿⠓⠁⠭⠧ ⠨⠓⠐⠷⠿⠂⠳⠈⠉⠷⠅⠉⠂⠚⠊⠓⠁⠣⠜⠭⠸⠜⠸⠊⠈⠉⠮⠨⠜⠸⠾⠁⠩⠽⠇⠾⠮⠸⠜⠸⠷⠿⠯⠁ 10 | ⠸⠜⠘⠚⠓⠭⠸⠷⠃⠿⠓⠋ ⠛⠚⠭⠘⠾⠇⠩⠽⠑⠚⠂ ⠸⠯⠛⠃⠓⠛⠐ 11 | ⠋⠛⠋⠁⠑⠇ ⠩⠽⠵⠯⠵⠙⠋⠃⠙⠊ 12 | ⠨⠜⠐⠿⠇⠋⠛⠓⠿⠊⠂⠓⠅⠛⠫⠅⠈⠉⠣⠜⠸⠜⠸⠑⠨⠜⠐⠵⠯⠱⠈⠉⠵⠚⠃⠩⠙⠑⠁ ⠐⠋⠃⠨⠑⠩⠙⠂⠚⠊⠃⠨⠛⠣⠜ 13 | ⠐⠯⠃⠛⠋⠃⠑⠯⠸⠜⠄⠩⠐⠽⠁⠵⠁⠯⠁⠨⠜⠐⠻⠁⠈⠉ ⠐⠳⠄⠃⠉⠅⠛⠯⠇⠮⠓⠈⠉⠣⠜⠐⠛⠸⠜⠸⠓⠃⠊⠁⠨⠜⠸⠚⠁⠩⠙⠃⠸⠜⠸⠋⠁ ⠐⠓⠿⠯⠿⠨⠑⠩⠽⠑⠭⠣⠜ 14 | ⠨⠜⠐⠱⠄⠁⠋⠁⠿⠩⠽⠑⠣⠆ 15 | ⠸⠜⠸⠱⠍⠑⠅⠋⠛⠷⠊⠓⠛ ⠓⠁⠘⠓⠍⠸⠋⠅⠛⠂⠓⠇⠮⠛⠇⠋⠑ ⠸⠾⠘⠚⠸⠋⠇⠑⠅⠩⠽⠂⠊⠸⠑⠇⠓⠃⠮⠋⠃⠙⠇⠊ ⠸⠵⠯⠵⠩⠽⠑⠁⠘⠊⠑⠭⠣⠆ 16 | ⠨⠜⠄⠣⠶⠭⠐⠵⠂⠯⠑⠡⠽⠾⠮⠚⠙⠑ ⠭⠷⠇⠿⠓⠁⠮⠾⠽⠚⠊⠓ ⠨⠳⠈⠉⠷⠩⠛⠇⠊⠓⠿⠷⠋ ⠐⠢⠯⠛⠈⠉⠟⠩⠏⠟⠡⠗⠛⠐⠊⠭⠨⠛⠇ 17 | ⠸⠜⠄⠣⠶⠸⠱⠇⠱⠡⠹ ⠚⠙⠚⠊⠂⠓⠮⠾⠅⠣⠜⠸⠱⠈⠉⠵⠋⠁⠙⠇⠑⠯⠵⠡⠛ ⠸⠙⠚⠙⠋⠃⠘⠊⠙⠇⠣⠜⠐⠢⠡⠸⠿⠋⠈⠉⠏⠡⠟⠏⠩⠕⠋⠐⠙⠭⠸⠋ 18 | ⠘⠺⠧⠧⠣⠜⠩⠸⠵⠋⠑⠩⠙⠵⠋⠛⠂⠓⠮⠚⠩⠙⠇⠩⠑ 19 | ⠨⠜⠨⠷⠛⠓⠊⠷⠛⠋⠑⠽⠂⠚⠊⠓ ⠟⠄⠂⠈⠉⠣⠜⠸⠜⠐⠋⠨⠜⠐⠯⠩⠵⠋⠋⠋⠵⠩⠽ ⠐⠛⠿⠷⠛⠛⠛⠇⠷⠮⠣⠜⠩⠐⠱⠧⠻⠇⠈⠉ ⠐⠳⠧⠫⠅⠈⠉⠣⠜ 20 | ⠐⠿⠋⠁⠩⠑⠛⠇⠯⠃⠡⠑⠩⠙⠇⠡⠙⠾⠁⠮⠃⠸⠜⠸⠷⠿⠃ ⠐⠯⠛⠂⠓⠋⠁⠿⠓⠩⠓⠊⠁⠾⠙⠑⠋⠣⠜⠸⠜⠸⠓⠭⠧⠧ ⠨⠑⠂⠉⠅⠭⠧⠧⠣⠜ 21 | ⠍⠨⠜⠐⠮⠩⠷⠇⠿⠷⠡⠛⠃⠋⠑⠇⠯⠑⠙⠚ 22 | ⠸⠜⠄⠭⠸⠋⠛⠓⠅⠊⠚⠇⠉⠂⠣⠜⠐⠏⠄⠂⠈⠉ ⠐⠽⠑⠙⠚⠽⠁⠚⠊⠓⠮⠁⠛⠂⠓⠊ ⠾⠙⠃⠚⠊⠾⠁⠛⠩⠑⠛⠘⠾⠑⠩⠙⠚ ⠸⠯⠁⠡⠙⠃⠚⠊⠷⠾⠸⠯⠩⠵⠂⠋⠡⠑⠂ 23 | ⠙⠐⠙⠍⠸⠋⠃⠑⠙⠵⠁⠙⠚⠊ ⠚⠅⠸⠚⠍⠸⠑⠃⠙⠚⠽⠁⠚⠊⠩⠓ 24 | ⠨⠜⠄⠍⠐⠙⠁⠑⠋⠵⠣⠋⠩⠛⠓⠿⠃⠓⠊⠚⠣⠜⠐⠝⠄⠈⠉ ⠐⠎⠄⠂⠉⠅⠈⠉⠣⠜⠐⠙⠓⠛⠋⠁⠵⠃⠚⠙⠊ ⠐⠊⠑⠇⠋⠛⠷⠁⠚⠊⠙⠣⠜ 25 | ⠸⠚⠃⠙⠁⠚⠸⠜⠸⠊⠁⠰⠖⠓⠄⠿⠐⠉ ⠐⠚⠊⠁⠚⠙⠐⠖⠇⠑⠄⠯ ⠱⠈⠉⠵⠚⠁⠙⠑⠯⠁⠛⠓⠊ ⠾⠷⠵⠾⠓⠃⠭⠧⠣⠆⠣⠅ 26 | ⠸⠜⠘⠊⠅⠸⠊⠍⠚⠃⠊⠓⠮⠁⠓⠛⠡⠋ ⠷⠋⠁⠑⠩⠙⠵⠁⠡⠙⠚⠊⠾⠁⠊⠓⠛ ⠷⠅⠸⠊⠓⠛⠷⠛⠋⠂⠩⠑⠫⠈⠉ ⠯⠅⠑⠂⠙⠋⠱⠄⠅⠘⠊⠅⠣⠜ 27 | ⠸⠳⠁⠈⠉⠷⠚⠃⠊⠁⠓⠿⠋⠁⠑⠙ ⠘⠚⠭⠭⠸⠋⠙⠑⠇⠣⠜⠘⠾⠵⠷⠾⠃⠑⠸⠓⠈⠉⠷⠮⠛⠃ ⠘⠳⠈⠉⠷⠚⠑⠇⠛⠳⠣⠜⠸⠳⠧⠧⠣⠆⠣⠅ 28 | -------------------------------------------------------------------------------- /test/input/bwv988-v13.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠲ 2 | ⠨⠜⠐⠞⠃⠝⠞⠎⠚⠂⠈⠉⠞⠟⠗⠁⠎⠾⠽⠐⠢⠕⠽⠚⠊⠓⠀⠨⠕⠂⠏⠕⠩⠝⠑⠈⠉⠕⠝⠕⠁⠏⠿⠷⠐⠢⠎⠷⠛⠋⠑⠀⠗⠎⠗⠟⠓⠈⠉⠗⠟⠏⠟⠷⠯⠐⠮⠨⠚⠊⠓ 3 | ⠐⠢⠗⠂⠟⠏⠟⠏⠑⠈⠉⠕⠩⠝⠕⠁⠏⠿⠷⠁⠮⠞⠡⠝⠾⠮ 4 | ⠸⠜⠸⠳⠄⠂⠓⠇⠛⠋⠣⠜⠭⠍⠸⠾⠕⠈⠉⠀⠸⠻⠄⠚⠊⠚⠣⠜⠐⠑⠄⠸⠮⠐⠕⠈⠉⠀⠸⠫⠄⠊⠃⠓⠊⠣⠜⠐⠑⠄⠾⠃⠩⠝⠀⠸⠱⠄⠋⠃⠑⠙⠣⠜⠭⠍⠸⠿⠇⠎ 5 | ⠨⠜⠨⠗⠡⠟⠃⠯⠐⠖⠇⠛⠇⠈⠉⠟⠕⠗⠎⠁⠞⠝⠵⠽⠚⠊⠓⠂⠀⠡⠟⠏⠵⠐⠢⠵⠃⠋⠈⠉⠏⠕⠝⠞⠃⠝⠁⠕⠯⠵⠓⠋⠂⠙ 6 | ⠞⠎⠃⠷⠊⠇⠈⠉⠎⠓⠊⠚⠙⠅⠐⠛⠓⠊⠕⠛⠋⠑⠊⠂⠓⠛⠨⠙⠀⠝⠂⠞⠮⠚⠈⠉⠞⠊⠓⠛⠃⠓⠁⠚⠑⠛⠗⠛⠇⠋⠑⠛⠃⠊⠇⠚⠙ 7 | ⠸⠜⠘⠺⠄⠅⠉⠂⠓⠊⠚⠅⠣⠜⠭⠍⠸⠵⠗⠈⠉⠀⠸⠹⠄⠊⠚⠙⠅⠣⠜⠸⠓⠄⠩⠿⠗⠈⠉⠀⠸⠱⠄⠑⠃⠙⠑⠣⠜⠸⠓⠄⠯⠟⠁⠀⠘⠳⠄⠓⠚⠑⠣⠜⠭⠍⠸⠵⠳⠧ 8 | ⠨⠜⠨⠞⠇⠎⠷⠈⠉⠗⠟⠂⠯⠈⠉⠏⠩⠕⠯⠁⠈⠉⠏⠟⠷⠈⠉⠗⠎⠾⠈⠉⠞⠗⠟⠏⠀⠎⠅⠗⠿⠈⠉⠟⠏⠵⠈⠉⠕⠩⠝⠵⠁⠈⠉⠕⠏⠿⠈⠉⠟⠗⠮⠈⠉⠎⠟⠏⠕ 9 | ⠗⠇⠉⠎⠉⠞⠉⠎⠦⠷⠦⠿⠏⠉⠟⠇⠉⠗⠉⠟⠦⠯⠦⠵⠩⠝⠇⠉⠕⠉⠏⠉⠕⠦⠽⠦⠾⠀⠐⠖⠪⠄⠈⠉⠎⠩⠝⠞⠎⠞⠝⠕⠁⠏⠿⠠⠲⠷ 10 | ⠸⠜⠸⠳⠄⠁⠉⠂⠓⠇⠛⠋⠣⠜⠭⠸⠚⠐⠏⠈⠉⠀⠸⠻⠄⠚⠊⠚⠣⠜⠐⠋⠸⠊⠐⠕⠈⠉⠀⠸⠫⠄⠛⠋⠑⠣⠜⠐⠑⠚⠗⠁⠈⠉⠀⠩⠸⠹⠄⠋⠃⠘⠊⠅⠓⠂⠣⠜⠸⠷⠮⠃⠷⠁⠿⠓⠐ 11 | ⠭⠧ 12 | ⠨⠜⠄⠦⠨⠎⠑⠉⠉⠩⠙⠃⠑⠋⠑⠙⠉⠑⠐⠎⠨⠑⠂⠐⠓⠁⠨⠑⠅⠐⠛⠃⠨⠑⠐⠋⠨⠑⠐⠟⠨⠑⠐⠊⠨⠑⠐⠛⠨⠑⠐⠑⠡⠨⠙⠂ 13 | ⠦⠞⠁⠑⠉⠉⠩⠙⠑⠋⠑⠙⠉⠑⠞⠑⠅⠐⠊⠨⠑⠐⠓⠨⠑⠐⠛⠃⠨⠑⠐⠗⠨⠑⠚⠂⠑⠐⠓⠃⠨⠑⠐⠋⠨⠑ 14 | ⠦⠩⠝⠐⠓⠉⠉⠛⠃⠓⠊⠓⠛⠉⠓⠁⠨⠏⠙⠉⠉⠚⠁⠙⠑⠙⠚⠉⠙⠦⠗⠋⠉⠉⠑⠃⠋⠁⠊⠓⠛⠉⠋⠀⠿⠅⠉⠩⠙⠙⠇⠉⠑⠵⠅⠉⠐⠓⠓⠅⠉⠛⠻⠇⠣⠜⠠⠧⠭⠩⠐⠙⠱⠣⠆ 15 | ⠸⠜⠘⠛⠸⠿⠄⠇⠠⠣⠂⠏⠛⠊⠑⠛⠇⠣⠜⠭⠸⠊⠃⠐⠱⠄⠸⠊⠃⠀⠘⠓⠸⠷⠄⠇⠠⠣⠂⠟⠓⠚⠋⠓⠂⠣⠜⠸⠓⠚⠃⠐⠫⠄⠸⠚ 16 | ⠘⠊⠸⠮⠄⠂⠠⠣⠂⠗⠪⠄⠊⠃⠣⠜⠸⠊⠩⠙⠓⠋⠃⠹⠁⠀⠸⠕⠄⠣⠜⠐⠑⠸⠋⠛⠣⠚⠪⠁⠣⠆ 17 | ⠨⠜⠄⠣⠶⠨⠟⠇⠗⠟⠏⠛⠈⠉⠟⠏⠟⠗⠁⠮⠾⠐⠢⠝⠾⠊⠓⠛⠃⠀⠗⠎⠗⠟⠓⠅⠈⠉⠗⠐⠟⠁⠗⠁⠎⠾⠽⠐⠢⠕⠽⠚⠊⠓ 18 | ⠨⠏⠇⠟⠏⠩⠕⠋⠁⠈⠉⠯⠩⠓⠇⠓⠃⠊⠮⠃⠚⠚⠂⠙⠀⠨⠏⠩⠕⠇⠩⠽⠐⠖⠇⠑⠈⠉⠑⠈⠉⠕⠕⠃⠏⠟⠏⠁⠑⠂⠙⠚⠊⠓⠃⠊⠁⠨⠛ 19 | ⠸⠜⠄⠣⠶⠐⠱⠄⠇⠽⠾⠙⠊⠣⠜⠭⠍⠐⠿⠎⠀⠸⠺⠄⠑⠸⠓⠚⠣⠜⠭⠍⠐⠵⠗⠈⠉ 20 | ⠐⠹⠄⠇⠉⠂⠚⠅⠙⠊⠣⠜⠐⠓⠄⠩⠷⠃⠊⠑⠋⠡⠓⠈⠉⠀⠸⠺⠄⠂⠉⠅⠘⠚⠇⠩⠙⠩⠑⠣⠜⠐⠓⠿⠯⠛⠭⠧ 21 | ⠨⠜⠄⠦⠐⠗⠨⠋⠇⠉⠉⠩⠑⠋⠡⠛⠋⠑⠉⠋⠁⠩⠟⠋⠓⠋⠊⠋⠚⠋⠰⠝⠂⠨⠋⠰⠑⠨⠋⠰⠙⠨⠋⠚⠋ 22 | ⠦⠰⠝⠨⠋⠉⠉⠩⠑⠃⠋⠡⠛⠋⠑⠉⠋⠁⠰⠝⠨⠋⠚⠋⠊⠋⠓⠋⠩⠟⠋⠓⠋⠊⠋⠩⠑⠃⠩⠙ 23 | ⠦⠩⠕⠊⠂⠉⠉⠓⠊⠚⠊⠓⠉⠊⠦⠐⠞⠨⠓⠂⠉⠉⠛⠓⠊⠓⠛⠉⠓⠦⠐⠎⠨⠛⠇⠉⠉⠋⠛⠓⠊⠓⠉⠛ 24 | ⠷⠉⠩⠑⠑⠇⠉⠋⠯⠅⠉⠐⠮⠮⠅⠉⠷⠐⠖⠇⠓⠂⠃⠇⠈⠉⠗⠞⠁⠝⠡⠕⠣⠜⠠⠧⠭⠩⠐⠑⠋⠁⠭ 25 | ⠸⠜⠘⠋⠸⠷⠮⠓⠛⠫⠣⠜⠭⠸⠺⠪⠩⠓⠀⠘⠊⠸⠮⠇⠡⠷⠊⠙⠃⠊⠛⠣⠜⠭⠐⠹⠋⠙⠊ 26 | ⠘⠚⠩⠑⠂⠋⠅⠓⠂⠺⠇⠣⠜⠭⠸⠛⠓⠁⠐⠫⠩⠑⠀⠸⠏⠈⠉⠋⠡⠑⠂⠣⠜⠐⠋⠸⠛⠓⠐⠙⠃⠚⠁⠭ 27 | ⠨⠜⠨⠏⠡⠟⠏⠩⠕⠋⠈⠉⠯⠐⠮⠐⠢⠞⠇⠮⠷⠐⠢⠎⠂⠷⠩⠛⠛⠁⠨⠋⠀⠕⠇⠏⠕⠩⠝⠑⠈⠉⠵⠐⠷⠐⠢⠎⠇⠷⠡⠿⠐⠢⠗⠂⠿⠋⠋⠁⠨⠑ 28 | ⠝⠞⠮⠈⠉⠎⠗⠿⠇⠈⠉⠟⠏⠵⠈⠉⠕⠏⠿⠈⠉⠟⠗⠁⠮⠈⠉⠎⠞⠁⠽⠈⠉⠀⠝⠑⠙⠚⠙⠓⠛⠋⠁⠟⠚⠊⠓⠁⠊⠰⠑⠙⠚⠝⠚⠊⠓⠛⠇⠋⠑⠙⠃ 29 | ⠸⠜⠸⠹⠭⠐⠙⠚⠩⠊⠣⠜⠭⠍⠸⠷⠐⠽⠵⠃⠋⠑⠩⠙⠀⠸⠚⠁⠘⠚⠭⠸⠚⠊⠩⠓⠣⠜⠸⠚⠄⠁⠿⠾⠡⠽⠃⠑⠙⠚ 30 | ⠸⠊⠘⠊⠧⠧⠣⠜⠸⠊⠋⠊⠙⠃⠊⠁⠛⠃⠀⠭⠘⠊⠑⠛⠊⠸⠑⠣⠜⠸⠱⠁⠧⠧ 31 | ⠨⠜⠄⠦⠐⠞⠨⠓⠂⠉⠉⠛⠓⠊⠓⠛⠉⠓⠦⠝⠛⠇⠉⠉⠋⠛⠓⠛⠋⠉⠛⠦⠕⠡⠛⠉⠉⠋⠛⠓⠛⠋⠉⠑ 32 | ⠦⠏⠂⠙⠉⠉⠚⠙⠑⠙⠚⠉⠙⠇⠕⠚⠉⠉⠊⠚⠙⠚⠊⠉⠚⠇⠦⠩⠝⠣⠚⠉⠉⠊⠚⠇⠡⠙⠚⠊⠉⠓ 33 | ⠦⠟⠨⠙⠉⠉⠡⠚⠇⠙⠑⠙⠚⠉⠙⠁⠦⠟⠙⠉⠉⠚⠃⠙⠑⠙⠚⠉⠙⠁⠦⠨⠎⠨⠙⠉⠉⠚⠙⠑⠙⠚⠉⠊⠀⠾⠅⠉⠛⠃⠛⠇⠉⠓⠷⠅⠉⠙⠙⠇⠉⠚⠺⠁⠣⠆⠣⠅ 34 | ⠸⠜⠘⠓⠂⠸⠓⠅⠊⠂⠚⠇⠭⠓⠇⠣⠜⠭⠐⠋⠣⠋⠑⠃⠓⠸⠚⠃⠀⠸⠙⠋⠅⠡⠛⠩⠛⠓⠂⠿⠇⠯⠣⠜⠐⠙⠸⠓⠊⠐⠑⠋⠸⠊⠃⠈⠉⠀⠸⠱⠄⠛⠃⠋⠑⠣⠜⠸⠊⠮⠁⠷⠪⠓⠛ 35 | ⠘⠳⠧⠳⠣⠜⠠⠧⠭⠣⠸⠋⠃⠱⠣⠜⠸⠓⠊⠁⠨⠜⠸⠚⠁⠸⠜⠸⠛⠳⠣⠆⠣⠅ 36 | -------------------------------------------------------------------------------- /test/input/bwv988-v13.de.bmc: -------------------------------------------------------------------------------- 1 | 3#c/ 2 | $`!tbntsj,"ctqras}y!?oyjih $o,po3ne"conoap%{!?s{gfe rsrqh"crqpq{&!~$jih 3 | !?r,qpqpe"co3noap%{a~t1n}~ 4 | _`_8.,hlgf2`xm_}o"c _7.jij2`!e._~!o"c _6.ibhi2`!e.}b3n _5.fbed2`xm_%ls 5 | $`$r1qb&!+lgl"cqorsatnzyjih, 1qpz!?zbf"cpontbnao&zhf,d 6 | tsb{il"cshijdk!ghiogfei,hg$d n,t~j"ctihgbhajegrglfegbiljd 7 | _`>w.kc,hijk2`xm_zr"c _4.ijdk2`_h.3%r"c _5.ebde2`_h.&qa >8.hje2`xm_z8v 8 | $`$tls{"crq,&"cp3o&a"cpq{"crs}"ctrqp skr%"cqpz"co3nza"cop%"cqr~"csqpo 9 | rlcsctcs({(%pcqlcrcq(&(z3nlcocpco(y(} !+9."cs3ntstnoap%'/{ 10 | _`_8.ac,hlgf2`x_j!p"c _7.jij2`!f_i!o"c _6.gfe2`!ejra"c 3_4.fb>ikh,2`_{~b{a%h! 11 | xv 12 | $`.($secc3dbefedce!s$e,!ha$ek!gb$e!f$e!q$e!i$e!g$e!e1$d, 13 | (taecc3defedcetek!i$e!h$e!gb$e!r$ej,e!hb$e!f$e 14 | (3n!hccgbhihgcha$pdccjadedjcd(rfccebfaihgcf %kc3ddlcezkc!hhkcg7l2`'vx3!d52; 15 | _`>g_%.l'2,pgiegl2`x_ib!5._ib >h_{.l'2,qhjfh,2`_hjb!6._j 16 | >i_~.,'2,r9.ib2`_i3dhfb4a _o.2`!e_fg2j9a2; 17 | $`.2=$qlrqpg"cqpqra~}!?n}ihgb rsrqhk"cr!qaras}y!?oyjih 18 | $plqp3ofa"c&3hlhbi~bjj,d $p3ol3y!+le"ce"coobpqpae,djihbia$g 19 | _`.2=!5.ly}di2`xm!%s _w.e_hj2`xm!zr"c 20 | !4.lc,jkdi2`!h.3{bief1h"c _w.,ck>jl3d3e2`!h%&gxv 21 | $`.(!r$flcc3ef1gfecfa3qfhfifjff_{~hg62`x_w93h >i_~l1{idbig2`x!4fdi 26 | >j3e,fkh,wl2`x_gha!63e _p"cf1e,2`!f_gh!dbjax 27 | $`$p1qp3of"c&!~!?tl~{!?s,{3gga$f olpo3ne"cz!{!?sl{1%!?r,%ffa$e 28 | nt~"csr%l"cqpz"cop%"cqra~"cstay"c nedjdhgfaqjihaijx_ji3h2`_j.a%}1ybedj 30 | _i>ivv2`_ifidbiagb x>iegi_e2`_5avv 31 | $`.(!t$h,ccghihgch(nglccfghgfcg(o1gccfghgfce 32 | (p,dccjdedjcdlojccijdjicjl(3n2jccijl1djich 33 | (q$dcc1jldedjcda(qdccjbdedjcda($s$dccjdedjci }kcgbglch{kcddlcjwa2;2k 34 | _`>h,_hki,jlxhl2`x!f2febh_jb _dfk1g3gh,%l&2`!d_hi!ef_ib"c _5.gbfe2`_i~a{9hg 35 | >8v82`'vx2_fb52`_hia$`_ja_`_g82;2k 36 | -------------------------------------------------------------------------------- /test/input/bwv988-v14.bmc: -------------------------------------------------------------------------------- 1 | ⠀⠀⠀⠀⠩⠀⠼⠉⠲ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠦⠀⠨⠜⠐⠖⠇⠘⠓⠇⠭⠰⠖⠨⠳⠄⠈⠉⠷⠟⠗⠀⠊⠭⠐⠖⠇⠸⠻⠇⠈⠉⠿⠊⠓⠛⠀⠋⠭⠨⠋⠂⠉⠉⠑⠩⠙⠵⠉⠯⠀⠐⠛⠭⠰⠖⠸⠹⠄⠈⠉⠽⠞⠝⠇ 3 | ⠚⠓⠚⠑⠓⠘⠚⠃⠀⠙⠁⠋⠓⠐⠙⠸⠋⠓⠀⠛⠃⠊⠑⠛⠊⠙⠀⠚⠓⠁⠚⠑⠓⠭ 4 | ⠀⠀⠸⠜⠸⠾⠓⠑⠓⠾⠓⠂⠐⠑⠚⠷⠚⠊⠓⠀⠐⠵⠸⠊⠛⠊⠐⠵⠸⠊⠅⠐⠊⠛⠃⠵⠛⠋⠑⠀⠷⠋⠸⠚⠐⠋⠷⠋⠅⠚⠓⠯⠚⠊⠓⠀⠨⠵⠐⠊⠛⠊⠨⠵⠐⠊⠅⠨⠊⠛⠃⠵⠛⠋⠑ 5 | ⠷⠑⠚⠑⠷⠑⠅⠨⠚⠃⠓⠇⠵⠡⠛⠁⠋⠑⠀⠯⠃⠙⠇⠐⠓⠨⠙⠯⠙⠂⠓⠋⠽⠑⠁⠙⠚⠀⠮⠁⠋⠑⠛⠮⠛⠂⠨⠑⠐⠊⠿⠊⠁⠓⠛⠀⠷⠑⠚⠑⠷⠑⠅⠐⠚⠓⠨⠵⠙⠚⠊ 6 | ⠀⠀⠼⠃⠀⠼⠔⠤⠂⠆⠀⠨⠜⠄⠍⠨⠞⠇⠎⠦⠾⠸⠜⠨⠗⠃⠟⠦⠷⠨⠜⠨⠏⠇⠕⠦⠯⠸⠜⠄⠩⠨⠝⠃⠞⠦⠽⠨⠜⠐⠎⠇⠗⠦⠮⠸⠜⠐⠟⠃⠏ 7 | ⠦⠿⠨⠎⠗⠦⠮⠨⠟⠏⠦⠿⠨⠕⠩⠝⠦⠵⠐⠞⠎⠦⠾⠐⠗⠟⠦⠷⠐⠏⠃⠕⠀⠦⠯⠨⠗⠟⠦⠷⠨⠏⠕⠦⠯⠐⠞⠎⠦⠾⠐⠗⠟⠦⠷⠐⠏⠕⠦⠯⠩⠐⠝⠞ 8 | ⠦⠩⠽⠸⠗⠟⠦⠷⠸⠏⠕⠦⠯⠩⠸⠝⠞⠦⠽⠘⠎⠗⠦⠮⠘⠗⠟⠦⠷⠘⠟⠃⠏ 9 | ⠀⠀⠸⠜⠐⠓⠭⠥⠀⠍⠀⠍⠀⠍ 10 | ⠀⠀⠼⠉⠀⠼⠂⠒⠤⠂⠖⠀⠨⠜⠄⠥⠐⠑⠋⠛⠊⠛⠋⠑⠶⠶⠀⠦⠐⠚⠭⠦⠡⠸⠛⠇⠭⠦⠋⠭⠀⠍⠐⠏⠃⠕⠦⠯⠎⠗⠦⠮⠕⠁⠩⠝⠦⠵⠁⠗⠅⠟⠦⠷⠝⠃⠞⠦⠽⠟⠇⠏ 11 | ⠦⠿⠑⠩⠙⠑⠁⠟⠏⠵⠎⠂⠗⠿⠨⠑⠭⠣⠆ 12 | ⠀⠀⠸⠜⠄⠦⠘⠛⠭⠦⠨⠑⠃⠭⠦⠙⠭⠀⠥⠸⠓⠊⠚⠑⠚⠊⠓⠥⠓⠊⠣⠚⠑⠚⠊⠓⠥⠩⠓⠊⠡⠚⠑⠚⠊⠓⠀⠮⠩⠝⠃⠞⠦⠽⠸⠟⠇⠏⠦⠿⠞⠎⠦⠾⠏⠂⠕⠦⠯⠎⠗⠦⠮⠕⠃⠩⠝ 13 | ⠕⠋⠛⠇⠓⠊⠓⠛⠋⠁⠵⠇⠿⠃⠘⠮⠸⠵⠁⠘⠑⠭⠣⠆ 14 | ⠀⠀⠼⠙⠀⠼⠂⠶⠤⠆⠲⠀⠨⠜⠄⠣⠶⠨⠿⠃⠊⠰⠑⠨⠊⠿⠊⠑⠛⠮⠂⠛⠓⠊⠀⠵⠓⠚⠓⠵⠓⠅⠐⠚⠑⠷⠐⠚⠙⠑⠀⠐⠷⠨⠙⠇⠋⠙⠮⠁⠙⠅⠐⠛⠊⠽⠐⠛⠓⠊ 15 | ⠩⠵⠃⠛⠚⠛⠵⠛⠸⠚⠑⠿⠂⠑⠋⠛⠀⠸⠾⠐⠋⠓⠋⠸⠾⠐⠋⠅⠸⠓⠚⠐⠯⠩⠑⠃⠋⠓⠀⠽⠡⠛⠇⠊⠛⠽⠛⠸⠊⠙⠿⠋⠃⠛⠊⠀⠩⠵⠩⠛⠊⠛⠵⠛⠸⠚⠑⠅⠸⠿⠃⠊⠓⠛ 16 | ⠷⠁⠚⠐⠋⠸⠚⠷⠚⠂⠋⠛⠷⠋⠓⠚ 17 | ⠀⠀⠸⠜⠄⠣⠶⠸⠑⠭⠰⠖⠡⠰⠹⠄⠈⠉⠽⠞⠝⠀⠚⠭⠐⠖⠇⠡⠐⠻⠁⠂⠇⠈⠉⠿⠊⠓⠛⠀⠋⠭⠩⠨⠛⠃⠉⠉⠊⠩⠑⠯⠉⠿⠀⠐⠚⠭⠰⠖⠘⠪⠄⠈⠉⠮⠗⠎⠀⠓⠅⠋⠓⠚⠓⠃⠋⠀⠊⠈⠊⠘⠊⠙⠃⠚⠊ 18 | ⠚⠅⠩⠑⠇⠛⠚⠘⠚⠐⠯⠇⠩⠵⠀⠋⠓⠃⠚⠨⠯⠃⠩⠵⠋⠭ 19 | ⠀⠀⠼⠑⠀⠼⠆⠢⠤⠆⠦⠀⠨⠜⠐⠯⠸⠜⠸⠝⠃⠞⠦⠽⠨⠜⠸⠏⠇⠡⠕⠦⠯⠸⠜⠸⠎⠩⠗⠦⠮⠨⠜⠐⠝⠞⠦⠽⠸⠜⠐⠏⠕⠦⠯⠨⠜⠐⠎⠡⠗⠀⠦⠐⠮⠘⠞⠎⠦⠾⠸⠕⠝⠦⠵⠸⠗⠟⠦⠷⠸⠞⠎⠦⠾⠐⠕⠝⠦⠵⠐⠗⠟ 20 | ⠦⠷⠘⠎⠗⠦⠮⠸⠝⠞⠦⠽⠸⠏⠕⠦⠯⠸⠎⠗⠦⠮⠐⠝⠞⠦⠽⠐⠟⠏⠀⠦⠿⠐⠎⠗⠦⠮⠨⠕⠝⠦⠵⠨⠟⠏⠦⠿⠨⠗⠟⠦⠷⠨⠎⠗⠦⠮⠨⠞⠎ 21 | ⠀⠀⠸⠜⠄⠍⠀⠍⠀⠍⠀⠍ 22 | ⠀⠀⠼⠋⠀⠼⠆⠔⠤⠒⠆⠀⠨⠜⠄⠦⠨⠚⠭⠦⠐⠑⠃⠭⠦⠡⠛⠭⠀⠥⠋⠡⠛⠓⠨⠙⠐⠓⠛⠋⠥⠩⠛⠃⠓⠇⠊⠙⠊⠓⠛⠥⠓⠁⠊⠣⠚⠩⠙⠚⠊⠓ 23 | ⠦⠨⠵⠡⠝⠂⠡⠞⠦⠽⠞⠎⠦⠾⠣⠞⠃⠎⠦⠾⠇⠎⠗⠦⠮⠨⠕⠝⠦⠵⠐⠗⠁⠟⠀⠗⠁⠊⠡⠚⠙⠑⠙⠚⠊⠷⠾⠐⠵⠷⠅⠸⠓⠃⠭⠣⠆⠣⠅ 24 | ⠀⠀⠸⠜⠄⠥⠐⠓⠊⠚⠑⠚⠊⠓⠶⠶⠀⠦⠨⠙⠭⠦⠸⠊⠁⠭⠦⠋⠭⠀⠦⠿⠎⠗⠂⠦⠮⠇⠐⠕⠝⠦⠵⠸⠗⠇⠟⠦⠷⠐⠝⠡⠞⠦⠽⠸⠟⠇⠏⠦⠿⠞⠎⠀⠦⠾⠓⠛⠓⠞⠎⠂⠷⠐⠕⠃⠝⠾⠐⠓⠭⠣⠆⠣⠅ -------------------------------------------------------------------------------- /test/input/bwv988-v15.bmc: -------------------------------------------------------------------------------- 1 | ⠀⠀⠀⠀⠣⠣⠀⠼⠃⠲ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠖⠀⠨⠜⠄⠍⠐⠓⠃⠓⠇⠉⠛⠿⠇⠉⠋⠋⠉⠑⠀⠍⠨⠑⠇⠑⠃⠡⠋⠯⠃⠩⠛⠛⠓⠀⠳⠁⠈⠉⠷⠊⠚⠙⠀⠵⠨⠮⠎⠂⠩⠗⠮⠱⠁⠉⠅⠈⠉ 3 | ⠑⠯⠂⠉⠿⠯⠉⠑⠑⠂⠉⠙⠀⠚⠅⠭⠭⠙⠁ 4 | ⠀⠀⠸⠜⠸⠓⠘⠓⠭⠸⠓⠇⠈⠉⠀⠷⠩⠟⠡⠏⠛⠭⠑⠣⠜⠐⠱⠈⠉⠵⠙⠃⠉⠁⠚⠊⠁⠀⠣⠸⠋⠡⠋⠭⠣⠐⠋⠇⠣⠜⠸⠷⠩⠐⠽⠝⠁⠕⠁⠽⠳⠈⠉ 5 | ⠐⠵⠩⠽⠑⠍⠡⠙⠚⠂⠊⠁⠣⠜⠐⠓⠩⠿⠡⠯⠿⠃⠉⠷⠨⠜⠐⠷⠉⠮⠀⠸⠗⠉⠩⠟⠉⠷⠽⠅⠷⠐⠽⠉⠸⠛⠂⠛⠇⠉⠓⠣⠜⠨⠜⠐⠚⠭⠭⠊ 6 | ⠸⠷⠁⠩⠿⠇⠷⠮⠑⠋⠂⠣⠜⠨⠜⠐⠕⠃⠝⠯⠵⠽⠾⠃⠸⠜⠸⠮⠃⠷⠁⠮ 7 | ⠀⠀⠼⠃⠀⠼⠶⠤⠂⠂⠀⠨⠜⠨⠗⠇⠎⠩⠿⠷⠮⠁⠾⠙⠑⠙⠁⠀⠾⠂⠐⠢⠊⠷⠑⠁⠉⠂⠈⠉⠑⠋⠀⠑⠭⠍⠋⠑⠂⠙⠀⠾⠉⠙⠙⠇⠉⠑⠵⠇⠣⠋⠋⠑⠀⠑⠅⠭⠭⠊⠂ 8 | ⠀⠀⠸⠜⠘⠚⠸⠾⠅⠽⠑⠑⠣⠜⠸⠾⠵⠇⠓⠈⠉⠓⠰⠖⠩⠛⠀⠸⠓⠘⠞⠇⠝⠕⠞⠓⠭⠣⠜⠐⠓⠭⠍⠨⠜⠄⠩⠐⠿⠁⠷⠁⠮ 9 | ⠍⠩⠸⠿⠇⠷⠮⠚⠃⠊⠁⠣⠜⠨⠜⠐⠾⠉⠊⠊⠇⠉⠓⠷⠁⠉⠩⠛⠛⠉⠓⠁ 10 | ⠸⠷⠩⠛⠡⠯⠅⠟⠂⠎⠓⠿⠣⠜⠨⠜⠐⠓⠭⠭⠸⠜⠐⠙⠀⠸⠷⠊⠁⠚⠃⠊⠁⠗⠇⠎⠷⠇⠟⠗⠿⠣⠜⠸⠚⠨⠜⠐⠷⠃⠿⠈⠉⠿⠸⠜⠄⠡⠐⠋⠁⠵ 11 | ⠀⠀⠼⠉⠀⠼⠂⠆⠤⠂⠖⠀⠨⠜⠨⠚⠨⠵⠃⠡⠯⠈⠉⠯⠛⠂⠉⠇⠷⠀⠊⠐⠚⠃⠡⠙⠁⠨⠊⠀⠭⠗⠇⠎⠷⠈⠉⠷⠓⠂⠷⠇⠈⠉⠀⠷⠟⠗⠮⠾⠮⠿⠩⠙⠁⠀⠭⠓⠈⠉⠷⠩⠟⠡⠏⠛⠣⠆ 12 | ⠀⠀⠸⠜⠄⠡⠸⠯⠛⠇⠓⠋⠇⠩⠽⠅⠑⠋⠙⠣⠜⠩⠐⠙⠁⠨⠜⠐⠚⠊⠸⠜⠄⠩⠐⠙⠀⠸⠟⠇⠡⠏⠵⠳⠇⠉⠂⠩⠛⠣⠜⠭⠐⠕⠩⠝⠵⠈⠉⠵⠑⠵⠈⠉ 13 | ⠸⠚⠂⠡⠋⠊⠇⠩⠸⠙⠅⠣⠜⠐⠵⠡⠏⠃⠕⠁⠩⠽⠃⠡⠾⠁⠽⠃⠯⠨⠜⠐⠊⠀⠸⠑⠅⠿⠇⠡⠯⠛⠅⠊⠅⠣⠜⠭⠸⠜⠐⠑⠈⠉⠵⠡⠏⠃⠟⠏⠃⠕⠯⠀⠐⠵⠁⠡⠝⠞⠎⠗⠮⠃⠱⠣⠜ 14 | ⠐⠱⠁⠧⠣⠆ 15 | ⠀⠀⠼⠙⠀⠼⠂⠶⠤⠆⠴⠀⠨⠜⠄⠣⠶⠭⠩⠐⠛⠃⠓⠊⠀⠭⠨⠋⠑⠙⠣⠜⠐⠵⠨⠑⠂⠽⠈⠉⠽⠚⠮⠀⠨⠷⠐⠓⠁⠣⠮⠇⠈⠉⠮⠚⠽⠅⠣⠜⠐⠚⠃⠉⠂⠋⠃⠑⠓⠇ 16 | ⠐⠚⠂⠉⠇⠨⠛⠅⠉⠂⠓⠑⠇⠣⠜⠐⠿⠃⠷⠁⠣⠊⠃⠉⠁⠍⠚⠃⠮ 17 | ⠀⠀⠸⠜⠄⠣⠶⠸⠵⠉⠣⠐⠋⠁⠋⠃⠉⠑⠵⠃⠉⠙⠙⠃⠉⠚⠀⠾⠃⠉⠩⠛⠂⠛⠇⠉⠓⠷⠁⠉⠵⠑⠁⠈⠉⠀⠵⠝⠞⠽⠘⠿⠸⠿⠘⠾⠅⠸⠋⠈⠉⠀⠯⠕⠝⠕⠁⠝⠾⠸⠯⠘⠓⠇⠣⠊⠚ 18 | ⠀⠀⠼⠑⠀⠼⠆⠂⠤⠆⠲⠀⠨⠜⠨⠯⠵⠙⠁⠍⠚⠃⠽⠣⠜⠐⠷⠚⠨⠋⠂⠓⠿⠋⠇⠑⠂⠙⠀⠨⠵⠅⠚⠂⠛⠑⠯⠛⠁⠓⠣⠊⠣⠜⠐⠞⠃⠈⠉⠀⠐⠞⠅⠈⠉⠣⠜ 19 | ⠐⠾⠅⠣⠎⠇⠗⠟⠗⠮⠷⠟⠏⠃⠟⠏⠵⠀⠐⠾⠅⠉⠇⠝⠁⠕⠏⠕⠽⠵⠏⠟⠏⠟⠷⠣⠜⠸⠜⠐⠋⠁⠭⠧ 20 | ⠀⠀⠸⠜⠘⠽⠓⠸⠙⠚⠇⠣⠮⠷⠊⠈⠉⠀⠮⠣⠸⠊⠚⠊⠇⠷⠁⠛⠋⠛⠀⠷⠣⠮⠃⠚⠘⠚⠄⠸⠮⠃⠀⠷⠇⠉⠛⠛⠇⠉⠋⠿⠉⠓⠁⠓⠃⠉⠣⠊ 21 | ⠀⠀⠼⠋⠀⠼⠆⠢⠤⠆⠔⠀⠨⠜⠨⠛⠂⠭⠧⠣⠜⠍⠨⠜⠄⠣⠐⠮⠮⠃⠉⠷⠩⠿⠡⠛⠨⠑⠐⠛⠃⠀⠍⠨⠙⠅⠙⠂⠉⠑⠯⠂⠡⠋⠐⠓⠨⠋⠇⠣⠜⠐⠫⠈⠉⠯⠸⠜⠐⠵⠃⠽⠁⠾ 22 | ⠩⠨⠻⠈⠉⠿⠓⠁⠊⠚⠣⠜⠸⠜⠸⠮⠁⠚⠂⠙⠑⠯⠵⠋⠈⠉⠀⠰⠽⠚⠊⠓⠩⠿⠂⠷⠛⠈⠉⠣⠜⠸⠜⠐⠯⠽⠑⠭⠨⠜⠐⠊⠀⠩⠨⠿⠮⠓⠭⠙⠣⠜⠨⠑⠄⠽⠾⠃⠊⠓⠃⠛ 23 | ⠀⠀⠸⠜⠸⠙⠂⠡⠚⠍⠊⠂⠚⠓⠀⠸⠙⠐⠙⠭⠸⠙⠈⠉⠀⠽⠐⠑⠃⠋⠸⠚⠮⠚⠙⠸⠓⠀⠓⠂⠉⠩⠿⠷⠮⠞⠝⠕⠇⠏⠽⠁⠀⠞⠇⠕⠽⠞⠝⠮⠗⠎⠁⠿⠃⠏⠟⠵ 24 | ⠀⠀⠼⠛⠀⠼⠒⠴⠤⠒⠆⠀⠨⠜⠐⠓⠄⠂⠮⠾⠇⠙⠑⠡⠋⠂⠣⠜⠐⠯⠑⠁⠉⠃⠙⠋⠵⠡⠯⠩⠟⠗⠁⠸⠜⠸⠮⠃⠈⠉⠀⠩⠨⠯⠇⠓⠊⠛⠷⠿⠡⠏⠕⠰⠽⠈⠉⠣⠜ 25 | ⠸⠜⠸⠮⠣⠐⠋⠁⠑⠁⠙⠁⠾⠃⠊⠁⠓⠃⠩⠛⠀⠰⠽⠩⠨⠛⠓⠁⠊⠾⠽⠑⠣⠜⠸⠜⠸⠳⠁⠧⠣⠆⠣⠅ 26 | ⠀⠀⠸⠜⠸⠽⠏⠕⠁⠯⠩⠘⠿⠓⠍⠽⠀⠑⠍⠯⠂⠙⠑⠂⠀⠷⠁⠕⠃⠝⠞⠝⠮⠂⠳⠣⠆⠣⠅ 27 | -------------------------------------------------------------------------------- /test/input/bwv988-v16.bmc: -------------------------------------------------------------------------------- 1 | ⠀⠀⠀⠀⠩⠸⠉ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠢⠀⠨⠜⠄⠧⠥⠐⠗⠎⠞⠝⠕⠏⠟⠓⠄⠵⠚⠄⠷⠀⠐⠖⠇⠨⠱⠄⠋⠰⠖⠹⠈⠉⠙⠈⠉⠝⠞⠝⠕⠀⠐⠓⠄⠨⠗⠟⠓⠄⠯⠐⠢⠑⠩⠙⠄⠨⠾⠊⠄⠷ 3 | ⠰⠖⠻⠄⠂⠓⠐⠂⠨⠱⠁⠠⠧⠨⠅⠐⠢⠨⠓⠎⠈⠉⠀⠨⠊⠈⠉⠎⠎⠗⠟⠓⠄⠵⠈⠉⠨⠅⠐⠢⠨⠋⠐⠖⠇⠡⠻⠄⠓⠅⠐⠂⠨⠕ 4 | ⠀⠀⠸⠜⠘⠳⠧⠧⠭⠍⠸⠷⠃⠣⠜⠘⠺⠬⠴⠧⠧⠭⠍⠸⠾⠀⠸⠻⠈⠉⠬⠟⠕⠏⠟⠗⠎⠞⠝⠑⠄⠸⠮⠛⠄⠵⠀⠫⠄⠓⠁⠰⠖⠫⠈⠉⠋⠈⠉⠏⠕⠏⠟ 5 | ⠑⠄⠡⠐⠝⠞⠙⠄⠮⠛⠄⠅⠐⠯⠑⠄⠽⠀⠰⠖⠺⠄⠁⠚⠚⠈⠉⠞⠝⠞⠎⠚⠄⠷ 6 | ⠀⠀⠼⠃⠀⠼⠖⠤⠔⠀⠨⠜⠐⠢⠡⠨⠛⠋⠇⠉⠂⠈⠉⠬⠏⠕⠝⠞⠙⠂⠈⠉⠝⠞⠎⠗⠊⠄⠮⠁⠐⠖⠇⠨⠓⠄⠷⠀⠜⠅⠳⠂⠈⠉⠼⠴⠗⠞⠎⠗⠟⠏⠕⠃⠝⠨⠊⠄⠨⠽⠨⠊⠄⠨⠽ 7 | ⠰⠖⠺⠇⠈⠉⠚⠈⠉⠞⠎⠗⠇⠟⠷⠁⠦⠦⠨⠑⠃⠋⠛⠷⠛⠃⠓⠦⠊⠀⠚⠈⠉⠞⠎⠗⠟⠓⠈⠉⠗⠟⠏⠩⠕⠃⠋⠄⠐⠾⠐⠖⠇⠩⠙⠄⠡⠵⠬ 8 | ⠀⠀⠸⠜⠐⠖⠇⠐⠹⠈⠉⠙⠃⠈⠉⠝⠕⠝⠞⠙⠁⠈⠉⠝⠞⠎⠗⠊⠁⠈⠉⠎⠗⠟⠏⠀⠘⠣⠂⠕⠅⠉⠁⠈⠉⠵⠝⠞⠎⠁⠗⠟⠏⠵⠛⠊⠸⠑ 9 | ⠦⠦⠘⠷⠸⠑⠁⠋⠇⠛⠷⠛⠓⠦⠊⠇⠰⠖⠺⠈⠉⠚⠈⠉⠞⠎⠁⠗⠟⠀⠦⠦⠷⠚⠩⠙⠇⠩⠑⠯⠑⠂⠋⠦⠛⠓⠄⠸⠷⠐⠓⠄⠷⠃ 10 | ⠀⠀⠼⠉⠀⠼⠂⠴⠤⠂⠆⠀⠨⠜⠐⠢⠨⠑⠇⠩⠙⠈⠉⠝⠏⠂⠟⠇⠗⠊⠄⠮⠪⠈⠉⠊⠈⠉⠎⠎⠗⠟⠣⠜⠐⠪⠭⠍⠨⠮⠩⠑⠄⠿⠐⠺⠈⠉ 11 | ⠨⠓⠅⠈⠉⠗⠟⠏⠩⠕⠋⠄⠾⠰⠖⠡⠨⠱⠄⠩⠽⠾⠣⠜⠐⠺⠠⠧⠞⠀⠩⠨⠙⠂⠈⠉⠝⠕⠝⠃⠕⠰⠖⠑⠄⠝⠕⠫⠂⠉⠅⠈⠉⠏⠑⠙⠚⠊⠓⠂⠛⠋⠣⠜⠐⠪⠃⠉⠁⠺⠩⠹⠠⠧ 12 | ⠀⠀⠸⠜⠐⠳⠁⠈⠉⠓⠈⠉⠗⠗⠟⠏⠛⠈⠉⠟⠸⠞⠩⠝⠩⠕⠋⠄⠯⠁⠀⠫⠃⠈⠉⠋⠈⠉⠏⠝⠁⠞⠎⠩⠓⠄⠾⠁⠋⠄⠷⠀⠪⠁⠈⠉⠮⠘⠎⠞⠩⠝⠕⠏⠟⠃⠓⠄⠯⠙⠄⠮ 13 | ⠀⠀⠼⠙⠀⠼⠂⠒⠤⠂⠖⠼⠂⠀⠨⠜⠐⠑⠄⠿⠐⠖⠇⠊⠄⠇⠾⠉⠹⠈⠉⠬⠔⠙⠈⠉⠝⠝⠇⠞⠎⠀⠚⠈⠉⠞⠩⠝⠕⠏⠰⠖⠑⠈⠉⠕⠝⠕⠏⠐⠊⠈⠉⠎⠨⠏⠃⠟⠗⠊⠄⠨⠽⠃⠉ 14 | ⠲⠱⠄⠂⠁⠋⠇⠨⠅⠰⠖⠨⠫⠄⠑⠐⠂⠩⠨⠝⠁⠀⠼⠂⠨⠵⠼⠴⠣⠆⠀⠩⠼⠉⠦ 15 | ⠀⠀⠸⠜⠸⠻⠃⠈⠉⠛⠈⠉⠟⠗⠟⠏⠑⠁⠈⠉⠕⠝⠞⠎⠓⠈⠉⠗⠸⠕⠏⠇⠟⠀⠐⠖⠇⠓⠄⠘⠷⠸⠓⠄⠷⠂⠳⠂⠈⠉⠓⠈⠉⠗⠗⠃⠟⠏⠣⠜⠠⠧⠭⠍⠸⠾⠩⠹⠠⠧ 16 | ⠸⠿⠈⠉⠟⠕⠏⠟⠗⠎⠚⠄⠃⠷⠪⠁⠘⠪⠃⠀⠼⠂⠘⠱⠈⠉⠵⠸⠕⠏⠇⠟⠗⠎⠇⠞⠡⠙⠄⠮⠛⠄⠵⠣⠆⠀⠩⠼⠉⠦ 17 | ⠀⠀⠀⠀⠩⠼⠉⠦ 18 | ⠀⠀⠼⠑⠀⠼⠂⠖⠼⠆⠤⠆⠲⠀⠨⠜⠄⠼⠆⠨⠑⠁⠮⠂⠷⠿⠯⠀⠣⠶⠨⠛⠠⠲⠓⠊⠀⠵⠛⠇⠋⠓⠛⠊⠀⠓⠛⠓⠅⠀⠋⠇⠩⠑⠋⠣⠜⠨⠹⠄⠁⠈⠉ 19 | ⠨⠪⠄⠈⠉⠣⠜⠨⠽⠓⠛⠋⠁⠩⠑⠃⠋⠀⠨⠊⠷⠯⠿⠩⠵⠣⠜⠐⠺⠄⠈⠉⠀⠨⠺⠄⠈⠉⠣⠜⠐⠾⠩⠙⠩⠑⠋⠁⠛⠇⠑⠃⠀⠨⠾⠙⠂⠚⠊⠓⠛⠃⠣⠜⠨⠋⠠⠭⠠⠭ 20 | ⠀⠀⠸⠜⠄⠼⠆⠘⠱⠭⠀⠣⠶⠍⠣⠜⠭⠨⠵⠁⠡⠽⠾⠮⠀⠍⠣⠜⠐⠚⠙⠑⠀⠍⠣⠜⠐⠷⠚⠊⠙⠚⠑⠀⠍⠣⠜⠭⠐⠮⠁⠷⠿⠯⠀⠍⠣⠜⠐⠛⠓⠊⠀⠍⠣⠜⠩⠐⠵⠂⠛⠋⠓⠛⠂⠊ 21 | ⠭⠸⠾⠇⠮⠷⠿⠂⠣⠜⠐⠓⠁⠛⠁⠭⠀⠸⠓⠅⠊⠂⠚⠇⠣⠜⠭⠐⠋⠩⠑⠃ 22 | ⠀⠀⠼⠋⠀⠼⠆⠢⠤⠒⠆⠀⠨⠜⠨⠷⠋⠊⠋⠚⠋⠀⠰⠽⠚⠊⠓⠁⠛⠂⠋⠀⠵⠛⠋⠓⠛⠇⠊⠣⠜⠐⠊⠚⠙⠀⠨⠷⠇⠮⠰⠖⠊⠄⠗⠎⠣⠜⠨⠑⠋⠛⠀⠨⠺⠬⠓⠅⠼⠀⠋⠂⠴⠛⠴⠩⠑⠴ 23 | ⠫⠭⠣⠜⠐⠓⠰⠖⠩⠓⠄⠟⠗⠀⠭⠨⠯⠵⠽⠾⠁⠣⠜⠐⠪⠁⠸⠜⠄⠩⠐⠓⠁ 24 | ⠀⠀⠸⠜⠸⠯⠓⠛⠊⠓⠅⠚⠣⠜⠐⠫⠄⠈⠉⠀⠸⠊⠚⠙⠁⠣⠜⠐⠫⠭⠀⠸⠿⠂⠊⠓⠚⠊⠂⠙⠀⠚⠙⠑⠀⠸⠷⠅⠚⠊⠙⠚⠑⠀⠙⠊⠚⠁⠀⠋⠭⠭⠣⠜⠭⠐⠯⠵⠇⠽⠾⠀⠐⠙⠑⠋⠃ 25 | ⠀⠀⠼⠛⠀⠼⠒⠒⠤⠲⠆⠀⠨⠜⠨⠙⠇⠑⠋⠣⠜⠐⠊⠃⠡⠳⠀⠐⠮⠃⠡⠙⠚⠁⠑⠩⠙⠋⠣⠜⠸⠜⠐⠛⠃⠓⠨⠜⠐⠋⠀⠨⠕⠁⠏⠿⠰⠖⠛⠄⠏⠟⠣⠜⠐⠿⠍⠭⠭⠀⠨⠓⠿⠯⠵⠽⠃ 26 | ⠾⠑⠙⠋⠑⠡⠛⠀⠫⠄⠂⠉⠅⠈⠉⠣⠜⠭⠩⠐⠛⠃⠠⠲⠓⠀⠨⠯⠑⠙⠚⠙⠁⠛⠣⠜⠐⠊⠭⠭⠀⠨⠮⠑⠃⠙⠚⠇⠙⠊⠀⠾⠁⠨⠋⠂⠑⠙⠑⠁⠩⠓⠀⠾⠋⠃⠑⠙⠃⠑⠚ 27 | ⠀⠀⠸⠜⠸⠮⠅⠙⠚⠑⠩⠙⠋⠀⠱⠄⠂⠈⠉⠀⠭⠸⠵⠃⠽⠾⠮⠣⠜⠐⠑⠭⠭⠀⠘⠚⠙⠑⠃⠣⠜⠭⠸⠓⠛⠀⠘⠷⠚⠊⠙⠚⠂⠑⠣⠜⠸⠳⠄⠈⠉⠀⠸⠽⠚⠊⠁⠓⠛⠋⠣⠜⠸⠓⠠⠭⠠⠭ 28 | ⠘⠛⠠⠲⠓⠊⠀⠵⠛⠋⠓⠛⠊⠀⠓⠇⠠⠲⠊⠚⠀⠯⠩⠓⠛⠊⠓⠚ 29 | ⠀⠀⠼⠓⠀⠼⠲⠒⠤⠲⠶⠼⠆⠀⠨⠜⠨⠹⠄⠅⠈⠉⠣⠜⠍⠐⠓⠇⠛⠓⠊⠛⠀⠨⠽⠚⠊⠚⠙⠊⠣⠜⠐⠱⠄⠈⠉⠀⠨⠱⠚⠅⠣⠜⠐⠵⠿⠯⠷⠇⠛⠀⠐⠓⠂⠴⠊⠴⠛⠴⠀⠼⠂⠐⠳⠴⠭ 30 | ⠭⠨⠮⠂⠷⠿⠯⠣⠆⠀⠩⠸⠉⠀⠼⠆⠐⠷⠼⠴⠣⠅ 31 | ⠀⠀⠸⠜⠘⠮⠅⠸⠋⠊⠓⠛⠋⠀⠿⠓⠛⠋⠁⠑⠙⠀⠾⠑⠙⠋⠑⠂⠛⠀⠋⠙⠑⠁⠀⠼⠂⠘⠷⠇⠛⠓⠊⠚⠙⠃⠀⠑⠘⠑⠭⠣⠆⠀⠩⠸⠉⠀⠼⠆⠘⠷⠣⠅ 32 | -------------------------------------------------------------------------------- /test/input/bwv988-v17.bmc: -------------------------------------------------------------------------------- 1 | ⠩ ⠼⠉⠲ 2 | ⠼⠁ ⠼⠂⠤⠲ ⠨⠜⠐⠾⠵⠿⠮⠓⠄⠽⠾⠂⠊⠓⠚ ⠮⠁⠩⠙⠋⠓⠛⠄⠐⠾⠮⠂⠓⠛⠊ ⠷⠁⠾⠵⠿⠅⠋⠄⠐⠮⠷⠇⠛⠋⠓ ⠿⠋⠛⠋⠿⠊⠨⠑⠩⠙⠵⠁⠛⠂⠊⠡⠨⠙⠃ 3 | ⠸⠜⠘⠷⠂⠚⠊⠙⠾⠂⠑⠙⠋⠵⠂⠛⠋⠓ ⠿⠊⠓⠚⠮⠂⠩⠙⠚⠑⠽⠃⠋⠑⠂⠛ ⠯⠓⠛⠂⠊⠷⠚⠊⠂⠩⠙⠾⠑⠙⠇⠋ ⠵⠩⠙⠑⠙⠕⠈⠉ 4 | ⠼⠃ ⠼⠢⠤⠦ ⠨⠜⠐⠾⠨⠓⠐⠊⠨⠛⠂⠐⠷⠨⠋⠅⠡⠐⠛⠨⠑⠅⠐⠯⠨⠙⠅⠐⠑⠐⠚⠂ ⠽⠐⠋⠁⠚⠅⠐⠑⠁⠮⠐⠙⠓⠸⠚⠩⠐⠿⠂⠸⠊⠐⠋⠅⠸⠓ 5 | ⠮⠃⠐⠛⠸⠓⠐⠋⠅⠸⠿⠃⠐⠑⠸⠋⠐⠙⠸⠵⠸⠚⠸⠙⠸⠊ ⠘⠾⠊⠃⠚⠊⠾⠁⠵⠷⠿⠓⠭ 6 | ⠸⠜⠈⠉⠨⠵⠚⠇⠙⠊⠾⠁⠓⠊⠃⠡⠛⠷⠁⠋⠛⠑ ⠯⠁⠙⠑⠚⠽⠊⠚⠓⠮⠩⠛⠃⠓⠋ ⠿⠃⠑⠋⠙⠵⠁⠚⠙⠊⠾⠁⠓⠊⠛ ⠷⠁⠛⠓⠛⠳⠁⠉⠅⠈⠉⠷⠸⠑⠓⠛⠂ 7 | ⠼⠉ ⠼⠔⠤⠂⠆ ⠨⠜⠨⠵⠨⠚⠨⠙⠨⠊⠐⠾⠨⠓⠐⠊⠨⠛⠂⠐⠷⠨⠋⠐⠛⠃⠨⠑ ⠐⠯⠨⠑⠩⠙⠇⠚⠁⠽⠯⠊⠐⠖⠇⠊⠭ 8 | ⠐⠾⠨⠓⠐⠊⠨⠛⠐⠷⠨⠋⠐⠛⠃⠨⠑⠐⠯⠩⠨⠙⠐⠑⠐⠚ ⠩⠐⠽⠃⠐⠚⠊⠩⠓⠮⠁⠩⠽⠋⠐⠖⠇⠫⠇⠈⠉ 9 | ⠸⠜⠸⠷⠾⠵⠿⠃⠓⠄⠮⠂⠾⠩⠙⠑⠚ ⠩⠽⠚⠊⠁⠓⠿⠋⠁⠩⠑⠩⠙⠾⠁⠊⠓⠛ ⠯⠷⠾⠩⠵⠃⠋⠄⠿⠂⠷⠊⠚⠓ ⠮⠑⠩⠙⠂⠚⠽⠋⠊⠚⠩⠽⠋⠓⠐⠚⠂ 10 | ⠼⠙ ⠼⠂⠒⠤⠂⠖ ⠨⠜⠈⠉⠨⠯⠑⠁⠋⠂⠩⠙⠵⠚⠡⠙⠂⠊⠾⠓⠊⠂⠛ ⠷⠁⠨⠋⠐⠛⠨⠑⠐⠯⠩⠨⠽⠇⠐⠢⠕⠽⠉⠾⠐⠢⠝⠾⠊⠚⠨⠓ 11 | ⠓⠄⠂⠟⠏⠿⠑⠚⠃⠓⠮⠇⠛⠃⠓⠁⠨⠋ ⠐⠿⠃⠋⠛⠋⠿⠊⠨⠑⠩⠙⠐ 12 | ⠑⠭⠣⠆ 13 | ⠸⠜⠐⠮⠨⠛⠃⠐⠓⠅⠨⠋⠃⠐⠿⠅⠨⠑⠃⠐⠋⠡⠨⠙⠐⠵⠐⠚⠐⠙⠐⠊ ⠸⠾⠐⠓⠸⠊⠐⠛⠸⠷⠐⠋⠁⠸⠛⠂⠐⠑⠸⠯⠩⠐⠙⠸⠑⠸⠚⠁ 14 | ⠩⠸⠽⠂⠸⠊⠘⠚⠸⠓⠘⠮⠸⠛⠘⠓⠸⠋⠘⠿⠸⠑⠘⠋⠸⠙⠃ ⠵⠩⠙⠑⠙⠵⠘⠮⠿⠮⠑⠭⠣⠆ 15 | ⠼⠑ ⠼⠂⠶⠤⠆⠴ ⠨⠜⠄⠣⠶⠨⠮⠅⠛⠓⠋⠿⠑⠋⠂⠡⠙⠵⠚⠙⠂⠊ ⠾⠓⠊⠛⠷⠋⠛⠩⠑⠯⠙⠡⠑⠚ ⠽⠊⠚⠅⠩⠓⠮⠛⠡⠓⠋⠡⠿⠅⠩⠑⠋⠩⠙ 16 | ⠩⠵⠩⠙⠑⠙⠱⠇⠉⠃⠈⠉⠵⠛⠚⠊ 17 | ⠸⠜⠄⠣⠶⠘⠵⠿⠮⠁⠩⠽⠃⠑⠄⠯⠂⠿⠓⠊⠛⠇ ⠷⠁⠘⠚⠙⠇⠑⠘⠓⠄⠸⠿⠃⠷⠊⠃⠚⠩⠓ ⠮⠁⠸⠽⠵⠇⠯⠘⠊⠄⠩⠸⠷⠮⠚⠙⠩⠊⠇ 18 | ⠾⠩⠊⠚⠊⠾⠁⠿⠇⠷⠡⠮⠘⠚⠠⠲⠩⠐⠑ 19 | ⠼⠋ ⠼⠆⠂⠤⠆⠲ ⠨⠜⠸⠷⠁⠚⠊⠙⠾⠁⠩⠑⠩⠙⠋⠵⠇⠛⠂⠋⠁⠓ ⠿⠊⠓⠚⠮⠁⠙⠚⠑⠽⠁⠋⠩⠑⠛ ⠯⠓⠛⠊⠷⠚⠊⠡⠙⠾⠓⠊⠂⠛ 20 | ⠷⠋⠛⠂⠩⠑⠯⠙⠚⠇⠊⠷⠿⠃⠋⠈⠉ 21 | ⠸⠜⠐⠯⠓⠃⠛⠊⠷⠛⠋⠓⠿⠇⠩⠑⠂⠋⠁⠩⠙⠇ ⠩⠵⠩⠙⠚⠡⠑⠡⠽⠁⠊⠚⠩⠓⠮⠁⠡⠓⠇⠛⠊ 22 | ⠷⠁⠋⠛⠩⠑⠯⠁⠑⠩⠙⠋⠵⠂⠋⠛⠑ ⠯⠁⠘⠓⠂⠊⠚⠯⠛⠓⠊⠾⠙⠇⠑⠚ 23 | ⠼⠛ ⠼⠆⠢⠤⠆⠦ ⠨⠜⠈⠉⠐⠯⠨⠋⠐⠚⠑⠽⠚⠊⠙⠾⠑⠙⠋ ⠵⠚⠊⠙⠾⠊⠩⠓⠃⠚⠮⠁⠙⠚⠑ ⠽⠊⠡⠓⠃⠚⠮⠁⠨⠛⠂⠓⠋⠿⠑⠋⠁⠰⠙ ⠙⠂⠈⠉⠝⠞⠎⠗⠿⠇⠷⠮⠿⠐⠢⠋⠱⠈⠉ 24 | ⠸⠜⠸⠽⠋⠑⠂⠡⠛⠯⠓⠩⠛⠂⠊⠩⠷⠚⠊⠙ ⠾⠑⠙⠋⠵⠡⠛⠋⠩⠓⠩⠿⠊⠓⠚ ⠮⠙⠚⠑⠽⠊⠚⠁⠓⠮⠛⠓⠁⠋ ⠿⠑⠋⠇⠩⠙⠵⠐⠚⠡⠐⠙⠐⠊⠸⠾⠐⠓⠸⠊⠐⠛ 25 | ⠼⠓ ⠼⠆⠔⠤⠒⠆ ⠨⠜⠈⠉⠨⠵⠚⠃⠙⠊⠾⠨⠓⠐⠊⠡⠨⠛⠐⠷⠨⠋⠡⠐⠛⠨⠑ ⠐⠋⠥⠗⠃⠎⠞⠽⠊⠚⠓⠁⠮⠂⠩⠛⠓⠋ ⠿⠨⠯⠑⠂⠉⠁⠈⠉⠕⠋⠛⠓⠛⠋⠑⠙⠃⠾⠨⠓⠐⠊⠨⠛ 26 | ⠐⠷⠛⠃⠓⠛⠷⠁⠾⠵⠿⠓⠭⠣⠆⠣⠅ 27 | ⠸⠜⠸⠚⠥⠕⠂⠏⠟⠷⠋⠡⠛⠑⠯⠁⠙⠑⠚ ⠷⠁⠋⠡⠛⠑⠯⠐⠙⠸⠑⠸⠚⠸⠽⠸⠊⠘⠚⠸⠓ ⠘⠮⠸⠓⠛⠙⠂⠾⠑⠓⠚⠇⠵⠚⠙⠊ 28 | ⠾⠊⠚⠊⠾⠷⠁⠵⠾⠓⠭⠣⠆⠣⠅ 29 | -------------------------------------------------------------------------------- /test/input/bwv988-v18.bmc: -------------------------------------------------------------------------------- 1 | ⠀⠀⠀⠀⠩⠸⠉ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠦⠀⠨⠜⠄⠥⠨⠗⠈⠉⠣⠜⠐⠾⠃⠀⠨⠗⠟⠂⠉⠅⠈⠉⠣⠜⠐⠎⠄⠚⠇⠊⠀⠨⠻⠅⠉⠂⠓⠛⠏⠅⠈⠉⠣⠜⠐⠗⠄⠛⠋⠀⠨⠫⠑⠩⠙⠕⠣⠜⠐⠟⠃⠉⠁⠥ 3 | ⠥⠨⠏⠈⠉⠣⠜⠐⠗⠄⠁⠛⠃⠓⠁⠀⠨⠫⠑⠇⠋⠟⠈⠉⠣⠜⠐⠎⠄⠃⠉⠁⠙⠃⠚⠀⠨⠻⠅⠉⠂⠊⠓⠎⠈⠉⠣⠜⠨⠝⠈⠉⠙⠚⠁⠙⠊⠀⠨⠊⠓⠊⠛⠗⠣⠜⠐⠞⠃⠉⠁⠥ 4 | ⠀⠀⠸⠜⠄⠧⠸⠓⠅⠊⠺⠹⠀⠱⠸⠱⠐⠕⠀⠧⠋⠑⠩⠹⠪⠀⠐⠱⠸⠱⠐⠱⠡⠹⠀⠐⠖⠺⠊⠚⠹⠁⠸⠹⠀⠐⠹⠚⠇⠙⠱⠸⠪⠃⠀⠱⠛⠋⠻⠱⠀⠳⠁⠱⠘⠳⠸⠓⠊⠃ 5 | ⠀⠀⠼⠃⠀⠼⠔⠤⠂⠖⠀⠨⠜⠄⠥⠨⠏⠈⠉⠣⠜⠐⠷⠃⠀⠨⠏⠕⠈⠉⠣⠜⠐⠟⠄⠁⠓⠊⠁⠀⠨⠱⠋⠛⠂⠗⠈⠉⠣⠜⠐⠞⠈⠉⠚⠊⠚⠓⠀⠨⠓⠛⠓⠋⠟⠅⠈⠉⠣⠜⠐⠎⠄⠃⠉⠁⠪⠃ 6 | ⠨⠻⠻⠂⠏⠅⠈⠉⠣⠜⠐⠗⠄⠳⠃⠀⠨⠫⠫⠕⠂⠉⠅⠈⠉⠣⠜⠐⠟⠄⠺⠇⠀⠨⠱⠳⠩⠙⠃⠑⠫⠅⠈⠉⠣⠜⠐⠋⠛⠗⠄⠀⠨⠏⠕⠣⠜⠐⠿⠃⠉⠁⠣⠆ 7 | ⠀⠀⠸⠜⠸⠺⠊⠂⠚⠩⠹⠚⠙⠀⠱⠩⠹⠺⠁⠪⠀⠳⠻⠫⠁⠱⠀⠩⠹⠚⠙⠱⠁⠙⠑⠀⠺⠊⠚⠩⠹⠚⠙⠀⠩⠪⠇⠩⠓⠊⠚⠁⠡⠊⠡⠓⠛⠀⠳⠫⠪⠈⠪⠀⠘⠱⠪⠸⠕⠣⠆ 8 | ⠀⠀⠼⠉⠀⠼⠂⠶⠤⠆⠲⠀⠨⠜⠄⠣⠶⠥⠨⠎⠈⠉⠣⠜⠨⠽⠃⠀⠨⠎⠗⠂⠉⠅⠈⠉⠣⠜⠐⠞⠄⠙⠑⠀⠨⠳⠊⠇⠚⠝⠈⠉⠣⠜⠨⠏⠁⠈⠉⠋⠩⠑⠫⠁⠉⠃⠀⠰⠙⠚⠹⠞⠣⠜⠩⠨⠕⠥ 9 | ⠥⠨⠏⠈⠉⠣⠜⠐⠷⠁⠀⠨⠏⠩⠱⠫⠅⠉⠂⠣⠜⠐⠻⠳⠁⠎⠈⠉⠀⠨⠟⠄⠋⠇⠛⠣⠜⠐⠪⠓⠊⠞⠁⠈⠉⠀⠨⠗⠈⠉⠓⠛⠋⠑⠣⠜⠐⠚⠊⠃⠓⠸⠜⠐⠛⠃⠫⠁⠧ 10 | ⠀⠀⠸⠜⠄⠣⠶⠧⠸⠑⠂⠋⠻⠱⠀⠳⠘⠳⠸⠳⠊⠇⠚⠀⠹⠺⠪⠓⠊⠀⠺⠄⠊⠁⠓⠛⠋⠩⠑⠀⠫⠐⠋⠑⠹⠺⠁⠀⠪⠇⠚⠙⠸⠻⠂⠓⠊⠁⠀⠩⠱⠂⠋⠛⠘⠺⠅⠩⠙⠑ 11 | ⠫⠅⠐⠋⠩⠑⠇⠫⠁⠛⠇⠓ 12 | ⠀⠀⠼⠙⠀⠼⠆⠢⠤⠒⠆⠀⠨⠜⠨⠹⠁⠉⠃⠧⠨⠎⠈⠉⠣⠜⠨⠜⠨⠽⠁⠉⠃⠀⠨⠎⠗⠈⠉⠣⠜⠐⠞⠄⠙⠑⠁⠀⠨⠳⠊⠚⠂⠝⠈⠉⠣⠜⠨⠏⠈⠉⠋⠑⠁⠋⠙ 13 | ⠰⠙⠚⠙⠊⠞⠅⠈⠉⠣⠜⠨⠕⠄⠃⠉⠁⠱⠃⠀⠨⠺⠺⠎⠂⠉⠅⠈⠉⠣⠜⠨⠝⠄⠹⠃⠀⠨⠪⠪⠗⠂⠉⠅⠈⠉⠣⠜⠐⠞⠄⠨⠫⠀⠨⠳⠰⠹⠨⠛⠓⠪⠅⠈⠉⠣⠜⠐⠊⠚⠝⠄⠁⠉⠃ 14 | ⠨⠎⠗⠣⠜⠐⠾⠣⠆⠣⠅ 15 | ⠀⠀⠸⠜⠐⠪⠓⠊⠻⠋⠛⠀⠳⠁⠻⠫⠱⠁⠀⠹⠺⠪⠁⠳⠀⠻⠋⠛⠳⠛⠓⠁⠀⠫⠑⠋⠻⠋⠛⠀⠩⠱⠇⠩⠙⠑⠋⠁⠡⠑⠡⠙⠚⠀⠹⠪⠸⠱⠘⠱⠀⠳⠸⠱⠗⠣⠆⠣⠅ 16 | -------------------------------------------------------------------------------- /test/input/bwv988-v19.bmc: -------------------------------------------------------------------------------- 1 | ⠩⠼⠉⠦ 2 | ⠀⠀⠨⠜⠨⠑⠅⠱⠈⠉⠣⠜⠐⠾⠂⠊⠚⠓⠑⠓⠀⠨⠑⠱⠈⠉⠣⠜⠐⠮⠓⠊⠛⠑⠛⠀⠨⠑⠑⠩⠙⠣⠜⠐⠷⠁⠛⠓⠁⠚⠊⠓⠀⠨⠱⠭⠣⠜⠐⠿⠋⠛⠓⠁⠊⠇⠛⠃ 3 | ⠨⠷⠛⠓⠑⠚⠑⠣⠜⠐⠓⠳⠈⠉⠀⠨⠯⠑⠋⠅⠙⠇⠊⠙⠣⠜⠐⠓⠳⠈⠉⠀⠨⠵⠂⠙⠑⠋⠑⠂⠙⠅⠣⠜⠐⠓⠓⠛⠀⠐⠾⠇⠊⠚⠙⠚⠊⠣⠜⠐⠳⠁⠭ 4 | ⠀⠀⠸⠜⠸⠓⠘⠓⠸⠓⠀⠛⠁⠘⠛⠸⠛⠀⠋⠘⠋⠸⠋⠀⠑⠘⠑⠡⠸⠙⠃⠀⠚⠸⠚⠓⠀⠐⠙⠸⠙⠐⠙⠀⠾⠂⠮⠾⠽⠑⠀⠸⠓⠁⠘⠷⠅⠸⠵⠷⠮⠇ 5 | ⠀⠀⠨⠜⠐⠓⠨⠳⠈⠉⠣⠜⠭⠭⠨⠑⠇⠀⠨⠓⠻⠂⠈⠉⠣⠜⠩⠨⠹⠡⠙⠀⠨⠛⠔⠃⠋⠤⠑⠂⠩⠔⠀⠩⠽⠵⠫⠈⠉⠣⠜⠐⠪⠡⠓⠃⠀⠨⠋⠑⠡⠙⠅⠈⠉⠣⠜⠐⠻⠊⠃ 6 | ⠨⠙⠒⠚⠬⠨⠓⠈⠉⠴⠁⠀⠷⠋⠂⠛⠑⠋⠩⠙⠣⠜⠩⠨⠙⠊⠓⠈⠉⠀⠨⠱⠄⠅⠣⠜⠐⠓⠻⠃⠣⠆ 7 | ⠀⠀⠸⠜⠸⠾⠊⠚⠁⠓⠋⠓⠀⠮⠓⠊⠁⠛⠑⠛⠀⠷⠛⠓⠁⠋⠃⠘⠚⠸⠋⠀⠡⠷⠛⠓⠋⠩⠙⠋⠀⠮⠓⠊⠛⠑⠛⠀⠾⠊⠚⠓⠋⠓⠀⠊⠘⠊⠸⠊⠃⠀⠐⠵⠩⠙⠑⠸⠊⠛⠑⠣⠆ 8 | ⠀⠀⠨⠜⠄⠣⠶⠨⠿⠂⠋⠛⠑⠐⠊⠨⠑⠣⠜⠸⠜⠐⠑⠱⠈⠉⠀⠨⠷⠛⠓⠑⠇⠚⠑⠂⠣⠜⠸⠜⠐⠑⠚⠨⠜⠐⠓⠈⠉⠀⠨⠯⠩⠵⠇⠯⠷⠿⠯⠅⠣⠜⠐⠓⠓⠨⠙⠃ 9 | ⠩⠨⠵⠇⠋⠛⠑⠚⠃⠑⠂⠣⠜⠐⠛⠭⠭⠀⠨⠋⠫⠈⠉⠣⠜⠐⠾⠃⠊⠚⠇⠓⠋⠓⠀⠨⠋⠫⠈⠉⠣⠜⠨⠽⠚⠙⠊⠁⠛⠃⠊⠁⠀⠨⠋⠋⠩⠑⠂⠣⠜⠐⠾⠊⠚⠙⠚⠁⠊⠃ 10 | ⠨⠫⠭⠣⠜⠐⠷⠛⠓⠁⠊⠚⠓⠃ 11 | ⠀⠀⠸⠜⠄⠣⠶⠐⠑⠸⠑⠡⠐⠙⠀⠚⠓⠚⠃⠀⠙⠚⠊⠀⠚⠁⠮⠷⠮⠿⠀⠓⠋⠓⠀⠊⠁⠘⠊⠸⠊⠀⠷⠇⠿⠷⠮⠚⠀⠋⠐⠋⠑ 12 | ⠀⠀⠨⠜⠄⠭⠨⠯⠽⠂⠮⠽⠣⠜⠐⠫⠭⠀⠨⠱⠄⠈⠉⠣⠜⠭⠐⠵⠷⠾⠷⠀⠨⠑⠽⠂⠾⠙⠈⠉⠣⠜⠐⠫⠄⠀⠨⠙⠵⠽⠾⠮⠣⠜⠐⠑⠭⠭⠀⠨⠵⠙⠇⠑⠚⠓⠚⠃ 13 | ⠨⠯⠑⠋⠙⠊⠙⠃⠀⠿⠂⠋⠛⠊⠑⠃⠛⠀⠷⠛⠓⠑⠚⠓⠣⠆⠣⠅ 14 | ⠀⠀⠸⠜⠐⠽⠚⠙⠁⠊⠃⠛⠊⠀⠾⠊⠚⠓⠋⠓⠀⠮⠓⠊⠙⠸⠋⠂⠓⠀⠿⠋⠛⠊⠑⠂⠛⠀⠘⠚⠓⠚⠣⠜⠸⠓⠳⠈⠉⠀⠸⠙⠔⠊⠬⠙⠤⠈⠉⠀⠑⠒⠙⠴⠃⠑⠅⠒⠈⠉ 15 | ⠳⠄⠣⠜⠐⠙⠺⠣⠆⠣⠅ 16 | -------------------------------------------------------------------------------- /test/input/bwv988-v22.bmc: -------------------------------------------------------------------------------- 1 | ⠀⠀⠀⠀⠩⠸⠉ 2 | ⠀⠀⠼⠁⠀⠼⠂⠤⠦⠀⠨⠜⠄⠍⠣⠜⠍⠀⠶⠀⠍⠣⠜⠥⠐⠗⠈⠉⠀⠍⠣⠜ 3 | ⠐⠳⠛⠇⠋⠻⠪⠀⠥⠨⠕⠈⠉⠣⠜⠐⠕⠄⠡⠻⠃⠀⠨⠱⠙⠚⠹⠫⠣⠜ 4 | ⠐⠏⠄⠳⠃⠉⠁⠈⠉⠀⠐⠪⠇⠨⠕⠹⠂⠉⠅⠈⠉⠣⠜⠐⠳⠛⠋⠻⠪⠇⠈⠉ 5 | ⠨⠹⠚⠊⠇⠞⠈⠉⠣⠜⠐⠪⠓⠛⠃⠳⠺ 6 | ⠀⠀⠸⠜⠸⠷⠁⠣⠜⠥⠨⠜⠐⠏⠂⠈⠉⠀⠸⠿⠣⠜⠨⠜⠐⠫⠑⠩⠙⠕⠈⠉ 7 | ⠸⠯⠣⠜⠨⠜⠐⠱⠩⠙⠚⠹⠫⠀⠸⠕⠄⠂⠉⠇⠹⠣⠜⠸⠜⠸⠮⠁⠈⠉ 8 | ⠘⠾⠣⠜⠸⠪⠓⠛⠗⠁⠈⠉⠀⠸⠽⠣⠜⠸⠳⠫⠎⠈⠉⠀⠸⠵⠅⠣⠜⠸⠪⠐ 9 | ⠊⠓⠪⠻⠃⠀⠘⠷⠈⠉⠣⠜⠨⠜⠐⠕⠥ 10 | ⠀⠀⠼⠃⠀⠼⠔⠤⠂⠖⠀⠨⠜⠈⠉⠐⠺⠚⠇⠊⠺⠁⠨⠫⠣⠜⠐⠏⠞⠁ 11 | ⠩⠨⠹⠃⠨⠎⠓⠛⠣⠜⠐⠎⠨⠕⠃⠉⠁⠀⠰⠖⠨⠷⠬⠨⠉⠀⠰⠖⠷⠬⠨⠉ 12 | ⠨⠳⠂⠉⠅⠬⠛⠂⠬⠁⠋⠩⠬⠻⠬⠪⠬⠀⠕⠃⠗⠈⠉⠣⠜⠐⠞⠄⠨⠋⠑ 13 | ⠨⠳⠻⠂⠏⠇⠉⠅⠣⠜⠨⠫⠕⠁⠩⠹⠇⠀⠨⠵⠣⠜⠨⠱⠐⠊⠓⠎⠣⠆ 14 | ⠀⠀⠸⠜⠈⠉⠘⠳⠸⠓⠛⠂⠗⠇⠈⠉⠣⠜⠥⠸⠜⠐⠏⠈⠉ 15 | ⠸⠳⠛⠋⠻⠺⠣⠜⠐⠫⠑⠩⠙⠕⠈⠉⠀⠸⠏⠄⠱⠈⠉⠣⠜⠐⠱⠩⠙⠚⠹⠫ 16 | ⠸⠱⠩⠙⠂⠚⠹⠇⠫⠣⠜⠸⠮⠃⠉⠁⠀⠘⠟⠸⠟⠃⠣⠜⠥⠸⠎⠈⠉ 17 | ⠘⠗⠸⠏⠇⠣⠜⠸⠪⠓⠁⠛⠳⠁⠉⠃⠺⠀⠘⠮⠣⠜⠩⠸⠹⠂⠱⠋⠁⠛⠃⠳⠈⠉ 18 | ⠸⠵⠣⠜⠸⠳⠛⠋⠟⠣⠆ 19 | ⠀⠀⠼⠉⠀⠼⠂⠶⠤⠆⠲⠀⠨⠜⠄⠣⠶⠥⠨⠎⠅⠈⠉⠣⠜⠍⠀⠨⠪⠓⠛⠳⠺⠐ 20 | ⠣⠜⠥⠐⠞⠈⠉⠀⠨⠯⠇⠉⠅⠈⠉⠣⠜⠐⠺⠊⠃⠓⠪⠹⠀⠨⠫⠩⠑⠩⠙⠐ 21 | ⠱⠂⠉⠇⠻⠂⠣⠜⠐⠟⠁⠞⠃⠉⠁⠀⠨⠺⠐⠺⠨⠞⠈⠉⠣⠜⠥⠨⠗⠈⠉ 22 | ⠨⠺⠬⠬⠊⠓⠪⠹⠬⠀⠨⠻⠃⠳⠎⠅⠈⠉⠣⠜⠩⠨⠱⠏⠱⠃⠀⠨⠪⠓⠛⠳⠺⠐ 23 | ⠣⠜⠨⠏⠃⠐⠞⠈⠉ 24 | ⠀⠀⠸⠜⠄⠣⠶⠐⠕⠄⠃⠹⠀⠺⠱⠳⠸⠳⠀⠐⠹⠫⠹⠃⠪⠀⠺⠁⠘⠺⠨⠅ 25 | ⠸⠺⠇⠪⠐⠂⠐⠟⠈⠉⠀⠸⠷⠣⠜⠐⠻⠋⠩⠑⠫⠳⠀⠸⠮⠂⠣⠜⠐⠹⠇⠫⠃⠐ 26 | ⠎⠈⠉⠀⠸⠾⠅⠣⠜⠐⠪⠳⠟⠀⠸⠏⠄⠱⠂⠣⠜⠐⠏⠥ 27 | ⠀⠀⠼⠙⠀⠼⠆⠢⠤⠒⠆⠀⠨⠜⠨⠯⠅⠣⠜⠈⠉⠐⠺⠊⠃⠓⠪⠹⠂⠀⠨⠵⠣⠜ 28 | ⠐⠻⠃⠱⠗⠃⠉⠁⠈⠉⠀⠨⠽⠂⠉⠅⠣⠜⠐⠳⠛⠃⠋⠻⠪⠀⠥⠨⠕⠈⠉⠣⠜ 29 | ⠐⠕⠥⠀⠨⠱⠙⠚⠹⠫⠣⠜⠥⠐⠗⠈⠉⠀⠐⠎⠇⠈⠉⠊⠨⠋⠑⠋⠣⠜ 30 | ⠐⠳⠓⠁⠛⠗⠈⠉⠀⠐⠪⠇⠨⠕⠹⠂⠉⠅⠈⠉⠣⠜⠐⠳⠛⠋⠻⠪⠇⠈⠉ 31 | ⠨⠹⠬⠬⠚⠊⠞⠬⠣⠆⠣⠅ 32 | ⠀⠀⠸⠜⠸⠝⠐⠝⠈⠉⠣⠜⠍⠀⠐⠹⠚⠊⠺⠐⠫⠣⠜⠍⠀⠸⠎⠄⠇⠳⠣⠜ 33 | ⠥⠐⠝⠈⠉⠀⠸⠟⠗⠣⠜⠐⠹⠚⠊⠺⠱⠀⠸⠏⠄⠇⠬⠃⠱⠴⠀⠝⠬⠩⠝⠴⠈⠉ 34 | ⠵⠅⠣⠜⠸⠪⠊⠓⠪⠻⠀⠘⠷⠣⠜⠨⠜⠐⠵⠣⠆⠣⠅ 35 | 36 | -------------------------------------------------------------------------------- /test/input/bwv988-v30.bmc: -------------------------------------------------------------------------------- 1 | ⠩ 2 | ⠨⠜⠄⠭⠐⠂⠭⠀⠥⠧⠭⠐⠑⠁⠣⠜⠠⠍⠀⠐⠓⠃⠊⠁⠚⠇⠙⠑⠽⠾⠊⠃⠭⠣⠜⠐⠳⠃⠳⠃⠪⠁⠪ 3 | ⠨⠱⠅⠱⠫⠫⠅⠣⠜⠐⠓⠁⠊⠓⠡⠛⠃⠋⠑⠸⠜⠐⠙⠨⠜⠐⠚⠁⠀⠨⠑⠂⠼⠃⠋⠴⠑⠼⠙⠅⠔⠁⠨⠅⠐⠖⠐⠚⠊⠳⠐⠂⠐⠳⠓⠑ 4 | ⠸⠜⠄⠭⠐⠂⠸⠑⠅⠀⠸⠗⠃⠟⠣⠜⠸⠓⠃⠨⠜⠸⠊⠁⠚⠙⠑⠽⠾⠸⠜⠸⠊⠁⠷⠮⠀⠸⠏⠱⠄⠂⠙⠣⠜⠸⠚⠃⠊⠗⠁⠐⠖⠛⠯⠿ 5 | ⠘⠞⠝⠣⠜⠸⠳⠭⠐⠑⠙⠚⠊⠸⠓⠁⠀⠸⠕⠘⠳⠭⠸⠾⠮⠣⠜⠰⠖⠸⠻⠈⠉⠿⠏⠟⠑⠁⠈⠉⠱⠧⠐⠉ 6 | ⠨⠜⠄⠥⠧⠭⠨⠑⠇⠣⠜⠐⠓⠊⠚⠙⠑⠽⠾⠊⠁⠨⠑⠇⠈⠉⠣⠜⠐⠳⠳⠪⠪⠁ 7 | ⠨⠓⠛⠂⠋⠅⠑⠐⠖⠩⠙⠾⠽⠊⠃⠭⠣⠜⠨⠑⠡⠙⠺⠪⠄⠾⠁⠩⠽⠣⠜⠐⠓⠊⠓⠃⠛⠋⠸⠜⠐⠑⠩⠙⠭⠐⠉ 8 | ⠨⠪⠪⠺⠺⠣⠜⠨⠑⠋⠛⠑⠃⠚⠑⠓⠂⠛⠀⠨⠊⠂⠚⠊⠓⠅⠛⠋⠅⠑⠐⠂⠨⠋⠄⠵⠈⠉⠵⠩⠽⠃⠋⠈⠉⠯⠑⠽⠑⠐⠂⠠⠧⠠⠭⠐⠊⠈⠉⠊⠓⠛⠨⠅⠣⠆ 9 | ⠸⠜⠸⠓⠿⠷⠁⠋⠵⠯⠻⠄⠚⠀⠫⠄⠂⠿⠷⠪⠁⠉⠂⠈⠉⠮⠓⠛⠂⠋⠀⠸⠻⠇⠱⠳⠘⠳⠣⠜⠸⠛⠇⠓⠊⠛⠃⠓⠛⠋⠁⠑⠀⠘⠎⠅⠱⠭⠐⠂⠩⠸⠙⠑⠋⠙⠃⠱⠑⠨⠅⠣⠆ 10 | ⠨⠜⠄⠣⠶⠨⠊⠐⠂⠭⠀⠨⠛⠊⠛⠊⠑⠃⠯⠿⠓⠋⠣⠜⠐⠪⠪⠺⠺⠀⠨⠊⠤⠓⠂⠴⠛⠇⠴⠋⠅⠴⠨⠅⠐⠖⠩⠨⠑⠩⠽⠵⠚⠨⠚⠐⠂⠸⠜⠐⠛⠁⠋⠩⠑⠭ 11 | ⠨⠋⠚⠋⠚⠩⠨⠵⠃⠯⠂⠿⠇⠷⠊⠷⠿⠣⠜⠨⠜⠐⠺⠺⠹⠹⠀⠨⠓⠅⠿⠯⠅⠩⠵⠇⠋⠛⠑⠏⠅⠈⠉⠣⠜⠐⠚⠙⠚⠊⠓⠿⠃⠷⠃⠋⠭ 12 | ⠨⠯⠉⠑⠁⠛⠇⠉⠋⠷⠉⠿⠊⠱⠄⠁⠉⠇⠽⠵⠣⠜⠥⠸⠜⠐⠳⠨⠜⠐⠳⠁ 13 | ⠸⠜⠄⠣⠶⠭⠐⠂⠐⠛⠁⠀⠐⠱⠃⠹⠺⠳⠣⠜⠐⠑⠃⠛⠑⠛⠓⠑⠑⠃⠓⠀⠐⠙⠇⠚⠙⠊⠺⠄⠊⠣⠜⠐⠋⠃⠭⠧⠻⠁⠻⠀⠸⠓⠐⠋⠸⠓⠐⠋⠸⠪⠄⠩⠊⠂⠣⠜⠐⠳⠳⠛⠁⠓⠁⠛⠃⠋⠁ 14 | ⠸⠺⠅⠘⠺⠸⠫⠄⠇⠉⠅⠡⠑⠣⠜⠩⠐⠑⠃⠯⠿⠃⠸⠺⠈⠉⠚⠮⠾⠓⠇⠮⠁⠾⠃⠀⠸⠹⠐⠹⠺⠄⠽⠇⠾⠣⠜⠐⠙⠑⠁⠋⠇⠛⠓⠿⠯⠑⠁⠭ 15 | ⠨⠜⠨⠋⠂⠿⠇⠷⠊⠓⠂⠐⠖⠿⠠⠣⠂⠏⠟⠅⠑⠇⠧⠣⠜⠨⠙⠄⠁⠵⠙⠚⠊⠚⠃⠙⠁⠑ 16 | ⠨⠚⠅⠉⠂⠙⠑⠂⠚⠙⠅⠚⠂⠊⠅⠓⠂⠉⠅⠣⠜⠐⠚⠸⠜⠐⠮⠁⠨⠜⠐⠾⠁⠸⠜⠐⠓⠁⠭⠭⠨⠜⠨⠯⠃⠵⠙⠁⠋ 17 | ⠨⠛⠓⠊⠛⠳⠓⠐⠂⠐⠮⠨⠑⠇⠙⠚⠽⠮⠨⠑⠈⠉⠑⠽⠵⠚⠨⠅⠣⠆⠣⠅ 18 | ⠸⠜⠸⠪⠄⠾⠽⠱⠄⠇⠽⠵⠣⠜⠭⠐⠊⠋⠃⠵⠯⠁⠛⠃⠳⠛⠀⠸⠓⠊⠚⠇⠓⠐⠹⠄⠇⠉⠅⠩⠙⠣⠜⠐⠱⠃⠱⠫⠫⠃ 19 | ⠐⠱⠇⠸⠱⠳⠂⠘⠓⠐⠂⠐⠑⠇⠋⠑⠁⠙⠃⠚⠁⠊⠓⠨⠅⠣⠆⠣⠅ 20 | -------------------------------------------------------------------------------- /test/m21.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from music21.key import Key 3 | from music21.tinyNotation import TinyNotationStream 4 | from os import system 5 | from sys import argv, exit 6 | 7 | class Snippet(TinyNotationStream): 8 | def __init__(self, key=None, time=None, melody='', fingering=None): 9 | TinyNotationStream.__init__(self, melody, time) 10 | if key is not None: 11 | self.insert(0, Key(key)) 12 | if fingering is not None: 13 | for (note_index, finger) in fingering: 14 | self.notes[note_index].fingering = finger 15 | 16 | convertible_snippets = [ 17 | # In theory, an ambiguous measure since we have half and 32th notes in 4/4 time. 18 | # However, since the 32th notes fall on a beat, music21 correctly transforms 19 | # them into a notegroup, which ends up as unambiguous. Neat special case! 20 | Snippet(melody="C2 C32 D E F E F G A B4") 21 | 22 | # music21 correctly recognizes the repeated measure and uses a simile sign to 23 | # indicate it. This is correctly recognized by BMC and transformed into the 24 | # equivalent "\repeat unfold" in LilyPond. 25 | , Snippet(time="3/4", melody="C4 E G C E G c2.") 26 | 27 | # music21 transcribes the tie and makes notegroups out of the second and third 28 | # beat (⠐⠷⠿⠓⠈⠉⠷⠑⠋⠛⠷⠊⠚⠩⠙), which BMC handles correctly including beaming output. 29 | # The key signature is also handled properly on all sides. 30 | , Snippet("G", "3/4", "g16 f# g8~ g16 d e f# g a b c'#", [(0, '4'), (7, '1')]) 31 | ] 32 | 33 | if __name__ == "__main__": 34 | if len(argv) < 2: 35 | print "Missing path to BMC." 36 | exit(1) 37 | bmc = argv[1] 38 | for stream in convertible_snippets: 39 | assert(system('%s --lilypond %s' % (bmc, stream.write('braille'))) == 0) 40 | -------------------------------------------------------------------------------- /test/m21.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | python $@ | lilypond -lWARNING -o music21_snippets - 6 | -------------------------------------------------------------------------------- /test/output/score_tuplet_test4.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | music = 5 | << 6 | \new Staff { 7 | c''4 \times 2/3 { e''8 f'' g'' } \times 2/3 { f'' \times 2/3 { e''16 f'' e'' } d''8 } c''4 | % 1 8 | } 9 | >> 10 | 11 | \score { 12 | \music 13 | \layout { } 14 | } 15 | \score { 16 | \unfoldRepeats \articulate \music 17 | \midi { } 18 | } 19 | -------------------------------------------------------------------------------- /test/output/score_tuplet_test8.ly: -------------------------------------------------------------------------------- 1 | % Automatically generated by BMC, the braille music compiler 2 | \version "2.14.2" 3 | \include "articulate.ly" 4 | music = 5 | << 6 | \new Staff { 7 | \key e \major 8 | \time 2/2 9 | \repeat unfold 2 { \times 2/3 { gis8 cis' e' gis cis' e' } \times 2/3 { gis cis' e' gis cis' e' } } | % 1 10 | \times 2/3 { a8 cis' e' } \times 2/3 { a cis' e' } \times 2/3 { a d' fis' } \times 2/3 { a d' fis' } | % 2 11 | \times 2/3 { gis8 bis fis' gis cis' e' gis cis' dis' } \times 2/3 { fis bis dis' } | % 3 12 | } 13 | >> 14 | 15 | \score { 16 | \music 17 | \layout { } 18 | } 19 | \score { 20 | \unfoldRepeats \articulate \music 21 | \midi { } 22 | } 23 | -------------------------------------------------------------------------------- /ui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(UNIX) 2 | add_subdirectory(gtk) 3 | endif() 4 | add_subdirectory(qt) 5 | 6 | -------------------------------------------------------------------------------- /ui/gtk/BrailleMusicEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef BRAILLEMUSICEDITOR_H 2 | #define BRAILLEMUSICEDITOR_H 3 | 4 | /** 5 | * \file BrailleMusicEditor.h 6 | * \brief BrailleMusicEditor Structure. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * BrailleMusicEditor Structure 12 | * 13 | */ 14 | 15 | 16 | /** 17 | *\struct BrailleMusicEditor 18 | *\brief This structure holds pointers to the objects that build the GUI. 19 | * 20 | * The structure BrailleMusicEditor was necessary for purposes of 21 | * not using global variables which can be harmfull to the program. 22 | * Thus, the structure holds everything necessary to the GUI. 23 | */ 24 | 25 | 26 | typedef struct 27 | { 28 | GtkWidget *window; /*!< A pointer to the window.*/ 29 | GtkWidget *vbox; /*!< A pointer to the container 30 | that organizes all its widgets vertically.*/ 31 | GtkWidget *hbox; /*!< A pointer to the container 32 | that organizes all its widgets horizontally*/ 33 | GtkWidget *menubar; /*!< A pointer to the menubar.*/ 34 | GtkWidget *toolbar; /*! A pointer to the toolbar.*/ 35 | GtkWidget *edit_scrollbar; /*!< A pointer to the editing scrollbar.*/ 36 | GtkWidget *score_scrollbar; /*!< A pointer to the partiture scrollbar.*/ 37 | GtkWidget *error_scrollbar; /*!< A pointer to 38 | the error messages textview scrollbar.*/ 39 | GtkWidget *textview; /*!< A pointer to the text view 40 | (the editing part of the window).*/ 41 | GtkWidget *score_view; /*!< A pointer to the partiture view 42 | (the right part of the window).*/ 43 | GtkWidget *error_view; /*!< A pointer to the error messages textview.*/ 44 | gchar *filename; /*!< A pointer to the name of the opened file.*/ 45 | gboolean text_changed; /*!< A pointer which indicate 46 | if the opened file has been modified.*/ 47 | } BrailleMusicEditor; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /ui/gtk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(FindPkgConfig) 2 | include(FindSDL) 3 | pkg_check_modules(PKG_CONFIG_GTK3 gtk+-3.0) 4 | pkg_check_modules(PKG_CONFIG_GTKSOURCEVIEW3 gtksourceview-3.0) 5 | pkg_check_modules(PKG_CONFIG_EVINCE_VIEW3 evince-view-3.0) 6 | FIND_LIBRARY(SDL_MIXER_LIBRARY 7 | NAMES SDL_mixer SDL_mixer-1.2 8 | HINTS $ENV{SDLDIR} 9 | PATH_SUFFIXES lib64 lib) 10 | if(PKG_CONFIG_GTK3_FOUND AND 11 | PKG_CONFIG_GTKSOURCEVIEW3_FOUND AND 12 | PKG_CONFIG_EVINCE_VIEW3_FOUND AND 13 | SDL_FOUND) 14 | include_directories(${PKG_CONFIG_GTK3_INCLUDE_DIRS}) 15 | include_directories(${PKG_CONFIG_GTKSOURCEVIEW3_INCLUDE_DIRS}) 16 | include_directories(${PKG_CONFIG_EVINCE_VIEW3_INCLUDE_DIRS}) 17 | include_directories(${SDL_INCLUDE_DIRS}) 18 | add_executable(bmc_gtk color.c edit.c goto.c menubar.c open.c save.c toolbar.c 19 | window.c compile.c errors.c main.c new.c player.c scoreviewer.c tops.c) 20 | target_link_libraries(bmc_gtk ${PKG_CONFIG_GTK3_LIBRARIES}) 21 | target_link_libraries(bmc_gtk ${PKG_CONFIG_GTKSOURCEVIEW3_LIBRARIES}) 22 | target_link_libraries(bmc_gtk ${PKG_CONFIG_EVINCE_VIEW3_LIBRARIES}) 23 | target_link_libraries(bmc_gtk ${SDL_MIXER_LIBRARY}) 24 | endif() 25 | -------------------------------------------------------------------------------- /ui/gtk/color.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_H 2 | #define COLOR_H 3 | 4 | /** 5 | * \file color.h 6 | * \brief Braille Music lexical coloration. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Lexical Highlighting functions prototypes 12 | * 13 | */ 14 | 15 | void lexical_coloration(GtkWidget *widget, BrailleMusicEditor *editor); 16 | 17 | void lexical_coloration_off(BrailleMusicEditor *editor); 18 | 19 | void coloration_update(GtkWidget *widget, BrailleMusicEditor *editor); 20 | 21 | void init_braille_table(); 22 | 23 | void init_colors(); 24 | 25 | void set_tags(GtkTextBuffer *buffer); 26 | 27 | void color(BrailleMusicEditor *editor); 28 | 29 | void lexical_coloration_off(BrailleMusicEditor *editor); 30 | 31 | void color_options(GtkWidget *widget, BrailleMusicEditor *editor); 32 | 33 | void color_selection(GtkWidget *widget, BrailleMusicEditor *editor); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /ui/gtk/color_test: -------------------------------------------------------------------------------- 1 | octave ⠈ ⠘ ⠸ ⠐ ⠨ ⠰ ⠠ 2 | note ⠊ ⠋ ⠎ ⠏ ⠑ ⠓ ⠕ ⠗ ⠙ ⠚ ⠛ ⠝ ⠞ ⠟ ⠪ ⠫ ⠮ ⠯ ⠱ ⠳ ⠵ ⠷ ⠹ ⠺ ⠻ ⠽ ⠾ ⠿ 3 | rest ⠍ ⠥ ⠧ ⠭ 4 | accidental ⠡ ⠣ ⠩ 5 | bar ⠣⠅ ⠣⠅⠄ 6 | fingering ⠁ ⠃ ⠇ ⠂ ⠅ 7 | dot ⠄ 8 | tie ⠈⠉ ⠨⠉ ⠘⠉ 9 | slur ⠉ ⠰⠃ ⠘⠆ ⠠⠉ ⠸⠉ ⠐⠉ ⠈⠇ ⠐⠇ ⠰⠉ ⠈⠆ 10 | ornament ⠐⠢ ⠢ ⠖ ⠲ ⠠⠲ ⠲⠇ ⠐⠖ ⠰⠖ ⠖⠇ ⠠⠲⠇ ⠐⠖⠇ ⠰⠖⠇ 11 | nuance ⠦ ⠠⠦ ⠐⠦ ⠸⠦ ⠨⠦ ⠈⠦ ⠰⠦ ⠣⠇ ⠜⠂ ⠜⠅ ⠡⠄ ⠜⠉ ⠜⠒ 12 | bracket ⠰⠂ ⠐⠆ ⠰⠄ ⠠⠆ ⠐⠄ ⠠⠂ 13 | interval ⠌ ⠬ ⠼ ⠔ ⠴ 14 | in_accord ⠣⠜ ⠐⠂ ⠨⠅ 15 | stem ⠸⠄ ⠸⠅ ⠸⠁ ⠸⠃ ⠸⠇ ⠸⠂ 16 | Repetition & Tremolo ⠘⠃ ⠘⠇ ⠘⠂ ⠘⠅ ⠘⠄ ⠨⠃ ⠨⠇ ⠨⠂ ⠨⠁ ⠨⠄ 17 | clef ⠜⠌⠇ ⠜⠼⠇ ⠜⠬⠇ 18 | rigth hand ⠨⠜ 19 | left hand ⠸⠜ 20 | -------------------------------------------------------------------------------- /ui/gtk/compile.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file compile.c 3 | * \brief Compile the current file. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Compile the current file by calling BMC. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "BrailleMusicEditor.h" 18 | #include "scoreviewer.h" 19 | #include "save.h" 20 | #include "tops.h" 21 | #include 22 | 23 | #define BMC_DIR "../../bmc" 24 | #define BMC_EXE "./bmc" 25 | 26 | 27 | /** 28 | * \fn void compile(GtkWidget *widget, BrailleMusicEditor *editor) 29 | * \brief Compile callback function 30 | * \param widget The widget which triggered the call. 31 | * \param editor The GUI structure. 32 | * 33 | * This function triggers the compilation of the current file by using BMC. 34 | * it save the current opened file. 35 | */ 36 | void compile(GtkWidget *widget, BrailleMusicEditor *editor) { 37 | 38 | 39 | GPid pid; 40 | GtkTextBuffer *buffer; 41 | char *argv[2]; 42 | gchar cmd[] = BMC_EXE; 43 | int standard_output, standard_error; 44 | gchar buf[1024]; 45 | gint chars_read = 1024; 46 | GtkTextIter iter; 47 | int fd, ly_fd; 48 | 49 | unlink("score.ly"); 50 | unlink("score.ps"); 51 | unlink("score.pdf"); 52 | unlink("score.midi"); 53 | save_file(widget, editor); 54 | 55 | fd = open(editor->filename, O_RDONLY); 56 | ly_fd = open("score.ly", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 57 | 58 | dup2(fd, STDIN_FILENO); 59 | argv[0]=cmd; 60 | argv[1]=NULL; 61 | g_spawn_async_with_pipes( BMC_DIR , // const gchar *working_directory 62 | argv, // gchar **argv 63 | NULL, // gchar **envp 64 | G_SPAWN_SEARCH_PATH | 65 | G_SPAWN_CHILD_INHERITS_STDIN , // GSpawnFlags flags 66 | NULL, // GSpawnChildSetupFunc child_setup 67 | NULL, // gpointer user_data 68 | &pid, // GPid *child_pid 69 | NULL, // gint *standard_input 70 | &standard_output, // gint *standard_output 71 | &standard_error, // gint *standard_error 72 | NULL); // GError **error 73 | 74 | buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->error_view)); 75 | gtk_text_buffer_get_end_iter(buffer, &iter); 76 | 77 | while (chars_read > 0){ 78 | chars_read = read(standard_error, buf, 1024); 79 | gtk_text_buffer_insert (buffer, &iter, buf, chars_read); 80 | 81 | } 82 | chars_read = 1024; 83 | while (chars_read > 0){ 84 | chars_read = read(standard_output, buf, 1024); 85 | write(ly_fd, buf, chars_read); 86 | } 87 | tops("score"); 88 | close(fd); 89 | close(ly_fd); 90 | close(standard_error); 91 | close(standard_output); 92 | show_score(editor); 93 | } 94 | -------------------------------------------------------------------------------- /ui/gtk/compile.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPILE_H 2 | #define COMPILE_H 3 | 4 | /** 5 | * \file compile.h 6 | * \brief Compile the current file. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Compile the current file by calling BMC. 12 | * 13 | */ 14 | 15 | 16 | void compile(GtkWidget *widget, BrailleMusicEditor *editor); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /ui/gtk/edit.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file edit.c 3 | * \brief Edit callback functions. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Edit callback functions. 9 | * 10 | */ 11 | 12 | #include 13 | #include "BrailleMusicEditor.h" 14 | 15 | 16 | /** 17 | * \fn void on_undo(GtkWidget *widget, BrailleMusicEditor *editor) 18 | * \param widget The widget which triggered the call. 19 | * \param editor The GUI structure. 20 | */ 21 | void on_undo(GtkWidget *widget, BrailleMusicEditor *editor) 22 | { 23 | g_signal_emit_by_name(editor->textview, "undo", NULL); 24 | } 25 | 26 | /** 27 | * \fn void on_redo(GtkWidget *widget, BrailleMusicEditor *editor) 28 | * \param widget The widget which triggered the call. 29 | * \param editor The GUI structure. 30 | */ 31 | void on_redo(GtkWidget *widget, BrailleMusicEditor *editor) 32 | { 33 | g_signal_emit_by_name(editor->textview, "redo", NULL); 34 | } 35 | 36 | 37 | /** 38 | * \fn void on_copy(GtkWidget *widget, BrailleMusicEditor *editor) 39 | * \param widget The widget which triggered the call. 40 | * \param editor The GUI structure. 41 | */ 42 | void on_copy(GtkWidget *widget, BrailleMusicEditor *editor) 43 | { 44 | g_signal_emit_by_name(editor->textview, "copy-clipboard", NULL); 45 | } 46 | 47 | /** 48 | * \fn void on_cut(GtkWidget *widget, BrailleMusicEditor *editor) 49 | * \param widget The widget which triggered the call. 50 | * \param editor The GUI structure. 51 | */ 52 | void on_cut(GtkWidget *widget, BrailleMusicEditor *editor) 53 | { 54 | g_signal_emit_by_name(editor->textview, "cut-clipboard", NULL); 55 | } 56 | 57 | /** 58 | * \fn void on_paste(GtkWidget *widget, BrailleMusicEditor *editor) 59 | * \param widget The widget which triggered the call. 60 | * \param editor The GUI structure. 61 | */ 62 | void on_paste(GtkWidget *widget, BrailleMusicEditor *editor) 63 | { 64 | g_signal_emit_by_name(editor->textview, "paste-clipboard", NULL); 65 | } 66 | 67 | /** 68 | * \fn void on_select_all(GtkWidget *widget, BrailleMusicEditor *editor) 69 | * \param widget The widget which triggered the call. 70 | * \param editor The GUI structure. 71 | */ 72 | void on_select_all(GtkWidget *widget, BrailleMusicEditor *editor) 73 | { 74 | GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->textview)); 75 | GtkTextIter start; 76 | GtkTextIter end; 77 | gtk_text_buffer_get_start_iter(buffer,&start); 78 | gtk_text_buffer_get_end_iter(buffer,&end); 79 | gtk_text_buffer_create_mark(buffer, "selection_bound", &start, FALSE); 80 | gtk_text_buffer_move_mark_by_name(buffer, "insert", &end); 81 | } 82 | 83 | 84 | /** 85 | * \fn void text_changed(GtkWidget *widget, BrailleMusicEditor *editor) 86 | * \param widget The widget which triggered the call. 87 | * \param editor The GUI structure. 88 | */ 89 | void on_text_changed(GtkWidget *widget, BrailleMusicEditor *editor) 90 | { 91 | editor->text_changed = TRUE; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /ui/gtk/edit.h: -------------------------------------------------------------------------------- 1 | #ifndef EDIT_H 2 | #define EDIT_H 3 | 4 | /** 5 | * \file edit.h 6 | * \brief Edit callback functions. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Edit callback function prototypes. 12 | * 13 | */ 14 | 15 | 16 | void on_undo(GtkWidget *widget, BrailleMusicEditor *editor); 17 | 18 | void on_redo(GtkWidget *widget, BrailleMusicEditor *editor); 19 | 20 | void on_copy(GtkWidget *widget, BrailleMusicEditor *editor); 21 | 22 | void on_cut(GtkWidget *widget, BrailleMusicEditor *editor); 23 | 24 | void on_paste(GtkWidget *widget, BrailleMusicEditor *editor); 25 | 26 | void on_select(GtkWidget *widget, BrailleMusicEditor *editor); 27 | 28 | void on_select_all(GtkWidget *widget, BrailleMusicEditor *editor); 29 | 30 | void on_text_changed(GtkWidget *widget, BrailleMusicEditor *editor); 31 | #endif 32 | -------------------------------------------------------------------------------- /ui/gtk/errors.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file errors.c 3 | * \brief Error alert functions. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Error alert functions. 9 | * 10 | */ 11 | 12 | 13 | #include 14 | 15 | /** 16 | * \fn void open_error(GtkWidget *file_selection, FILE *file, 17 | * const gchar * message_format, const gchar* path) 18 | * \brief Display un dialog on file selection window when file == NULL. 19 | * \param file_selection The file selection GtkWidget 20 | * \param file The pointer to the file. 21 | * \param message_format The message diplayed in the dialog box 22 | * (must contain only one "%s" with is the path of the file). 23 | * \param path The path to the file. 24 | */ 25 | 26 | void open_error(GtkWidget *file_selection, FILE *file, 27 | const gchar * message_format, const gchar* path) 28 | { 29 | if(file == NULL){ 30 | GtkWidget *dialog; 31 | dialog = gtk_message_dialog_new(GTK_WINDOW(file_selection), 32 | GTK_DIALOG_MODAL, 33 | GTK_MESSAGE_ERROR, 34 | GTK_BUTTONS_OK, 35 | message_format, 36 | g_locale_to_utf8( 37 | path, -1, NULL, 38 | NULL, NULL)); 39 | gtk_dialog_run(GTK_DIALOG(dialog)); 40 | gtk_widget_destroy(dialog); 41 | return; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ui/gtk/errors.h: -------------------------------------------------------------------------------- 1 | #ifndef ERRORS_H 2 | #define ERRORS_H 3 | 4 | /** 5 | * \file errors.h 6 | * \brief Error alert functions. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Error alert function prototypes. 12 | * 13 | */ 14 | 15 | 16 | void open_error(GtkWidget *file_selection, FILE *file, 17 | const gchar * message_format, const gchar* path); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /ui/gtk/goto.h: -------------------------------------------------------------------------------- 1 | #ifndef GOTO_H 2 | #define GOTO_H 3 | 4 | /** 5 | * \file goto.h 6 | * \brief Insert cursor moving funtions. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Insert cursor moving funtion prototypes. 12 | * 13 | */ 14 | 15 | 16 | void goto_next_prev(GtkWidget * widget, BrailleMusicEditor *editor, char n_p); 17 | 18 | void goto_next(GtkWidget * widget, BrailleMusicEditor *editor); 19 | 20 | void goto_prev(GtkWidget * widget, BrailleMusicEditor *editor); 21 | 22 | void goto_num(GtkWidget * widget, BrailleMusicEditor *editor); 23 | 24 | void goto_num_(unsigned int n, GtkTextBuffer *buffer); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /ui/gtk/menubar.h: -------------------------------------------------------------------------------- 1 | #ifndef MENUBAR_H 2 | #define MENUBAR_H 3 | 4 | /** 5 | * \file menubar.h 6 | * \brief Menubar creating function. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Menubar creating function prototypes. 12 | * 13 | */ 14 | 15 | void create_menubar(BrailleMusicEditor *editor); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ui/gtk/new.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file new.c 3 | * \brief New file callback. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * New file callback. 9 | * 10 | */ 11 | 12 | #include 13 | #include "BrailleMusicEditor.h" 14 | #include "new.h" 15 | #include "save.h" 16 | 17 | 18 | /** 19 | * \fn void new_file(GtkWidget * widget, BrailleMusicEditor *editor) 20 | * \brief The function called when creating a new file. 21 | * \param widget The widget which triggered the call. 22 | * \param editor The GUI structure. 23 | * 24 | * The function will check and see if there is data on the editor 25 | * and ask the user to save or not by calling check_for_save. 26 | */ 27 | 28 | void new_file(GtkWidget * widget, BrailleMusicEditor *editor) 29 | { 30 | gint resp=check_for_save (editor); 31 | if (resp == 1){ 32 | save_file(widget, editor); 33 | new_file_(editor); 34 | } 35 | else if(resp == 0) 36 | new_file_(editor); 37 | } 38 | 39 | 40 | /** 41 | * \fn void new_file_(BrailleMusicEditor *editor) 42 | * \brief This function actually opens a new file. 43 | * \param editor The GUI structure. 44 | */ 45 | void new_file_(BrailleMusicEditor *editor) 46 | { 47 | GtkTextBuffer *buffer; 48 | editor->filename = NULL; 49 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->textview)); 50 | gtk_text_buffer_set_text (buffer, "", -1); 51 | gtk_text_buffer_set_modified (buffer, FALSE); 52 | } 53 | -------------------------------------------------------------------------------- /ui/gtk/new.h: -------------------------------------------------------------------------------- 1 | #ifndef NEW_H 2 | #define NEW_H 3 | 4 | /** 5 | * \file new.h 6 | * \brief New file callback. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * New file callback prototype. 12 | * 13 | */ 14 | 15 | void new_file(GtkWidget * widget, BrailleMusicEditor *editor); 16 | 17 | void new_file_(BrailleMusicEditor *editor); 18 | #endif 19 | -------------------------------------------------------------------------------- /ui/gtk/open.h: -------------------------------------------------------------------------------- 1 | #ifndef OPEN_H 2 | #define OPEN_H 3 | 4 | /** 5 | * \file open.h 6 | * \brief Open file callback. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Open file callback prototype. 12 | * 13 | */ 14 | 15 | void open_file(GtkWidget *widget, BrailleMusicEditor *editor); 16 | 17 | void open_file_with_path(BrailleMusicEditor *editor, const gchar *path); 18 | 19 | void open_file_with_selection(BrailleMusicEditor *editor); 20 | 21 | void open_file_(BrailleMusicEditor *editor, const gchar *path); 22 | #endif 23 | -------------------------------------------------------------------------------- /ui/gtk/player.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file player.c 3 | * \brief Midi player functions. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Midi player functions. 9 | * 10 | */ 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "player.h" 18 | 19 | /** 20 | * \def MUSIC_FILE 21 | */ 22 | 23 | #define MUSIC_FILE "score.midi" 24 | 25 | //Mix_Music holds the music information. 26 | static Mix_Music* myMus=NULL; 27 | 28 | 29 | 30 | 31 | /** 32 | * \fn void *bmc_play_(void *) 33 | * \brief This function plays the music contained in an instance of Mix_Music. 34 | */ 35 | void *bmc_play_(void *v) 36 | { 37 | 38 | // initialize thz sound 39 | SDL_Init(SDL_INIT_AUDIO); 40 | 41 | // open up an audio device. 42 | if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)) { 43 | printf("Unable to open audio!\n"); 44 | exit(1); 45 | } 46 | 47 | // load the music file 48 | myMus = Mix_LoadMUS(MUSIC_FILE); 49 | 50 | /* play the music */ 51 | Mix_PlayMusic(myMus, 1); 52 | 53 | while (Mix_PlayingMusic() == 1) { 54 | //While the music isn't finshed, we do something o 55 | //therwise the programme exits and stops playing 56 | SDL_Delay(10); 57 | } 58 | if(myMus != NULL) 59 | free_mix_music(); 60 | return NULL; 61 | } 62 | 63 | /** 64 | * \fn void bmc_play() 65 | * \brief This function calls bmc_play_() in a new thread. 66 | */ 67 | 68 | void bmc_play() 69 | { 70 | if(!Mix_PlayingMusic()) { 71 | pthread_t t; 72 | pthread_create(&t,NULL, bmc_play_, NULL); 73 | } 74 | else { 75 | bmc_resume(); 76 | } 77 | } 78 | 79 | 80 | 81 | /** 82 | * \fn void bmc_pause() 83 | * \brief This function pauses the music. 84 | */ 85 | 86 | void bmc_pause() 87 | { 88 | if(Mix_PlayingMusic()) 89 | Mix_PauseMusic(); 90 | } 91 | 92 | /** 93 | * \fn void bmc_resume() 94 | * \brief This function resumes the paused music. 95 | */ 96 | 97 | void bmc_resume() 98 | { 99 | if(Mix_PausedMusic()) 100 | Mix_ResumeMusic(); 101 | } 102 | 103 | /** 104 | * \fn void bmc_stop() 105 | * \brief This function stop the music. 106 | */ 107 | 108 | void bmc_stop() 109 | { 110 | if(myMus!=NULL && (Mix_PausedMusic() || Mix_PlayingMusic())) 111 | free_mix_music(); 112 | } 113 | 114 | /** 115 | * \fn void free_mix_music(Mix_Music *myMus) 116 | * \brief This function delete the instance of Mix_Music 117 | * which is created by bmc_play_(). 118 | */ 119 | 120 | void free_mix_music() 121 | { 122 | Mix_FreeMusic(myMus); 123 | myMus=NULL; 124 | Mix_CloseAudio(); 125 | SDL_Quit(); 126 | } 127 | -------------------------------------------------------------------------------- /ui/gtk/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | /** 5 | * \file player.h 6 | * \brief Midi player functions. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Midi player function prototypes. 12 | * 13 | */ 14 | 15 | void *bmc_play_(void *); 16 | 17 | void bmc_play(); 18 | 19 | void bmc_pause(); 20 | 21 | void bmc_resume(); 22 | 23 | void bmc_stop(); 24 | 25 | void free_mix_music(); 26 | #endif 27 | -------------------------------------------------------------------------------- /ui/gtk/save.h: -------------------------------------------------------------------------------- 1 | #ifndef SAVE_H 2 | #define SAVE_H 3 | 4 | /** 5 | * \file save.h 6 | * \brief Save file callback. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Save file callback prototypes. 12 | * 13 | */ 14 | 15 | void save_file(GtkWidget *widget, BrailleMusicEditor *editor); 16 | 17 | void save_file_as(GtkWidget *widget, BrailleMusicEditor *editor); 18 | 19 | void write_file(gchar *path,GtkTextBuffer *buffer, 20 | GtkWidget *file_selection, BrailleMusicEditor *editor); 21 | 22 | gint check_for_save (BrailleMusicEditor *editor); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /ui/gtk/scoreviewer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file scoreviewer.c 3 | * \brief Scoreviewer creating functions. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Scoreviewer creating functions. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "BrailleMusicEditor.h" 17 | 18 | /** 19 | * \fn void external_link_catch(GtkWidget *w, GObject *link) 20 | * \brief This function catch the signal when a clic is made on a note. 21 | * \param w The widget which triggered the call. 22 | * \param link ev_link_action. 23 | * \param editor The GUI structure. 24 | */ 25 | void external_link_catch(GtkWidget *widget, GObject *link, BrailleMusicEditor *editor) { 26 | EvLinkAction *l = EV_LINK_ACTION(link); 27 | ev_view_copy_link_address(EV_VIEW(widget), l); 28 | //get line:column link 29 | const gchar * lc = ev_link_action_get_uri(l); 30 | int line, column; 31 | int i = 0; 32 | char c = ' ', temp[2048]; 33 | while(c != ':' || i >= strlen(lc)) { 34 | c = lc[i]; 35 | temp[i] = c; 36 | i++; 37 | } 38 | temp[i+1]='\0'; 39 | line = atoi(temp); 40 | line--; 41 | column = atoi(lc+i); 42 | GtkTextIter it; 43 | GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->textview)); 44 | if(gtk_text_buffer_get_line_count(buffer) < line ) { 45 | line = 0; 46 | column = 0; 47 | } 48 | 49 | gtk_text_buffer_get_iter_at_line(buffer, &it, line); 50 | while(column >0 && !gtk_text_iter_ends_line(&it)) { 51 | gtk_text_iter_forward_char(&it); 52 | column--; 53 | } 54 | gtk_widget_grab_focus(editor->textview); 55 | gtk_text_buffer_place_cursor(buffer, &it); 56 | gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(editor->textview), &it, 0.0, FALSE, 0.5, 0.5); 57 | } 58 | 59 | /** 60 | * \fn void show_score(BrailleMusicEditor *editor) 61 | * \brief This function create a scoreviewer in a widget. 62 | * \param editor The GUI structure. 63 | */ 64 | void show_score(BrailleMusicEditor *editor) { 65 | GError *err = NULL; 66 | GFile *file; 67 | gchar *filename = "score.pdf"; 68 | file = g_file_new_for_commandline_arg (filename); 69 | gchar *uri = g_file_get_uri (file); 70 | g_object_unref (file); 71 | EvDocument *doc = ev_document_factory_get_document (uri, &err); 72 | if(err) { 73 | g_warning ("Trying to read the score pdf file %s gave an error: %s", 74 | uri, err->message); 75 | if(err) 76 | g_error_free (err); 77 | err = NULL; 78 | } else { 79 | EvDocumentModel *docmodel = ev_document_model_new_with_document(EV_DOCUMENT(doc)); 80 | ev_view_set_model(EV_VIEW(editor->score_view), EV_DOCUMENT_MODEL(docmodel)); 81 | g_signal_connect(editor->score_view, "external-link", 82 | G_CALLBACK(external_link_catch), editor); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ui/gtk/scoreviewer.h: -------------------------------------------------------------------------------- 1 | #ifndef SCOREVIEWER_H 2 | #define SCOREVIEWER_H 3 | 4 | /** 5 | * \file scoreviewer.h 6 | * \brief Scoreviewer creating functions. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Scoreviewer creating function prototype. 12 | * 13 | */ 14 | 15 | void show_score(BrailleMusicEditor *editor); 16 | 17 | void external_link_catch(GtkWidget *widget, GObject *link, BrailleMusicEditor *editor); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /ui/gtk/toolbar.h: -------------------------------------------------------------------------------- 1 | #ifndef TOOLBAR_H 2 | #define TOOLBAR_H 3 | 4 | /** 5 | * \file toolbar.h 6 | * \brief Toolbar creating function. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Toolbar creating function prototype. 12 | * 13 | */ 14 | 15 | 16 | void create_toolbar(BrailleMusicEditor *editor); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /ui/gtk/tops.h: -------------------------------------------------------------------------------- 1 | #ifndef _TO_PS_H_ 2 | #define _TO_PS_H_ 3 | 4 | /** 5 | * \file tops.h 6 | * \brief .ly to .ps and .pdf conversion function. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * .ly to .to conversion function. 12 | * 13 | */ 14 | 15 | int tops(char* file_name); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ui/gtk/window.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file window.c 3 | * \brief Main window creating function. 4 | * \author Team BMC 5 | * \version 1.0 6 | * \date 07 April 2012 7 | * 8 | * Main window creating function prototype. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include "BrailleMusicEditor.h" 15 | #include "window.h" 16 | #include "save.h" 17 | 18 | /** 19 | * \fn void create_window(const gchar *title, gint width, gint height, 20 | * BrailleMusicEditor *editor) 21 | * \brief Create a new window. 22 | * \param title The title of the window 23 | * \param width The width of the window 24 | * \param height The height of the window 25 | * \param editor A pointer to a structure BrailleMusicEditor 26 | */ 27 | 28 | void create_window(const gchar* title, gint width , gint height, 29 | BrailleMusicEditor *editor) 30 | { 31 | editor->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 32 | gtk_window_set_title(GTK_WINDOW(editor->window), title); 33 | gtk_window_set_default_size(GTK_WINDOW(editor->window), width, height); 34 | gtk_window_set_position(GTK_WINDOW(editor->window), GTK_WIN_POS_CENTER); 35 | //main window background color 36 | GdkColor grey; 37 | gdk_color_parse("#AAAAAA",&grey); 38 | gtk_widget_modify_bg(editor->window, GTK_STATE_NORMAL, &grey); 39 | editor->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); 40 | 41 | g_signal_connect(G_OBJECT(editor->window), "delete_event", 42 | G_CALLBACK(window_delete_event), editor); 43 | g_signal_connect(G_OBJECT(editor->window), "destroy", 44 | G_CALLBACK(gtk_main_quit), NULL); 45 | } 46 | 47 | /** 48 | * \fn void window_destroy (GtkWidget *widget, BrailleMusicEditor *editor) 49 | * \brief Closes the window. 50 | * \param widget The window to close 51 | * \param editor A pointer to a structure BrailleMusicEditor. 52 | */ 53 | 54 | void window_destroy (GtkWidget *widget, BrailleMusicEditor *editor) 55 | { 56 | gint resp=check_for_save (editor); 57 | if (resp == 1){ 58 | save_file(widget, editor); 59 | gtk_main_quit(); 60 | } 61 | else if(resp == 0) 62 | gtk_main_quit(); 63 | } 64 | 65 | // When the window is requested to be closed, we need to check if 66 | // there is unsaved work. We use this callback to prompt the 67 | // user to save their work before they exit the application. With the 68 | // "delete-event" signal, we can choose to cancel the 69 | // close based on the value we return. 70 | 71 | 72 | /** 73 | * \fn gboolean window_delete_event (GtkWidget *widget, GdkEvent *event, 74 | * BrailleMusicEditor *editor) 75 | * \brief When closing the window, checks if there is unsaved work. 76 | * \param widget The window to close 77 | * \param event 78 | * \param editor A pointer to a structure BrailleMusicEditor. 79 | */ 80 | gboolean window_delete_event (GtkWidget *widget, GdkEvent *event, 81 | BrailleMusicEditor *editor) 82 | { 83 | gint resp=check_for_save (editor); 84 | if (resp == 1) 85 | save_file(widget, editor); 86 | else if(resp == 2) 87 | return TRUE; 88 | return FALSE; //propogate event to destroy window 89 | } 90 | -------------------------------------------------------------------------------- /ui/gtk/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | /** 5 | * \file window.c 6 | * \brief Main window creating function. 7 | * \author Team BMC 8 | * \version 1.0 9 | * \date 07 April 2012 10 | * 11 | * Main window creating function prototypes. 12 | * 13 | */ 14 | 15 | 16 | void create_window(const gchar* title, gint width , gint height, 17 | BrailleMusicEditor *editor); 18 | 19 | void window_destroy (GtkWidget *widget, BrailleMusicEditor *editor); 20 | 21 | gboolean window_delete_event (GtkWidget *widget, GdkEvent *event, 22 | BrailleMusicEditor *editor); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /ui/qt/.gitignore: -------------------------------------------------------------------------------- 1 | moc_*.cpp 2 | 3 | -------------------------------------------------------------------------------- /ui/qt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.0) 2 | set(CMAKE_AUTOMOC ON) 3 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 4 | list(APPEND CMAKE_PREFIX_PATH /usr/local/Cellar/qt5/5.5.1_2) 5 | find_package(Qt5 COMPONENTS Core Multimedia Svg Widgets Xml) 6 | if(Qt5_FOUND) 7 | qt5_add_resources(RESOURCES app.qrc) 8 | configure_file(config.h.in config.h) 9 | add_executable(bmc-ui MACOSX_BUNDLE 10 | app.cpp 11 | mainwindow.cpp mainwindow.h 12 | lilypondsvgwidget.cpp lilypondsvgwidget.h 13 | lilypondsvgcontainer.h 14 | optionsdialog.cpp optionsdialog.h 15 | ${RESOURCES} 16 | ) 17 | target_compile_features(bmc-ui PRIVATE cxx_range_for) 18 | target_link_libraries(bmc-ui 19 | Qt5::Widgets Qt5::Multimedia Qt5::Svg Qt5::Xml 20 | braillemusic-static 21 | ) 22 | install(TARGETS bmc-ui 23 | BUNDLE DESTINATION . COMPONENT Runtime 24 | RUNTIME DESTINATION bin COMPONENT Runtime 25 | ) 26 | if(APPLE) 27 | set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/bmc-ui") 28 | if(APPLE) 29 | set(APPS "\${CMAKE_INSTALL_PREFIX}/bmc-ui.app") 30 | elseif(MSVC) 31 | set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/bmc-ui.exe") 32 | endif() 33 | set(DIRS ${QT_LIBRARY_DIRS}) 34 | install(CODE " 35 | include(BundleUtilities) 36 | set(BU_CHMOD_BUNDLE_ITEMS ON) 37 | fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")" 38 | COMPONENT Runtime 39 | ) 40 | endif(APPLE) 41 | endif() 42 | 43 | -------------------------------------------------------------------------------- /ui/qt/app.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | std::locale::global(std::locale("")); 10 | bmc::braille::set_default_table_from_locale(); 11 | 12 | QApplication app(argc, argv); 13 | QApplication::setApplicationName("Braille Music Compiler"); 14 | QApplication::setApplicationVersion(BMC_VERSION); 15 | QApplication::setOrganizationName("Blind Guru"); 16 | QApplication::setOrganizationDomain("blind.guru"); 17 | BrailleMusicEditor window; 18 | window.show(); 19 | 20 | return app.exec(); 21 | } 22 | -------------------------------------------------------------------------------- /ui/qt/app.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ./sounds/ok.wav 5 | ./sounds/fail.wav 6 | ./images/empty.svg 7 | 8 | ../../test/input/bwv988-v01.bmc 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ui/qt/config.h.in: -------------------------------------------------------------------------------- 1 | #define LILYPOND_EXECUTABLE "${LILYPOND_EXECUTABLE}" 2 | 3 | -------------------------------------------------------------------------------- /ui/qt/lilypondsvgcontainer.h: -------------------------------------------------------------------------------- 1 | #ifndef LILYPOND_SVG_CONTAINER_H 2 | #define LILYPOND_SVG_CONTAINER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "lilypondsvgwidget.h" 9 | 10 | class LilyPondSvgContainer: public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | private: 15 | QString const &lilypondCode; 16 | 17 | signals: 18 | void clicked(int); 19 | void noteHovered(int); 20 | 21 | public slots: 22 | void highlight(int id) { 23 | for (int i = 0; i < layout()->count(); ++i) { 24 | if (LilyPondSvgWidget *widget = qobject_cast 25 | (layout()->itemAt(i)->widget())) { 26 | widget->hilightNote(id); 27 | } 28 | } 29 | } 30 | 31 | private slots: 32 | void click(int id) { emit clicked(id); } 33 | void noteHover(int id) { emit noteHovered(id); } 34 | 35 | public: 36 | LilyPondSvgContainer(QStringList svgFiles, QString const &lilypondCode) 37 | : lilypondCode{lilypondCode} { 38 | auto vbox = new QVBoxLayout; 39 | for (auto &&fileName : svgFiles) { 40 | auto svgWidget = new LilyPondSvgWidget{lilypondCode}; 41 | connect(svgWidget, &LilyPondSvgWidget::clicked, 42 | this, &LilyPondSvgContainer::click); 43 | connect(svgWidget, &LilyPondSvgWidget::noteHovered, 44 | this, &LilyPondSvgContainer::noteHover); 45 | 46 | svgWidget->load(fileName); 47 | vbox->addWidget(svgWidget); 48 | svgWidget->setMouseTracking(true); 49 | } 50 | setLayout(vbox); 51 | } 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /ui/qt/lilypondsvgwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef LILYPOND_SVG_WIDGET_H 2 | #define LILYPOND_SVG_WIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class LilyPondSvgWidget : public QSvgWidget { 13 | Q_OBJECT 14 | 15 | private: 16 | QString const &lilypondCode; 17 | int find_id(int line, int character, int column); 18 | 19 | signals: 20 | void clicked(int id); 21 | void noteHovered(int id); 22 | 23 | public slots: 24 | void hilightNote(int id) { 25 | qDebug() << "old:" << _oldid << "id:" << id; 26 | qDebug() << "oldstyle:" << _oldFillStyle; 27 | 28 | if (id == _oldid) return; 29 | if (_oldid > 0) { _hilightNote(_oldid, false); } 30 | _hilightNote(id, true); 31 | } 32 | 33 | private: 34 | QString _oldFillStyle; 35 | int _oldid = -1; 36 | 37 | void _hilightNote(int id, bool highlight) { 38 | QDomNodeList paths = doc.elementsByTagName("path"); 39 | 40 | for (int i = 0; i < paths.size(); i++) { 41 | if (QString(paths.item(i).toElement().attribute("id")) == 42 | QString::number(id)) { 43 | if (highlight) { 44 | qDebug() << "highlighting id " << id; 45 | _oldFillStyle = paths.item(i).toElement().attribute("fill"); 46 | 47 | if (_oldFillStyle == "currentColor" || _oldFillStyle == "") { 48 | _oldFillStyle = "#000000"; 49 | } 50 | _oldid = id; 51 | qDebug() << "Setting oldid to " << i; 52 | paths.item(i).toElement().setAttribute("fill", "#FF0000"); 53 | 54 | } else { 55 | if (this->_oldFillStyle == QString("")) { 56 | this->_oldFillStyle = "#000000"; 57 | } 58 | qDebug() << "restoring id " << _oldid 59 | << ", style:" << this->_oldFillStyle; 60 | 61 | paths.item(i).toElement().setAttribute("fill", this->_oldFillStyle); 62 | } 63 | 64 | QByteArray bytearray = doc.toByteArray(); 65 | 66 | // qDebug()<< "reloading stuff!!"; 67 | QSvgWidget::load(bytearray); 68 | 69 | this->update(); 70 | break; 71 | } 72 | } 73 | } 74 | 75 | public: 76 | QList> rects; 77 | QDomDocument doc; 78 | 79 | LilyPondSvgWidget(QString const &lilypondCode); 80 | 81 | void load(const QString filename); 82 | void mouseMoveEvent(QMouseEvent *event); // { mousePressEvent(event); } 83 | 84 | void mousePressEvent(QMouseEvent *event); 85 | }; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /ui/qt/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef BRAILLE_MUSIC_EDITOR_H 2 | #define BRAILLE_MUSIC_EDITOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lilypondsvgcontainer.h" 19 | 20 | 21 | QT_BEGIN_NAMESPACE 22 | class QAction; 23 | class QTextCharFormat; 24 | class QMenu; 25 | class QPrinter; 26 | QT_END_NAMESPACE 27 | 28 | class BrailleMusicEditor : public QMainWindow 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | BrailleMusicEditor(QWidget *parent = 0); 34 | 35 | protected: 36 | virtual void closeEvent(QCloseEvent *e) Q_DECL_OVERRIDE; 37 | 38 | private: 39 | void setupSoundEffects(); 40 | void setupFileActions(); 41 | void setupEditActions(); 42 | void setupOptionsActions(); 43 | bool load(const QString &f); 44 | bool maybeSave(); 45 | void setCurrentFileName(const QString &fileName); 46 | void goTo(int line, int column); 47 | void showEmptySVG(); 48 | 49 | private slots: 50 | void fileNew(); 51 | void fileOpen(); 52 | bool fileSave(); 53 | bool fileSaveAs(); 54 | void fileCompile(); 55 | void fileExportMusicXML(); 56 | void fileExportLilyPond(); 57 | void filePrint(); 58 | void filePrintPreview(); 59 | void filePrintPdf(); 60 | 61 | void editReformat(); 62 | 63 | void textFamily(const QString &f); 64 | void textSize(const QString &p); 65 | 66 | void showOptions(); 67 | 68 | void cursorPositionChanged(); 69 | void textChanged(); 70 | 71 | void clipboardDataChanged(); 72 | void about(); 73 | void reportBug(); 74 | void printPreview(QPrinter *); 75 | 76 | void runLilyPond(bool); 77 | void lilyPondStarted(); 78 | void lilyPondFinished(int exitCode, QProcess::ExitStatus exitStatus); 79 | void lilyPondError(QProcess::ProcessError error); 80 | 81 | void goToObject(int id); 82 | void highlightObject(int id); 83 | signals: 84 | void scoreAvailable(bool); 85 | 86 | private: 87 | void mergeFormatOnWordOrSelection(const QTextCharFormat &format); 88 | void fontChanged(const QFont &f); 89 | void colorChanged(const QColor &c); 90 | void resizeEvent(QResizeEvent *event) override; 91 | 92 | QAction *actionSave; 93 | QAction *actionUndo; 94 | QAction *actionRedo; 95 | QAction *actionCut; 96 | QAction *actionCopy; 97 | QAction *actionPaste; 98 | 99 | QToolBar *tb; 100 | QString fileName; 101 | QTextEdit *textEdit; 102 | QScrollArea *svgScrollArea; 103 | 104 | boost::optional<::bmc::braille::ast::score> score; 105 | QProcess lilypond; 106 | QScopedPointer tmpdir; 107 | QString lilypondCode; 108 | 109 | QSoundEffect ok, fail; 110 | 111 | }; 112 | 113 | #endif // BRAILLE_MUSIC_EDITOR_H 114 | -------------------------------------------------------------------------------- /ui/qt/optionsdialog.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTIONSDIALOG_H 2 | #define OPTIONSDIALOG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class GenericTab : public QWidget { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit GenericTab(QWidget *parent) : QWidget(parent) {} 19 | 20 | virtual void persistSettings() = 0; 21 | virtual void setup() = 0; 22 | 23 | protected: 24 | QSettings settings; 25 | }; 26 | 27 | class LilypondTab : public GenericTab { 28 | Q_OBJECT 29 | 30 | public: 31 | explicit LilypondTab(QWidget *parent = 0); 32 | void persistSettings() override; 33 | void setup() override; 34 | 35 | private: 36 | QLabel *lilypondExeLabel; 37 | QLineEdit *lilypondExeEdit; 38 | 39 | QLabel *lilypondVerboseLabel; 40 | QCheckBox *lilypondVerboseCheckbox; 41 | }; 42 | 43 | class TimidityTab : public GenericTab { 44 | Q_OBJECT 45 | 46 | public: 47 | explicit TimidityTab(QWidget *parent = 0); 48 | 49 | void persistSettings() override; 50 | void setup() override; 51 | 52 | private: 53 | QLabel *timidityExeLabel; 54 | QLineEdit *timidityExeEdit; 55 | }; 56 | 57 | 58 | class UISettingsTab : public GenericTab { 59 | Q_OBJECT 60 | 61 | public: 62 | explicit UISettingsTab(QWidget *parent = 0); 63 | 64 | void persistSettings() override; 65 | void setup() override; 66 | 67 | private: 68 | QCheckBox *persistLayoutCheckBox; 69 | QCheckBox *persistWindowPosCheckBox; 70 | QPushButton *highlightingColorPushButton; 71 | QColor *highlightingColor; 72 | QPixmap *highlightingPixmap; 73 | private slots: 74 | void showColorChooser(); 75 | }; 76 | 77 | class OptionsDialog : public QDialog { 78 | Q_OBJECT 79 | 80 | public: 81 | explicit OptionsDialog(QWidget *parent = 0); 82 | 83 | void saveSettings(); 84 | 85 | private: 86 | QTabWidget *tabWidget; 87 | QDialogButtonBox *buttonBox; 88 | 89 | QSettings settings; 90 | }; 91 | 92 | 93 | 94 | 95 | 96 | 97 | #endif // OPTIONSDIALOG_H 98 | -------------------------------------------------------------------------------- /ui/qt/sounds/fail.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/ui/qt/sounds/fail.wav -------------------------------------------------------------------------------- /ui/qt/sounds/ok.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlang/bmc/d77eaeee2362e6ea544bc76f06fb2ba2a2dfe428/ui/qt/sounds/ok.wav --------------------------------------------------------------------------------