From 819f46147eb54ed3a9b390752e19c0085c9190a9 Mon Sep 17 00:00:00 2001 From: Florian Walpen Date: Mon, 30 May 2022 00:59:30 +0200 Subject: [PATCH] FreeBSD: Override UpdateLatencies() to fit OSS latencies. Reduce the base latencies for capture and playback by half a period, and let the update method account for the additional playback latency introduced by OSS buffer management. This fits actual OSS latencies better, so the same settings for the extra input-latency and output-latency parameters should apply to different period lengths. Beware that this change invalidates current input-latency and output-latency values, they have to be measured again. --- freebsd/oss/JackOSSDriver.cpp | 36 +++++++++++++++++++++++++---------- freebsd/oss/JackOSSDriver.h | 6 +++--- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/freebsd/oss/JackOSSDriver.cpp b/freebsd/oss/JackOSSDriver.cpp index ccdf4b67..d6f3e86c 100644 --- a/freebsd/oss/JackOSSDriver.cpp +++ b/freebsd/oss/JackOSSDriver.cpp @@ -868,12 +868,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, fIgnoreHW = ignorehwbuf; fNperiods = user_nperiods; fExcl = excl; - fExtraCaptureLatency = capture_latency; - fExtraPlaybackLatency = playback_latency; - // Additional playback latency introduced by the OSS buffer. The extra hardware - // latency given by the user should then be symmetric as reported by jack_iodelay. - playback_latency += user_nperiods * nframes; // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { @@ -1237,14 +1232,35 @@ int JackOSSDriver::Write() return 0; } +void JackOSSDriver::UpdateLatencies() +{ + // Reimplement from JackAudioDriver. Base latency is smaller, and there's + // additional latency due to OSS playback buffer management. + jack_latency_range_t input_range; + jack_latency_range_t output_range; + + for (int i = 0; i < fCaptureChannels; i++) { + input_range.max = input_range.min = (fEngineControl->fBufferSize / 2) + fCaptureLatency; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); + } + + for (int i = 0; i < fPlaybackChannels; i++) { + output_range.max = (fEngineControl->fBufferSize / 2) + fPlaybackLatency; + // Additional latency introduced by the OSS buffer. + output_range.max += fNperiods * fEngineControl->fBufferSize; + // Plus one period if in async mode. + if (!fEngineControl->fSyncMode) { + output_range.max += fEngineControl->fBufferSize; + } + output_range.min = output_range.max; + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); + } +} + int JackOSSDriver::SetBufferSize(jack_nframes_t buffer_size) { + // Close and reopen device, we have to adjust the OSS buffer management. CloseAux(); - - // Additional latency introduced by the OSS buffer, depends on buffer size. - fCaptureLatency = fExtraCaptureLatency; - fPlaybackLatency = fExtraPlaybackLatency + fNperiods * buffer_size; - JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails return OpenAux(); } diff --git a/freebsd/oss/JackOSSDriver.h b/freebsd/oss/JackOSSDriver.h index 6175fe06..c5449b37 100644 --- a/freebsd/oss/JackOSSDriver.h +++ b/freebsd/oss/JackOSSDriver.h @@ -53,8 +53,6 @@ class JackOSSDriver : public JackAudioDriver bool fPlayback; bool fExcl; bool fIgnoreHW; - jack_nframes_t fExtraCaptureLatency; - jack_nframes_t fExtraPlaybackLatency; unsigned int fInSampleSize; unsigned int fOutSampleSize; @@ -93,13 +91,15 @@ class JackOSSDriver : public JackAudioDriver int WriteSilence(jack_nframes_t frames); int WaitAndSync(); + protected: + virtual void UpdateLatencies(); + public: JackOSSDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fInFD(-1), fOutFD(-1), fBits(0), fNperiods(0), fCapture(false), fPlayback(false), fExcl(false), fIgnoreHW(true), - fExtraCaptureLatency(0), fExtraPlaybackLatency(0), fInSampleSize(0), fOutSampleSize(0), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL),