@@ -908,6 +908,47 @@ void SongTest::test_renderToEvents_midiSideChain_shouldClampAttackEvents()
908908 QVERIFY (targetEventFound);
909909}
910910
911+ void SongTest::test_transposePattern_drumTrackSet_shouldNotTransposeDrumTrack ()
912+ {
913+ Song song;
914+
915+ // Setup Track 0 as Drum Track
916+ auto drumInstrument = std::make_shared<Instrument>(" " );
917+ auto drumSettings = drumInstrument->settings ();
918+ drumSettings.drumTrack = true ;
919+ drumInstrument->setSettings (drumSettings);
920+ song.setInstrument (0 , drumInstrument);
921+
922+ // Setup Track 1 as normal track
923+ auto normalInstrument = std::make_shared<Instrument>(" " );
924+ song.setInstrument (1 , normalInstrument);
925+
926+ // Add note to Track 0 (should NOT be transposed)
927+ const Position pos0 = { 0 , 0 , 0 , 0 , 0 };
928+ song.noteDataAtPosition (pos0)->setAsNoteOn (60 , 100 );
929+
930+ // Add note to Track 1 (should be transposed)
931+ const Position pos1 = { 0 , 1 , 0 , 0 , 0 };
932+ song.noteDataAtPosition (pos1)->setAsNoteOn (60 , 100 );
933+
934+ // Transpose pattern by 1 semitone
935+ const auto changes = song.transposePattern ({ 0 , 0 , 0 , 0 , 0 }, 1 );
936+
937+ // Check results
938+ // pos0 (Drum Track) should NOT be in changes
939+ const auto it0 = std::find_if (changes.begin (), changes.end (), [&](auto && change) {
940+ return change.position == pos0;
941+ });
942+ QVERIFY (it0 == changes.end ());
943+
944+ // pos1 (Normal Track) SHOULD be in changes
945+ const auto it1 = std::find_if (changes.begin (), changes.end (), [&](auto && change) {
946+ return change.position == pos1;
947+ });
948+ QVERIFY (it1 != changes.end ());
949+ QCOMPARE (it1->newNoteData .note ().value (), 61 );
950+ }
951+
911952void SongTest::test_duration_skippedPattern_shouldReturnCorrectDuration ()
912953{
913954 Song song;
0 commit comments