From 30cbbd98e7159de08bb71ab4332dbd0bab19eba5 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Tue, 16 Oct 2018 09:12:19 +0200 Subject: WindowsAudioOutput: Introduce QT_WAVE_BUFFERS env var Currently by default 5 wave buffers are created where each buffer contains buffer_size/5 bytes. If total buffer size is small enough, playing of these wave buffers might be finished before refilling them. Which leads crackling and another noise. Introduced QT_WAVE_BUFFERS env var which contains number of wave buffers. Must not be less than 5. If number of wave buffers is big enough, it ensures that there is always data to play. Task-number: QTBUG-45174 Change-Id: I66bf997411f858fbff822394bb748dea2086060e Reviewed-by: Oliver Wolff --- src/plugins/windowsaudio/qwindowsaudiooutput.cpp | 33 +++++++++++++++--------- src/plugins/windowsaudio/qwindowsaudiooutput.h | 1 + 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp index 26eecb768..f39e1694b 100644 --- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp @@ -74,6 +74,7 @@ QWindowsAudioOutput::QWindowsAudioOutput(const QByteArray &device) pullMode = true; finished = false; volumeCache = qreal(1.0); + blocks_count = 5; } QWindowsAudioOutput::~QWindowsAudioOutput() @@ -110,8 +111,9 @@ void CALLBACK QWindowsAudioOutput::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, return; } qAudio->waveFreeBlockCount++; - if(qAudio->waveFreeBlockCount >= qAudio->buffer_size/qAudio->period_size) - qAudio->waveFreeBlockCount = qAudio->buffer_size/qAudio->period_size; + if (qAudio->waveFreeBlockCount >= qAudio->blocks_count) + qAudio->waveFreeBlockCount = qAudio->blocks_count; + qAudio->feedback(); break; default: @@ -144,10 +146,7 @@ WAVEHDR* QWindowsAudioOutput::allocateBlocks(int size, int count) void QWindowsAudioOutput::freeBlocks(WAVEHDR* blockArray) { WAVEHDR* blocks = blockArray; - - int count = buffer_size/period_size; - - for(int i = 0; i < count; i++) { + for (int i = 0; i < blocks_count; ++i) { waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR)); blocks++; } @@ -252,16 +251,26 @@ bool QWindowsAudioOutput::open() return false; } - waveBlocks = allocateBlocks(period_size, buffer_size/period_size); + const int periods = buffer_size / period_size; + bool ok = false; + static int wave_buffers = qEnvironmentVariableIntValue("QT_WAVE_BUFFERS", &ok); + if (wave_buffers < periods) { + if (ok) + qWarning("Number of WAVE buffers (QT_WAVE_BUFFERS=%d) cannot be less than %d.", wave_buffers, periods); + wave_buffers = periods; + } + + blocks_count = wave_buffers; + waveBlocks = allocateBlocks(period_size, blocks_count); mutex.lock(); - waveFreeBlockCount = buffer_size/period_size; + waveFreeBlockCount = blocks_count; mutex.unlock(); waveCurrentBlock = 0; if(audioBuffer == 0) - audioBuffer = new char[buffer_size]; + audioBuffer = new char[blocks_count * period_size]; timeStamp.restart(); elapsedTimeOffset = 0; @@ -440,7 +449,7 @@ qint64 QWindowsAudioOutput::write( const char *data, qint64 len ) totalTimeValue += current->dwBufferLength; waveCurrentBlock++; - waveCurrentBlock %= buffer_size/period_size; + waveCurrentBlock %= blocks_count; current = &waveBlocks[waveCurrentBlock]; current->dwUser = 0; errorState = QAudio::NoError; @@ -547,7 +556,7 @@ bool QWindowsAudioOutput::deviceReady() check = waveFreeBlockCount; mutex.unlock(); - if(check == buffer_size/period_size) { + if (check == blocks_count) { if (deviceState != QAudio::IdleState) { errorState = QAudio::UnderrunError; deviceState = QAudio::IdleState; @@ -567,7 +576,7 @@ bool QWindowsAudioOutput::deviceReady() buffered = waveFreeBlockCount; mutex.unlock(); - if (buffered >= buffer_size/period_size && deviceState == QAudio::ActiveState) { + if (buffered >= blocks_count && deviceState == QAudio::ActiveState) { if (deviceState != QAudio::IdleState) { errorState = QAudio::UnderrunError; deviceState = QAudio::IdleState; diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.h b/src/plugins/windowsaudio/qwindowsaudiooutput.h index b71f00e98..30ee1defe 100644 --- a/src/plugins/windowsaudio/qwindowsaudiooutput.h +++ b/src/plugins/windowsaudio/qwindowsaudiooutput.h @@ -123,6 +123,7 @@ private: QTime timeStampOpened; qint32 buffer_size; qint32 period_size; + qint32 blocks_count; qint64 totalTimeValue; bool pullMode; int intervalTime; -- cgit v1.2.3