-
-
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
Enable beatloop activation directly after activating a hotcue #2190
Changes from 3 commits
7a418a7
255fd69
c8f9a5b
cc375f6
d441ca8
2fdffa2
7ea5f07
0d1cb49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -430,10 +430,10 @@ void EngineBuffer::seekCloneBuffer(EngineBuffer* pOtherBuffer) { | |
|
||
// WARNING: This method is not thread safe and must not be called from outside | ||
// the engine callback! | ||
void EngineBuffer::setNewPlaypos(double newpos, bool adjustingPhase) { | ||
void EngineBuffer::setNewPlaypos(double dNewPlayPos, double dSyncedNewPlayPos, bool adjustingPhase) { | ||
//qDebug() << m_group << "engine new pos " << newpos; | ||
|
||
m_filepos_play = newpos; | ||
m_filepos_play = dSyncedNewPlayPos; | ||
|
||
if (m_rate_old != 0.0) { | ||
// Before seeking, read extra buffer for crossfading | ||
|
@@ -449,7 +449,7 @@ void EngineBuffer::setNewPlaypos(double newpos, bool adjustingPhase) { | |
|
||
// Must hold the engineLock while using m_engineControls | ||
for (const auto& pControl: qAsConst(m_engineControls)) { | ||
pControl->notifySeek(m_filepos_play, adjustingPhase); | ||
pControl->notifySeek(dNewPlayPos, m_filepos_play, adjustingPhase); | ||
} | ||
|
||
verifyPlay(); // verify or update play button and indicator | ||
|
@@ -1125,7 +1125,7 @@ void EngineBuffer::processSeek(bool paused) { | |
// call anyway again. | ||
|
||
SeekRequests seekType = static_cast<SeekRequest>( | ||
m_iSeekQueued.fetchAndStoreRelease(SEEK_NONE)); | ||
m_iSeekQueued.fetchAndStoreRelaxed(SEEK_NONE)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here wee need to be sure that m_queuedSeekPosition.getValue() is not accessed before reading and writing m_iSeekQueued so I think fetchAndSubAcquire() would be the right call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That must be an autocomplete-mistake. I wanted to change it back to the original version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But it was originally wrong. We need the Aquire memory fence here, to stop the pipeline executing the reading of the seek position too early. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I will change that. But which value should I subtract? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ups ... of cause. |
||
double position = m_queuedSeekPosition.getValue(); | ||
|
||
// Don't allow the playposition to go past the end. | ||
|
@@ -1163,11 +1163,13 @@ void EngineBuffer::processSeek(bool paused) { | |
return; | ||
} | ||
|
||
double syncPosition = position; | ||
if (!paused && (seekType & SEEK_PHASE)) { | ||
position = m_pBpmControl->getNearestPositionInPhase(position, true, true); | ||
syncPosition = m_pBpmControl->getNearestPositionInPhase(position, true, true); | ||
} | ||
if (position != m_filepos_play) { | ||
setNewPlaypos(position, adjustingPhase); | ||
|
||
if (syncPosition != m_filepos_play) { | ||
setNewPlaypos(position, syncPosition, adjustingPhase); | ||
} | ||
} | ||
|
||
|
@@ -1284,6 +1286,11 @@ bool EngineBuffer::isTrackLoaded() { | |
return false; | ||
} | ||
|
||
bool EngineBuffer::isSeekQueued(double* pSeekPosition) { | ||
*pSeekPosition = m_queuedSeekPosition.getValue(); | ||
return m_iSeekQueued.load() != SEEK_NONE; | ||
} | ||
|
||
void EngineBuffer::slotEjectTrack(double v) { | ||
if (v > 0) { | ||
// Don't allow rejections while playing a track. We don't need to lock to | ||
|
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.
Can you clarify and finally ad a code comment why, we need to pass two positions here?
I am unsure, if we still need the adjustingPhase value. Is it only read here? Original it was to prevent jump out of a loop when adjusting phase.
Now we have the original and the adjusted position to detect this.
What was the case, you need this code for?
What are the cases, we need to considder?
Can you rename dNewPlayposition to
something more descriptive?
Like dRequestedPlaypos or such?
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.
Assume an active loop starting exactly at hotcue A. If I activate the hotcue the synced position is very likely in front of the loop. The adjustingPhase is still false, as it is was a SEEK_STANDARD_PHASE. If we set the adjustingPhase to true in that case, the loop would not be disabled for any other seek position outside the loop.
Thus, the loopcontroller should know about the position requested by the user but the remaining controllers should still be notified with the synced position.
I assume that the adjustPhase is still necessary. When there was no sync, both positions are equal. But (I guess) the same holds true if only a sync without any seeking is requested.
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.
I just had a thought on solving this case differently in the processSeek method. Let the loopingcontroller calculate a position inside a loop (if enabled) based on the requested and the synced position. If the requested position is outside the loop return the synced position and behave as currently. If the requested position is inside but the synced position is outside the loop, correct the synced position into the loop.
The setNewPos and notifySeek could be left unchanged.
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.
Yes, even better readability. Thank you.
But why do we need syncPosition outside the if block?
I think it would be even more clean to have a requested position as well and not reuse position for this.