diff --git a/src/private/mx/impl/DirectionWriter.cpp b/src/private/mx/impl/DirectionWriter.cpp index dd3d523f..79e60869 100644 --- a/src/private/mx/impl/DirectionWriter.cpp +++ b/src/private/mx/impl/DirectionWriter.cpp @@ -469,6 +469,11 @@ void DirectionWriter::emitTempo(const api::TempoData &tempo, core::Direction &di return; } + if (tempo.isParenthetical != api::Bool::unspecified) + { + metronome.setParentheses(myConverter.convert(tempo.isParenthetical)); + } + core::DirectionType dt{}; dt.setChoice(core::DirectionTypeChoice::metronome(metronome)); addDirectionType(std::move(dt), direction); diff --git a/src/private/mx/impl/MetronomeReader.cpp b/src/private/mx/impl/MetronomeReader.cpp index 99eb5fcc..cc8591dc 100644 --- a/src/private/mx/impl/MetronomeReader.cpp +++ b/src/private/mx/impl/MetronomeReader.cpp @@ -30,6 +30,12 @@ api::TempoData MetronomeReader::getTempoData() const myOutTempoData = api::TempoData{}; // the old core's beatUnitPer is the new core's group; the old core's // noteRelationNote (metronome-note based) is group2 + if (myMetronome.parentheses().has_value()) + { + Converter converter; + myOutTempoData.isParenthetical = converter.convert(*myMetronome.parentheses()); + } + using FirstChoice = core::MetronomeChoice::Kind; const auto firstChoice = myBeatUnitPerOrNoteRelationNoteChoice.kind(); diff --git a/src/private/mxtest/api/MetronomeApiTest.cpp b/src/private/mxtest/api/MetronomeApiTest.cpp index 5f5c90a3..f83a5a9e 100644 --- a/src/private/mxtest/api/MetronomeApiTest.cpp +++ b/src/private/mxtest/api/MetronomeApiTest.cpp @@ -201,4 +201,33 @@ TEST(roundTripMetricModulation, MetronomeApi) T_END +TEST(roundTripParentheses, MetronomeApi) +{ + // must round-trip via TempoData::isParenthetical. + ScoreData score; + score.ticksPerQuarter = 100; + score.parts.emplace_back(); + auto &part = score.parts.back(); + part.measures.emplace_back(); + auto &measure = part.measures.back(); + measure.staves.emplace_back(); + auto &staff = measure.staves.back(); + staff.directions.emplace_back(); + auto &direction = staff.directions.back(); + direction.tempos.emplace_back(); + auto &tempo = direction.tempos.back(); + tempo.tempoType = TempoType::beatsPerMinute; + tempo.isParenthetical = Bool::yes; + tempo.beatsPerMinute.durationName = DurationName::quarter; + tempo.beatsPerMinute.beatsPerMinute = 100; + + auto actualScoreData = roundTrip(score); + + const auto &actualTempo = + actualScoreData.parts.back().measures.back().staves.back().directions.back().tempos.back(); + CHECK(actualTempo.isParenthetical == Bool::yes); +} + +T_END + #endif diff --git a/src/private/mxtest/api/roundtrip-baseline.txt b/src/private/mxtest/api/roundtrip-baseline.txt index 70314f43..6626069b 100644 --- a/src/private/mxtest/api/roundtrip-baseline.txt +++ b/src/private/mxtest/api/roundtrip-baseline.txt @@ -414,3 +414,8 @@ synthetic/non-arpeggiate.3.1.xml ksuite/k001a_Articulations.xml musuite/testNoteAttributes2.xml musuite/testNoteAttributes2_ref.xml + +# Unblocked by wiring TempoData::isParenthetical: the metronome parentheses +# attribute now round-trips. +lysuite/ly31c_MetronomeMarks.xml +musuite/testTempo1.xml