Skip to content

Conversation

@regulus79
Copy link
Member

Fixes #8182

When #7454 was merged, the frameOffset variable inside Song::PlayPos which kept track of the actual frame position which the song was playing at relative to the last tick, was moved to Timeline. In the process, the type was inadvertently changed from float to f_cnt_t.

This caused the frame offset to be truncated ever time it was updated in Song::processNextBuffer, causing the song playback to slowly drift back ever so slightly, just a handful of frames every bar. This caused any new sample clips spawned to be created slightly late, becoming out of sync with any existing playing samples.

This PR fixes the issue by reverting the frameOffset variable type to be float again, allowing it to track sub-sample offsets over time.

Copy link
Contributor

@szeli1 szeli1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the understanding that these changes were present in lmms previously before the bug happened, therefor I approve this pull request.

@sakertooth
Copy link
Contributor

sakertooth commented Dec 29, 2025

Quite odd that a frame offset is a float.

Edit: Oh, it's an offset position within a frame? That makes more sense.

Copy link
Contributor

@sakertooth sakertooth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes look good to me.

@sakertooth
Copy link
Contributor

PS: I ran into a similar truncation somewhere else in the codebase, but using float caused the issue and switching to double fixed it. I have doubts that is something we need to look into though regarding this if the previous working code was using float, but maybe something to think about.

@regulus79
Copy link
Member Author

Thanks for approving!

Quite odd that a frame offset is a float.

I would agree. My understanding is that because the song playback position is tracked in ticks, but frames are smaller than ticks, frameOffset keeps track of the remainder frames relative to the start of the last tick. But because the number of frames per tick isn't usually a whole number, it has to be a float.

I imagine a simpler system would be to keep track of the total frame count and simply convert it to ticks when it needs to be compared with a TimePos or something. But I'm not sure.

@regulus79 regulus79 merged commit 2db75bd into LMMS:master Dec 29, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Samples getting out of sync when split/moved/resized

3 participants