diff --git a/.github/workflows/ci_build.yml b/.github/workflows/ci_build.yml index f6bbe77946c..ca515fa61ad 100644 --- a/.github/workflows/ci_build.yml +++ b/.github/workflows/ci_build.yml @@ -100,11 +100,11 @@ jobs: - os: macos-latest compiler: xcode - version: "13.1" + version: "14.3" - os: macos-latest compiler: xcode - version: "14.2" + version: "15.3" - os: macos-11 compiler: g++ diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml index e00c94d00fa..f79013e8515 100644 --- a/.github/workflows/clang-format-check.yml +++ b/.github/workflows/clang-format-check.yml @@ -18,8 +18,8 @@ jobs: steps: - uses: actions/checkout@v4 - name: Run clang-format style check for C/C++ programs. - uses: jidicula/clang-format-action@v4.9.0 + uses: jidicula/clang-format-action@v4.11.0 with: - clang-format-version: "15" + clang-format-version: "18" check-path: ${{ matrix.path['check'] }} exclude-regex: ${{ matrix.path['exclude'] }} diff --git a/Verovio.podspec b/Verovio.podspec index e401987e0fa..93b69a5ae10 100644 --- a/Verovio.podspec +++ b/Verovio.podspec @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '14.0' s.osx.deployment_target = '10.15' s.pod_target_xcconfig = { - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++20", "CLANG_CXX_LIBRARY" => "libc++", "GCC_C_LANGUAGE_STANDARD" => "gnu11", "GCC_DYNAMIC_NO_PIC" => "NO", diff --git a/Verovio.xcodeproj/project.pbxproj b/Verovio.xcodeproj/project.pbxproj index e2fda8406a0..9d46f1aadd8 100644 --- a/Verovio.xcodeproj/project.pbxproj +++ b/Verovio.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4D1693FF1E3A44F300569BF4 /* durationinterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBE188539540037FD8E /* durationinterface.cpp */; }; 4D1694001E3A44F300569BF4 /* toolkit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBF188539540037FD8E /* toolkit.cpp */; }; 4D1694011E3A44F300569BF4 /* MidiEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D1BE7671C688F5A0086DC0E /* MidiEvent.cpp */; }; - 4D1694021E3A44F300569BF4 /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* io.cpp */; }; + 4D1694021E3A44F300569BF4 /* iobase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* iobase.cpp */; }; 4D1694031E3A44F300569BF4 /* harm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D796B5D1D78641900A15238 /* harm.cpp */; }; 4D1694041E3A44F300569BF4 /* space.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DB3072E1AC9ED2500EE0982 /* space.cpp */; }; 4D1694051E3A44F300569BF4 /* iodarms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC1188539540037FD8E /* iodarms.cpp */; }; @@ -926,7 +926,7 @@ 8F086EE9188539540037FD8E /* doc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBD188539540037FD8E /* doc.cpp */; }; 8F086EEA188539540037FD8E /* durationinterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBE188539540037FD8E /* durationinterface.cpp */; }; 8F086EEB188539540037FD8E /* toolkit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBF188539540037FD8E /* toolkit.cpp */; }; - 8F086EEC188539540037FD8E /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* io.cpp */; }; + 8F086EEC188539540037FD8E /* iobase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* iobase.cpp */; }; 8F086EED188539540037FD8E /* iodarms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC1188539540037FD8E /* iodarms.cpp */; }; 8F086EEE188539540037FD8E /* iomei.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC2188539540037FD8E /* iomei.cpp */; }; 8F086EEF188539540037FD8E /* iomusxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC3188539540037FD8E /* iomusxml.cpp */; }; @@ -960,7 +960,7 @@ 8F3DD31E18854AFB0051330C /* bboxdevicecontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EB9188539540037FD8E /* bboxdevicecontext.cpp */; }; 8F3DD32018854AFB0051330C /* devicecontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EBC188539540037FD8E /* devicecontext.cpp */; }; 8F3DD32218854AFB0051330C /* svgdevicecontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086ED5188539540037FD8E /* svgdevicecontext.cpp */; }; - 8F3DD32418854B090051330C /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* io.cpp */; }; + 8F3DD32418854B090051330C /* iobase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* iobase.cpp */; }; 8F3DD32618854B090051330C /* iodarms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC1188539540037FD8E /* iodarms.cpp */; }; 8F3DD32818854B090051330C /* iomei.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC2188539540037FD8E /* iomei.cpp */; }; 8F3DD32A18854B090051330C /* iomusxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC3188539540037FD8E /* iomusxml.cpp */; }; @@ -1006,7 +1006,7 @@ 8F59293B18854BF800FE51AD /* doc.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291418854BF800FE51AD /* doc.h */; }; 8F59293C18854BF800FE51AD /* durationinterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291518854BF800FE51AD /* durationinterface.h */; }; 8F59293D18854BF800FE51AD /* toolkit.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291618854BF800FE51AD /* toolkit.h */; }; - 8F59293E18854BF800FE51AD /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291718854BF800FE51AD /* io.h */; }; + 8F59293E18854BF800FE51AD /* iobase.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291718854BF800FE51AD /* iobase.h */; }; 8F59293F18854BF800FE51AD /* iodarms.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291818854BF800FE51AD /* iodarms.h */; }; 8F59294018854BF800FE51AD /* iomei.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291918854BF800FE51AD /* iomei.h */; }; 8F59294118854BF800FE51AD /* iomusxml.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291A18854BF800FE51AD /* iomusxml.h */; }; @@ -1068,8 +1068,8 @@ BB4C4AAA22A932A0001F6AF0 /* devicecontextbase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D797B041A67C55F007637BD /* devicecontextbase.h */; settings = {ATTRIBUTES = (Public, ); }; }; BB4C4AAB22A932A0001F6AF0 /* svgdevicecontext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086ED5188539540037FD8E /* svgdevicecontext.cpp */; }; BB4C4AAC22A932A0001F6AF0 /* svgdevicecontext.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59292C18854BF800FE51AD /* svgdevicecontext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BB4C4AAD22A932A6001F6AF0 /* io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* io.cpp */; }; - BB4C4AAE22A932A6001F6AF0 /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291718854BF800FE51AD /* io.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BB4C4AAD22A932A6001F6AF0 /* iobase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC0188539540037FD8E /* iobase.cpp */; }; + BB4C4AAE22A932A6001F6AF0 /* iobase.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F59291718854BF800FE51AD /* iobase.h */; settings = {ATTRIBUTES = (Public, ); }; }; BB4C4AAF22A932A6001F6AF0 /* ioabc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 402197931F2E09DA00182DF1 /* ioabc.cpp */; }; BB4C4AB022A932A6001F6AF0 /* ioabc.h in Headers */ = {isa = PBXBuildFile; fileRef = 402197921F2E09CB00182DF1 /* ioabc.h */; settings = {ATTRIBUTES = (Public, ); }; }; BB4C4AB122A932A6001F6AF0 /* iodarms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F086EC1188539540037FD8E /* iodarms.cpp */; }; @@ -2093,7 +2093,7 @@ 8F086EBD188539540037FD8E /* doc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = doc.cpp; path = src/doc.cpp; sourceTree = ""; }; 8F086EBE188539540037FD8E /* durationinterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = durationinterface.cpp; path = src/durationinterface.cpp; sourceTree = ""; }; 8F086EBF188539540037FD8E /* toolkit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = toolkit.cpp; path = src/toolkit.cpp; sourceTree = ""; }; - 8F086EC0188539540037FD8E /* io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = io.cpp; path = src/io.cpp; sourceTree = ""; }; + 8F086EC0188539540037FD8E /* iobase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iobase.cpp; path = src/iobase.cpp; sourceTree = ""; }; 8F086EC1188539540037FD8E /* iodarms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iodarms.cpp; path = src/iodarms.cpp; sourceTree = ""; }; 8F086EC2188539540037FD8E /* iomei.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = iomei.cpp; path = src/iomei.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 8F086EC3188539540037FD8E /* iomusxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iomusxml.cpp; path = src/iomusxml.cpp; sourceTree = ""; }; @@ -2134,7 +2134,7 @@ 8F59291418854BF800FE51AD /* doc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = doc.h; path = include/vrv/doc.h; sourceTree = ""; }; 8F59291518854BF800FE51AD /* durationinterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = durationinterface.h; path = include/vrv/durationinterface.h; sourceTree = ""; }; 8F59291618854BF800FE51AD /* toolkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = toolkit.h; path = include/vrv/toolkit.h; sourceTree = ""; }; - 8F59291718854BF800FE51AD /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io.h; path = include/vrv/io.h; sourceTree = ""; }; + 8F59291718854BF800FE51AD /* iobase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iobase.h; path = include/vrv/iobase.h; sourceTree = ""; }; 8F59291818854BF800FE51AD /* iodarms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iodarms.h; path = include/vrv/iodarms.h; sourceTree = ""; }; 8F59291918854BF800FE51AD /* iomei.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = iomei.h; path = include/vrv/iomei.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 8F59291A18854BF800FE51AD /* iomusxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iomusxml.h; path = include/vrv/iomusxml.h; sourceTree = ""; }; @@ -2833,8 +2833,8 @@ 8F086F37188539C50037FD8E /* io */ = { isa = PBXGroup; children = ( - 8F086EC0188539540037FD8E /* io.cpp */, - 8F59291718854BF800FE51AD /* io.h */, + 8F086EC0188539540037FD8E /* iobase.cpp */, + 8F59291718854BF800FE51AD /* iobase.h */, 402197931F2E09DA00182DF1 /* ioabc.cpp */, 402197921F2E09CB00182DF1 /* ioabc.h */, 8F086EC1188539540037FD8E /* iodarms.cpp */, @@ -3194,7 +3194,7 @@ 4DEC4DD621C8295700D1D273 /* del.h in Headers */, 4DB726C81B8BB0F30040231B /* text.h in Headers */, 4D308101203DB69D00BC44F6 /* ref.h in Headers */, - 8F59293E18854BF800FE51AD /* io.h in Headers */, + 8F59293E18854BF800FE51AD /* iobase.h in Headers */, 4DF092A22497706600239195 /* phrase.h in Headers */, 8F59293F18854BF800FE51AD /* iodarms.h in Headers */, 4DDBBB571C7AE43E00054AFF /* hairpin.h in Headers */, @@ -3442,7 +3442,7 @@ 4DACC9E92990F29A00B55913 /* atts_fingering.h in Headers */, BB4C4A9422A9328F001F6AF0 /* doc.h in Headers */, BB4C4A9922A9328F001F6AF0 /* horizontalaligner.h in Headers */, - BB4C4AAE22A932A6001F6AF0 /* io.h in Headers */, + BB4C4AAE22A932A6001F6AF0 /* iobase.h in Headers */, BB4C4BAA22A932EB001F6AF0 /* view.h in Headers */, 4DACC9DD2990F29A00B55913 /* atts_header.h in Headers */, BB4C4BC422A9330D001F6AF0 /* pugixml.hpp in Headers */, @@ -3920,7 +3920,7 @@ E722106828F85981002CD6E9 /* findlayerelementsfunctor.cpp in Sources */, 4D1694011E3A44F300569BF4 /* MidiEvent.cpp in Sources */, 4DA0EAEF22BB77C300A7EBEB /* editortoolkit_cmn.cpp in Sources */, - 4D1694021E3A44F300569BF4 /* io.cpp in Sources */, + 4D1694021E3A44F300569BF4 /* iobase.cpp in Sources */, 4D1694031E3A44F300569BF4 /* harm.cpp in Sources */, 4D79641926C1522B0026288B /* pageelement.cpp in Sources */, 4DB3D8DE1F83D15200B5FC2B /* btrem.cpp in Sources */, @@ -4214,7 +4214,7 @@ 4D1BE76D1C688F5A0086DC0E /* MidiEvent.cpp in Sources */, E75EA9FD29CC3A88003A97A7 /* calcarticfunctor.cpp in Sources */, 35FDEBD124B6DC5B00AC1696 /* fing.cpp in Sources */, - 8F086EEC188539540037FD8E /* io.cpp in Sources */, + 8F086EEC188539540037FD8E /* iobase.cpp in Sources */, E75A69A029CCF8A200414819 /* adjustbeamsfunctor.cpp in Sources */, 4DACC9762990F29A00B55913 /* atts_neumes.cpp in Sources */, 4D796B5E1D78641900A15238 /* harm.cpp in Sources */, @@ -4638,7 +4638,7 @@ E7E9C11729B0A20400CFCE2F /* adjustaccidxfunctor.cpp in Sources */, 8F3DD33818854B250051330C /* system.cpp in Sources */, 4D72A5E1208A37F0009DEC1E /* mnum.cpp in Sources */, - 8F3DD32418854B090051330C /* io.cpp in Sources */, + 8F3DD32418854B090051330C /* iobase.cpp in Sources */, 4DACC9D62990F29A00B55913 /* atts_pagebased.cpp in Sources */, 4DA0EACD22BB779400A7EBEB /* zone.cpp in Sources */, 4DEC4DBC21C8288900D1D273 /* choice.cpp in Sources */, @@ -4791,7 +4791,7 @@ BB4C4A9322A9328F001F6AF0 /* doc.cpp in Sources */, 4D8135212322C41800F59C01 /* keyaccid.cpp in Sources */, BB4C4B9922A932E5001F6AF0 /* linkinginterface.cpp in Sources */, - BB4C4AAD22A932A6001F6AF0 /* io.cpp in Sources */, + BB4C4AAD22A932A6001F6AF0 /* iobase.cpp in Sources */, E74A806A28BC9843005274E7 /* functorinterface.cpp in Sources */, 4DD7C0FD27A55CEA00B9C017 /* timemap.cpp in Sources */, E78833632994EC7E00D44B01 /* calcchordnoteheadsfunctor.cpp in Sources */, diff --git a/bindings/iOS/all.h b/bindings/iOS/all.h index 0a5dbb6b62d..d99cbd442f9 100644 --- a/bindings/iOS/all.h +++ b/bindings/iOS/all.h @@ -121,7 +121,7 @@ #import #import #import -#import +#import #import #import #import diff --git a/fonts/poetry.lock b/fonts/poetry.lock index bd9153bf74d..53c2a8f35ed 100644 --- a/fonts/poetry.lock +++ b/fonts/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "astroid" @@ -39,36 +39,47 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "black" -version = "22.12.0" +version = "24.3.0" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, - {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, - {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"}, - {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"}, - {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"}, - {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"}, - {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"}, - {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"}, - {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"}, - {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"}, - {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"}, - {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"}, + {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, + {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, + {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, + {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, + {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, + {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, + {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, + {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, + {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, + {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, + {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, + {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, + {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, + {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, + {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, + {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, + {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, + {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, + {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, + {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, + {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, + {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" +packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] @@ -389,6 +400,17 @@ files = [ {file = "numpy-1.26.2.tar.gz", hash = "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea"}, ] +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + [[package]] name = "parso" version = "0.8.3" @@ -767,4 +789,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "8990a11839baa27daa52ec96424fdaf96f294140034d66d66d7fde50197b0749" +content-hash = "13dc88eb6e57ab4192765ec4d46f48aa0091403e19806d5c3ed58ffe35a76464" diff --git a/fonts/pyproject.toml b/fonts/pyproject.toml index 3bd27e61a62..6c68d206a6d 100644 --- a/fonts/pyproject.toml +++ b/fonts/pyproject.toml @@ -12,7 +12,7 @@ svgpathtools = "^1.6.0" [tool.poetry.group.dev.dependencies] ipython = "^8.10.0" -black = "^22.8.0" +black = "^24.3.0" mypy = "^0.971" pylint = "^2.15.3" diff --git a/include/midi/Binasc.h b/include/midi/Binasc.h index 6aa57f09478..686cc407c7c 100644 --- a/include/midi/Binasc.h +++ b/include/midi/Binasc.h @@ -13,11 +13,11 @@ #ifndef _BINASC_H_INCLUDED #define _BINASC_H_INCLUDED -#include +#include #include +#include #include -#include -#include /* needed for MinGW */ + namespace smf { @@ -149,6 +149,8 @@ class Binasc { int getWord (std::string& word, const std::string& input, const std::string& terminators, int index); + static const char *GMinstrument[128]; + }; } // end of namespace smf diff --git a/include/midi/MidiEvent.h b/include/midi/MidiEvent.h index 39f141ee9b1..f8141d17bba 100644 --- a/include/midi/MidiEvent.h +++ b/include/midi/MidiEvent.h @@ -15,8 +15,11 @@ #define _MIDIEVENT_H_INCLUDED #include "MidiMessage.h" + +#include #include + namespace smf { class MidiEvent : public MidiMessage { @@ -63,6 +66,10 @@ class MidiEvent : public MidiMessage { }; + +std::ostream& operator<<(std::ostream& out, MidiEvent& event); + + } // end of namespace smf #endif /* _MIDIEVENT_H_INCLUDED */ diff --git a/include/midi/MidiEventList.h b/include/midi/MidiEventList.h index e3bfb13cf5b..f9b1e8538e2 100644 --- a/include/midi/MidiEventList.h +++ b/include/midi/MidiEventList.h @@ -14,8 +14,10 @@ #define _MIDIEVENTLIST_H_INCLUDED #include "MidiEvent.h" + #include + namespace smf { class MidiEventList { diff --git a/include/midi/MidiFile.h b/include/midi/MidiFile.h index 4a363da5658..4972218f627 100644 --- a/include/midi/MidiFile.h +++ b/include/midi/MidiFile.h @@ -16,19 +16,24 @@ #include "MidiEventList.h" -#include -#include -#include #include +#include +#include +#include -#define TIME_STATE_DELTA 0 -#define TIME_STATE_ABSOLUTE 1 - -#define TRACK_STATE_SPLIT 0 -#define TRACK_STATE_JOINED 1 namespace smf { +enum { + TRACK_STATE_SPLIT = 0, // Tracks are separated into separate vector postions. + TRACK_STATE_JOINED = 1 // Tracks are merged into a single vector position, +}; // like a Type-0 MIDI file, but reversible. + +enum { + TIME_STATE_DELTA = 0, // MidiMessage::ticks are in delta time format (like MIDI file). + TIME_STATE_ABSOLUTE = 1 // MidiMessage::ticks are in absolute time format (0=start time). +}; + class _TickTime { public: int tick; @@ -217,7 +222,7 @@ class MidiFile { MidiEvent* addTempo (int aTrack, int aTick, double aTempo); MidiEvent* addKeySignature (int aTrack, int aTick, - int key, bool mode = 0); + int fifths, bool mode = 0); MidiEvent* addTimeSignature (int aTrack, int aTick, int top, int bottom, int clocksPerClick = 24, diff --git a/include/midi/MidiMessage.h b/include/midi/MidiMessage.h index 49bd88a73e7..b298e15b9a0 100644 --- a/include/midi/MidiMessage.h +++ b/include/midi/MidiMessage.h @@ -14,10 +14,12 @@ #ifndef _MIDIMESSAGE_H_INCLUDED #define _MIDIMESSAGE_H_INCLUDED +#include #include #include #include + namespace smf { typedef unsigned char uchar; @@ -122,6 +124,12 @@ class MidiMessage : public std::vector { void makePatchChange (int channel, int patchnum); void makeTimbre (int channel, int patchnum); void makeController (int channel, int num, int value); + void makePitchBend (int channel, int lsb, int msb); + void makePitchBend (int channel, int value); + void makePitchBendDouble (int channel, double value); + void makePitchbend (int channel, int lsb, int msb) { makePitchBend(channel, lsb, msb); } + void makePitchbend (int channel, int value) { makePitchBend(channel, value); } + void makePitchbendDouble (int channel, double value) { makePitchBendDouble(channel, value); } // helper functions to create various continuous controller messages: void makeSustain (int channel, int value); @@ -199,6 +207,9 @@ class MidiMessage : public std::vector { }; +std::ostream& operator<<(std::ostream& out, MidiMessage& event); + + } // end of namespace smf diff --git a/include/vrv/bboxdevicecontext.h b/include/vrv/bboxdevicecontext.h index 05b63b990ba..1c6ee4f9274 100644 --- a/include/vrv/bboxdevicecontext.h +++ b/include/vrv/bboxdevicecontext.h @@ -50,7 +50,7 @@ class BBoxDeviceContext : public DeviceContext { */ ///@{ void SetBackground(int color, int style = AxSOLID) override; - void SetBackgroundImage(void *image, double opacity = 1.0) override{}; + void SetBackgroundImage(void *image, double opacity = 1.0) override {}; void SetBackgroundMode(int mode) override; void SetTextForeground(int color) override; void SetTextBackground(int color) override; @@ -87,7 +87,7 @@ class BBoxDeviceContext : public DeviceContext { void DrawSpline(int n, Point points[]) override; void DrawGraphicUri(int x, int y, int width, int height, const std::string &uri) override; void DrawSvgShape(int x, int y, int width, int height, double scale, pugi::xml_node svg) override; - void DrawBackgroundImage(int x = 0, int y = 0) override{}; + void DrawBackgroundImage(int x = 0, int y = 0) override {}; ///@} /** @@ -150,7 +150,7 @@ class BBoxDeviceContext : public DeviceContext { * @name Method for adding description element */ ///@{ - void AddDescription(const std::string &text) override{}; + void AddDescription(const std::string &text) override {}; ///@} private: diff --git a/include/vrv/devicecontext.h b/include/vrv/devicecontext.h index e493d38b611..b319c835a1a 100644 --- a/include/vrv/devicecontext.h +++ b/include/vrv/devicecontext.h @@ -207,7 +207,7 @@ class DeviceContext { * Special method for forcing bounding boxes to be updated * Used for invisible elements (e.g., ) that needs to be take into account in spacing */ - virtual void DrawPlaceholder(int x, int y){}; + virtual void DrawPlaceholder(int x, int y) {}; /** * @name Method for starting and ending a text @@ -258,14 +258,14 @@ class DeviceContext { * For example, the method can be used for grouping shapes in in SVG */ ///@{ - virtual void StartCustomGraphic(const std::string &name, std::string gClass = "", std::string gId = ""){}; - virtual void EndCustomGraphic(){}; + virtual void StartCustomGraphic(const std::string &name, std::string gClass = "", std::string gId = "") {}; + virtual void EndCustomGraphic() {}; ///@} /** * Method for changing the color of a custom graphic */ - virtual void SetCustomGraphicColor(const std::string &color){}; + virtual void SetCustomGraphicColor(const std::string &color) {}; /** * @name Methods for re-starting and ending a graphic for objects drawn in separate steps @@ -308,7 +308,7 @@ class DeviceContext { * @name Method for adding description element */ ///@{ - virtual void AddDescription(const std::string &text){}; + virtual void AddDescription(const std::string &text) {}; ///@} /** diff --git a/include/vrv/ioabc.h b/include/vrv/ioabc.h index 4e830c11bba..f29892b0549 100644 --- a/include/vrv/ioabc.h +++ b/include/vrv/ioabc.h @@ -13,7 +13,7 @@ //---------------------------------------------------------------------------- -#include "io.h" +#include "iobase.h" #include "pugixml.hpp" #include "vrvdef.h" diff --git a/include/vrv/io.h b/include/vrv/iobase.h similarity index 97% rename from include/vrv/io.h rename to include/vrv/iobase.h index f07c2bf1448..e5cfc903acc 100644 --- a/include/vrv/io.h +++ b/include/vrv/iobase.h @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: io.h +// Name: iobase.h // Author: Laurent Pugin // Created: 2012 // Copyright (c) Authors and others. All rights reserved. ///////////////////////////////////////////////////////////////////////////// -#ifndef __VRV_IO_H__ -#define __VRV_IO_H__ +#ifndef __VRV_IOBASE_H__ +#define __VRV_IOBASE_H__ #include #include diff --git a/include/vrv/iodarms.h b/include/vrv/iodarms.h index ad3ad31820a..bd1f4bb8d56 100644 --- a/include/vrv/iodarms.h +++ b/include/vrv/iodarms.h @@ -11,7 +11,7 @@ //---------------------------------------------------------------------------- #include "attdef.h" -#include "io.h" +#include "iobase.h" namespace vrv { diff --git a/include/vrv/iohumdrum.h b/include/vrv/iohumdrum.h index f5ac61083e2..8a1cccb114d 100644 --- a/include/vrv/iohumdrum.h +++ b/include/vrv/iohumdrum.h @@ -25,7 +25,7 @@ #include "fing.h" #include "ftrem.h" #include "harm.h" -#include "io.h" +#include "iobase.h" #include "keysig.h" #include "label.h" #include "metersig.h" diff --git a/include/vrv/iomei.h b/include/vrv/iomei.h index 6b0d7800119..12f530bdacf 100644 --- a/include/vrv/iomei.h +++ b/include/vrv/iomei.h @@ -14,7 +14,7 @@ //---------------------------------------------------------------------------- #include "doc.h" -#include "io.h" +#include "iobase.h" //---------------------------------------------------------------------------- diff --git a/include/vrv/iomusxml.h b/include/vrv/iomusxml.h index 2d6decc245c..946f0d95b74 100644 --- a/include/vrv/iomusxml.h +++ b/include/vrv/iomusxml.h @@ -17,7 +17,7 @@ //---------------------------------------------------------------------------- #include "attdef.h" -#include "io.h" +#include "iobase.h" #include "metersig.h" #include "vrvdef.h" diff --git a/include/vrv/iopae.h b/include/vrv/iopae.h index 77313365e15..b02f0620adc 100644 --- a/include/vrv/iopae.h +++ b/include/vrv/iopae.h @@ -27,7 +27,7 @@ #include "atts_cmn.h" #include "clef.h" -#include "io.h" +#include "iobase.h" #include "keysig.h" #include "mensur.h" #include "metersig.h" diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index 085fa811845..cf8a7af9e32 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -296,7 +296,7 @@ class LayerElement : public Object, /** * Helper function to set shortening for elements with beam interface */ - virtual void SetElementShortening(int shortening){}; + virtual void SetElementShortening(int shortening) {}; /** * Get the stem mod for the element (if any) diff --git a/include/vrv/lb.h b/include/vrv/lb.h index 9b044f6d25b..52c97896da4 100644 --- a/include/vrv/lb.h +++ b/include/vrv/lb.h @@ -37,7 +37,7 @@ class Lb : public TextElement { /** * Lb is an empty element */ - void AddChild(Object *object) override{}; + void AddChild(Object *object) override {}; /** * Interface for class functor visitation diff --git a/include/vrv/options.h b/include/vrv/options.h index 98a66d74f36..0e9160240a7 100644 --- a/include/vrv/options.h +++ b/include/vrv/options.h @@ -652,6 +652,7 @@ class Options { OptionBool m_preserveAnalyticalMarkup; OptionBool m_removeIds; OptionBool m_scaleToPageSize; + OptionBool m_setLocale; OptionBool m_showRuntime; OptionBool m_shrinkToFit; OptionIntMap m_smuflTextFont; diff --git a/include/vrv/toolkit.h b/include/vrv/toolkit.h index 14a5499baeb..8ec0376e71d 100644 --- a/include/vrv/toolkit.h +++ b/include/vrv/toolkit.h @@ -732,6 +732,14 @@ class Toolkit { */ int GetOutputTo() { return m_outputTo; } + /** + * Setting the global locale. + */ + ///@{ + void SetLocale(); + void ResetLocale(); + ///@} + /** * Measuring runtime. * @@ -790,6 +798,8 @@ class Toolkit { Options *m_options; + std::optional m_previousLocale; + /** * The C buffer string. */ diff --git a/include/vrv/view.h b/include/vrv/view.h index c9137403e20..2f59e4c6657 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -122,7 +122,7 @@ class View { virtual void DoRefresh() {} virtual void DoResize() {} virtual void DoReset() {} - virtual void OnPageChange(){}; + virtual void OnPageChange() {}; ///@} /** diff --git a/src/beam.cpp b/src/beam.cpp index 775ccb9f55a..5e30dfde1c5 100644 --- a/src/beam.cpp +++ b/src/beam.cpp @@ -333,9 +333,8 @@ std::pair BeamSegment::GetMinimalStemLength(const BeamDrawingInterface const auto [topOffset, bottomOffset] = this->GetVerticalOffset(beamInterface); // lambda check whether coord has element set and whether that element is CHORD or NOTE - const auto isNoteOrChord = [](BeamElementCoord *coord) { - return (coord->m_element && coord->m_element->Is({ CHORD, NOTE })); - }; + const auto isNoteOrChord + = [](BeamElementCoord *coord) { return (coord->m_element && coord->m_element->Is({ CHORD, NOTE })); }; using CoordIt = ArrayOfBeamElementCoords::const_iterator; for (CoordIt it = m_beamElementCoordRefs.begin(); it != m_beamElementCoordRefs.end(); ++it) { @@ -460,9 +459,8 @@ void BeamSegment::AdjustBeamToFrenchStyle(const BeamDrawingInterface *beamInterf // set to store durations of relevant notes (it's ordered, so min duration is going to be first) std::set noteDurations; // lambda check whether coord has element set and whether that element is CHORD or NOTE - const auto isNoteOrChord = [](BeamElementCoord *coord) { - return (coord->m_element && coord->m_element->Is({ CHORD, NOTE })); - }; + const auto isNoteOrChord + = [](BeamElementCoord *coord) { return (coord->m_element && coord->m_element->Is({ CHORD, NOTE })); }; // iterators using CoordIt = ArrayOfBeamElementCoords::iterator; using CoordReverseIt = ArrayOfBeamElementCoords::reverse_iterator; diff --git a/src/filereader.cpp b/src/filereader.cpp index 4703dd56a44..2ae6dfc9659 100644 --- a/src/filereader.cpp +++ b/src/filereader.cpp @@ -58,7 +58,7 @@ bool ZipFileReader::Load(const std::string &filename) #else std::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary); if (!fin.is_open()) { - LogError("File archive '%s' could not be open.", filename.c_str()); + LogError("File archive '%s' could not be opened.", filename.c_str()); return false; } @@ -92,7 +92,7 @@ std::list ZipFileReader::GetFileList() const assert(m_file); std::list list; - for (miniz_cpp::zip_info &member : m_file->infolist()) { + for (const miniz_cpp::zip_info &member : m_file->infolist()) { list.push_back(member.filename); } return list; @@ -103,13 +103,9 @@ bool ZipFileReader::HasFile(const std::string &filename) assert(m_file); // Look for the file in the zip - for (miniz_cpp::zip_info &member : m_file->infolist()) { - if (member.filename == filename) { - return true; - } - } - - return true; + const std::vector &fileInfoList = m_file->infolist(); + return std::any_of(fileInfoList.cbegin(), fileInfoList.cend(), + [&filename](const auto &info) { return info.filename == filename; }); } std::string ZipFileReader::ReadTextFile(const std::string &filename) @@ -117,7 +113,7 @@ std::string ZipFileReader::ReadTextFile(const std::string &filename) assert(m_file); // Look for the meta file in the zip - for (miniz_cpp::zip_info &member : m_file->infolist()) { + for (const miniz_cpp::zip_info &member : m_file->infolist()) { if (member.filename == filename) { return m_file->read(member.filename); } diff --git a/src/io.cpp b/src/iobase.cpp similarity index 95% rename from src/io.cpp rename to src/iobase.cpp index 87c27c38159..3071a1c5599 100644 --- a/src/io.cpp +++ b/src/iobase.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: io.cpp +// Name: iobase.cpp // Author: Laurent Pugin // Created: 2012 // Copyright (c) Laurent Pugin. All rights reserved. ///////////////////////////////////////////////////////////////////////////// -#include "io.h" +#include "iobase.h" //---------------------------------------------------------------------------- diff --git a/src/iomusxml.cpp b/src/iomusxml.cpp index cab02b71ddf..667e4d99a68 100644 --- a/src/iomusxml.cpp +++ b/src/iomusxml.cpp @@ -3148,7 +3148,7 @@ void MusicXmlInput::ReadMusicXmlNote( } // ties - ReadMusicXmlTies(notations.node(), layer, note, measureNum); + ReadMusicXmlTies(node, layer, note, measureNum); // articulation std::vector artics; @@ -3834,7 +3834,9 @@ void MusicXmlInput::ReadMusicXmlBeamStart(const pugi::xml_node &node, const pugi void MusicXmlInput::ReadMusicXmlTies( const pugi::xml_node &node, Layer *layer, Note *note, const std::string &measureNum) { - for (pugi::xml_node xmlTie : node.children("tied")) { + pugi::xpath_node_set xmlTies = node.select_nodes("notations/tied"); + for (pugi::xpath_node_set::const_iterator it = xmlTies.begin(); it != xmlTies.end(); ++it) { + pugi::xml_node xmlTie = (*it).node(); std::string tieType = xmlTie.attribute("type").as_string(); if (tieType.empty()) { diff --git a/src/midi/Binasc.cpp b/src/midi/Binasc.cpp index f49aa563201..446dc03b9b0 100644 --- a/src/midi/Binasc.cpp +++ b/src/midi/Binasc.cpp @@ -11,12 +11,37 @@ #include "Binasc.h" +#include #include -#include namespace smf { +const char* Binasc::GMinstrument[128] = { + "acoustic grand piano", "bright acoustic piano", "electric grand piano", "honky-tonk piano", "rhodes piano", "chorused piano", + "harpsichord", "clavinet", "celeste", "glockenspiel", "music box", "vibraphone", + "marimba", "xylophone", "tubular bells", "dulcimer", "hammond organ", "percussive organ", + "rock organ", "church organ", "reed organ", "accordion", "harmonica", "tango accordion", + "nylon guitar", "steel guitar", "jazz guitar", "clean guitar", "muted guitar", "overdriven guitar", + "distortion guitar", "guitar harmonics", "acoustic bass", "fingered electric bass", "picked electric bass", "fretless bass", + "slap bass 1", "slap bass 2", "synth bass 1", "synth bass 2", "violin", "viola", + "cello", "contrabass", "tremolo strings", "pizzcato strings", "orchestral harp", "timpani", + "string ensemble 1", "string ensemble 2", "synth strings 1", "synth strings 1", "choir aahs", "voice oohs", + "synth voices", "orchestra hit", "trumpet", "trombone", "tuba", "muted trumpet", + "frenc horn", "brass section", "syn brass 1", "synth brass 2", "soprano sax", "alto sax", + "tenor sax", "baritone sax", "oboe", "english horn", "bassoon", "clarinet", + "piccolo", "flute", "recorder", "pan flute", "bottle blow", "shakuhachi", + "whistle", "ocarina", "square wave", "saw wave", "calliope lead", "chiffer lead", + "charang lead", "voice lead", "fifths lead", "brass lead", "newage pad", "warm pad", + "polysyn pad", "choir pad", "bowed pad", "metallic pad", "halo pad", "sweep pad", + "rain", "soundtrack", "crystal", "atmosphere", "brightness", "goblins", + "echoes", "sci-fi", "sitar", "banjo", "shamisen", "koto", + "kalimba", "bagpipes", "fiddle", "shanai", "tinkle bell", "agogo", + "steel drums", "woodblock", "taiko drum", "melodoc tom", "synth drum", "reverse cymbal", + "guitar fret noise", "breath noise", "seashore", "bird tweet", "telephone ring", "helicopter", + "applause", "gunshot" +}; + ////////////////////////////// // // Binasc::Binasc -- Constructor: set the default option values. @@ -717,7 +742,9 @@ int Binasc::readMidiEvent(std::ostream& out, std::istream& infile, output << " '" << std::dec << (int)byte1; if (m_commentsQ) { output << "\t"; - comment += "patch-change"; + comment += "patch-change ("; + comment += GMinstrument[byte1 & 0x7f]; + comment += ")"; } break; case 0xD0: // channel pressure: 1 bytes diff --git a/src/midi/MidiEvent.cpp b/src/midi/MidiEvent.cpp index 945e3c532eb..0cf590d8c97 100644 --- a/src/midi/MidiEvent.cpp +++ b/src/midi/MidiEvent.cpp @@ -13,7 +13,7 @@ #include "MidiEvent.h" -#include +#include namespace smf { @@ -278,6 +278,20 @@ double MidiEvent::getDurationInSeconds(void) const { } + +////////////////////////////// +// +// operator<<(MidiMessage) -- Print tick value followed by MIDI bytes for event. +// The tick value will be either relative or absolute depending on the state +// of the MidiFile object containing it. +// + +std::ostream& operator<<(std::ostream& out, MidiEvent& event) { + out << event.tick << '(' << static_cast(event) << ')'; + return out; +} + + } // end namespace smf diff --git a/src/midi/MidiEventList.cpp b/src/midi/MidiEventList.cpp index 52749c5d837..f38fefbc2ca 100644 --- a/src/midi/MidiEventList.cpp +++ b/src/midi/MidiEventList.cpp @@ -10,15 +10,14 @@ // Description: A class which stores a MidiEvents for a MidiFile track. // - #include "MidiEventList.h" -#include #include +#include #include #include +#include -#include namespace smf { @@ -54,8 +53,8 @@ MidiEventList::MidiEventList(const MidiEventList& other) { // MidiEventList::MidiEventList(MidiEventList&& other) { - list = std::move(other.list); - other.list.clear(); + list = std::move(other.list); + other.list.clear(); } @@ -124,12 +123,12 @@ const MidiEvent& MidiEventList::last(void) const { // MidiEvent& MidiEventList::getEvent(int index) { - return *list[index]; + return *list[index]; } const MidiEvent& MidiEventList::getEvent(int index) const { - return *list[index]; + return *list[index]; } @@ -141,10 +140,10 @@ const MidiEvent& MidiEventList::getEvent(int index) const { // void MidiEventList::clear(void) { - for (int i=0; i<(int)list.size(); i++) { - if (list[i] != NULL) { - delete list[i]; - list[i] = NULL; + for (auto& item : list) { + if (item != NULL) { + delete item; + item = NULL; } } list.resize(0); @@ -245,10 +244,10 @@ int MidiEventList::push_back(MidiEvent& event) { void MidiEventList::removeEmpties(void) { int count = 0; - for (int i=0; i<(int)list.size(); i++) { - if (list[i]->empty()) { - delete list[i]; - list[i] = NULL; + for (auto& item : list) { + if (item->empty()) { + delete item; + item = NULL; count++; } } @@ -257,9 +256,9 @@ void MidiEventList::removeEmpties(void) { } std::vector newlist; newlist.reserve(list.size() - count); - for (int i=0; i<(int)list.size(); i++) { - if (list[i]) { - newlist.push_back(list[i]); + for (auto& item : list) { + if (item) { + newlist.push_back(item); } } list.swap(newlist); @@ -292,8 +291,8 @@ int MidiEventList::linkNotePairs(void) { // dimension 3: List of active note-ons or note-offs. std::vector>> noteons; noteons.resize(16); - for (int i=0; i<(int)noteons.size(); i++) { - noteons[i].resize(128); + for (auto& noteon : noteons) { + noteon.resize(128); } // Controller linking: The following General MIDI controller numbers are @@ -433,7 +432,7 @@ void MidiEventList::clearLinks(void) { ////////////////////////////// // -// MidiEventList::clearSequence -- Remove any seqence serial numbers from +// MidiEventList::clearSequence -- Remove any sequence serial numbers from // MidiEvents in the list. This will cause the default ordering by // sortTracks() to be used, in which case the ordering of MidiEvents // occurring at the same tick may switch their ordering. @@ -454,7 +453,7 @@ void MidiEventList::clearSequence(void) { // to preseve the order of MIDI messages in a track when they occur // at the same tick time. Particularly for use with joinTracks() // or sortTracks(). markSequence will be done automatically when -// a MIDI file is read, in case the ordering of events occuring at +// a MIDI file is read, in case the ordering of events occurring at // the same time is important. Use clearSequence() to use the // default sorting behavior of sortTracks() when events occur at the // same time. Returns the next serial number that has not yet been diff --git a/src/midi/MidiFile.cpp b/src/midi/MidiFile.cpp index fa1534d79df..55956c8ce79 100644 --- a/src/midi/MidiFile.cpp +++ b/src/midi/MidiFile.cpp @@ -15,14 +15,14 @@ #include "MidiFile.h" #include "Binasc.h" -#include -#include -#include -#include +#include #include -#include +#include +#include #include -#include +#include +#include +#include namespace smf { @@ -71,21 +71,21 @@ const char* MidiFile::GMinstrument[128] = { ////////////////////////////// // -// MidiFile::MidiFile -- Constuctor. +// MidiFile::MidiFile -- Constructor. // MidiFile::MidiFile(void) { m_events.resize(1); - for (int i=0; i<(int)m_events.size(); i++) { - m_events[i] = new MidiEventList; + for (auto &event : m_events) { + event = new MidiEventList; } } MidiFile::MidiFile(const std::string& filename) { m_events.resize(1); - for (int i=0; i<(int)m_events.size(); i++) { - m_events[i] = new MidiEventList; + for (auto &event : m_events) { + event = new MidiEventList; } read(filename); } @@ -93,8 +93,8 @@ MidiFile::MidiFile(const std::string& filename) { MidiFile::MidiFile(std::istream& input) { m_events.resize(1); - for (int i=0; i<(int)m_events.size(); i++) { - m_events[i] = new MidiEventList; + for (auto &event : m_events) { + event = new MidiEventList; } read(input); } @@ -507,7 +507,7 @@ bool MidiFile::readSmf(std::istream& input) { m_events[i]->clear(); // Read MIDI events in the track, which are pairs of VLV values - // and then the bytes for the MIDI message. Running status messags + // and then the bytes for the MIDI message. Running status messages // will be filled in with their implicit command byte. // The timestamps are converted from delta ticks to absolute ticks, // with the absticks variable accumulating the VLV tick values. @@ -597,7 +597,7 @@ bool MidiFile::write(std::ostream& out) { shortdata = static_cast(getNumTracks()); writeBigEndianUShort(out, shortdata); - // 5. write out the number of ticks per quarternote. (avoiding SMTPE for now) + // 5. write out the number of ticks per quarternote. (avoiding SMPTE for now) shortdata = static_cast(getTicksPerQuarterNote()); writeBigEndianUShort(out, shortdata); @@ -774,7 +774,7 @@ bool MidiFile::writeHex(std::ostream& out, int width) { int wordcount = 1; int linewidth = width >= 0 ? width : 25; for (int i=0; iremoveEmpties(); + for (auto &event : m_events) { + event->removeEmpties(); } } @@ -954,7 +954,7 @@ void MidiFile::removeEmpties(void) { // a track when they occur at the same tick time. Particularly // for use with joinTracks() or sortTracks(). markSequence will // be done automatically when a MIDI file is read, in case the -// ordering of m_events occuring at the same time is important. +// ordering of m_events occurring at the same time is important. // Use clearSequence() to use the default sorting behavior of // sortTracks(). // @@ -982,7 +982,7 @@ void MidiFile::markSequence(int track, int sequence) { ////////////////////////////// // -// MidiFile::clearSequence -- Remove any seqence serial numbers from +// MidiFile::clearSequence -- Remove any sequence serial numbers from // MidiEvents in the MidiFile. This will cause the default ordering by // sortTracks() to be used, in which case the ordering of MidiEvents // occurring at the same tick may switch their ordering. @@ -1311,7 +1311,7 @@ void MidiFile::deltaTicks(void) { // absolute time, which means that the time field // in the MidiEvent struct represents the exact tick // time to play the event rather than the time since -// the last event to wait untill playing the current +// the last event to wait until playing the current // event. // @@ -1422,7 +1422,7 @@ int MidiFile::getFileDurationInTicks(void) { // in units of quarter notes. If the MidiFile is in delta tick mode, // then temporarily got into absolute tick mode to do the calculations. // Note that this is expensive, so you should normally call this function -// while in aboslute tick (default) mode. +// while in absolute tick (default) mode. // double MidiFile::getFileDurationInQuarters(void) { @@ -1434,7 +1434,7 @@ double MidiFile::getFileDurationInQuarters(void) { ////////////////////////////// // // MidiFile::getFileDurationInSeconds -- returns the duration of the -// logest track in the file. The tracks must be sorted before +// longest track in the file. The tracks must be sorted before // calling this function, since this function assumes that the // last MidiEvent in the track has the highest timestamp. // The file state can be in delta ticks since this function @@ -1906,7 +1906,7 @@ MidiEvent* MidiFile::addTimeSignature(int aTrack, int aTick, int top, int bottom // // MidiFile::addCompoundTimeSignature -- Add a time signature meta message // (meta #0x58), where the clocksPerClick parameter is set to three -// eighth notes for compount meters such as 6/8 which represents +// eighth notes for compound meters such as 6/8 which represents // two beats per measure. // // Default values: @@ -2347,7 +2347,7 @@ int MidiFile::getTicksPerQuarterNote(void) const { // setting for 25 frames a second with 40 subframes // which means one tick per millisecond. When SMPTE is // being used, there is no real concept of the quarter note, - // so presume 60 bpm as a simiplification here. + // so presume 60 bpm as a simplification here. // return 1000; } return m_ticksPerQuarterNote; @@ -2696,7 +2696,7 @@ double MidiFile::linearSecondInterpolationAtTick(int ticktime) { // MidiFile::buildTimeMap -- build an index of the absolute tick values // found in a MIDI file, and their corresponding time values in // seconds, taking into consideration tempo change messages. If no -// tempo messages are given (or untill they are given, then the +// tempo messages are given (or until they are given, then the // tempo is set to 120 beats per minute). If SMPTE time code is // used, then ticks are actually time values. So don't build // a time map for SMPTE ticks, and just calculate the time in @@ -2956,15 +2956,17 @@ int MidiFile::extractMidiData(std::istream& input, std::vector& array, ulong MidiFile::readVLValue(std::istream& input) { uchar b[5] = {0}; - for (int i=0; i<5; i++) { - b[i] = readByte(input); - if (!status()) { return m_rwstatus; } - if (b[i] < 0x80) { - break; - } - } + for (uchar &item : b) { + item = readByte(input); + if (!status()) { + return m_rwstatus; + } + if (item < 0x80) { + break; + } + } - return unpackVLV(b[0], b[1], b[2], b[3], b[4]); + return unpackVLV(b[0], b[1], b[2], b[3], b[4]); } @@ -3005,7 +3007,7 @@ ulong MidiFile::unpackVLV(uchar a, uchar b, uchar c, uchar d, uchar e) { // // MidiFile::writeVLValue -- write a number to the midifile // as a variable length value which segments a file into 7-bit -// values and adds a contination bit to each. Maximum size of input +// values and adds a continuation bit to each. Maximum size of input // aValue is 0x0FFFffff. // @@ -3392,7 +3394,7 @@ std::string MidiFile::base64Encode(const std::string& input) { output.reserve(((input.size()/3) + (input.size() % 3 > 0)) * 4); int vala = 0; int valb = -6; - for (unsigned char c : input) { + for (uchar c : input) { vala = (vala << 8) + c; valb += 8; while (valb >=0) { @@ -3423,7 +3425,7 @@ std::string MidiFile::base64Decode(const std::string& input) { std::string output; int vala = 0; int valb = -8; - for (unsigned char c : input) { + for (uchar c : input) { if (c == '=') { break; } else if (MidiFile::decodeLookup[c] == -1) { diff --git a/src/midi/MidiMessage.cpp b/src/midi/MidiMessage.cpp index 7b9eb33c289..5b19a36eb8a 100644 --- a/src/midi/MidiMessage.cpp +++ b/src/midi/MidiMessage.cpp @@ -14,10 +14,10 @@ #include "MidiMessage.h" #include +#include +#include #include #include -#include - namespace smf { @@ -315,11 +315,13 @@ bool MidiMessage::isMetaMessage(void) const { // bool MidiMessage::isNoteOff(void) const { - if (size() != 3) { + const MidiMessage& message = *this; + const vector& chars = message; + if (message.size() != 3) { return false; - } else if (((*this)[0] & 0xf0) == 0x80) { + } else if ((chars[0] & 0xf0) == 0x80) { return true; - } else if ((((*this)[0] & 0xf0) == 0x90) && ((*this)[2] == 0)) { + } else if (((chars[0] & 0xf0) == 0x90) && (chars[2] == 0x00)) { return true; } else { return false; @@ -676,7 +678,7 @@ bool MidiMessage::isInstrumentName(void) const { ////////////////////////////// // // MidiMessage::isLyricText -- Returns true if message is a meta message -// describing some lyric text (for karakoke MIDI files) +// describing some lyric text (for karaoke MIDI files) // (meta message type 0x05). // @@ -857,7 +859,7 @@ int MidiMessage::getKeyNumber(void) const { ////////////////////////////// // -// MidiMessage::getVelocity -- Return the key veolocity. If the message +// MidiMessage::getVelocity -- Return the key velocity. If the message // is not a note-on or a note-off, then return -1. If the value is // out of the range 0-127, then chop off the high-bits. // @@ -961,7 +963,7 @@ void MidiMessage::setP1(int value) { ////////////////////////////// // -// MidiMessage::setP2 -- Set the second paramter value. +// MidiMessage::setP2 -- Set the second paramater value. // If the MidiMessage is too short, add extra spaces // to allow for P2. The command byte and/or the P1 value // will be undefined if extra space needs to be added and @@ -980,7 +982,7 @@ void MidiMessage::setP2(int value) { ////////////////////////////// // -// MidiMessage::setP3 -- Set the third paramter value. +// MidiMessage::setP3 -- Set the third paramater value. // If the MidiMessage is too short, add extra spaces // to allow for P3. The command byte and/or the P1/P2 values // will be undefined if extra space needs to be added and @@ -1364,7 +1366,7 @@ void MidiMessage::setSpelling(int base7, int accidental) { // pc + octave * 7 // where pc is the numbers 0 through 6 representing the pitch classes // C through B, the octave is MIDI octave (not the scientific pitch -// octave which is one less than the MIDI ocatave, such as C4 = middle C). +// octave which is one less than the MIDI octave, such as C4 = middle C). // The second number is the accidental for the base-7 pitch. // @@ -1544,8 +1546,8 @@ void MidiMessage::setMetaContent(const std::string& content) { // add the size of the meta message data (VLV) int dsize = (int)content.size(); std::vector vlv = intToVlv(dsize); - for (int i=0; i<(int)vlv.size(); i++) { - this->push_back(vlv[i]); + for (uchar item : vlv) { + this->push_back(item); } std::copy(content.begin(), content.end(), std::back_inserter(*this)); } @@ -1764,6 +1766,61 @@ void MidiMessage::makeController(int channel, int num, int value) { +///////////////////////////// +// +// MidiMessage::makePitchBend -- Create a pitch-bend message. lsb is +// least-significant 7 bits of the 14-bit range, and msb is the +// most-significant 7 bits of the 14-bit range. The range depth +// is determined by a setting in the synthesizer. Typically it is +// +/- two semitones by default. See MidiFile::setPitchBendRange() +// to change the default (or change to the typical default). +// + +void MidiMessage::makePitchBend(int channel, int lsb, int msb) { + resize(0); + push_back(0xe0 | (0x0e & channel)); + push_back(0x7f & lsb); + push_back(0x7f & msb); +} + +// +// value is a 14-bit number, where 0 is the lowest pitch of the range, and +// 2^15-1 is the highest pitch of the range. +// + +void MidiMessage::makePitchBend(int channel, int value) { + resize(0); + int lsb = value & 0x7f; + int msb = (value >> 7) & 0x7f; + push_back(0xe0 | (0x7f & channel)); + push_back(lsb); + push_back(msb); +} + +// +// Input value is a number between -1.0 and +1.0. +// + +void MidiMessage::makePitchBendDouble(int channel, double value) { + // value is in the range from -1 for minimum and 2^18 - 1 for the maximum + resize(0); + double dvalue = (value + 1.0) * (pow(2.0, 15.0)); + if (dvalue < 0.0) { + dvalue = 0.0; + } + if (dvalue > pow(2.0, 15.0) - 1.0) { + dvalue = pow(2.0, 15.0) - 1.0; + } + ulong uivalue = (ulong)dvalue; + uchar lsb = uivalue & 0x7f; + uchar msb = (uivalue >> 7) & 0x7f; + push_back(0xe0 | (0x7f & channel)); + push_back(lsb); + push_back(msb); +} + + + ///////////////////////////// // // MidiMessage::makeSustain -- Create a sustain pedal message. @@ -1999,8 +2056,8 @@ void MidiMessage::makeSysExMessage(const std::vector& data) { int msize = endindex - startindex + 2; std::vector vlv = intToVlv(msize); - for (int i=0; i<(int)vlv.size(); i++) { - this->push_back(vlv[i]); + for (uchar item : vlv) { + this->push_back(item); } for (int i=startindex; i<=endindex; i++) { this->push_back(data.at(i)); @@ -2095,18 +2152,18 @@ void MidiMessage::makeMts2_KeyTuningsBySemitone(std::vector vlv = intToVlv((int)mapping.size()); - for (int i=0; i<(int)vlv.size(); i++) { - data.push_back(vlv[i]); + for (uchar item : vlv) { + data.push_back(item); } - for (int i=0; i<(int)mapping.size(); i++) { - int keynum = mapping[i].first; + for (auto &item : mapping) { + int keynum = item.first; if (keynum < 0) { keynum = 0; } else if (keynum > 127) { keynum = 127; } data.push_back((uchar)keynum); - double semitones = mapping[i].second; + double semitones = item.second; int sint = (int)semitones; if (sint < 0) { sint = 0; @@ -2120,8 +2177,8 @@ void MidiMessage::makeMts2_KeyTuningsBySemitone(std::vector> 7) & 0x7f; data.push_back(msb); data.push_back(lsb); - } - this->makeSysExMessage(data); + } + this->makeSysExMessage(data); } @@ -2204,8 +2261,8 @@ void MidiMessage::makeTemperamentBad(double maxDeviationCents, int referencePitc maxDeviationCents = 100.0; } std::vector temperament(12); - for (int i=0; i<(int)temperament.size(); i++) { - temperament[i] = ((rand() / (double)RAND_MAX) * 2.0 - 1.0) * maxDeviationCents; + for (double &item : temperament) { + item = ((rand() / (double)RAND_MAX) * 2.0 - 1.0) * maxDeviationCents; } this->makeMts9_TemperamentByCentsDeviationFromET(temperament, referencePitchClass, channelMask); } @@ -2294,6 +2351,30 @@ void MidiMessage::makeTemperamentMeantoneCommaHalf(int referencePitchClass, int } + +////////////////////////////// +// +// operator<<(MidiMessage) -- Print MIDI messages as text. 0x80 and above +// are printed as hex, below as dec (will look strange for meta messages +// and system exclusives which could be dealt with later). +// + +std::ostream& operator<<(std::ostream& out, MidiMessage& message) { + for (int i=0; i<(int)message.size(); i++) { + if (message[i] >= 0x80) { + out << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)message[i]; + out << std::dec << std::setw(0) << std::setfill(' '); + } else { + out << (int)message[i]; + } + if (i<(int)message.size() - 1) { + out << ' '; + } + } + return out; +} + + } // end namespace smf diff --git a/src/object.cpp b/src/object.cpp index 086e4589db2..d23e54181bf 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -28,7 +28,7 @@ #include "editorial.h" #include "featureextractor.h" #include "findfunctor.h" -#include "io.h" +#include "iobase.h" #include "keysig.h" #include "layer.h" #include "linkinginterface.h" diff --git a/src/options.cpp b/src/options.cpp index 0a24f1c16bd..86fd84f5c47 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -111,13 +111,11 @@ jsonxx::Object Option::ToJson() const const OptionBool *optBool = dynamic_cast(this); if (optBool) { - opt << "type" - << "bool"; + opt << "type" << "bool"; opt << "default" << optBool->GetDefault(); } else if (optDbl) { - opt << "type" - << "double"; + opt << "type" << "double"; jsonxx::Value value(optDbl->GetDefault()); value.precision_ = 2; opt << "default" << value; @@ -129,20 +127,17 @@ jsonxx::Object Option::ToJson() const opt << "max" << value; } else if (optInt) { - opt << "type" - << "int"; + opt << "type" << "int"; opt << "default" << optInt->GetDefault(); opt << "min" << optInt->GetMin(); opt << "max" << optInt->GetMax(); } else if (optString) { - opt << "type" - << "std::string"; + opt << "type" << "std::string"; opt << "default" << optString->GetDefault(); } else if (optArray) { - opt << "type" - << "array"; + opt << "type" << "array"; std::vector strValues = optArray->GetDefault(); std::vector::iterator strIter; jsonxx::Array values; @@ -152,8 +147,7 @@ jsonxx::Object Option::ToJson() const opt << "default" << values; } else if (optIntMap) { - opt << "type" - << "std::string-list"; + opt << "type" << "std::string-list"; opt << "default" << optIntMap->GetDefaultStrValue(); std::vector strValues = optIntMap->GetStrValues(false); std::vector::iterator strIter; @@ -1135,6 +1129,10 @@ Options::Options() m_scaleToPageSize.Init(false); this->Register(&m_scaleToPageSize, "scaleToPageSize", &m_general); + m_setLocale.SetInfo("Set the global locale", "Changes the global locale to C (this is not thread-safe)"); + m_setLocale.Init(false); + this->Register(&m_setLocale, "setLocale", &m_general); + m_showRuntime.SetInfo("Show runtime on CLI", "Display the total runtime on command-line"); m_showRuntime.Init(false); this->Register(&m_showRuntime, "showRuntime", &m_general); diff --git a/src/system.cpp b/src/system.cpp index 2a070dba54f..cbf3e6748f3 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -341,7 +341,7 @@ void System::AddToDrawingListIfNecessary(Object *object) else if (object->Is(DYNAM)) { Dynam *dynam = vrv_cast(object); assert(dynam); - if (dynam->GetEnd() || (dynam->GetNextLink() && (dynam->GetExtender() == BOOLEAN_true))) { + if ((dynam->GetEnd() || dynam->GetNextLink()) && (dynam->GetExtender() == BOOLEAN_true)) { this->AddToDrawingList(dynam); } } diff --git a/src/toolkit.cpp b/src/toolkit.cpp index 3552ff2279f..2ae7b97c19b 100644 --- a/src/toolkit.cpp +++ b/src/toolkit.cpp @@ -85,6 +85,8 @@ Toolkit::Toolkit(bool initFont) Toolkit::~Toolkit() { + this->ResetLocale(); + if (m_humdrumBuffer) { free(m_humdrumBuffer); m_humdrumBuffer = NULL; @@ -1136,6 +1138,8 @@ bool Toolkit::SetOptions(const std::string &jsonOptions) m_options->Sync(); + this->SetLocale(); + // Forcing font resource to be reset if the font is given in the options if (json.has("fontAddCustom")) { Resources &resources = m_doc.GetResourcesForModification(); @@ -2151,6 +2155,21 @@ std::string Toolkit::ConvertHumdrumToMIDI(const std::string &humdrumData) #endif } +void Toolkit::SetLocale() +{ + if (m_options->m_setLocale.GetValue() && !m_previousLocale) { + // Required for proper formatting, e.g., in StringFormat (see vrv.cpp) + m_previousLocale = std::locale::global(std::locale::classic()); + } +} + +void Toolkit::ResetLocale() +{ + if (m_previousLocale) { + std::locale::global(*m_previousLocale); + } +} + void Toolkit::InitClock() { #ifndef NO_RUNTIME diff --git a/tools/main.cpp b/tools/main.cpp index d30a41fca43..a57880eccb3 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -259,6 +259,8 @@ int main(int argc, char **argv) } options->Sync(); + toolkit.SetLocale(); + if (show_version) { display_version(); exit(0);