Skip to content

Commit f1dbc90

Browse files
committed
Fix song position clamping when song length decreases
1 parent 8dd2c59 commit f1dbc90

6 files changed

Lines changed: 59 additions & 1 deletion

File tree

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ New features:
2929

3030
Bug fixes:
3131

32+
* Fix song position clamping when song length decreases
33+
3234
Other:
3335

3436
* Update user manual with pan column documentation

src/application/service/editor_service.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2726,7 +2726,7 @@ void EditorService::setSongLength(quint64 songLength)
27262726
emit songLengthChanged();
27272727
updateDuration();
27282728
if (songPosition() >= m_song->length()) {
2729-
setSongPosition(songPosition() - 1);
2729+
setSongPosition(m_song->length() > 0 ? m_song->length() - 1 : 0);
27302730
}
27312731
setIsModified(true);
27322732
}

src/unit_tests/editor_service_test/editor_service_test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,31 @@ void EditorServiceTest::test_midiNotesAtPosition_shouldReturnCorrectNotes()
18351835
}
18361836
}
18371837

1838+
void EditorServiceTest::test_setSongLength_clampingPosition_shouldClampCorrectly()
1839+
{
1840+
EditorService editorService { std::make_shared<SelectionService>(), std::make_shared<SettingsService>(), std::make_shared<AutomationService>(std::make_shared<PropertyService>()), std::make_shared<DataService>() };
1841+
1842+
editorService.setSongPosition(0);
1843+
editorService.insertPatternToPlayOrder(); // Now length is 2
1844+
editorService.insertPatternToPlayOrder(); // Now length is 3
1845+
editorService.insertPatternToPlayOrder(); // Now length is 4
1846+
1847+
QCOMPARE(editorService.songLength(), 4);
1848+
1849+
editorService.setSongPosition(3); // Go to last position (3)
1850+
QCOMPARE(editorService.songPosition(), 3);
1851+
1852+
// Set song length to 2.
1853+
// If the clamping bug exists, this will set song length to 2, then set position to 2,
1854+
// which triggers extension back to 3!
1855+
editorService.setSongLength(2);
1856+
1857+
// The song length should be 2.
1858+
QCOMPARE(editorService.songLength(), 2);
1859+
// The song position should be clamped to 1.
1860+
QCOMPARE(editorService.songPosition(), 1);
1861+
}
1862+
18381863
} // namespace noteahead
18391864

18401865
QTEST_GUILESS_MAIN(noteahead::EditorServiceTest)

src/unit_tests/editor_service_test/editor_service_test.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ private slots:
119119

120120
void test_velocityAtPosition_shouldReturnCorrectVelocity();
121121
void test_midiNotesAtPosition_shouldReturnCorrectNotes();
122+
void test_setSongLength_clampingPosition_shouldClampCorrectly();
122123
};
123124

124125
} // namespace noteahead

src/unit_tests/song_test/song_test.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,35 @@ void SongTest::test_removePatternFromPlayOrder_shouldDecreaseLengthByOne()
12081208
QCOMPARE(song.patternAtSongPosition(0), 1);
12091209
}
12101210

1211+
void SongTest::test_deleteUnusedPatterns_recreatedPatternHasNoNoteData()
1212+
{
1213+
Song song;
1214+
song.createPattern(1);
1215+
song.createPattern(2);
1216+
QCOMPARE(song.patternCount(), 3);
1217+
1218+
Position pos { 2, 0, 0, 0 }; // pattern 2, track 0, column 0, line 0
1219+
NoteData note;
1220+
note.setAsNoteOn(60, 100);
1221+
song.pattern(2)->setNoteDataAtPosition(note, pos);
1222+
QVERIFY(song.pattern(2)->hasData());
1223+
1224+
song.setLength(2);
1225+
song.setPatternAtSongPosition(0, 0);
1226+
song.setPatternAtSongPosition(1, 1);
1227+
1228+
// Pattern 2 is unused, 0 and 1 are used
1229+
song.deleteUnusedPatterns();
1230+
1231+
QCOMPARE(song.patternCount(), 2);
1232+
QVERIFY(!song.hasPattern(2));
1233+
1234+
// Recreate pattern 2
1235+
song.createPattern(2);
1236+
QVERIFY(song.hasPattern(2));
1237+
QVERIFY(!song.pattern(2)->hasData()); // This should be empty, without the note data!
1238+
}
1239+
12111240
} // namespace noteahead
12121241

12131242
QTEST_GUILESS_MAIN(noteahead::SongTest)

src/unit_tests/song_test/song_test.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ private slots:
7878

7979
void test_deleteUnusedPatterns_shouldRemoveUnusedPatterns();
8080
void test_deleteUnusedPatterns_skippedButUsed_shouldNotBeRemoved();
81+
void test_deleteUnusedPatterns_recreatedPatternHasNoNoteData();
8182
void test_hasPatternInPlayOrder_shouldReturnCorrectValue();
8283
void test_duration_allPatternsSkipped_shouldReturnZero();
8384

0 commit comments

Comments
 (0)