lmms icon indicating copy to clipboard operation
lmms copied to clipboard

Fix Resized Samples getting Shifted after Tempo Change

Open regulus79 opened this issue 8 months ago • 3 comments

If you change the tempo of a song, the contents of all sample clips get scaled forwards/backwards. However, they get scaled relative to the internal 0 time of the clip, not the start of the clip. This causes issues when dealing with resized or cut/sliced sample clips.

This PR fixes this issue by updating the startTimeOffset of the sample clip when the tempo changes.

Originally I was just multiplying the startTimeOffset by the ratio of the new tempo to the old tempo, but that resulted in precision errors due to integer division. Instead, I decided to store the oldstartTimeOffset in terms of frames and calculate the new startTimeOffset based on that. That way, even if the user drastically changes the bpm from 140 to 10 to 999 to 300 to 10 and back to 140, the startTimeOffset will still return to its correct value, since it's being calculated by the original frame offset.

Note

In order to store the old startTimeOffset in frames between tempo changes, I have it track with the startTimeOffset when resizing/splitting, but leaving it unaffected when changing the tempo. To do this, I overrode Clip::setStartTimeOffset in SampleClip to make it also update the frame offset. That way, resizing the clip by the user, or splitting the clip, or any other action which calls that function will update it correctly. But in the function which handles the tempo change, I still use Clip::startTimeOffset.

Before

https://github.com/user-attachments/assets/5abfcfa6-c239-4ada-bdbe-e65a37ff4ae0

After

https://github.com/user-attachments/assets/09cbe676-8d3c-4e29-979e-75cbd2c8b94c

regulus79 avatar May 14 '25 00:05 regulus79

looks good (haven't tested yet, to be clear). will this break older projects?

AW1534 avatar May 14 '25 06:05 AW1534

As far as I know it shouldn't. This PR doesn't change how samples clips are saved or loaded, and the start frame offset should always be synced with the start time offset, so the only change in behavior should happen when changing the tempo.

regulus79 avatar May 14 '25 15:05 regulus79

Ok It works properly. Congrats? just kidding nice job

firiox avatar May 17 '25 15:05 firiox