-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sync Lock: make sure to reinit leader params after scratching ends #4005
Conversation
If you put the renaming commits into a separate PR, they can already merged without extensive testing. We can also ignore the unrelated formatting issues there (or not as you prefer). |
feae5ec
to
f598252
Compare
Pull Request Test Coverage Report for Build 1068940914
💛 - Coveralls |
src/engine/sync/synccontrol.cpp
Outdated
m_leaderBpmAdjustFactor = kBpmUnity; | ||
|
||
m_pBpmControl->updateLocalBpm(); | ||
if (isSynchronized()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can invert this condition and exit early to reduce nesting depth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Now that #3944 is in, this one is ready for review! To demonstrate the issue, play two tracks in sync and then drag the waveform around -- with this change, the scratched waveform snaps back into place. Without, it stays out of sync. |
Can you rebase this on main? This way we avoid that the same commit appears in different branches. |
src/engine/enginebuffer.cpp
Outdated
@@ -1305,6 +1287,7 @@ void EngineBuffer::processSeek(bool paused) { | |||
kLogger.trace() << "EngineBuffer::processSeek" << getGroup() << "Seek to" << position; | |||
} | |||
setNewPlaypos(position); | |||
m_pBpmControl->updateBeatDistance(position); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setNewPlaypos above calls the virtual EngineControl::notifySeek to inform the controls.
I think it would be better to use this for BpmControl as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1171,12 +1159,6 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) { | |||
} | |||
#endif | |||
|
|||
if (isLeader(m_pSyncControl->getSyncMode())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can we remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
player speed reporting here is redundant to the call in postProcess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original intend to have the master speed updated, before the followers are processed:
d9d8a2c
EngineBuffer::postProcess()
postProcess() is still called in a consecutive loop, so I am afraid that the followers with lower index will use the old speed and the higher index channels will use the new speed.
Do we have a test for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the PR you linked states, a test was added for this circumstance. What happens now is the Internal Clock is updated with the new speed, and it is always post-processed first. So, when the other followers get their speed, it is up to date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah OK, thank you. It might be helpful to put this info as comment to the loop of all controls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already noted here: https://github.com/mixxxdj/mixxx/blob/main/src/engine/enginemaster.cpp#L370-L374
Let me know if it could be improved
Fixes an issue where scratching the leader while another stopped deck was present would cause the leader to change pitch to resync.
b084a5f
to
1fa010f
Compare
I did a manual diff / apply round to clean it up, trying to rebase was impractical with the number of intermediate refactors |
src/engine/controls/bpmcontrol.h
Outdated
/// updateBeatDistance is adjusted to include the user offset so | ||
/// it's transparent to other decks. | ||
double updateBeatDistance(); | ||
/// Updates the beat distance based on the provided play position. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What position should be provided? The current position? Can we rename the parameter to make this obvious?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is used in two different ways: on every engine callback to determine the current beat position, and after a seek to determine the beat position. (the overload of this function with no parameter takes the current position). I'm not sure what it should be called... "newPlayPos" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah Ok, In that case it should be sufficient to just copy the essence of your post as a comment to the source.
@@ -1171,12 +1159,6 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) { | |||
} | |||
#endif | |||
|
|||
if (isLeader(m_pSyncControl->getSyncMode())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah OK, thank you. It might be helpful to put this info as comment to the loop of all controls.
src/engine/controls/bpmcontrol.h
Outdated
/// updateBeatDistance is adjusted to include the user offset so | ||
/// it's transparent to other decks. | ||
double updateBeatDistance(); | ||
/// Updates the beat distance based on the provided play position. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah Ok, In that case it should be sufficient to just copy the essence of your post as a comment to the source.
In case of spinny scratching the scratched track does bit always snap to the right position and is slowly moved to it afterwards: |
Because of half/double math, a phased seek might cause the Leader to be 0.5 beats off from where it used to be. Therefore after a seek, make sure to update the leader beat distance with the new value.
This is another half-double edge case :(. I wish I had never written that feature. A phase seek can cause the leader track to suddenly be half a beat off from where it was before, so we need to make sure to update the leader beat distance after a seek. |
If the original author of a feature says this, I think we should get rid of it. |
Unfortunately it's a feature some people do seem to like! And actually the fix here is not specific to half-double, it is more correct than before. So it's still worth fixing this way here. But yes it would be nice to open a discussion about half-double and decide if we really want to keep it. |
I confirm scratching is now working without any issues. Thank you very much. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Fixes an issue where scratching the leader while another stopped deck was present would cause the leader to change pitch to resync.