Skip to content

Commit 3a2b8c4

Browse files
committed
Make sure that m_targetTime is only adjusted once in case of multiple broadcast connections.
1 parent 9e46fef commit 3a2b8c4

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

src/soundio/sounddevicenetwork.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "soundio/sounddevicenetwork.h"
22

33
#include <QtDebug>
4+
#include <atomic>
45

56
#include "control/controlobject.h"
67
#include "engine/sidechain/enginenetworkstream.h"
@@ -29,6 +30,19 @@ constexpr int kNetworkLatencyFrames = 8192; // 185 ms @ 44100 Hz
2930
const mixxx::Logger kLogger("SoundDeviceNetwork");
3031

3132
const QString kAppGroup = QStringLiteral("[App]");
33+
34+
bool updateIfGreater(std::atomic_int* pAtomic, int newValue) {
35+
int current = pAtomic->load(std::memory_order_relaxed);
36+
while (newValue > current &&
37+
pAtomic->compare_exchange_weak(
38+
current, // non const reference, updated each call
39+
newValue)) {
40+
// pAtomic has now newValue
41+
return true;
42+
}
43+
return false;
44+
}
45+
3246
} // namespace
3347

3448
SoundDeviceNetwork::SoundDeviceNetwork(
@@ -327,7 +341,10 @@ void SoundDeviceNetwork::workerWriteProcess(NetworkOutputStreamWorkerPtr pWorker
327341
workerWriteSilence(pWorker, silenceFrames);
328342
// Inform the engine cycle about the extra frames written to avoid
329343
// underflows in other code paths.
330-
m_targetTime += static_cast<qint64>(silenceFrames / m_sampleRate.toDouble() * 1000000);
344+
// Note, this is called for each pWorker (broadcats connection) all
345+
// running at the same network clock. The value is used for shifting
346+
// the m_targetTime and then reset to 0.
347+
updateIfGreater(&m_extraFramesWritten, silenceFrames);
331348
m_pSoundManager->underflowHappened(24);
332349
} else if (writeExpected - readAvailable > outChunkSize / 2) {
333350
// try to keep PAs buffer filled up to 0.5 chunks
@@ -522,7 +539,8 @@ void SoundDeviceNetwork::callbackProcessClkRef() {
522539
void SoundDeviceNetwork::updateCallbackEntryToDacTime(SINT framesPerBuffer) {
523540
m_clkRefTimer.start();
524541
qint64 currentTime = m_pNetworkStream->getInputStreamTimeUs();
525-
// This deadline for the next buffer in microseconds since the Unix epoch
542+
// Calculate the deadline for the next buffer in microseconds since the Unix epoch
543+
framesPerBuffer += m_extraFramesWritten.exchange(0, std::memory_order_relaxed);
526544
m_targetTime += static_cast<qint64>(framesPerBuffer / m_sampleRate.toDouble() * 1000000);
527545
double callbackEntrytoDacSecs = (m_targetTime - currentTime) / 1000000.0;
528546
callbackEntrytoDacSecs = math_max(callbackEntrytoDacSecs, 0.0001);

src/soundio/sounddevicenetwork.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class SoundDeviceNetwork : public SoundDevice {
6767
bool m_denormals;
6868
/// The deadline for the next buffer, in microseconds since the Unix epoch.
6969
qint64 m_targetTime;
70+
std::atomic_int m_extraFramesWritten;
7071
PerformanceTimer m_clkRefTimer;
7172
};
7273

0 commit comments

Comments
 (0)