diff --git a/.github/workflows/build-macos-artifact.yml b/.github/workflows/build-macos-artifact.yml index d3ae9cc6..4cf8ef07 100644 --- a/.github/workflows/build-macos-artifact.yml +++ b/.github/workflows/build-macos-artifact.yml @@ -37,7 +37,7 @@ jobs: # shell: bash FOO # working-directory: build # cd build; cmake --build . - cd build ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . + cd build ; uname -a ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . # - name: Setup TeX Live # uses: teatimeguest/setup-texlive-action@v4 diff --git a/.github/workflows/build-ubuntu-20.04-artifact.yml b/.github/workflows/build-ubuntu-20.04-artifact.yml index a1cb1b7f..16dc04b5 100644 --- a/.github/workflows/build-ubuntu-20.04-artifact.yml +++ b/.github/workflows/build-ubuntu-20.04-artifact.yml @@ -31,7 +31,7 @@ jobs: - name: Build MusicFormats for Ubuntu run: # cd build; cmake --build . - cd build ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . + cd build ; uname -a ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . - name: Upload libraries and executables for Ubuntu uses: actions/upload-artifact@v4 diff --git a/.github/workflows/build-ubuntu-artifact.yml b/.github/workflows/build-ubuntu-artifact.yml index ae858214..b4a92d87 100644 --- a/.github/workflows/build-ubuntu-artifact.yml +++ b/.github/workflows/build-ubuntu-artifact.yml @@ -33,7 +33,7 @@ jobs: # shell: bash # working-directory: build # cd build; cmake --build . - cd build ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . + cd build ; uname -a ; cmake -S . -B . . ; ls -salR . ; make ; ls -salR . - name: Upload libraries and executables for Ubuntu uses: actions/upload-artifact@v4 diff --git a/.github/workflows/build-windows-artifact.yml b/.github/workflows/build-windows-artifact.yml index 0f63f595..c6f8d624 100644 --- a/.github/workflows/build-windows-artifact.yml +++ b/.github/workflows/build-windows-artifact.yml @@ -37,7 +37,7 @@ jobs: # working-directory: build # cd build; cmake --build . # cd build ; cmake . ; ls D:/a/musicformats/musicformats/build ; make - cd build ; cmake --help ; cmake -S . -B . . ; ls . ; make ; ls . + cd build ; uname -a ; cmake --help ; cmake -S . -B . . ; ls . ; make ; ls . - name: Upload libraries and executables for Windows diff --git a/MusicFormatsVersionDate.txt b/MusicFormatsVersionDate.txt index 6b3f14b5..5e623699 100644 --- a/MusicFormatsVersionDate.txt +++ b/MusicFormatsVersionDate.txt @@ -1 +1 @@ -December 09, 2024 +December 11, 2024 diff --git a/MusicFormatsVersionNumber.txt b/MusicFormatsVersionNumber.txt index 8830886a..45ff4944 100644 --- a/MusicFormatsVersionNumber.txt +++ b/MusicFormatsVersionNumber.txt @@ -1 +1 @@ -v0.9.72-step-9 \ No newline at end of file +v0.9.72-step-10 \ No newline at end of file diff --git a/include/MusicFormatsVersionDate.h b/include/MusicFormatsVersionDate.h index b0da6998..742bdbdb 100644 --- a/include/MusicFormatsVersionDate.h +++ b/include/MusicFormatsVersionDate.h @@ -1 +1 @@ -#define MUSICFORMATS_VERSION_DATE "December 08, 2024" +#define MUSICFORMATS_VERSION_DATE "December 09, 2024" diff --git a/include/MusicFormatsVersionNumber.h b/include/MusicFormatsVersionNumber.h index 6eed0bd2..e7bff476 100644 --- a/include/MusicFormatsVersionNumber.h +++ b/include/MusicFormatsVersionNumber.h @@ -1 +1 @@ -#define MUSICFORMATS_VERSION_NUMBER "v0.9.72-step-8" +#define MUSICFORMATS_VERSION_NUMBER "v0.9.72-step-9" diff --git a/include/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h b/include/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h index 41807d2b..0e86e0eb 100644 --- a/include/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h +++ b/include/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h @@ -518,17 +518,8 @@ class mxsr2msrPendingTupletStop : public smartable private: -// // private methods -// // ------------------------------------------------------ -// -// void displayTupletsStack ( -// const std::string& context); -// -// void handleTupletsPendingOnTupletsStack ( -// int inputLineNumber); -// -// void displayLastHandledTupletInVoiceMap ( -// const std::string& header); + // private methods + // ------------------------------------------------------ }; typedef SMARTP S_mxsr2msrPendingTupletStop; EXP std::ostream& operator << (std::ostream& os, const mxsr2msrPendingTupletStop& elt); @@ -1160,6 +1151,9 @@ class EXP mxsr2msrSkeletonBuilder : // so they aref kept aside until they are handled std::list fPendingTupletsList; + void handleChordMemberNoteIfRelevant ( + int inputStartLineNumber); + void displayPendingTupletsList ( const std::string& title, int inputStartLineNumber) const; diff --git a/include/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h b/include/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h index 20f83196..b8d8254f 100644 --- a/include/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h +++ b/include/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h @@ -2598,6 +2598,7 @@ class EXP mxsr2msrSkeletonPopulator : Bool fCurrentNoteBelongsToATuplet; Bool fATupletIsEnding; + int fEndingTupletNumber; // a tuplet stop may occur in a chord before the latter's last note, hence: Bool fThereIsAPendingTupletStop; // CHORD_TUP diff --git a/include/representations/mxsr/mxsrEvents.h b/include/representations/mxsr/mxsrEvents.h index d073930b..67ef1112 100644 --- a/include/representations/mxsr/mxsrEvents.h +++ b/include/representations/mxsr/mxsrEvents.h @@ -550,12 +550,14 @@ class EXP mxsrEventsCollection : public smartable int getCurrentEventSequentialNumber () const { return fCurrentEventSequentialNumber; } + // implicit initial forward repeat void setThereIsAnImplicitInitialForwardRepeat () { fThereIsAnImplicitInitialForwardRepeat = true; } Bool getInitialRepeatBarIsImplicit () const { return fThereIsAnImplicitInitialForwardRepeat; } + // staff change events const std::map & getStaffChangeTakeOffsMap () const { return fStaffChangeTakeOffsMap; } @@ -568,14 +570,25 @@ class EXP mxsrEventsCollection : public smartable getStaffChangeEventsList () const { return fStaffChangeEventsList; } + // chord events const std::map & getChordsEventMap () const { return fChordsEventsMap; } + // tuplet events + const std::list & + getTupletsBeginsList () const + { return fTupletsBeginsList; } + + const std::list & + getTupletsEndsList () const + { return fTupletsEndsList; } + const std::multimap & getTupletsEventMultiMap () const { return fTupletsEventsMultiMap; } + // all events const std::list & getAllEventsList () const { return fAllEventsList; } @@ -615,17 +628,25 @@ class EXP mxsrEventsCollection : public smartable int eventInputStartLineNumber, int eventInputEndLineNumber); - void registerTupletEvent ( + void registerTupletBeginEvent ( + int noteSequentialNumber, + int noteEventStaffNumber, + int noteEventVoiceNumber, + int tupletNumber, + int eventInputStartLineNumber, + int eventInputEndLineNumber); + + void registerTupletEndEvent ( int noteSequentialNumber, int noteEventStaffNumber, int noteEventVoiceNumber, - mxsrTupletEventKind tupletEventKind, int tupletNumber, int eventInputStartLineNumber, int eventInputEndLineNumber); void sortTheMxsrEventsLists (); + // staff changes S_mxsrStaffChangeEvent fetchStaffChangeTakeOffAtNoteSequentialNumber ( int noteSequentialNumber) const; @@ -639,15 +660,13 @@ class EXP mxsrEventsCollection : public smartable int noteSequentialNumber) const; // tuplet events -// S_mxsrTupletEvent fetchTupletEventAtNoteSequentialNumber ( -// int noteSequentialNumber) const; + void fetchTupletBeginsList ( + int noteSequentialNumber, + std::list & collectedBeginsList); - void fetchTupletEventsRange ( - int noteSequentialNumber, - std::multimap ::const_iterator& - firstInRange, - std::multimap ::const_iterator& - lastInRange) const; + void fetchTupletEndsList ( + int noteSequentialNumber, + std::list & collectedEndsList); private: @@ -670,6 +689,12 @@ class EXP mxsrEventsCollection : public smartable void printChordEvents (std::ostream& os) const; void printTupletEvents (std::ostream& os) const; + void printTupletEventsList ( + std::ostream& os, + const std::list & tupletsList, + const std::string& context, + int inputLineNumber) const; + private: // private fields @@ -681,8 +706,9 @@ class EXP mxsrEventsCollection : public smartable // initial repeat bar Bool fThereIsAnImplicitInitialForwardRepeat; - // there can be two staff changes per note, - // hence these two maps, indexed by note sequential number + // staff changes events + // there can be two staff changes per note, + // hence these two maps, indexed by note sequential number std::map fStaffChangeTakeOffsMap, fStaffChangeLandingsMap; @@ -690,18 +716,24 @@ class EXP mxsrEventsCollection : public smartable std::list fStaffChangeEventsList; - // there can be only one chord begin or end per note, - // hence this map, indexed by note sequential number + // chords events + // there can be only one chord begin or end per note, + // hence this map, indexed by note sequential number std::map fChordsEventsMap; - // there can be several tuplets start and/or stop events per note, - // hence this multimap, indexed by note sequential number, + // tuplet events + // there can be several tuplets start and/or stop events per note, + // hence this multimap, indexed by note sequential number, + + std::list + fTupletsBeginsList, + fTupletsEndsList; std::multimap fTupletsEventsMultiMap; - // all events list + // all events std::list fAllEventsList; }; diff --git a/musicxmlfiles/tuplets/ChordsInTupletWithTupletStopNotOnTheChordLastNoteB.xml b/musicxmlfiles/tuplets/ChordsInTupletWithTupletStopNotOnTheChordLastNoteB.xml deleted file mode 100644 index 1209843a..00000000 --- a/musicxmlfiles/tuplets/ChordsInTupletWithTupletStopNotOnTheChordLastNoteB.xml +++ /dev/null @@ -1,211 +0,0 @@ - - - - Chords In Tuplet With Tuplet Stop Not On The Chord Last Note - - - MuseScore 4.2.1 - 2024-03-28 - - - - - - - - - - 7.05556 - 40 - - - 1683.78 - 1190.55 - - 56.6929 - 56.6929 - 56.6929 - 113.386 - - - 56.6929 - 56.6929 - 56.6929 - 113.386 - - - - 1.8 - 5.5 - 5 - 4.5 - 1 - 1 - 1.1 - 1 - 1.6 - 1.1 - 1.1 - 2.1 - 0.5 - 1.1 - 1 - 2.1 - 0.5 - 1 - 1.2 - 70 - 70 - 49 - - - - - - - title - Chords In Tuplet With Tuplet Stop Not On The Chord Last Note - - - - - - - keyboard.piano.grand - - - - 1 - 1 - 78.7402 - 0 - - - - - - - - - 50.00 - 821.77 - - 170.00 - - - - 3 - - 0 - - - - G - 2 - - - - - D - 5 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - - - - - F - 5 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - G - 4 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - - B - 4 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - C - 4 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - - - - - E - 4 - - 2 - 1 - quarter - - 3 - 2 - - down - - - - 6 - 1 - half - - - - diff --git a/src/MusicFormatsVersionDate.h b/src/MusicFormatsVersionDate.h index 742bdbdb..86c803c2 100644 --- a/src/MusicFormatsVersionDate.h +++ b/src/MusicFormatsVersionDate.h @@ -1 +1 @@ -#define MUSICFORMATS_VERSION_DATE "December 09, 2024" +#define MUSICFORMATS_VERSION_DATE "December 11, 2024" diff --git a/src/MusicFormatsVersionNumber.h b/src/MusicFormatsVersionNumber.h index e7bff476..52fb8b9f 100644 --- a/src/MusicFormatsVersionNumber.h +++ b/src/MusicFormatsVersionNumber.h @@ -1 +1 @@ -#define MUSICFORMATS_VERSION_NUMBER "v0.9.72-step-9" +#define MUSICFORMATS_VERSION_NUMBER "v0.9.72-step-10" diff --git a/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.cpp b/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.cpp index 2ac03816..6d63993e 100644 --- a/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.cpp +++ b/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.cpp @@ -2452,6 +2452,84 @@ S_msrVoice mxsr2msrSkeletonBuilder::createPartFiguredBassVoiceIfNotYetDone ( } //________________________________________________________________________ +void mxsr2msrSkeletonBuilder::handleChordMemberNoteIfRelevant ( + int inputStartLineNumber) +{ + // an end of measure enforces the end of a chord or tuplets CHORD_TUP + // the current note is then the one preceding the end of measure + +#ifdef MF_TRACE_IS_ENABLED + if (gTraceOahGroup->getTraceMxsrEvents ()) { + gLog << + "===> visitEnd (S_measure& elt)" << + ", fCurrentNoteStartInputLineNumber: " << + fCurrentNoteStartInputLineNumber << + + ", currentEventSequentialNumber: " << + fResultingEventsCollection.getCurrentEventSequentialNumber () << + + ", fCurrentNoteSequentialNumber: " << + fCurrentNoteSequentialNumber << + ", fPreviousNoteSequentialNumber: " << + fPreviousNoteSequentialNumber << + + ", fCurrentNoteBelongsToAChord: " << + fCurrentNoteBelongsToAChord << + ", fPreviousNoteBelongsToAChord: " << + fPreviousNoteBelongsToAChord << + ", fPreviousNoteIsATakeOffCandidate: " << + fPreviousNoteIsATakeOffCandidate << + ", line " << inputStartLineNumber << + std::endl; + + if (gTraceOahGroup->getTraceTupletsBasics ()) { + gLog << + ", fCurrentTupletNumber: " << + fCurrentTupletNumber << + std::endl; + + displayPendingTupletsStopsMap ( + "=====> visitEnd (S_measure& elt)", + fCurrentNoteStartInputLineNumber); + } + } +#endif // MF_TRACE_IS_ENABLED + + // Q_MEASURE + + // register the chord end event if any, before pending tuplets stops if any + if (fCurrentNoteBelongsToAChord) { + // the note before the measure end is the last one of the chord + // it is still the current note + + fResultingEventsCollection.registerChordEvent ( + fCurrentNoteSequentialNumber, + fCurrentNoteStaffNumber, + fCurrentNoteVoiceNumber, + mxsrChordEventKind::kEventChordEnd, + fCurrentNoteStartInputLineNumber, + fCurrentNoteEndInputLineNumber); + } + + else { +// // is this note the one that follows the last one of a chord? +// if (fPreviousNoteBelongsToAChord) { +// // this the note after the last one of the chord +// // we're one note late! +// fResultingEventsCollection.registerChordEndEvent ( +// fPreviousNoteSequentialNumber, +// fCurrentNoteSequentialNumber, +// fCurrentNoteStaffNumber, +// fCurrentNoteVoiceNumber, +// fPreviousNoteStartInputLineNumber, +// fPreviousNoteEndInputLineNumber, +// fCurrentNoteVoiceNumber); +// } +// else { +// } + } +} + void mxsr2msrSkeletonBuilder::displayPendingTupletsList ( const std::string& title, int inputStartLineNumber) const @@ -2592,11 +2670,10 @@ void mxsr2msrSkeletonBuilder::handePendingTupletsStopsIfAny ( // register the tuplet end event with the corresponding info, // except the input start end and end line numbers, // which are those of the current note - fResultingEventsCollection.registerTupletEvent ( + fResultingEventsCollection.registerTupletEndEvent ( fCurrentNoteSequentialNumber, // was 0 temporarily pendingTupletStop->getStaffNumber (), pendingTupletStop->getVoiceNumber (), - mxsrTupletEventKind::kEventTupletEnd, pendingTupletStop->getTupletNumber (), inputStartLineNumber, inputStartLineNumber); // should be inputEndLineNumber JMI v0.9.72 @@ -5009,85 +5086,15 @@ void mxsr2msrSkeletonBuilder::visitEnd (S_measure& elt) } #endif // MF_TRACE_IS_ENABLED - // an end of measure enforces the end of a chord or tuplets CHORD_TUP - // the current note is then the one preceding the end of measure - -#ifdef MF_TRACE_IS_ENABLED - if (gTraceOahGroup->getTraceMxsrEvents ()) { - gLog << - "===> visitEnd (S_measure& elt)" << - ", fCurrentNoteStartInputLineNumber: " << - fCurrentNoteStartInputLineNumber << - - ", currentEventSequentialNumber: " << - fResultingEventsCollection.getCurrentEventSequentialNumber () << - - ", fCurrentNoteSequentialNumber: " << - fCurrentNoteSequentialNumber << - ", fPreviousNoteSequentialNumber: " << - fPreviousNoteSequentialNumber << - - ", fCurrentNoteBelongsToAChord: " << - fCurrentNoteBelongsToAChord << - ", fPreviousNoteBelongsToAChord: " << - fPreviousNoteBelongsToAChord << - ", fPreviousNoteIsATakeOffCandidate: " << - fPreviousNoteIsATakeOffCandidate << - ", line " << elt->getInputStartLineNumber () << - std::endl; - - if (gTraceOahGroup->getTraceTupletsBasics ()) { - gLog << - ", fCurrentTupletNumber: " << - fCurrentTupletNumber << - std::endl; - - displayPendingTupletsStopsMap ( - "=====> visitEnd (S_measure& elt)", - fCurrentNoteStartInputLineNumber); - } - } -#endif // MF_TRACE_IS_ENABLED - - // Q_MEASURE - - // register the chord end event if any, before pending tuplets stops if any - if (fCurrentNoteBelongsToAChord) { - // the note before the measure end is the last one of the chord - // it is still the current note - - fResultingEventsCollection.registerChordEvent ( - fCurrentNoteSequentialNumber, - fCurrentNoteStaffNumber, - fCurrentNoteVoiceNumber, - mxsrChordEventKind::kEventChordEnd, - fCurrentNoteStartInputLineNumber, - fCurrentNoteEndInputLineNumber); - } - - else { -// // is this note the one that follows the last one of a chord? -// if (fPreviousNoteBelongsToAChord) { -// // this the note after the last one of the chord -// // we're one note late! -// fResultingEventsCollection.registerChordEndEvent ( -// fPreviousNoteSequentialNumber, -// fCurrentNoteSequentialNumber, -// fCurrentNoteStaffNumber, -// fCurrentNoteVoiceNumber, -// fPreviousNoteStartInputLineNumber, -// fPreviousNoteEndInputLineNumber, -// fCurrentNoteVoiceNumber); -// } -// else { -// } - } + handleChordMemberNoteIfRelevant ( + elt->getInputStartLineNumber () ); // Q_MEASURE - // handle pending tuplet stops if any, after the chord end if any + // handle pending tuplet stops if any, after the chord end if any, + // which occurs on the current notes, i.e. the one at the end of the measure JMI v0.9.72 handePendingTupletsStopsIfAny ( - fPreviousNoteEndInputLineNumber); + fCurrentNoteStartInputLineNumber); --gIndenter; } @@ -5481,6 +5488,18 @@ void mxsr2msrSkeletonBuilder::handleTupletEventIfAny () } #endif // MF_TRACE_IS_ENABLED + std::list collectedBeginsList; + + fResultingEventsCollection.fetchTupletBeginsList ( + fCurrentNoteStartInputLineNumber, + collectedBeginsList); + + std::list collectedEndsList; + + fResultingEventsCollection.fetchTupletBeginsList ( + fCurrentNoteStartInputLineNumber, + collectedEndsList); + for ( std::list ::const_iterator it = fPendingTupletsList.cbegin (); it != fPendingTupletsList.cend (); @@ -5521,9 +5540,7 @@ void mxsr2msrSkeletonBuilder::handleTupletEventIfAny () // handle the values switch (tupletKind) { case msrTupletTypeKind::kTupletTypeNone: - // handle pending tuplet stops if any -// handePendingTupletsStopsIfAny ( // JMI ??? v0.9.72 -// fCurrentNoteEndInputLineNumber); + // nothing to do // JMI v0.9.72 break; case msrTupletTypeKind::kTupletTypeStart: @@ -5533,11 +5550,10 @@ void mxsr2msrSkeletonBuilder::handleTupletEventIfAny () fCurrentNoteEndInputLineNumber); // register the new tuplet begin event upon the current note at once - fResultingEventsCollection.registerTupletEvent ( + fResultingEventsCollection.registerTupletBeginEvent ( fCurrentNoteSequentialNumber, fCurrentNoteStaffNumber, fCurrentNoteVoiceNumber, - mxsrTupletEventKind::kEventTupletBegin, tupletNumber, noteInputStartLineNumber, fCurrentNoteEndInputLineNumber); @@ -5555,7 +5571,7 @@ void mxsr2msrSkeletonBuilder::handleTupletEventIfAny () // it will be set when the tuplet stop event is created // the temporary values will be ignored when the actual ones become known later, - // when the tuplet stop event is created by registerTupletEvent() + // when the tuplet stop event is created by registerTupletEndEvent() fPendingTupletsStopsMap.insert ( std::make_pair ( fCurrentNoteSequentialNumber, @@ -5885,7 +5901,7 @@ void mxsr2msrSkeletonBuilder::visitStart (S_tuplet& elt) // there can be multiple upon a given note, // so we put them aside fPendingTupletsList.push_back ( - mxsrTuplet::create ( + mxsrTuplet::create ( // temporary, fCurrentNoteStartInputLineNumber, fCurrentTupletNumber, tupletTypeKind)); diff --git a/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h b/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h index 41807d2b..0e86e0eb 100644 --- a/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h +++ b/src/passes/mxsr2msr/mxsr2msrSkeletonBuilder.h @@ -518,17 +518,8 @@ class mxsr2msrPendingTupletStop : public smartable private: -// // private methods -// // ------------------------------------------------------ -// -// void displayTupletsStack ( -// const std::string& context); -// -// void handleTupletsPendingOnTupletsStack ( -// int inputLineNumber); -// -// void displayLastHandledTupletInVoiceMap ( -// const std::string& header); + // private methods + // ------------------------------------------------------ }; typedef SMARTP S_mxsr2msrPendingTupletStop; EXP std::ostream& operator << (std::ostream& os, const mxsr2msrPendingTupletStop& elt); @@ -1160,6 +1151,9 @@ class EXP mxsr2msrSkeletonBuilder : // so they aref kept aside until they are handled std::list fPendingTupletsList; + void handleChordMemberNoteIfRelevant ( + int inputStartLineNumber); + void displayPendingTupletsList ( const std::string& title, int inputStartLineNumber) const; diff --git a/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.cpp b/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.cpp index 685968fd..364c0338 100644 --- a/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.cpp +++ b/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.cpp @@ -24211,7 +24211,7 @@ void mxsr2msrSkeletonPopulator::populateCurrentNoteBeforeItIsHandled ( displayStaffAndVoiceInformation ( fCurrentNote->getInputStartLineNumber (), - "mxsr2msrSkeletonPopulator::visitEnd (S_note& elt)"); + "populateCurrentNoteBeforeItIsHandled())"); } #endif // MF_TRACE_IS_ENABLED @@ -24615,7 +24615,6 @@ void mxsr2msrSkeletonPopulator::attachPendingGraceNotesGroupToNoteIfRelevant ( "+++++++++++++++++" << std::endl; - // // fetch note to attach to // JMI v0.9.67 // S_msrNote // noteToAttachTo = @@ -24712,7 +24711,7 @@ void mxsr2msrSkeletonPopulator::attachThePendingDalSegnosIfAny () void mxsr2msrSkeletonPopulator::handleStaffChangeTakeOffEventIfAny () { /* - Note 1: + Event 1: [StaffChangeEvent fEventInputStartLineNumber : L120 fEventSequentialNumber : E1 @@ -24722,7 +24721,9 @@ void mxsr2msrSkeletonPopulator::handleStaffChangeTakeOffEventIfAny () fStaffChangeEventKind : kEventStaffChangeTakeOff fTakeOffInputStartLineNumber : L120 fLandingInputStartLineNumber : L132 - staff number change : S2 ->> S1 + fTakeOffStaffNumber : S2 + fLandingStaffNumber : S1 + staff change : S2/V1 ->> S1/V1 ] */ @@ -24753,39 +24754,21 @@ void mxsr2msrSkeletonPopulator::handleStaffChangeTakeOffEventIfAny () if (fCurrentNoteStaffChangeTakeOff) { // there is a staff change landing #ifdef MF_TRACE_IS_ENABLED - gLog << - "There is a staff change handleStaffChangeTakeOffEventIfAny():" << - std::endl << - fCurrentNoteStaffChangeTakeOff << - "fCurrentRecipientStaffNumber: " << fCurrentRecipientStaffNumber << - std::endl << - std::endl; + if (gTraceOahGroup->getTraceStaffChangesBasics ()) { + std::stringstream ss; -// if (false && gTraceOahGroup->getTraceStaffChangesBasics ()) { -// std::stringstream ss; -// -// ss << -// "There is a staff change FII " << -// fCurrentNoteStaffChangeTakeOff->getStaffChangeEventKind () << -// " event at fCurrentNoteSequentialNumber: " << -// fCurrentNoteSequentialNumber << -// ": " << -// fCurrentNoteStaffChangeTakeOff->asString () << -// ", line " << -// fCurrentNoteStaffChangeTakeOff->getEventInputStartLineNumber (); -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -#endif // MF_TRACE_IS_ENABLED + ss << + "There is a staff change handleStaffChangeTakeOffEventIfAny():" << + '\n' << + fCurrentNoteStaffChangeTakeOff << + "fCurrentRecipientStaffNumber: " << fCurrentRecipientStaffNumber << + "\n\n"; -// fCurrentTakeOffStaffNumber = -// fCurrentNoteStaffChangeTakeOff-> -// getTakeOffStaffNumber (); -// fCurrentLandingStaffNumber = -// fCurrentNoteStaffChangeTakeOff-> -// getLandingStaffNumber (); + gWaeHandler->waeTrace ( + __FILE__, __LINE__, + ss.str ()); + } +#endif // MF_TRACE_IS_ENABLED int noteSequentialNumber = @@ -24848,13 +24831,6 @@ void mxsr2msrSkeletonPopulator::handleStaffChangeTakeOffEventIfAny () ss.str ()); } #endif // MF_TRACE_IS_ENABLED - -// // fetch the current note's staff -// S_msrStaff -// takeOffStaff = -// fCurrentPartStavesVector [takeOffStaffNumber], -// landingStaff = -// fCurrentPartStavesVector [landingStaffNumber]; // JMI v0.9.72 } fOnGoingStaffChange = true; @@ -25097,48 +25073,75 @@ void mxsr2msrSkeletonPopulator::populateCurrentChordFromNote ( } //______________________________________________________________________________ +// void mxsr2msrSkeletonPopulator::handleTupletEventIfAny () +// { +// fCurrentNoteChordEvent = +// fKnownEventsCollection. +// fetchChordEventAtNoteSequentialNumber ( +// fCurrentNoteSequentialNumber); +// +// if (fCurrentNoteChordEvent) { +// // there is a chord event +// switch (fCurrentNoteChordEvent->getChordEventKind ()) { +// case mxsrChordEventKind::kEventChord_NONE: +// // should not occur +// break; +// +// case mxsrChordEventKind::kEventChordBegin: +// fCurrentNoteBelongsToAChord = true; +// +// // create a chord +// fCurrentChord = +// msrChord::create ( +// fCurrentNoteChordEvent-> +// getEventInputStartLineNumber ()); +// +// // register it as not yet populated fron its first note +// fCurrentChordHasToBePopulatedFromItsFIrstNote = true; +// +// // append it to the current recipient staff +// fCurrentPartStaffVoicesMap +// [fCurrentRecipientStaffNumber][fCurrentNoteVoiceNumber]-> +// appendChordToVoice ( +// fCurrentChord); +// +// fOnGoingChord = true; +// break; +// +// case mxsrChordEventKind::kEventChordEnd: +// fCurrentNoteBelongsToAChord = true; +// break; +// } // switch +// } +// else { +// fCurrentNoteBelongsToAChord = fOnGoingChord; +// } +// } + void mxsr2msrSkeletonPopulator::handleTupletEventsIfAny () { /* - fTupletsEventsMultiMap: 4 elements, in note sequential number order - Note 2: + fTupletsBeginsList: 1 element, in note sequential number order + Note 1: [TupletEvent - fEventInputStartLineNumber : 99 + fEventInputStartLineNumber : 33 fEventSequentialNumber : E1 - fNoteSequentialNumber : N2 + fNoteSequentialNumber : N1 fNoteEventStaffNumber : S1 fNoteEventVoiceNumber : V1 fTupletEventKind : kEventTupletBegin fTupletNumber : T1 ] - Note 2: - [TupletEvent - fEventInputStartLineNumber : 99 - fEventSequentialNumber : E2 - fNoteSequentialNumber : N2 - fNoteEventStaffNumber : S1 - fNoteEventVoiceNumber : V1 - fTupletEventKind : kEventTupletBegin - fTupletNumber : T2 - ] - Note 4: - [TupletEvent - fEventInputStartLineNumber : 206 - fEventSequentialNumber : E3 - fNoteSequentialNumber : N4 - fNoteEventStaffNumber : S1 - fNoteEventVoiceNumber : V1 - fTupletEventKind : kEventTupletEnd - fTupletNumber : T2 - ] + -------- - Note 7: + fTupletsEndsList: 1 element, in note sequential number order + Note 2: [TupletEvent - fEventInputStartLineNumber : 206 - fEventSequentialNumber : E4 - fNoteSequentialNumber : N7 + fEventInputStartLineNumber : 59 + fEventSequentialNumber : E2 + fNoteSequentialNumber : N3 fNoteEventStaffNumber : S1 fNoteEventVoiceNumber : V1 fTupletEventKind : kEventTupletEnd @@ -25149,26 +25152,53 @@ void mxsr2msrSkeletonPopulator::handleTupletEventsIfAny () */ // fetch the tuplet events range upon this note if any - std::multimap ::const_iterator - firstTupletEventInRange, - lastTupletEventInRange; +// std::multimap ::const_iterator +// firstTupletEventInRange, +// lastTupletEventInRange; +// +// fKnownEventsCollection.fetchTupletEventsRange ( +// fCurrentNoteSequentialNumber, +// firstTupletEventInRange, +// lastTupletEventInRange); + +#ifdef MF_TRACE_IS_ENABLED + if (true || gTraceOahGroup->getTraceTupletsBasics ()) { + std::stringstream ss; + + ss << + "--------> handleTupletEventsIfAny()"; +// ", tupletEventKind: " << tupletEventKind << +// ", tupletNumber: " << tupletNumber << +// ", line " << tupletEvent->getEventInputStartLineNumber (); - fKnownEventsCollection.fetchTupletEventsRange ( + gWaeHandler->waeTrace ( + __FILE__, __LINE__, + ss.str ()); + } +#endif + + std::list tupletBeginsList; + + fKnownEventsCollection.fetchTupletBeginsList ( + fCurrentNoteSequentialNumber, + tupletBeginsList); + + std::list tupletEndsList; + + fKnownEventsCollection.fetchTupletEndsList ( fCurrentNoteSequentialNumber, - firstTupletEventInRange, - lastTupletEventInRange); + tupletEndsList); + +// printTupletEventsList ( +// gLog, +// noteSequentialNumber, +// collectedEndsList, +// "fetchTupletEndsList(), resultingEndsList:"); // is this note the last one in a tuplet ? fATupletIsEnding = false; - for ( - std::multimap ::const_iterator it = - firstTupletEventInRange; - it != lastTupletEventInRange; - ++it - ) { - S_mxsrTupletEvent tupletEvent = it->second; - + for (S_mxsrTupletEvent tupletEvent : tupletBeginsList) { mxsrTupletEventKind tupletEventKind = tupletEvent->getTupletEventKind (); @@ -25203,6 +25233,7 @@ void mxsr2msrSkeletonPopulator::handleTupletEventsIfAny () case mxsrTupletEventKind::kEventTupletEnd: fATupletIsEnding = true; + fEndingTupletNumber = tupletNumber; #ifdef MF_TRACE_IS_ENABLED if (gTraceOahGroup->getTraceTupletsBasics ()) { @@ -25254,7 +25285,7 @@ void mxsr2msrSkeletonPopulator::finalizeTupletIfAny ( voiceHandler-> finalizeTupletStackTopAndPopItFromTupletsStack ( inputLineNumber, - "visitEnd (S_note& elt)"); + "finalizeTupletIfAny()"); } else { std::stringstream ss; @@ -27460,6 +27491,10 @@ void mxsr2msrSkeletonPopulator::handleTupletMemberNote ( [fCurrentNoteStaffNumber][fCurrentNoteVoiceNumber]; switch (fCurrentTupletTypeKind) { + case msrTupletTypeKind::kTupletTypeNone: + // nothing to do JMI v0.9.72 + break; + case msrTupletTypeKind::kTupletTypeStart: { #ifdef MF_TRACE_IS_ENABLED @@ -27599,10 +27634,6 @@ void mxsr2msrSkeletonPopulator::handleTupletMemberNote ( "handleTupletMemberNote() 7"); } break; - - case msrTupletTypeKind::kTupletTypeNone: - // JMI v0.9.71 ??? - break; } // switch /* JMI ??? @@ -30779,148 +30810,6 @@ void mxsr2msrSkeletonPopulator::visitStart (S_midi_instrument& elt) -/* JMI -#ifdef MF_TRACE_IS_ENABLED - if (gTraceOahGroup->getTraceFiguredBasses ()) { - gLog << - "--> figured bass" << - ", line " << elt->getInputStartLineNumber () << ":" << - std::endl; - - ++gIndenter; - - const int fieldWidth = 31; - - gLog << std::left << - std::setw (fieldWidth) << "fCurrentPart" << ": " << - fCurrentPart->fetchPartCombinedName () << - std::endl << - std::setw (fieldWidth) << "fCurrentFiguredBassSoundingWholeNotes" << ": " << - fCurrentFiguredBassSoundingWholeNotes << - std::endl; - - --gIndenter; - } -#endif // MF_TRACE_IS_ENABLED - - if (fCurrentFiguredBassSoundingWholeNotes.getNumerator () == 0) { - // no duration has been found, - // use the note's sounding whole notes - fCurrentFiguredBassSoundingWholeNotes = - fCurrentNoteSoundingWholeNotes; - } - - // create the figured bass - // if the sounding whole notes is 0/1 (no was found), - // it will be set to the next note's sounding whole notes later - S_msrFiguredBass - figuredBass = - msrFiguredBass::create ( - elt->getInputStartLineNumber (), - fCurrentPart, - fCurrentFiguredBassSoundingWholeNotes, -// fFiguredBassWholeNotesDuration, - fCurrentFiguredBassParenthesesKind); - - // attach pending figures to the figured bass - if (fPendingFiguredBassFiguresList.size ()) { - for ( - std::list ::const_iterator i = fPendingFiguredBassFiguresList.begin (); - i != fPendingFiguredBassFiguresList.end (); - ++i - ) { - figuredBass-> - appendFigureToFiguredBass ((*i)); - } // for - - fPendingFiguredBassFiguresList.clear (); - } - - // append the figured bass to the current part - fCurrentPart-> - appendFiguredBassToPart ( - fCurrentPartStaffVoicesMap - [fCurrentNoteStaffNumber][fCurrentNoteVoiceNumber], - figuredBass); - */ - -/* -group-symbol -group-barLine -part-symbol -// color JMI - - -*/ - -/* JMI -#ifdef MF_TRACE_IS_ENABLED - if (gTraceOahGroup->getTraceNotes ()) { // JMI - const int fieldWidth = 27; - - gLog << std::left << - std::endl << - "==> AFTER visitEnd (S_note&) " << - fCurrentNote->asString () << - ", line " << elt->getInputStartLineNumber () << - " we have:" << - std::endl << - std::setw (fieldWidth) << - "--> fCurrentNoteStaffNumber" << ": " << - mfStaffNumberAsString (fCurrentNoteStaffNumber) << - std::endl << - std::setw (fieldWidth) << - "--> fCurrentNoteVoiceNumber" << ": " << - mfVoiceNumberAsString (fCurrentNoteVoiceNumber) << - std::endl << - std::setw (fieldWidth) << - "--> current voice" << ": \"" << - currentNoteVoice->getVoiceName () << "\"" << - std::endl << - "<=="; - - gWaeHandler->waeTrace ( - __FILE__, __LINE__, - ss.str ()); - } -#endif // MF_TRACE_IS_ENABLED -*/ - -/* JMI -#ifdef MF_TRACE_IS_ENABLED - if (gTraceOahGroup->getTraceNotes ()) { // JMI - gLog << - std::endl << - "==> BEFORE visitEnd (S_note&)" << - ", line " << elt->getInputStartLineNumber () << - " we have:" << - std::endl; - - ++gIndenter; - - const int fieldWidth = 27; - - gLog << std::left << - std::setw (fieldWidth) << "--> fCurrentNoteStaffNumber" << ": " << - mfStaffNumberAsString (fCurrentNoteStaffNumber) << - std::endl << - std::setw (fieldWidth) << "--> fCurrentNoteVoiceNumber" << ": " << - mfVoiceNumberAsString (fCurrentNoteVoiceNumber) << - std::endl << - std::setw (fieldWidth) << "--> current voice" << ": \"" << - currentNoteVoice->getVoiceName () << "\"" << - std::endl; - - --gIndenter; - - gLog << - "<==" << - std::endl << - * std::endl; - } -#endif // MF_TRACE_IS_ENABLED -*/ - // void mxsr2msrSkeletonPopulator::convertWordsToTempo ( // int inputLineNumber, // const std::string& wordsValue) @@ -31339,375 +31228,5 @@ part-symbol -// void mxsr2msrPopulatorVoiceHandler::handleTupletStartByHandler ( -// const S_msrTuplet& tuplet, -// const S_msrVoice& currentNoteVoice) -// { -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTuplets ()) { -// std::stringstream ss; -// -// ss << -// "Handling tuplet start of tuplet:" << -// std::endl; -// ++gIndenter; -// ss << -// tuplet->asString (); -// --gIndenter; -// ss << -// " in voice" << -// currentNoteVoice->getVoiceNumber (); -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // handle tuplet -// switch (fTupletsStack.size ()) { -// case 0: -// // tuplet is an outermost tuplet -// -// // register tuplet by pushing it onto the tuplet stack -// fTupletsStack.push_front (tuplet); -// -// // append it to currentNoteVoice -// // so that we know its measure position at once -// currentNoteVoice-> -// appendTupletToVoice (tuplet); -// -// break; -// -// default: -// // tuplet is a nested tuplet -// -// // register tuplet by pushing it onto the tuplet stack -// fTupletsStack.push_front (tuplet); -// break; -// } //switch - - // register the 'started' tuplet number in the set -// fExpectedTupletsStopNumbersSet.insert (fCurrentTupletNumber); -// fExpectedTupletsStopNumbersSet.insert (tuplet->getTupletNumber ()); -// -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTupletsDetails ()) { -// displayTupletsStack ( -// "############## mxsr2msrPopulatorVoiceHandler::handleTupletStart() 1"); -// } -// if (gTraceOahGroup->getTraceTupletsDetails ()) { -// displayVoicesTupletsStacksMap ( -// "############## mxsr2msrPopulatorVoiceHandler::handleTupletStart() 1"); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // register tuplet in the last handled tuplet in voice map -// fLastHandledTupletInVoiceMap [ -// std::make_pair ( -// fCurrentNoteStaffNumber, -// fCurrentNoteVoiceNumber) -// ] = -// tuplet; - -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTupletsDetails ()) { -// displayLastHandledTupletInVoiceMap ( -// "############## mxsr2msrPopulatorVoiceHandler::handleTupletStart() 2"); -// } -// #endif // MF_TRACE_IS_ENABLED -// } - -// void mxsr2msrPopulatorVoiceHandler::handleTupletContinueByHandler ( -// const S_msrNote& note, -// const S_msrVoice& currentNoteVoice) -// { -// if (fTupletsStack.size ()) { -// S_msrTuplet -// tupletStackTop = -// fTupletsStack.front (); -// -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTuplets ()) { -// std::stringstream ss; -// -// ss << -// "Handling tuplet continue of tuplet stack top:" << -// std::endl; -// ++gIndenter; -// ss << -// tupletStackTop->asString (); -// --gIndenter; -// ss << -// " in voice" << -// currentNoteVoice->getVoiceNumber (); -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // populate tupletStackTop -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTuplets ()) { -// gLog << -// "--> mxsr2msrPopulatorVoiceHandler::handleTupletContinue(), kTupletTypeContinue: adding tuplet member note " << -// note->asShortString () << -// " to stack top tuplet " << -// tupletStackTop->asString () << -// " in voice" << -// currentNoteVoice->getVoiceNumber () << -// ", line " << note->getInputStartLineNumber () << -// std::endl; -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // add note to tupletStackTop -// tupletStackTop-> -// appendNoteToTuplet ( -// note); -// -// currentNoteVoice-> -// registerTupletNoteInVoice (note); -// -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceTupletsDetails ()) { -// displayTupletsStack ( -// "############## mxsr2msrPopulatorVoiceHandler:kTupletTypeContinue"); -// } -// // if (gTraceOahGroup->getTraceTupletsDetails ()) { -// // displayVoicesTupletsStacksMap ( -// // "############## mxsr2msrPopulatorVoiceHandler:kTupletTypeContinue"); -// // } -// #endif // MF_TRACE_IS_ENABLED -// } -// -// else { -// std::stringstream ss; -// -// ss << -// "handleTupletContinue() 2:" << -// std::endl << -// "tuplet member note " << -// note-> -// asShortString () << -// " cannot be added, tuplets stack is empty" << -// ", line " << note->getInputStartLineNumber (); -// -// mxsr2msrInternalError ( -// gServiceRunData->getInputSourceName (), -// note->getInputStartLineNumber (), -// __FILE__, __LINE__, -// ss.str ()); -// } -// -// // #ifdef MF_TRACE_IS_ENABLED -// // if (gTraceOahGroup->getTraceTupletsDetails ()) { -// // displayLastHandledTupletInVoiceMap ( -// // "############## mxsr2msrPopulatorVoiceHandler:handleTupletContinue() 2"); -// // } -// // #endif // MF_TRACE_IS_ENABLED -// } - - -/* -==== -print-dot -Controls the printing of an augmentation dot separately from the rest of the note or rest. This is especially useful for notes that overlap in different voices, or for chord sheets that contain lyrics and chords but no melody. If print-object is set to no, this attribute is also interpreted as being set to no if not present. - -print-leger -Indicates whether leger lines are printed. Notes without leger lines are used to indicate indeterminate high and low notes. It is yes if not present unless print-object is set to no. This attribute is ignored for rests. -print-lyric yes-no No Controls the printing of a lyric separately from the rest of the note or rest. This is especially useful for notes that overlap in different voices, or for chord sheets that contain lyrics and chords but no melody. If print-object is set to no, this attribute is also interpreted as being set to no if not present. - -print-object -Specifies whether or not to print an object. It is yes if not specified. - -print-spacing -Controls whether or not spacing is left for an invisible note or object. It is used only if no note, dot, or lyric is being printed. The value is yes (leave spacing) if not specified. - -*/ - - - - -// std::stringstream ss; -// -// ss << -// "--> visitEnd (S_note& elt) 1 (all):" -// ", fCurrentNoteSequentialNumber: " << -// fCurrentNoteSequentialNumber << -// ", fPreviousNoteSequentialNumber: " << -// fPreviousNoteSequentialNumber << -// -// ", fCurrentNoteStartInputLineNumber: " << -// fCurrentNoteStartInputLineNumber << -// -// ", fCurrentNoteStaffNumber: " << -// mfStaffNumberAsString (fCurrentNoteStaffNumber) << -// ", fCurrentNoteVoiceNumber: " << -// mfVoiceNumberAsString (fCurrentNoteVoiceNumber) << -// -// ", getStaffName(): " << -// staff->getStaffName () << -// ", getVoiceName(): " << -// noteVoice->getVoiceName () << -// -// ", fCurrentNoteBelongsToAChord: " << -// fCurrentNoteBelongsToAChord << -// -// ", fCurrentNoteBelongsToATuplet: " << -// fCurrentNoteBelongsToATuplet << -// std::endl; -// -// displayPendingTupletsStopsMap ( -// "=====> visitEnd(S_note& elt) 1", -// fCurrentNoteStartInputLineNumber); - - - -// std::multimap ::const_iterator -// firstStaffChangeInRange, -// lastStaffChangeInRange; -// -// fKnownEventsCollection.fetchStaffChangeEventRange ( -// fCurrentNoteSequentialNumber, -// firstStaffChangeInRange, -// lastStaffChangeInRange); - -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceStaffChangesBasics ()) { -// gLog << -// "--->> Note: " << fCurrentNoteSequentialNumber << -// std::endl; -// -// for ( -// std::multimap ::const_iterator it = -// firstStaffChangeInRange; -// it != lastStaffChangeInRange; -// ++it -// ) { -// S_mxsrStaffChangeEvent staffChangeEvent = it->second; -// gLog << ' ' << staffChangeEvent; -// } // for -// -// gLog << std::endl; -// } -// #endif // MF_TRACE_IS_ENABLED - - // handle the staff changes events on this note if any -// for ( -// std::multimap ::const_iterator it = -// firstStaffChangeInRange; -// it != lastStaffChangeInRange; -// ++it -// ) { -// S_mxsrStaffChangeEvent staffChangeEvent = it->second; -// -// switch (staffChangeEvent->getStaffChangeEventKind ()) { -// case mxsrStaffChangeEventKind::kEventStaffChange_NONE: -// // should not occur -// break; -// -// case mxsrStaffChangeEventKind::kEventStaffChangeTakeOff: -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceNotes ()) { -// std::stringstream ss; -// -// ss << -// "==> kEventStaffChangeTakeOff at fCurrentNoteSequentialNumber: " << -// fCurrentNoteSequentialNumber << -// ": " << -// staffChangeEvent->asString () << -// ", line " << elt->getInputStartLineNumber (); -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // thereIsAStaffChange = true; -// break; -// -// case mxsrStaffChangeEventKind::kEventStaffChangeLanding: -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceNotes ()) { -// std::stringstream ss; -// -// ss << -// "==> kEventStaffChangeLanding at fCurrentNoteSequentialNumber: " << -// fCurrentNoteSequentialNumber << -// ": " << -// staffChangeEvent->asString () << -// ", line " << elt->getInputStartLineNumber (); -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// // thereIsAStaffChange = true; -// break; -// } // switch -// } // for - - - -// Bool thereIsAStaffChange; -// - /* JMI - std::map , S_msrNote>::iterator - it = - fStaffVoicesLastMetNoteMap.find ( - std::make_pair ( - fPreviousNoteStaffNumber, - fCurrentNoteVoiceNumber)); // JMI ??? - - if (it != fStaffVoicesLastMetNoteMap.end ()) { - S_msrNote - lastMetNoteInVoice = - (*it).second; - - attachPendingDalSegnosToCurrentNote (lastMetNoteInVoice); - } - else { - // FOO JMI - } -*/ - - -// // JMI v0.9.67 -// // attach the pre-pending elements if any to fCurrentNote, -// // before the note itself is handled, because that may cause -// // tuplets or chords to be appended to the voice -// #ifdef MF_TRACE_IS_ENABLED -// if (gTraceOahGroup->getTraceNotes () || gTraceOahGroup->getTraceStaffChanges ()) { -// std::stringstream ss; -// -// ss << -// "==> fetching voice to insert harmonies, figured bass elements and/or frames into" << -// ", fCurrentNoteStaffNumber: " << -// mfStaffNumberAsString (fCurrentNoteStaffNumber) << -// ", fCurrentNoteVoiceNumber: " << -// mfVoiceNumberAsString (fCurrentNoteVoiceNumber) << -// ", line " << elt->getInputStartLineNumber () << -// std::endl; -// -// gWaeHandler->waeTrace ( -// __FILE__, __LINE__, -// ss.str ()); -// } -// #endif // MF_TRACE_IS_ENABLED -// -// /* JMI -// // fetch the staff from current part -// S_msrStaff -// staff = -// fetchStaffFromCurrentPart ( -// elt->getInputStartLineNumber (), -// fCurrentNoteStaffNumber); -// */ diff --git a/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h b/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h index 20f83196..b8d8254f 100644 --- a/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h +++ b/src/passes/mxsr2msr/mxsr2msrSkeletonPopulator.h @@ -2598,6 +2598,7 @@ class EXP mxsr2msrSkeletonPopulator : Bool fCurrentNoteBelongsToATuplet; Bool fATupletIsEnding; + int fEndingTupletNumber; // a tuplet stop may occur in a chord before the latter's last note, hence: Bool fThereIsAPendingTupletStop; // CHORD_TUP diff --git a/src/representations/mxsr/mxsrEvents.cpp b/src/representations/mxsr/mxsrEvents.cpp index 6a5b2f05..484978d8 100644 --- a/src/representations/mxsr/mxsrEvents.cpp +++ b/src/representations/mxsr/mxsrEvents.cpp @@ -9,6 +9,7 @@ https://github.com/jacques-menu/musicformats */ +#include #include #include #include @@ -833,11 +834,53 @@ void mxsrEventsCollection::registerChordEvent ( fAllEventsList.push_back (chordEvent); } -void mxsrEventsCollection::registerTupletEvent ( +void mxsrEventsCollection::registerTupletBeginEvent ( + int noteSequentialNumber, + int noteEventStaffNumber, + int noteEventVoiceNumber, + int tupletNumber, + int eventInputStartLineNumber, + int eventInputEndLineNumber) +{ + S_mxsrTupletEvent + tupletEvent = + mxsrTupletEvent::create ( + ++fCurrentEventSequentialNumber, + noteSequentialNumber, + noteEventStaffNumber, + noteEventVoiceNumber, + mxsrTupletEventKind::kEventTupletBegin, + tupletNumber, + eventInputStartLineNumber, + eventInputEndLineNumber); + +#ifdef MF_TRACE_IS_ENABLED + if (true || gGlobalMxsrOahGroup->getTraceTupletsBasics ()) { + std::stringstream ss; + + ss << + "--> Registering tuplet event " << + tupletEvent->asString () << + ", line " << eventInputStartLineNumber; + + gWaeHandler->waeTrace ( + __FILE__, __LINE__, + ss.str ()); + } +#endif // MF_TRACE_IS_ENABLED + + fTupletsBeginsList.push_back (tupletEvent); + + fTupletsEventsMultiMap.insert ( + std::make_pair (noteSequentialNumber, tupletEvent)); + + fAllEventsList.push_back (tupletEvent); +} + +void mxsrEventsCollection::registerTupletEndEvent ( int noteSequentialNumber, int noteEventStaffNumber, int noteEventVoiceNumber, - mxsrTupletEventKind tupletEventKind, int tupletNumber, int eventInputStartLineNumber, int eventInputEndLineNumber) @@ -849,13 +892,13 @@ void mxsrEventsCollection::registerTupletEvent ( noteSequentialNumber, noteEventStaffNumber, noteEventVoiceNumber, - tupletEventKind, + mxsrTupletEventKind::kEventTupletEnd, tupletNumber, eventInputStartLineNumber, eventInputEndLineNumber); #ifdef MF_TRACE_IS_ENABLED - if (true || GlobalMxsrOahGroup->getTraceTupletsBasics ()) { + if (true || gGlobalMxsrOahGroup->getTraceTupletsBasics ()) { std::stringstream ss; ss << @@ -869,13 +912,15 @@ void mxsrEventsCollection::registerTupletEvent ( } #endif // MF_TRACE_IS_ENABLED -// fTupletsEventsMultiMap [eventSequentialNumber] = tupletEvent; + fTupletsEndsList.push_back (tupletEvent); + fTupletsEventsMultiMap.insert ( std::make_pair (noteSequentialNumber, tupletEvent)); fAllEventsList.push_back (tupletEvent); } +//________________________________________________________________________ void mxsrEventsCollection::sortTheMxsrEventsLists () { #ifdef MF_TRACE_IS_ENABLED @@ -898,6 +943,7 @@ void mxsrEventsCollection::sortTheMxsrEventsLists () compareStaffChangeEventsByIncreasingInputStartLineNumber); } +//________________________________________________________________________ S_mxsrStaffChangeEvent mxsrEventsCollection::fetchStaffChangeTakeOffAtNoteSequentialNumber ( int noteSequentialNumber) const { @@ -930,6 +976,7 @@ S_mxsrStaffChangeEvent mxsrEventsCollection::fetchStaffChangeLandingAtNoteSequen return result; } +//________________________________________________________________________ S_mxsrChordEvent mxsrEventsCollection::fetchChordEventAtNoteSequentialNumber ( int noteSequentialNumber) const { @@ -946,39 +993,141 @@ S_mxsrChordEvent mxsrEventsCollection::fetchChordEventAtNoteSequentialNumber ( return result; } -// S_mxsrTupletEvent mxsrEventsCollection::fetchTupletEventAtNoteSequentialNumber ( -// int noteSequentialNumber) const -// { -// S_mxsrTupletEvent result; -// -// std::multimap ::const_iterator it; -// -// it = fTupletsEventsMultiMap.find (noteSequentialNumber); -// -// if (it != fTupletsEventsMultiMap.end ()) { -// result = (*it).second; -// } -// -// return result; -// } +/* +#include +#include +#include -void mxsrEventsCollection::fetchTupletEventsRange ( - int noteSequentialNumber, - std::multimap ::const_iterator& - firstInRange, - std::multimap ::const_iterator& - lastInRange) const +int main() +{ + std::list myList{ 5, 19, 34, 3, 33 }; + + + auto it = std::find_if( std::begin( myList ), + std::end( myList ), + [&]( const int v ){ return 0 == ( v % 17 ); } ); + + if ( myList.end() == it ) + { + std::cout << "item not found" << std::endl; + } + else + { + const int pos = std::distance( myList.begin(), it ) + 1; + std::cout << "item divisible by 17 found at position " << pos << std::endl; + } +} +*/ + +void mxsrEventsCollection::fetchTupletBeginsList ( + int noteSequentialNumber, + std::list & collectedBeginsList) +{ + // look for the first tuplet event matching noteSequentialNumber + std::list ::iterator startIt = + std::find_if ( + std::begin (fTupletsBeginsList), + std::end (fTupletsBeginsList), + [&] (const S_mxsrTupletEvent tupletEvent ) + { + return + tupletEvent->getNoteSequentialNumber () == noteSequentialNumber; + }); + + if (startIt != fTupletsBeginsList.end ()) { + gLog << "(*startIt): " << (*startIt) << std::endl << std::flush; + + // look for the first next tuplet event not matching noteSequentialNumber + std::list ::iterator endIt = + std::find_if ( + std::begin (fTupletsBeginsList), + std::end (fTupletsBeginsList), + [&] (const S_mxsrTupletEvent tupletEvent ) + { + return + tupletEvent->getNoteSequentialNumber () != noteSequentialNumber; + }); + + gLog << "(*endIt): "; + if (endIt == fTupletsBeginsList.end ()) { + gLog << "fTupletsBeginsList.end ()"; + } + else { + gLog << (*endIt); + } + gLog << std::endl << std::endl << std::flush; + + // move the found tuplets events to collectedBeginsList + collectedBeginsList.splice ( + collectedBeginsList.begin (), fTupletsBeginsList, startIt, endIt); + } + +#ifdef MF_TRACE_IS_ENABLED + if (gGlobalMxsrOahGroup->getTraceTupletsBasics ()) { + printTupletEventsList ( + gLog, + noteSequentialNumber, + collectedBeginsList, + "fetchTupletBeginsList(), collectedBeginsList:"); + } +#endif // MF_TRACE_IS_ENABLED +} + +void mxsrEventsCollection::fetchTupletEndsList ( + int noteSequentialNumber, + std::list & collectedEndsList) { - std::pair < - std::multimap ::const_iterator, - std::multimap ::const_iterator - > thePair = - getTupletsEventMultiMap ().equal_range ( - noteSequentialNumber); - - std::tie (firstInRange, lastInRange) = thePair; + // look for the first tuplet event matching noteSequentialNumber + std::list ::iterator startIt = + std::find_if ( + std::begin (fTupletsEndsList), + std::end (fTupletsEndsList), + [&] (const S_mxsrTupletEvent tupletEvent ) + { + return + tupletEvent->getNoteSequentialNumber () == noteSequentialNumber; + }); + + if (startIt != fTupletsEndsList.end ()) { + gLog << "(*startIt): " << (*startIt) << std::endl << std::flush; + + // look for the first next tuplet event not matching noteSequentialNumber + std::list ::iterator endIt = + std::find_if ( + std::begin (fTupletsEndsList), + std::end (fTupletsEndsList), + [&] (const S_mxsrTupletEvent tupletEvent ) + { + return + tupletEvent->getNoteSequentialNumber () != noteSequentialNumber; + }); + + gLog << "(*endIt): "; + if (endIt == fTupletsEndsList.end ()) { + gLog << "fTupletsEndsList.end ()"; + } + else { + gLog << (*endIt); + } + gLog << std::endl << std::endl << std::flush; + + // move the found tuplets events to collectedEndsList + collectedEndsList.splice ( + collectedEndsList.begin (), fTupletsEndsList, startIt, endIt); + } + +#ifdef MF_TRACE_IS_ENABLED + if (gGlobalMxsrOahGroup->getTraceTupletsBasics ()) { + printTupletEventsList ( + gLog, + noteSequentialNumber, + collectedEndsList, + "fetchTupletEndsList(), resultingEndsList:"); + } +#endif // MF_TRACE_IS_ENABLED } +//________________________________________________________________________ std::string mxsrEventsCollection::asShortString () const { std::stringstream ss; @@ -987,8 +1136,13 @@ std::string mxsrEventsCollection::asShortString () const "[EventsCollection" << ", fStaffChangeTakeOffsMap.size (): " << fStaffChangeTakeOffsMap.size () << ", fStaffChangeLandingsMap.size (): " << fStaffChangeLandingsMap.size () << + ", fChordsEventsMap.size (): " << fChordsEventsMap.size () << + + ", fTupletsBeginsList.size (): " << fTupletsEventsMultiMap.size () << + ", fTupletsEndsList.size (): " << fTupletsEventsMultiMap.size () << ", fTupletsEventsMultiMap.size (): " << fTupletsEventsMultiMap.size () << + ", fAllEventsList.size (): " << fAllEventsList.size () << ']'; @@ -1000,6 +1154,7 @@ std::string mxsrEventsCollection::asString () const return asShortString (); } +//------------------------------------------------------------------------ void mxsrEventsCollection::printAllEvents (std::ostream& os) const { os << @@ -1029,6 +1184,7 @@ void mxsrEventsCollection::printAllEvents (std::ostream& os) const --gIndenter; } +//------------------------------------------------------------------------ void mxsrEventsCollection::printStaffChangeEvents (std::ostream& os) const { os << @@ -1124,6 +1280,7 @@ void mxsrEventsCollection::printStaffChangeEvents (std::ostream& os) const --gIndenter; } +//------------------------------------------------------------------------ void mxsrEventsCollection::printChordEvents (std::ostream& os) const { os << @@ -1158,6 +1315,7 @@ void mxsrEventsCollection::printChordEvents (std::ostream& os) const --gIndenter; } +//------------------------------------------------------------------------ void mxsrEventsCollection::printTupletEvents (std::ostream& os) const { os << @@ -1190,6 +1348,107 @@ void mxsrEventsCollection::printTupletEvents (std::ostream& os) const } // for --gIndenter; + + os << std::endl << "--------" << std::endl << std::endl; + + os << + "fTupletsBeginsList: " << + mfSingularOrPlural ( + fTupletsBeginsList.size (), + "element", + "elements") << + ", in note sequential number order" << + std::endl; + + ++gIndenter; + + for (S_mxsrTupletEvent tupletEvent : fTupletsBeginsList) { + int + eventSequentialNumber = tupletEvent->getEventSequentialNumber (); + + os << + "Note " << eventSequentialNumber << + ':' << + std::endl; + + ++gIndenter; + os << + tupletEvent << + std::endl; + --gIndenter; + } // for + + --gIndenter; + + os << std::endl << "--------" << std::endl << std::endl; + + os << + "fTupletsEndsList: " << + mfSingularOrPlural ( + fTupletsEndsList.size (), + "element", + "elements") << + ", in note sequential number order" << + std::endl; + + ++gIndenter; + + for (S_mxsrTupletEvent tupletEvent : fTupletsEndsList) { + int + eventSequentialNumber = tupletEvent->getEventSequentialNumber (); + + os << + "Note " << eventSequentialNumber << + ':' << + std::endl; + + ++gIndenter; + os << + tupletEvent << + std::endl; + --gIndenter; + } // for + + --gIndenter; +} + +//________________________________________________________________________ +void mxsrEventsCollection::printTupletEventsList ( + std::ostream& os, + const std::list & tupletsList, + const std::string& context, + int inputLineNumber) const +{ + os << + "--> printTupletEventsList()" << + ", context " << + mfSingularOrPlural ( + tupletsList.size (), + "element", + "elements") << + ", in note sequential number order" << + ", line " << inputLineNumber << + std::endl; + + ++gIndenter; + + for (S_mxsrTupletEvent tupletEvent : tupletsList) { + int + eventSequentialNumber = tupletEvent->getEventSequentialNumber (); + + os << + "Note " << eventSequentialNumber << + ':' << + std::endl; + + ++gIndenter; + os << + tupletEvent << + std::endl; + --gIndenter; + } // for + + --gIndenter; } void mxsrEventsCollection::print (std::ostream& os) const diff --git a/src/representations/mxsr/mxsrEvents.h b/src/representations/mxsr/mxsrEvents.h index d073930b..67ef1112 100644 --- a/src/representations/mxsr/mxsrEvents.h +++ b/src/representations/mxsr/mxsrEvents.h @@ -550,12 +550,14 @@ class EXP mxsrEventsCollection : public smartable int getCurrentEventSequentialNumber () const { return fCurrentEventSequentialNumber; } + // implicit initial forward repeat void setThereIsAnImplicitInitialForwardRepeat () { fThereIsAnImplicitInitialForwardRepeat = true; } Bool getInitialRepeatBarIsImplicit () const { return fThereIsAnImplicitInitialForwardRepeat; } + // staff change events const std::map & getStaffChangeTakeOffsMap () const { return fStaffChangeTakeOffsMap; } @@ -568,14 +570,25 @@ class EXP mxsrEventsCollection : public smartable getStaffChangeEventsList () const { return fStaffChangeEventsList; } + // chord events const std::map & getChordsEventMap () const { return fChordsEventsMap; } + // tuplet events + const std::list & + getTupletsBeginsList () const + { return fTupletsBeginsList; } + + const std::list & + getTupletsEndsList () const + { return fTupletsEndsList; } + const std::multimap & getTupletsEventMultiMap () const { return fTupletsEventsMultiMap; } + // all events const std::list & getAllEventsList () const { return fAllEventsList; } @@ -615,17 +628,25 @@ class EXP mxsrEventsCollection : public smartable int eventInputStartLineNumber, int eventInputEndLineNumber); - void registerTupletEvent ( + void registerTupletBeginEvent ( + int noteSequentialNumber, + int noteEventStaffNumber, + int noteEventVoiceNumber, + int tupletNumber, + int eventInputStartLineNumber, + int eventInputEndLineNumber); + + void registerTupletEndEvent ( int noteSequentialNumber, int noteEventStaffNumber, int noteEventVoiceNumber, - mxsrTupletEventKind tupletEventKind, int tupletNumber, int eventInputStartLineNumber, int eventInputEndLineNumber); void sortTheMxsrEventsLists (); + // staff changes S_mxsrStaffChangeEvent fetchStaffChangeTakeOffAtNoteSequentialNumber ( int noteSequentialNumber) const; @@ -639,15 +660,13 @@ class EXP mxsrEventsCollection : public smartable int noteSequentialNumber) const; // tuplet events -// S_mxsrTupletEvent fetchTupletEventAtNoteSequentialNumber ( -// int noteSequentialNumber) const; + void fetchTupletBeginsList ( + int noteSequentialNumber, + std::list & collectedBeginsList); - void fetchTupletEventsRange ( - int noteSequentialNumber, - std::multimap ::const_iterator& - firstInRange, - std::multimap ::const_iterator& - lastInRange) const; + void fetchTupletEndsList ( + int noteSequentialNumber, + std::list & collectedEndsList); private: @@ -670,6 +689,12 @@ class EXP mxsrEventsCollection : public smartable void printChordEvents (std::ostream& os) const; void printTupletEvents (std::ostream& os) const; + void printTupletEventsList ( + std::ostream& os, + const std::list & tupletsList, + const std::string& context, + int inputLineNumber) const; + private: // private fields @@ -681,8 +706,9 @@ class EXP mxsrEventsCollection : public smartable // initial repeat bar Bool fThereIsAnImplicitInitialForwardRepeat; - // there can be two staff changes per note, - // hence these two maps, indexed by note sequential number + // staff changes events + // there can be two staff changes per note, + // hence these two maps, indexed by note sequential number std::map fStaffChangeTakeOffsMap, fStaffChangeLandingsMap; @@ -690,18 +716,24 @@ class EXP mxsrEventsCollection : public smartable std::list fStaffChangeEventsList; - // there can be only one chord begin or end per note, - // hence this map, indexed by note sequential number + // chords events + // there can be only one chord begin or end per note, + // hence this map, indexed by note sequential number std::map fChordsEventsMap; - // there can be several tuplets start and/or stop events per note, - // hence this multimap, indexed by note sequential number, + // tuplet events + // there can be several tuplets start and/or stop events per note, + // hence this multimap, indexed by note sequential number, + + std::list + fTupletsBeginsList, + fTupletsEndsList; std::multimap fTupletsEventsMultiMap; - // all events list + // all events std::list fAllEventsList; };