summaryrefslogtreecommitdiffstats
path: root/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-03-13 16:25:15 +0100
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-04-14 14:42:21 +0000
commit07606dde9a1f6b89f582ff8f1fbc53e2d4eb2c22 (patch)
treefe9d60b38e6f4232619ba44dd8f15dd1eada444a /src/plugins/windowsaudio/qwindowsaudiooutput.cpp
parentb529cf242a596b47ebb0fc659e63439fa6e7cb79 (diff)
WindowsAudio: improve supported formats detection.
QAudioDeviceInfo::isFormatSupported() now tries to open the device with that format to theck if it is supported. We were before simply checking that its parameters were included in the list of supported values, which might be incomplete. In addition, since the Windows API to check device capabilities is quite limited, we now test additional common formats and add them to the supported formats if the device can open them. Task-number: QTBUG-42648 Change-Id: Idd0affbd6d91d4fd027a6a4c86c2f3fe008a118f Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
Diffstat (limited to 'src/plugins/windowsaudio/qwindowsaudiooutput.cpp')
-rw-r--r--src/plugins/windowsaudio/qwindowsaudiooutput.cpp119
1 files changed, 9 insertions, 110 deletions
diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
index a9230139c..923488794 100644
--- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
@@ -43,55 +43,10 @@
//
#include "qwindowsaudiooutput.h"
+#include "qwindowsaudiodeviceinfo.h"
+#include "qwindowsaudioutils.h"
#include <QtEndian>
-#ifndef SPEAKER_FRONT_LEFT
- #define SPEAKER_FRONT_LEFT 0x00000001
- #define SPEAKER_FRONT_RIGHT 0x00000002
- #define SPEAKER_FRONT_CENTER 0x00000004
- #define SPEAKER_LOW_FREQUENCY 0x00000008
- #define SPEAKER_BACK_LEFT 0x00000010
- #define SPEAKER_BACK_RIGHT 0x00000020
- #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
- #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
- #define SPEAKER_BACK_CENTER 0x00000100
- #define SPEAKER_SIDE_LEFT 0x00000200
- #define SPEAKER_SIDE_RIGHT 0x00000400
- #define SPEAKER_TOP_CENTER 0x00000800
- #define SPEAKER_TOP_FRONT_LEFT 0x00001000
- #define SPEAKER_TOP_FRONT_CENTER 0x00002000
- #define SPEAKER_TOP_FRONT_RIGHT 0x00004000
- #define SPEAKER_TOP_BACK_LEFT 0x00008000
- #define SPEAKER_TOP_BACK_CENTER 0x00010000
- #define SPEAKER_TOP_BACK_RIGHT 0x00020000
- #define SPEAKER_RESERVED 0x7FFC0000
- #define SPEAKER_ALL 0x80000000
-#endif
-
-#ifndef _WAVEFORMATEXTENSIBLE_
-
- #define _WAVEFORMATEXTENSIBLE_
- typedef struct
- {
- WAVEFORMATEX Format; // Base WAVEFORMATEX data
- union
- {
- WORD wValidBitsPerSample; // Valid bits in each sample container
- WORD wSamplesPerBlock; // Samples per block of audio data; valid
- // if wBitsPerSample=0 (but rarely used).
- WORD wReserved; // Zero if neither case above applies.
- } Samples;
- DWORD dwChannelMask; // Positions of the audio channels
- GUID SubFormat; // Format identifier GUID
- } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
- typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
-
-#endif
-
-#if !defined(WAVE_FORMAT_EXTENSIBLE)
-#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
-#endif
-
//#define DEBUG_AUDIO 1
QT_BEGIN_NAMESPACE
@@ -264,16 +219,8 @@ bool QWindowsAudioOutput::open()
period_size = 0;
- if (!settings.isValid()) {
+ if (!qt_convertFormat(settings, &wfx)) {
qWarning("QAudioOutput: open error, invalid format.");
- } else if (settings.channelCount() <= 0) {
- qWarning("QAudioOutput: open error, invalid number of channels (%d).",
- settings.channelCount());
- } else if (settings.sampleSize() <= 0) {
- qWarning("QAudioOutput: open error, invalid sample size (%d).",
- settings.sampleSize());
- } else if (settings.sampleRate() < 8000 || settings.sampleRate() > 96000) {
- qWarning("QAudioOutput: open error, sample rate out of range (%d).", settings.sampleRate());
} else if (buffer_size == 0) {
// Default buffer size, 200ms, default period size is 40ms
buffer_size
@@ -307,67 +254,19 @@ bool QWindowsAudioOutput::open()
timeStamp.restart();
elapsedTimeOffset = 0;
- wfx.nSamplesPerSec = settings.sampleRate();
- wfx.wBitsPerSample = settings.sampleSize();
- wfx.nChannels = settings.channelCount();
- wfx.cbSize = 0;
-
- bool surround = false;
-
- if (settings.channelCount() > 2)
- surround = true;
-
- wfx.wFormatTag = WAVE_FORMAT_PCM;
- wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
- wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
-
QDataStream ds(&m_device, QIODevice::ReadOnly);
quint32 deviceId;
ds >> deviceId;
- if (!surround) {
- if (waveOutOpen(&hWaveOut, UINT_PTR(deviceId), &wfx,
+ if (waveOutOpen(&hWaveOut, UINT_PTR(deviceId), &wfx.Format,
(DWORD_PTR)&waveOutProc,
(DWORD_PTR) this,
CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioOutput: open error");
- return false;
- }
- } else {
- WAVEFORMATEXTENSIBLE wfex;
- wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
- wfex.Format.nChannels = settings.channelCount();
- wfex.Format.wBitsPerSample = settings.sampleSize();
- wfex.Format.nSamplesPerSec = settings.sampleRate();
- wfex.Format.nBlockAlign = wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
- wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*wfex.Format.nBlockAlign;
- wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
- static const GUID _KSDATAFORMAT_SUBTYPE_PCM = {
- 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
- wfex.SubFormat=_KSDATAFORMAT_SUBTYPE_PCM;
- wfex.Format.cbSize=22;
-
- wfex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
- if (settings.channelCount() >= 4)
- wfex.dwChannelMask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
- if (settings.channelCount() >= 6)
- wfex.dwChannelMask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY;
- if (settings.channelCount() == 8)
- wfex.dwChannelMask |= SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
-
- if (waveOutOpen(&hWaveOut, UINT_PTR(deviceId), &wfex.Format,
- (DWORD_PTR)&waveOutProc,
- (DWORD_PTR) this,
- CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioOutput: open error");
- return false;
- }
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
}
totalTimeValue = 0;