Skip to content

Commit

Permalink
fix #25899: fixed clearing events inside repeats
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanPudashkin committed Feb 28, 2025
1 parent 6d5490f commit d8d14c5
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/engraving/playback/playbackmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,9 @@ void PlaybackModel::clearExpiredEvents(const int tickFrom, const int tickTo, con
int removeEventsFromTick = std::max(tickFrom, repeatStartTick);
timestamp_t removeEventsFrom = timestampFromTicks(m_score, removeEventsFromTick + tickPositionOffset);

int removeEventsToTick = std::min(tickTo, repeatEndTick);
//! NOTE: the end tick of the current repeat segment == the start tick of the next repeat segment
//! so subtract 1 to avoid removing events belonging to the next segment
int removeEventsToTick = std::min(tickTo, repeatEndTick - 1);
timestamp_t removeEventsTo = timestampFromTicks(m_score, removeEventsToTick + tickPositionOffset);

removeEventsFromRange(trackFrom, trackTo, removeEventsFrom, removeEventsTo);
Expand Down
15 changes: 13 additions & 2 deletions src/engraving/tests/playback/playbackmodel_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,22 +845,33 @@ TEST_F(Engraving_PlaybackModelTests, SimpleRepeat_Changes_Notification)
model.load(score);

PlaybackData result = model.resolveTrackPlaybackData(part->id(), part->instrumentId());
EXPECT_EQ(result.originEvents.size(), expectedChangedEventsCount);

// [THEN] Updated events map will match our expectations
result.mainStream.onReceive(this, [expectedChangedEventsCount](const PlaybackEventsMap& updatedEvents, const DynamicLevelLayers&,
const PlaybackParamLayers&) {
EXPECT_EQ(updatedEvents.size(), expectedChangedEventsCount);
});

// [WHEN] Notation has been changed
// [WHEN] Score has been changed: the range starts ouside the repeat and ends inside it
ScoreChangesRange range;
range.tickFrom = 480; // 2nd note of the 1st measure
range.tickFrom = 480; // 2nd note of the 1st measure (outside the repeat)
range.tickTo = 3840; // 1st note of the 3rd measure (inside the repeat)
range.staffIdxFrom = 0;
range.staffIdxTo = 0;
range.changedTypes = { ElementType::NOTE };

score->changesChannel().send(range);

// [WHEN] Score has been changed: the range is inside the repeat and tickTo == the end tick of the repeat
// See: https://github.com/musescore/MuseScore/issues/25899
range.tickFrom = 4800; // 3rd note of the 3rd measure (inside the repeat)
range.tickTo = 5760; // end tick of the repeat
range.staffIdxFrom = 0;
range.staffIdxTo = 0;
range.changedTypes = { ElementType::PEDAL };

score->changesChannel().send(range);
}

/**
Expand Down

0 comments on commit d8d14c5

Please sign in to comment.