diff options
Diffstat (limited to 'src/plugins/wasapi/qwasapiaudioinput.cpp')
-rw-r--r-- | src/plugins/wasapi/qwasapiaudioinput.cpp | 121 |
1 files changed, 62 insertions, 59 deletions
diff --git a/src/plugins/wasapi/qwasapiaudioinput.cpp b/src/plugins/wasapi/qwasapiaudioinput.cpp index 3bcf50367..22a77df38 100644 --- a/src/plugins/wasapi/qwasapiaudioinput.cpp +++ b/src/plugins/wasapi/qwasapiaudioinput.cpp @@ -120,7 +120,7 @@ qint64 WasapiInputDevicePrivate::readData(char* data, qint64 len) qFatal("Could not release buffer"); if (m_input->m_interval && m_input->m_openTime.elapsed() - m_input->m_openTimeOffset > m_input->m_interval) { - QMetaObject::invokeMethod(m_input, "notify", Qt::QueuedConnection); + emit m_input->notify(); m_input->m_openTimeOffset = m_input->m_openTime.elapsed(); } @@ -128,8 +128,7 @@ qint64 WasapiInputDevicePrivate::readData(char* data, qint64 len) if (m_input->m_currentState != QAudio::ActiveState) { m_input->m_currentState = QAudio::ActiveState; - QMetaObject::invokeMethod(m_input, "stateChanged", Qt::QueuedConnection, - Q_ARG(QAudio::State, QAudio::ActiveState)); + emit m_input->stateChanged(m_input->m_currentState); } return readBytes; } @@ -192,13 +191,9 @@ qreal QWasapiAudioInput::volume() const void QWasapiAudioInput::process() { qCDebug(lcMmAudioInput) << __FUNCTION__; - const quint32 channelCount = m_currentFormat.channelCount(); - const quint32 sampleBytes = m_currentFormat.sampleSize() / 8; - BYTE* buffer; - HRESULT hr; DWORD waitRet; - bool processing = true; + m_processing = true; do { waitRet = WaitForSingleObjectEx(m_event, 2000, FALSE); if (waitRet != WAIT_OBJECT_0) { @@ -210,67 +205,75 @@ void QWasapiAudioInput::process() if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState) break; + QMetaObject::invokeMethod(this, "processBuffer", Qt::QueuedConnection); + } while (m_processing); +} - if (!m_pullMode) { - QMetaObject::invokeMethod(m_eventDevice, "readyRead", Qt::QueuedConnection); - ResetEvent(m_event); - continue; - } +void QWasapiAudioInput::processBuffer() +{ + if (!m_pullMode) { + emit m_eventDevice->readyRead(); + ResetEvent(m_event); + return; + } - quint32 packetFrames; - hr = m_capture->GetNextPacketSize(&packetFrames); + QMutexLocker locker(&m_mutex); + const quint32 channelCount = m_currentFormat.channelCount(); + const quint32 sampleBytes = m_currentFormat.sampleSize() / 8; + BYTE* buffer; + HRESULT hr; - while (packetFrames != 0 && m_currentState == QAudio::ActiveState) { - DWORD flags; - quint64 devicePosition; - hr = m_capture->GetBuffer(&buffer, &packetFrames, &flags, &devicePosition, NULL); - if (hr != S_OK) { - m_currentError = QAudio::FatalError; - QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, - Q_ARG(QAudio::Error, QAudio::UnderrunError)); - // Also Error Buffers need to be released - hr = m_capture->ReleaseBuffer(packetFrames); - qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer."; - return; - } - const quint32 writeBytes = packetFrames * channelCount * sampleBytes; - if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) { - // In case this flag is set, user is supposed to ignore the content - // of the buffer and manually write silence - qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: " - << "Ignoring buffer and writing silence."; - buffer = new BYTE[writeBytes]; - memset(buffer, 0, writeBytes); - } + quint32 packetFrames; + hr = m_capture->GetNextPacketSize(&packetFrames); + + while (packetFrames != 0 && m_currentState == QAudio::ActiveState) { + DWORD flags; + quint64 devicePosition; + hr = m_capture->GetBuffer(&buffer, &packetFrames, &flags, &devicePosition, NULL); + if (hr != S_OK) { + m_currentError = QAudio::FatalError; + emit errorChanged(m_currentError); + // Also Error Buffers need to be released + hr = m_capture->ReleaseBuffer(packetFrames); + qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer."; + return; + } + const quint32 writeBytes = packetFrames * channelCount * sampleBytes; + if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) { + // In case this flag is set, user is supposed to ignore the content + // of the buffer and manually write silence + qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: " + << "Ignoring buffer and writing silence."; + buffer = new BYTE[writeBytes]; + memset(buffer, 0, writeBytes); + } - qint64 written = m_eventDevice->write(reinterpret_cast<const char *>(buffer), writeBytes); + const qint64 written = m_eventDevice->write(reinterpret_cast<const char *>(buffer), writeBytes); - if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) - delete [] buffer; + if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) + delete [] buffer; - if (written < static_cast<qint64>(writeBytes)) { - if (m_currentError != QAudio::UnderrunError) { - m_currentError = QAudio::UnderrunError; - QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, - Q_ARG(QAudio::Error, QAudio::UnderrunError)); - } + if (written < static_cast<qint64>(writeBytes)) { + if (m_currentError != QAudio::UnderrunError) { + m_currentError = QAudio::UnderrunError; + emit errorChanged(m_currentError); } - hr = m_capture->ReleaseBuffer(packetFrames); - if (hr != S_OK) - qFatal("Could not release buffer"); + } + hr = m_capture->ReleaseBuffer(packetFrames); + if (hr != S_OK) + qFatal("Could not release buffer"); - m_bytesProcessed += writeBytes; + m_bytesProcessed += writeBytes; - hr = m_capture->GetNextPacketSize(&packetFrames); - } - ResetEvent(m_event); + hr = m_capture->GetNextPacketSize(&packetFrames); + } + ResetEvent(m_event); - if (m_interval && m_openTime.elapsed() - m_openTimeOffset > m_interval) { - QMetaObject::invokeMethod(this, "notify", Qt::QueuedConnection); - m_openTimeOffset = m_openTime.elapsed(); - } - processing = m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState; - } while (processing); + if (m_interval && m_openTime.elapsed() - m_openTimeOffset > m_interval) { + emit notify(); + m_openTimeOffset = m_openTime.elapsed(); + } + m_processing = m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState; } bool QWasapiAudioInput::initStart(bool pull) |