-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
JACK buffer size fix. #11121
Changes from 1 commit
c2b1af8
82c7f71
fefbfd2
cfeffa7
1451803
b1b14b1
8f97592
4c1eb24
e52de39
75d0e29
f1bc670
096089d
6d24c26
705e097
e15cda3
b48e06d
185a681
44fa755
32379a6
31ba28e
f49bf12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,10 +65,10 @@ SoundDeviceError SoundDeviceNetwork::open(bool isClkRefDevice, int syncBuffers) | |
|
||
qDebug() << "framesPerBuffer:" << m_framesPerBuffer; | ||
|
||
m_audioBufferTime = mixxx::Duration::fromSeconds( | ||
const auto requestedBufferTime = mixxx::Duration::fromSeconds( | ||
m_framesPerBuffer / m_dSampleRate); | ||
qDebug() << "Requested sample rate: " << m_dSampleRate << "Hz, latency:" | ||
<< m_audioBufferTime; | ||
<< requestedBufferTime; | ||
|
||
// Feed the network device buffer directly from the | ||
// clock reference device callback | ||
|
@@ -89,15 +89,15 @@ SoundDeviceError SoundDeviceNetwork::open(bool isClkRefDevice, int syncBuffers) | |
// Update the samplerate and latency ControlObjects, which allow the | ||
// waveform view to properly correct for the latency. | ||
ControlObject::set(ConfigKey("[Master]", "latency"), | ||
m_audioBufferTime.toDoubleMillis()); | ||
requestedBufferTime.toDoubleMillis()); | ||
ControlObject::set(ConfigKey("[Master]", "samplerate"), m_dSampleRate); | ||
ControlObject::set(ConfigKey("[Master]", "audio_buffer_size"), | ||
m_audioBufferTime.toDoubleMillis()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it's highly unlikely that this CO is used somewhere in mappings or skins - and therefore can be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to mention that it also needs to be removed from the Mixxx Controls section in the manual, but that CO does not seem to be documented anyway. 🤷 |
||
requestedBufferTime.toDoubleMillis()); | ||
|
||
// Network stream was just started above so we have to wait until | ||
// we can pass one chunk. | ||
// The first callback runs early to do the one time setups | ||
m_targetTime = m_audioBufferTime.toIntegerMicros(); | ||
m_targetTime = requestedBufferTime.toIntegerMicros(); | ||
|
||
m_pThread = std::make_unique<SoundDeviceNetworkThread>(this); | ||
m_pThread->start(QThread::TimeCriticalPriority); | ||
|
@@ -129,12 +129,12 @@ QString SoundDeviceNetwork::getError() const { | |
return QString(); | ||
} | ||
|
||
void SoundDeviceNetwork::readProcess() { | ||
void SoundDeviceNetwork::readProcess(SINT framesPerBuffer) { | ||
if (!m_inputFifo || !m_pNetworkStream || !m_iNumInputChannels) { | ||
return; | ||
} | ||
|
||
int inChunkSize = m_framesPerBuffer * m_iNumInputChannels; | ||
int inChunkSize = framesPerBuffer * m_iNumInputChannels; | ||
int readAvailable = m_pNetworkStream->getReadExpected() | ||
* m_iNumInputChannels; | ||
int writeAvailable = m_inputFifo->writeAvailable(); | ||
|
@@ -220,15 +220,15 @@ void SoundDeviceNetwork::readProcess() { | |
clearInputBuffer(inChunkSize - readCount, readCount); | ||
} | ||
|
||
m_pSoundManager->pushInputBuffers(m_audioInputs, m_framesPerBuffer); | ||
m_pSoundManager->pushInputBuffers(m_audioInputs, framesPerBuffer); | ||
} | ||
|
||
void SoundDeviceNetwork::writeProcess() { | ||
void SoundDeviceNetwork::writeProcess(SINT framesPerBuffer) { | ||
if (!m_outputFifo || !m_pNetworkStream) { | ||
return; | ||
} | ||
|
||
int outChunkSize = m_framesPerBuffer * m_iNumOutputChannels; | ||
int outChunkSize = framesPerBuffer * m_iNumOutputChannels; | ||
int writeAvailable = m_outputFifo->writeAvailable(); | ||
int writeCount = outChunkSize; | ||
if (outChunkSize > writeAvailable) { | ||
|
@@ -410,7 +410,9 @@ void SoundDeviceNetwork::workerWriteSilence(NetworkOutputStreamWorkerPtr pWorker | |
|
||
void SoundDeviceNetwork::callbackProcessClkRef() { | ||
// This must be the very first call, to measure an exact value | ||
updateCallbackEntryToDacTime(); | ||
// NOTE: For network streams the buffer size is always the configured buffer | ||
// size | ||
updateCallbackEntryToDacTime(m_framesPerBuffer); | ||
|
||
Trace trace("SoundDeviceNetwork::callbackProcessClkRef %1", | ||
m_deviceId.name); | ||
|
@@ -462,33 +464,34 @@ void SoundDeviceNetwork::callbackProcessClkRef() { | |
} | ||
} | ||
|
||
m_pSoundManager->readProcess(); | ||
m_pSoundManager->readProcess(m_framesPerBuffer); | ||
|
||
{ | ||
ScopedTimer t("SoundDevicePortAudio::callbackProcess prepare %1", | ||
m_deviceId.name); | ||
m_pSoundManager->onDeviceOutputCallback(m_framesPerBuffer); | ||
} | ||
|
||
m_pSoundManager->writeProcess(); | ||
m_pSoundManager->writeProcess(m_framesPerBuffer); | ||
|
||
m_pSoundManager->processUnderflowHappened(); | ||
m_pSoundManager->processUnderflowHappened(m_framesPerBuffer); | ||
|
||
updateAudioLatencyUsage(); | ||
updateAudioLatencyUsage(m_framesPerBuffer); | ||
} | ||
|
||
void SoundDeviceNetwork::updateCallbackEntryToDacTime() { | ||
void SoundDeviceNetwork::updateCallbackEntryToDacTime(SINT framesPerBuffer) { | ||
m_clkRefTimer.start(); | ||
qint64 currentTime = m_pNetworkStream->getInputStreamTimeUs(); | ||
m_targetTime += m_audioBufferTime.toIntegerMicros(); | ||
// This deadline for the next buffer in microseconds since the Unix epoch | ||
m_targetTime += static_cast<qint64>(framesPerBuffer / m_dSampleRate * 1000000); | ||
double callbackEntrytoDacSecs = (m_targetTime - currentTime) / 1000000.0; | ||
callbackEntrytoDacSecs = math_max(callbackEntrytoDacSecs, 0.0001); | ||
Comment on lines
+487
to
489
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't we have an abstraction for sample and frame related time calculations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not aware of something for this special case. |
||
VisualPlayPosition::setCallbackEntryToDacSecs(callbackEntrytoDacSecs, m_clkRefTimer); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that for rate syncing with the frequency of the network clock There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case the latency of the main DAC is lost. It would be an extra feature to compensate this. This calculation is only to compensate the jitter that happens due to the different cycles of the audio and video thread. At least this is unrelated to this PR. Do we want to file a bug for that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, please create a bug for this. It would be great, if you could add some pointers to this report, how a possible fix could look like. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it is: #11219 |
||
//qDebug() << callbackEntrytoDacSecs << timeSinceLastCbSecs; | ||
} | ||
|
||
void SoundDeviceNetwork::updateAudioLatencyUsage() { | ||
m_framesSinceAudioLatencyUsageUpdate += m_framesPerBuffer; | ||
void SoundDeviceNetwork::updateAudioLatencyUsage(SINT framesPerBuffer) { | ||
m_framesSinceAudioLatencyUsageUpdate += framesPerBuffer; | ||
if (m_framesSinceAudioLatencyUsageUpdate | ||
> (m_dSampleRate / CPU_USAGE_UPDATE_RATE)) { | ||
double secInAudioCb = m_timeInAudioCallback.toDoubleSeconds(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the use of
const auto
here 👍