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..51f45825ac 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -522,8 +522,11 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile) GenerateMIDIFunctor generateScoreDefMIDI(midiFile); generateScoreDefMIDI.SetChannel(midiChannel); generateScoreDefMIDI.SetTrack(midiTrack); + scoreDef->Process(generateScoreDefMIDI); + bool controlEvents = true; + for (auto &layers : staves.second.child) { filters.Clear(); // Create ad comparison object for each type / @n @@ -543,11 +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 + controlEvents = false; } } midiFile->sortTracks(); diff --git a/src/midifunctor.cpp b/src/midifunctor.cpp index 1ba9f2df13..149d75fc31 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,6 +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 change how it is called + if (!m_controlEvents || !this->GetFilters()) return FUNCTOR_CONTINUE; + + // Check if the pedal applies to the staff filtered + const Measure *measure = vrv_cast(pedal->GetFirstAncestor(MEASURE)); + assert(measure); + std::vector staffList = pedal->GetTstampStaves(measure, pedal); + bool applies = false; + for (const 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();