From 34e1467ca0384fa176dea61db8c00ec85ebc9646 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 08:48:04 +0100 Subject: [PATCH 1/7] Apply filters when processing pedals * const_cast should be avoided, but needs refactoring of GetTstampStaves --- src/midifunctor.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index 1ba9f2df13..128fa5dd5f 100644 --- a/src/midifunctor.cpp +++ b/src/midifunctor.cpp @@ -717,6 +717,19 @@ FunctorCode GenerateMIDIFunctor::VisitPedal(const Pedal *pedal) { if (!pedal->HasDir()) return FUNCTOR_CONTINUE; + // Check if the pedal applies to the staff filtered + if (this->GetFilters()) { + Pedal *nonConstPedal = const_cast(pedal); + Measure *measure = vrv_cast(nonConstPedal->GetFirstAncestor(MEASURE)); + assert(measure); + std::vector staffList = nonConstPedal->GetTstampStaves(measure, nonConstPedal); + bool applies = false; + for (Staff *staff : staffList) { + applies = (applies || this->GetFilters()->Apply(staff)); + } + if (!applies) return FUNCTOR_CONTINUE; + } + double pedalTime = pedal->GetStart()->GetAlignment()->GetTime().ToDouble() * SCORE_TIME_UNIT; double startTime = m_totalTime + pedalTime; int tpq = m_midiFile->getTPQ(); From 226fa1535c762cc70091252a76babc366db6e099 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 12:56:58 +0100 Subject: [PATCH 2/7] Add a flag to process pedals only once --- include/vrv/midifunctor.h | 3 +++ src/doc.cpp | 8 ++++++-- src/midifunctor.cpp | 22 ++++++++++++---------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/include/vrv/midifunctor.h b/include/vrv/midifunctor.h index 9e883a83d1..050a9fae72 100644 --- a/include/vrv/midifunctor.h +++ b/include/vrv/midifunctor.h @@ -299,6 +299,7 @@ class GenerateMIDIFunctor : public ConstFunctor { void SetTempoEventTicks(const std::set &ticks) { m_tempoEventTicks = ticks; } void SetTrack(int track) { m_midiTrack = track; } void SetTransSemi(int transSemi) { m_transSemi = transSemi; } + void SetControlEvents(bool controlEvents) { m_controlEvents = controlEvents; } ///@} /* @@ -372,6 +373,8 @@ class GenerateMIDIFunctor : public ConstFunctor { bool m_cueExclusion; // Tablature held notes indexed by (course - 1) std::vector m_heldNotes; + // A flag indicating we want to process control events + bool m_controlEvents; }; //---------------------------------------------------------------------------- diff --git a/src/doc.cpp b/src/doc.cpp index 83fefeb500..92f991fd1f 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -522,8 +522,12 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) GenerateMIDIFunctor generateScoreDefMIDI(midiFile); generateScoreDefMIDI.SetChannel(midiChannel); generateScoreDefMIDI.SetTrack(midiTrack); + scoreDef->Process(generateScoreDefMIDI); + GenerateMIDIFunctor generateMIDI(midiFile); + generateMIDI.SetControlEvents(true); + for (auto &layers : staves.second.child) { filters.Clear(); // Create ad comparison object for each type / @n @@ -531,8 +535,6 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) AttNIntegerComparison matchLayer(LAYER, layers.first); filters.Add(&matchStaff); filters.Add(&matchLayer); - - GenerateMIDIFunctor generateMIDI(midiFile); generateMIDI.SetFilters(&filters); generateMIDI.SetChannel(midiChannel); @@ -548,6 +550,8 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) this->Process(generateMIDI); tempoEventTicks = generateMIDI.GetTempoEventTicks(); + // Process them only once per staff + generateMIDI.SetControlEvents(false); } } midiFile->sortTracks(); diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index 128fa5dd5f..0135703859 100644 --- a/src/midifunctor.cpp +++ b/src/midifunctor.cpp @@ -368,6 +368,7 @@ GenerateMIDIFunctor::GenerateMIDIFunctor(smf::MidiFile *midiFile) : ConstFunctor m_lastNote = NULL; m_accentedGraceNote = false; m_cueExclusion = false; + m_controlEvents = false; } FunctorCode GenerateMIDIFunctor::VisitBeatRpt(const BeatRpt *beatRpt) @@ -717,18 +718,19 @@ FunctorCode GenerateMIDIFunctor::VisitPedal(const Pedal *pedal) { if (!pedal->HasDir()) return FUNCTOR_CONTINUE; + // Check the functor flag - filters should always be there, but just in case we can the call + if (!m_controlEvents || !this->GetFilters()) return FUNCTOR_CONTINUE; + // Check if the pedal applies to the staff filtered - if (this->GetFilters()) { - Pedal *nonConstPedal = const_cast(pedal); - Measure *measure = vrv_cast(nonConstPedal->GetFirstAncestor(MEASURE)); - assert(measure); - std::vector staffList = nonConstPedal->GetTstampStaves(measure, nonConstPedal); - bool applies = false; - for (Staff *staff : staffList) { - applies = (applies || this->GetFilters()->Apply(staff)); - } - if (!applies) return FUNCTOR_CONTINUE; + Pedal *nonConstPedal = const_cast(pedal); + Measure *measure = vrv_cast(nonConstPedal->GetFirstAncestor(MEASURE)); + assert(measure); + std::vector staffList = nonConstPedal->GetTstampStaves(measure, nonConstPedal); + bool applies = false; + for (Staff *staff : staffList) { + applies = (applies || this->GetFilters()->Apply(staff)); } + if (!applies) return FUNCTOR_CONTINUE; double pedalTime = pedal->GetStart()->GetAlignment()->GetTime().ToDouble() * SCORE_TIME_UNIT; double startTime = m_totalTime + pedalTime; From 1e3fc62d4c6943ca0e5eadef0b02968da1716c9f Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 13:09:46 +0100 Subject: [PATCH 3/7] Remove const_cast --- src/midifunctor.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index 0135703859..e4819ffefe 100644 --- a/src/midifunctor.cpp +++ b/src/midifunctor.cpp @@ -722,12 +722,11 @@ FunctorCode GenerateMIDIFunctor::VisitPedal(const Pedal *pedal) if (!m_controlEvents || !this->GetFilters()) return FUNCTOR_CONTINUE; // Check if the pedal applies to the staff filtered - Pedal *nonConstPedal = const_cast(pedal); - Measure *measure = vrv_cast(nonConstPedal->GetFirstAncestor(MEASURE)); + const Measure *measure = vrv_cast(pedal->GetFirstAncestor(MEASURE)); assert(measure); - std::vector staffList = nonConstPedal->GetTstampStaves(measure, nonConstPedal); + std::vector staffList = pedal->GetTstampStaves(measure, pedal); bool applies = false; - for (Staff *staff : staffList) { + for (const Staff *staff : staffList) { applies = (applies || this->GetFilters()->Apply(staff)); } if (!applies) return FUNCTOR_CONTINUE; From 33f1191d7cb04878b481fba6ec435567aa4bc6ab Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 17:33:21 +0100 Subject: [PATCH 4/7] Keep functor variable within layer loop --- src/doc.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/doc.cpp b/src/doc.cpp index 92f991fd1f..c7d562d941 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -525,8 +525,7 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) scoreDef->Process(generateScoreDefMIDI); - GenerateMIDIFunctor generateMIDI(midiFile); - generateMIDI.SetControlEvents(true); + bool controlEvents = true; for (auto &layers : staves.second.child) { filters.Clear(); @@ -535,6 +534,8 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) AttNIntegerComparison matchLayer(LAYER, layers.first); filters.Add(&matchStaff); filters.Add(&matchLayer); + + GenerateMIDIFunctor generateMIDI(midiFile); generateMIDI.SetFilters(&filters); generateMIDI.SetChannel(midiChannel); @@ -545,13 +546,14 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) generateMIDI.SetCurrentTempo(tempo); generateMIDI.SetDeferredNotes(initMIDI.GetDeferredNotes()); generateMIDI.SetCueExclusion(this->GetOptions()->m_midiNoCue.GetValue()); + generateMIDI.SetControlEvents(controlEvents); // LogDebug("Exporting track %d ----------------", midiTrack); this->Process(generateMIDI); tempoEventTicks = generateMIDI.GetTempoEventTicks(); // Process them only once per staff - generateMIDI.SetControlEvents(false); + controlEvents = false; } } midiFile->sortTracks(); From 0baf87067df323e5c19ae918bf22e031a806bba3 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 17:36:38 +0100 Subject: [PATCH 5/7] Fix formatting --- src/doc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc.cpp b/src/doc.cpp index c7d562d941..51f45825ac 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -534,7 +534,7 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) AttNIntegerComparison matchLayer(LAYER, layers.first); filters.Add(&matchStaff); filters.Add(&matchLayer); - + GenerateMIDIFunctor generateMIDI(midiFile); generateMIDI.SetFilters(&filters); From b7c07cc254b26048d90dc8a11a6f5ab676b076e7 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 9 Dec 2024 17:57:48 +0100 Subject: [PATCH 6/7] Correct comment --- src/midifunctor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index e4819ffefe..6cc697cf00 100644 --- a/src/midifunctor.cpp +++ b/src/midifunctor.cpp @@ -718,7 +718,7 @@ FunctorCode GenerateMIDIFunctor::VisitPedal(const Pedal *pedal) { if (!pedal->HasDir()) return FUNCTOR_CONTINUE; - // Check the functor flag - filters should always be there, but just in case we can the call + // Check the functor flag - filters should always be there, but just in case we change how it is calle if (!m_controlEvents || !this->GetFilters()) return FUNCTOR_CONTINUE; // Check if the pedal applies to the staff filtered From 1e807987e870544e07803390cebae68f37acdfe7 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 10 Dec 2024 11:13:33 +0100 Subject: [PATCH 7/7] Update src/midifunctor.cpp Co-authored-by: Andrew Hankinson --- src/midifunctor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index 6cc697cf00..149d75fc31 100644 --- a/src/midifunctor.cpp +++ b/src/midifunctor.cpp @@ -718,7 +718,7 @@ FunctorCode GenerateMIDIFunctor::VisitPedal(const Pedal *pedal) { if (!pedal->HasDir()) return FUNCTOR_CONTINUE; - // Check the functor flag - filters should always be there, but just in case we change how it is calle + // Check the functor flag - filters should always be there, but just in case we change how it is called if (!m_controlEvents || !this->GetFilters()) return FUNCTOR_CONTINUE; // Check if the pedal applies to the staff filtered