Skip to content
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

Fix bad phase seek when starting from preroll. #4093

Merged
merged 1 commit into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/engine/controls/bpmcontrol.cpp
Expand Up @@ -812,9 +812,11 @@ double BpmControl::getBeatMatchPosition(
}
if (playing) {
if (!pOtherEngineBuffer || pOtherEngineBuffer->getSpeed() == 0.0) {
// "this" track is playing, or just starting
// only match phase if the sync target is playing as well
// else use the previous phase of "this" track before the seek
// "this" track is playing, or just starting.
// Only match phase if the sync target is playing as well,
// otherwise use the previous phase of "this" track before the seek.
// This occurs when the DJ does a quantized seek -- we preserve
// the exact beat distance.
pOtherEngineBuffer = getEngineBuffer();
}
} else if (!pOtherEngineBuffer) {
Expand Down
8 changes: 2 additions & 6 deletions src/engine/enginebuffer.cpp
Expand Up @@ -1353,14 +1353,10 @@ void EngineBuffer::slotEjectTrack(double v) {
}

double EngineBuffer::getExactPlayPos() {
double visualPlayPos = getVisualPlayPos();
if (visualPlayPos > 0) {
return getVisualPlayPos() * getTrackSamples();
} else {
// Track was just loaded and the first buffer was not processed yet.
// assume it is at 0:00
if (!m_visualPlayPos->isValid()) {
return 0.0;
}
return m_visualPlayPos->getEnginePlayPos() * getTrackSamples();
}

double EngineBuffer::getVisualPlayPos() {
Expand Down
20 changes: 20 additions & 0 deletions src/test/enginesynctest.cpp
Expand Up @@ -1361,6 +1361,26 @@ TEST_F(EngineSyncTest, ZeroBPMRateAdjustIgnored) {
ControlObject::getControl(ConfigKey(m_sGroup2, "rate"))->get());
}

TEST_F(EngineSyncTest, BeatDistanceBeforeStart) {
// https://bugs.launchpad.net/mixxx/+bug/1930143
// If the start position is before zero, we should still initialize the beat distance
// correctly. Unfortunately, this currently doesn't work.

mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(
m_pTrack1->getSampleRate(), 128, 0);
m_pTrack1->trySetBeats(pBeats1);
ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0);
ControlObject::set(ConfigKey(m_sGroup1, "playposition"), -.05);
ProcessBuffer();
ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0);
ProcessBuffer();
// This fraction is one buffer beyond the seek position -- indicating that
// we seeked correctly.
EXPECT_NEAR(0.49143461829176116,
ControlObject::getControl(ConfigKey(m_sGroup1, "beat_distance"))->get(),
kMaxBeatDistanceEpsilon);
}

TEST_F(EngineSyncTest, ZeroLatencyRateChangeNoQuant) {
// Confirm that a rate change in an explicit master is instantly communicated
// to followers.
Expand Down
3 changes: 3 additions & 0 deletions src/waveform/visualplayposition.h
Expand Up @@ -60,6 +60,9 @@ class VisualPlayPosition : public QObject {
static void setCallbackEntryToDacSecs(double secs, const PerformanceTimer& time);

void setInvalid() { m_valid = false; };
bool isValid() const {
return m_valid;
}

private slots:
void slotAudioBufferSizeChanged(double sizeMs);
Expand Down