diff options
| -rw-r--r-- | pica-client/audiodevice.cpp | 15 | ||||
| -rw-r--r-- | pica-client/audiodevice.h | 8 |
2 files changed, 22 insertions, 1 deletions
diff --git a/pica-client/audiodevice.cpp b/pica-client/audiodevice.cpp index 487df7e..aa4c42a 100644 --- a/pica-client/audiodevice.cpp +++ b/pica-client/audiodevice.cpp @@ -235,6 +235,12 @@ void AudioDevice::Capture() enc_ctx->time_base = AVRational{1, m_sampleRate}; applyMonoLayout(enc_ctx); + // "voip" favors speech intelligibility over faithfulness and has lower + // algorithmic delay than the default "audio" mode - a better fit for a + // live call than for e.g. music. Only libopus exposes this private + // option; harmless no-op on the native "opus" encoder fallback. + av_opt_set(enc_ctx->priv_data, "application", "voip", 0); + if ((ret = avcodec_open2(enc_ctx, enc, nullptr)) < 0) { QString msg = QString("Could not open Opus encoder: %1").arg(ff_errstr(ret)); @@ -473,6 +479,15 @@ void AudioDevice::Play() bool loggedResamplerError = false; bool loggedEncodeError = false; + // Preroll: wait for a small cushion of buffered packets before writing + // the first one, so ordinary arrival jitter doesn't immediately drain + // the queue and starve the ALSA buffer (heard as crackling/xruns). + { + QMutexLocker locker(&m_queueMutex); + while (m_playQueue.size() < kPrerollDepth && !m_abort.loadRelaxed()) + m_queueCond.wait(&m_queueMutex, 100); + } + while (true) { QByteArray pktData; diff --git a/pica-client/audiodevice.h b/pica-client/audiodevice.h index ef78f8e..60f64a5 100644 --- a/pica-client/audiodevice.h +++ b/pica-client/audiodevice.h @@ -97,7 +97,13 @@ private: QMutex m_queueMutex; QWaitCondition m_queueCond; QQueue<QByteArray> m_playQueue; - static const int kMaxQueueDepth = 4; + static const int kMaxQueueDepth = 8; + + // Number of packets Play() waits to have buffered before writing the + // first one, to build up a cushion against arrival jitter (packets + // this call apart arrive roughly every 20ms - see + // AudioVideoCallController::startAudioPipeline()). + static const int kPrerollDepth = 3; }; #endif // AUDIODEVICE_H |
