From 2d2b485c648e39223e0eaa36b85125148f696010 Mon Sep 17 00:00:00 2001
From: Owen Williams <owilliams@mixxx.org>
Date: Tue, 15 Jun 2021 22:21:04 -0400
Subject: [PATCH] Sync Lock: Don't recalc half/double multiplier on every
 callback

---
 src/engine/sync/enginesync.cpp | 10 ++++++----
 src/test/enginesynctest.cpp    | 35 +++++++++++++++++++++++++---------
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp
index 595be45439c..7be0f0fe283 100644
--- a/src/engine/sync/enginesync.cpp
+++ b/src/engine/sync/enginesync.cpp
@@ -415,11 +415,13 @@ void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) {
     }
 
     if (mbaseBpm != 0.0) {
-        // resync to current master
-        pSyncable->reinitMasterParams(beatDistance, mbaseBpm, mbpm);
+        // update from current master
+        pSyncable->updateMasterBeatDistance(beatDistance);
+        pSyncable->updateMasterBpm(mbpm);
     } else {
-        // There is no other master, adopt this bpm as master
-        pSyncable->reinitMasterParams(0.0, 0.0, bpm);
+        // There is no master, adopt this bpm as master value
+        pSyncable->updateMasterBeatDistance(0.0);
+        pSyncable->updateMasterBpm(bpm);
     }
 }
 
diff --git a/src/test/enginesynctest.cpp b/src/test/enginesynctest.cpp
index 953c9405e62..fc51115364a 100644
--- a/src/test/enginesynctest.cpp
+++ b/src/test/enginesynctest.cpp
@@ -1670,18 +1670,22 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) {
     mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 140, 0.0);
     m_pTrack2->trySetBeats(pBeats2);
 
+    // Mixxx will choose the first playing deck to be master.  Let's start deck 2 first.
+    ControlObject::getControl(ConfigKey(m_sGroup1, "volume"))->set(1.0);
+    ControlObject::getControl(ConfigKey(m_sGroup2, "volume"))->set(1.0);
+    ProcessBuffer();
     ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0);
     ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0);
-    ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode"))
-            ->set(SYNC_FOLLOWER);
-    ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode"))
-            ->set(SYNC_FOLLOWER);
-
-    // Mixxx will choose the first playing deck to be master.  Let's start deck 2 first.
+    ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->set(1);
+    ControlObject::getControl(ConfigKey(m_sGroup1, "sync_enabled"))->set(1);
+    ProcessBuffer();
     ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0);
     ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0);
     ProcessBuffer();
 
+    ASSERT_TRUE(isSoftMaster(m_sGroup2));
+    ASSERT_TRUE(isFollower(m_sGroup1));
+
     EXPECT_EQ(0.5,
             m_pChannel1->getEngineBuffer()
                     ->m_pSyncControl->m_masterBpmAdjustFactor);
@@ -1777,9 +1781,15 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) {
     ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0);
 
     // We expect that m_sGroup1 has adjusted its own bpm to the second deck and becomes a single master.
-    // When the second deck is synced the master bpm is adopted by the internal clock
+    // The internal clock is initialized right away.
     EXPECT_TRUE(isSoftMaster(m_sGroup1));
     EXPECT_TRUE(isFollower(m_sGroup2));
+    EXPECT_DOUBLE_EQ(1.0,
+            m_pChannel1->getEngineBuffer()
+                    ->m_pSyncControl->m_masterBpmAdjustFactor);
+    EXPECT_DOUBLE_EQ(2.0,
+            m_pChannel2->getEngineBuffer()
+                    ->m_pSyncControl->m_masterBpmAdjustFactor);
     EXPECT_DOUBLE_EQ(87.5,
             ControlObject::getControl(ConfigKey(m_sInternalClockGroup, "bpm"))
                     ->get());
@@ -1790,9 +1800,10 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) {
     EXPECT_DOUBLE_EQ(87.5 / 80,
             ControlObject::getControl(ConfigKey(m_sGroup1, "rate_ratio"))
                     ->get());
-    EXPECT_DOUBLE_EQ(1,
+    EXPECT_DOUBLE_EQ(1.0,
             ControlObject::getControl(ConfigKey(m_sGroup2, "rate_ratio"))
                     ->get());
+    // Local bpms are not adjusted by the multiplier
     EXPECT_DOUBLE_EQ(80,
             ControlObject::getControl(ConfigKey(m_sGroup1, "local_bpm"))
                     ->get());
@@ -1828,13 +1839,19 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) {
     ProcessBuffer();
     pButtonSyncEnabled2->slotSet(1.0);
     pButtonSyncEnabled1->slotSet(1.0);
+    EXPECT_DOUBLE_EQ(1.0,
+            m_pChannel1->getEngineBuffer()
+                    ->m_pSyncControl->m_masterBpmAdjustFactor);
+    EXPECT_DOUBLE_EQ(1.0,
+            m_pChannel2->getEngineBuffer()
+                    ->m_pSyncControl->m_masterBpmAdjustFactor);
     ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0);
     ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0);
 
     EXPECT_DOUBLE_EQ(87.5 / 80,
             ControlObject::getControl(ConfigKey(m_sGroup1, "rate_ratio"))
                     ->get());
-    EXPECT_DOUBLE_EQ(1,
+    EXPECT_DOUBLE_EQ(1.0,
             ControlObject::getControl(ConfigKey(m_sGroup2, "rate_ratio"))
                     ->get());