Skip to content

Commit 6781d9d

Browse files
committed
SoundDeviceNetwork: Be more relaxed in case of one delayed callback. This allows to catch up without immediately replacing the delayed frames with silence. The worker has a longer latency and enough buffer to compensate that.
1 parent 351d71c commit 6781d9d

1 file changed

Lines changed: 47 additions & 45 deletions

File tree

src/soundio/sounddevicenetwork.cpp

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -300,69 +300,71 @@ void SoundDeviceNetwork::workerWriteProcess(NetworkOutputStreamWorkerPtr pWorker
300300
int writeExpected = writeExpectedFrames * m_numOutputChannels;
301301

302302
if (writeExpected <= 0) {
303-
// Overflow
304-
// kLogger.debug() << "workerWriteProcess: buffer full"
303+
// Overflow: We more than one buffer ahead. That happens if the engine tries to catch up
304+
// already earlier misses already filled with silence
305+
// kLogger.debug() << "workerWriteProcess: ahead of time"
305306
// << "outChunkSize" << outChunkSize
306307
// << "readAvailable" << readAvailable
307308
// << "writeExpected" << writeExpected
308309
// << "streamTime" << pWorker->getStreamTimeFrames();
309310
// catch up by skipping chunk
310311
m_pSoundManager->underflowHappened(25);
312+
return;
311313
}
312-
int copyCount = qMin(readAvailable, writeExpected);
313314

314-
if (copyCount > 0) {
315-
if (writeExpected - copyCount > outChunkSize) {
316-
// Underflow
315+
if (writeExpected - readAvailable > outChunkSize) {
316+
// Underflow: We are late by more than one buffer outChunkSize
317+
if (pWorker->outputDrift()) {
317318
// kLogger.debug() << "workerWriteProcess: buffer empty."
318319
// << "Catch up with silence:" << writeExpected - copyCount
319320
// << "streamTime" << pWorker->getStreamTimeFrames();;
320321
// catch up by filling buffer until we are synced
321-
workerWriteSilence(pWorker, writeExpected - copyCount);
322+
workerWriteSilence(pWorker, writeExpected - readAvailable);
322323
m_pSoundManager->underflowHappened(24);
323-
} else if (writeExpected - copyCount > outChunkSize / 2) {
324-
// try to keep PAs buffer filled up to 0.5 chunks
325-
if (pWorker->outputDrift()) {
326-
// duplicate one frame
327-
// kLogger.debug() << "workerWriteProcess() duplicate one frame"
328-
// << (float)writeExpected / outChunkSize
329-
// << (float)readAvailable / outChunkSize;
330-
workerWrite(pWorker, dataPtr1, 1);
331-
} else {
332-
pWorker->setOutputDrift(true);
333-
}
334-
} else if (writeExpected < outChunkSize / 2) {
335-
// We will overshoot by more than a half of the new frames
336-
if (pWorker->outputDrift()) {
337-
// kLogger.debug() << "SoundDeviceNetwork::workerWriteProcess() "
338-
// "skip one frame"
339-
// << (float)writeAvailable / outChunkSize
340-
// << (float)readAvailable / outChunkSize;
341-
if (size1 >= m_numOutputChannels) {
342-
dataPtr1 += m_numOutputChannels;
343-
size1 -= m_numOutputChannels;
344-
}
345-
} else {
346-
pWorker->setOutputDrift(true);
324+
} else {
325+
pWorker->setOutputDrift(true);
326+
}
327+
} else if (writeExpected - readAvailable > outChunkSize / 2) {
328+
// try to keep PAs buffer filled up to 0.5 chunks
329+
if (pWorker->outputDrift()) {
330+
// duplicate one frame
331+
// kLogger.debug() << "workerWriteProcess() duplicate one frame"
332+
// << (float)writeExpected / outChunkSize
333+
// << (float)readAvailable / outChunkSize;
334+
workerWrite(pWorker, dataPtr1, 1);
335+
} else {
336+
pWorker->setOutputDrift(true);
337+
}
338+
} else if (writeExpected < outChunkSize / 2) {
339+
// We will overshoot by more than a half of the new frames
340+
if (pWorker->outputDrift()) {
341+
// kLogger.debug() << "SoundDeviceNetwork::workerWriteProcess() "
342+
// "skip one frame"
343+
// << (float)writeAvailable / outChunkSize
344+
// << (float)readAvailable / outChunkSize;
345+
if (size1 >= m_numOutputChannels) {
346+
dataPtr1 += m_numOutputChannels;
347+
size1 -= m_numOutputChannels;
347348
}
348349
} else {
349-
pWorker->setOutputDrift(false);
350+
pWorker->setOutputDrift(true);
350351
}
352+
} else {
353+
pWorker->setOutputDrift(false);
354+
}
351355

352-
workerWrite(pWorker, dataPtr1, size1 / m_numOutputChannels);
353-
if (size2 > 0) {
354-
workerWrite(pWorker, dataPtr2, size2 / m_numOutputChannels);
355-
}
356+
workerWrite(pWorker, dataPtr1, size1 / m_numOutputChannels);
357+
if (size2 > 0) {
358+
workerWrite(pWorker, dataPtr2, size2 / m_numOutputChannels);
359+
}
356360

357-
QSharedPointer<FIFO<CSAMPLE>> pFifo = pWorker->getOutputFifo();
358-
if (pFifo) {
359-
// interval = copyCount
360-
// Check for desired kNetworkLatencyFrames + 1/2 interval to
361-
// avoid big jitter due to interferences with sync code
362-
if (pFifo->readAvailable() + copyCount / 2 >=
363-
(m_numOutputChannels * kNetworkLatencyFrames)) {
364-
pWorker->outputAvailable();
365-
}
361+
QSharedPointer<FIFO<CSAMPLE>> pFifo = pWorker->getOutputFifo();
362+
if (pFifo) {
363+
// Check for desired kNetworkLatencyFrames + 1/2 interval to
364+
// avoid big jitter due to interferences with sync code
365+
if (pFifo->readAvailable() + outChunkSize / 2 >=
366+
(m_numOutputChannels * kNetworkLatencyFrames)) {
367+
pWorker->outputAvailable();
366368
}
367369
}
368370
}

0 commit comments

Comments
 (0)