diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp index 26eecb76830be4146d5af276a52baaa29190c052..f39e1694bfd4b8ff67cfb9117e786d09d6309669 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 b71f00e98d911064def85eed641627744322d354..30ee1defe004b5f6941258136492e2fe9be7f495 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;