Skip to content

Commit

Permalink
Fix bad phase seek when starting from preroll.
Browse files Browse the repository at this point in the history
We were interpreting all <0 playposition as "invalid", which is not correct.
fixes https://bugs.launchpad.net/mixxx/+bug/1930143
  • Loading branch information
ywwg committed Jul 9, 2021
1 parent a05daa5 commit 31e9bd3
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 7 deletions.
4 changes: 3 additions & 1 deletion src/engine/controls/bpmcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,9 @@ double BpmControl::getBeatMatchPosition(
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
// else use the previous phase of "this" track before the seek.
// This means when the DJ does a quantized seek, we presere
// the exact beat distance.
pOtherEngineBuffer = getEngineBuffer();
}
} else if (!pOtherEngineBuffer) {
Expand Down
8 changes: 2 additions & 6 deletions src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit 31e9bd3

Please sign in to comment.