Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JACK buffer size fix. #11121

Merged
merged 21 commits into from
Feb 4, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c2b1af8
Fix condition in JACK backend check
robbert-vdh Nov 24, 2022
82c7f71
Replace m_framesPerBuffer uses with runtime size
robbert-vdh Dec 6, 2022
fefbfd2
Use std::unique_ptr for FIFOs in PortAudio backend
robbert-vdh Dec 6, 2022
cfeffa7
Remove unused getProcessingLatency() function
robbert-vdh Dec 6, 2022
1451803
renamed m_framesPerBuffer to m_configFramesPerBuffer
daschuer Dec 3, 2022
b1b14b1
Improve the comment that explains paFramesPerBufferUnspecified
daschuer Dec 3, 2022
8f97592
Don't use the m_configFramesPerBuffe and improve debug output and com…
daschuer Dec 4, 2022
4c1eb24
dispose m_iBufferSize and use always the callback value as parameter
daschuer Dec 4, 2022
e52de39
Always use the real framesPerBuffer value received via the callback
daschuer Dec 4, 2022
75d0e29
Deduplicate code in VisualPlayPosition
daschuer Dec 6, 2022
f1bc670
Apply a better offset limit in VisualPlayposition
daschuer Dec 6, 2022
096089d
Dispose audio_buffer_size and use directly the callback parameter
daschuer Dec 6, 2022
6d24c26
Use MAX_BUFFER_LEN for all non clock reference devices in case of JACK.
daschuer Dec 7, 2022
705e097
Don't allow setting device sync and network clock with the JACK API
daschuer Dec 8, 2022
e15cda3
Avoid implicit conversion from double to bool
daschuer Dec 8, 2022
b48e06d
Improve comment about vectorization
daschuer Dec 8, 2022
185a681
Improve comments and debug output
daschuer Dec 8, 2022
44fa755
check channel count for > 0 instead of implicit bool conversion
daschuer Dec 8, 2022
32379a6
Remove unused variable
daschuer Dec 9, 2022
31ba28e
Fix jackApiUsed() implementation
daschuer Dec 16, 2022
f49bf12
Use the correct term frames per period
daschuer Jan 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/engine/enginemaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ void EngineMaster::processHeadphones(
// buffer with a mono mix of the master output buffer.
if (m_pHeadSplitEnabled->toBool()) {
// note: NOT VECTORIZED because of in place copy
// with all compilers, except clang >= 14.
for (SINT i = 0; i + 1 < iBufferSize; i += 2) {
m_pHead[i] = (m_pHead[i] + m_pHead[i + 1]) / 2;
m_pHead[i + 1] = (m_pMaster[i] + m_pMaster[i + 1]) / 2;
Expand Down
25 changes: 13 additions & 12 deletions src/soundio/sounddeviceportaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
// PortAudio's JACK back end has its own buffering to split or merge the buffer
// received from JACK to the desired size.
// However, we use here paFramesPerBufferUnspecified to use the JACK buffer size
// which offers the best responds time without additional jitter.
// which offers the best response time without additional jitter due to two
// successive callback without the expected pause.
framesPerBuffer = paFramesPerBufferUnspecified;
qDebug() << "framesPerBuffer: Unspecified";
qDebug() << "Using JACK server's frames per buffer";
JoergAtGithub marked this conversation as resolved.
Show resolved Hide resolved
} else {
qDebug() << "framesPerBuffer:" << framesPerBuffer;
}
Expand Down Expand Up @@ -261,7 +262,7 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
// This causes even with the "Experimental (no delay)" setting
// one extra buffer delay for the non clock reference device
Copy link
Contributor

@Be-ing Be-ing Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no way to avoid this extra latency when using PortAudio with multiple JACK clients? If so, I think that's a good justification to not use PortAudio for JACK. (That's beyond the scope of this bugfix, of course.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no way. And yes that is only one reason why Mixxx should become a native JACK client.

pCallback = paV19Callback;
if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
m_outputFifo = std::make_unique<FIFO<CSAMPLE>>(MAX_BUFFER_LEN);
}
if (m_inputParams.channelCount) {
Expand All @@ -272,7 +273,7 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
// to avoid overflows when one callback overtakes the other or
// when there is a clock drift compared to the clock reference device
// we need an additional artificial delay
if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
// On chunk for reading one for writing and on for drift correction
m_outputFifo = std::make_unique<FIFO<CSAMPLE>>(
m_outputParams.channelCount * framesPerBuffer * kFifoSize);
Expand All @@ -291,7 +292,7 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
SampleUtil::clear(dataPtr2, size2);
m_outputFifo->releaseWriteRegions(writeCount);
}
if (m_inputParams.channelCount) {
if (m_inputParams.channelCount > 0) {
m_inputFifo = std::make_unique<FIFO<CSAMPLE>>(
m_inputParams.channelCount * framesPerBuffer * kFifoSize);
// Clear first 1.5 chunks (see above)
Expand All @@ -311,7 +312,7 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
// this can be used on a second device when it is driven by the Clock
// reference device clock
pCallback = paV19Callback;
if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
m_outputFifo = std::make_unique<FIFO<CSAMPLE>>(
m_outputParams.channelCount * framesPerBuffer);
}
Expand All @@ -320,11 +321,11 @@ SoundDeviceError SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffers
m_inputParams.channelCount * framesPerBuffer);
}
} else if (m_syncBuffers == 0) { // "Experimental (no delay)"
if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
m_outputFifo = std::make_unique<FIFO<CSAMPLE>>(
m_outputParams.channelCount * framesPerBuffer * 2);
}
if (m_inputParams.channelCount) {
if (m_inputParams.channelCount > 0) {
m_inputFifo = std::make_unique<FIFO<CSAMPLE>>(
m_inputParams.channelCount * framesPerBuffer * 2);
}
Expand Down Expand Up @@ -768,7 +769,7 @@ int SoundDevicePortAudio::callbackProcessDrift(
}
}

if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
int outChunkSize = framesPerBuffer * m_outputParams.channelCount;
int readAvailable = m_outputFifo->readAvailable();

Expand Down Expand Up @@ -815,7 +816,7 @@ int SoundDevicePortAudio::callbackProcessDrift(
m_pSoundManager->underflowHappened(11);
//qDebug() << "callbackProcess read:" << (float)readAvailable / outChunkSize << "Buffer empty";
}
}
}
return paContinue;
}

Expand Down Expand Up @@ -848,7 +849,7 @@ int SoundDevicePortAudio::callbackProcess(const SINT framesPerBuffer,
}
}

if (m_outputParams.channelCount) {
if (m_outputParams.channelCount > 0) {
int outChunkSize = framesPerBuffer * m_outputParams.channelCount;
int readAvailable = m_outputFifo->readAvailable();
if (readAvailable >= outChunkSize) {
Expand All @@ -867,7 +868,7 @@ int SoundDevicePortAudio::callbackProcess(const SINT framesPerBuffer,
m_pSoundManager->underflowHappened(5);
//qDebug() << "callbackProcess read:" << "Buffer empty";
}
}
}
return paContinue;
}

Expand Down
2 changes: 1 addition & 1 deletion src/waveform/visualplayposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void VisualPlayPosition::set(
double VisualPlayPosition::calcPosAtNextVSync(
VSyncThread* pVSyncThread, const VisualPlayPositionData& data) {
double playPos = data.m_enginePlayPos; // load playPos for the first sample in Buffer
if (data.m_audioBufferMicroS) {
if (data.m_audioBufferMicroS != 0.0) {
int refToVSync = pVSyncThread->fromTimerToNextSyncMicros(data.m_referenceTime);
int offset = refToVSync - data.m_callbackEntrytoDac;
// The offset is limited to the audio buffer + waveform sync interval
Expand Down