diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-15 09:26:14 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-15 09:26:14 +0200 |
commit | 1925bb404ec47b6e074c5e3b334fe0be12176d7b (patch) | |
tree | 8d7d79ac1b3a549c20bb4fa77c6f457bf1bb61ea /src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp | |
parent | 6187b72c51d0c05955d9d814baf8866b8e70fcfe (diff) | |
parent | f9145aca166ad2ca1514524ce88ded7834eb207c (diff) |
Merge remote-tracking branch 'origin/5.4' into 5.5
Conflicts:
src/multimedia/playback/playlistfileparser.cpp
src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
Change-Id: I52950def2b8283ae15797d05d4ead6a1256eba19
Diffstat (limited to 'src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp')
-rw-r--r-- | src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp | 199 |
1 files changed, 94 insertions, 105 deletions
diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp index ede60c963..801f792e0 100644 --- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp @@ -47,6 +47,7 @@ #include <QtCore/QDataStream> #include <mmsystem.h> #include "qwindowsaudiodeviceinfo.h" +#include "qwindowsaudioutils.h" #if defined(Q_CC_MINGW) && !defined(__MINGW64_VERSION_MAJOR) struct IBaseFilter; // Needed for strmif.h from stock MinGW. @@ -167,8 +168,7 @@ QString QWindowsAudioDeviceInfo::deviceName() const QStringList QWindowsAudioDeviceInfo::supportedCodecs() { - updateLists(); - return codecz; + return QStringList() << QStringLiteral("audio/pcm"); } QList<int> QWindowsAudioDeviceInfo::supportedSampleRates() @@ -191,8 +191,7 @@ QList<int> QWindowsAudioDeviceInfo::supportedSampleSizes() QList<QAudioFormat::Endian> QWindowsAudioDeviceInfo::supportedByteOrders() { - updateLists(); - return byteOrderz; + return QList<QAudioFormat::Endian>() << QAudioFormat::LittleEndian; } QList<QAudioFormat::SampleType> QWindowsAudioDeviceInfo::supportedSampleTypes() @@ -213,118 +212,50 @@ void QWindowsAudioDeviceInfo::close() bool QWindowsAudioDeviceInfo::testSettings(const QAudioFormat& format) const { - // Set nearest to closest settings that do work. - // See if what is in settings will work (return value). - - bool failed = false; - bool match = false; - - // check codec - for( int i = 0; i < codecz.count(); i++) { - if (format.codec() == codecz.at(i)) - match = true; - } - if (!match) failed = true; - - // check channel - match = false; - if (!failed) { - for (int i = 0; i < channelz.count(); i++) { - if (format.channelCount() == channelz.at(i)) { - match = true; - break; - } - } - if (!match) - failed = true; - } - - // check sampleRate - match = false; - if (!failed) { - for (int i = 0; i < sampleRatez.count(); i++) { - if (format.sampleRate() == sampleRatez.at(i)) { - match = true; - break; - } - } - if (!match) - failed = true; - } - - // check sample size - match = false; - if (!failed) { - for( int i = 0; i < sizez.count(); i++) { - if (format.sampleSize() == sizez.at(i)) { - match = true; - break; - } - } - if (!match) - failed = true; - } - - // check byte order - match = false; - if (!failed) { - for( int i = 0; i < byteOrderz.count(); i++) { - if (format.byteOrder() == byteOrderz.at(i)) { - match = true; - break; - } - } - if (!match) - failed = true; - } - - // check sample type - match = false; - if (!failed) { - for( int i = 0; i < typez.count(); i++) { - if (format.sampleType() == typez.at(i)) { - match = true; - break; - } + WAVEFORMATEXTENSIBLE wfx; + if (qt_convertFormat(format, &wfx)) { + // query only, do not open device + if (mode == QAudio::AudioOutput) { + return (waveOutOpen(NULL, UINT_PTR(devId), &wfx.Format, NULL, NULL, + WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); + } else { // AudioInput + return (waveInOpen(NULL, UINT_PTR(devId), &wfx.Format, NULL, NULL, + WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); } - if (!match) - failed = true; } - if(!failed) { - // settings work - return true; - } return false; } void QWindowsAudioDeviceInfo::updateLists() { - // redo all lists based on current settings - bool match = false; + if (!sizez.isEmpty()) + return; + + bool hasCaps = false; DWORD fmt = 0; if(mode == QAudio::AudioOutput) { WAVEOUTCAPS woc; if (waveOutGetDevCaps(devId, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR) { - match = true; + hasCaps = true; fmt = woc.dwFormats; } } else { WAVEINCAPS woc; if (waveInGetDevCaps(devId, &woc, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) { - match = true; + hasCaps = true; fmt = woc.dwFormats; } } + sizez.clear(); sampleRatez.clear(); channelz.clear(); - byteOrderz.clear(); typez.clear(); - codecz.clear(); - if(match) { + if (hasCaps) { + // Check sample size if ((fmt & WAVE_FORMAT_1M08) || (fmt & WAVE_FORMAT_1S08) || (fmt & WAVE_FORMAT_2M08) @@ -334,8 +265,7 @@ void QWindowsAudioDeviceInfo::updateLists() || (fmt & WAVE_FORMAT_48M08) || (fmt & WAVE_FORMAT_48S08) || (fmt & WAVE_FORMAT_96M08) - || (fmt & WAVE_FORMAT_96S08) - ) { + || (fmt & WAVE_FORMAT_96S08)) { sizez.append(8); } if ((fmt & WAVE_FORMAT_1M16) @@ -347,10 +277,11 @@ void QWindowsAudioDeviceInfo::updateLists() || (fmt & WAVE_FORMAT_48M16) || (fmt & WAVE_FORMAT_48S16) || (fmt & WAVE_FORMAT_96M16) - || (fmt & WAVE_FORMAT_96S16) - ) { + || (fmt & WAVE_FORMAT_96S16)) { sizez.append(16); } + + // Check sample rate if ((fmt & WAVE_FORMAT_1M08) || (fmt & WAVE_FORMAT_1S08) || (fmt & WAVE_FORMAT_1M16) @@ -381,23 +312,81 @@ void QWindowsAudioDeviceInfo::updateLists() || (fmt & WAVE_FORMAT_96S16)) { sampleRatez.append(96000); } - channelz.append(1); - channelz.append(2); - if (mode == QAudio::AudioOutput) { - channelz.append(4); - channelz.append(6); - channelz.append(8); - } - byteOrderz.append(QAudioFormat::LittleEndian); + // Check channel count + if (fmt & WAVE_FORMAT_1M08 + || fmt & WAVE_FORMAT_1M16 + || fmt & WAVE_FORMAT_2M08 + || fmt & WAVE_FORMAT_2M16 + || fmt & WAVE_FORMAT_4M08 + || fmt & WAVE_FORMAT_4M16 + || fmt & WAVE_FORMAT_48M08 + || fmt & WAVE_FORMAT_48M16 + || fmt & WAVE_FORMAT_96M08 + || fmt & WAVE_FORMAT_96M16) { + channelz.append(1); + } + if (fmt & WAVE_FORMAT_1S08 + || fmt & WAVE_FORMAT_1S16 + || fmt & WAVE_FORMAT_2S08 + || fmt & WAVE_FORMAT_2S16 + || fmt & WAVE_FORMAT_4S08 + || fmt & WAVE_FORMAT_4S16 + || fmt & WAVE_FORMAT_48S08 + || fmt & WAVE_FORMAT_48S16 + || fmt & WAVE_FORMAT_96S08 + || fmt & WAVE_FORMAT_96S16) { + channelz.append(2); + } typez.append(QAudioFormat::SignedInt); typez.append(QAudioFormat::UnSignedInt); - codecz.append(QLatin1String("audio/pcm")); + // WAVEOUTCAPS and WAVEINCAPS contains information only for the previously tested parameters. + // WaveOut and WaveInt might actually support more formats, the only way to know is to try + // opening the device with it. + QAudioFormat testFormat; + testFormat.setCodec(QStringLiteral("audio/pcm")); + testFormat.setByteOrder(QAudioFormat::LittleEndian); + testFormat.setSampleType(QAudioFormat::SignedInt); + testFormat.setChannelCount(channelz.first()); + testFormat.setSampleRate(sampleRatez.at(sampleRatez.size() / 2)); + testFormat.setSampleSize(sizez.last()); + const QAudioFormat defaultTestFormat(testFormat); + + // Check if float samples are supported + testFormat.setSampleType(QAudioFormat::Float); + testFormat.setSampleSize(32); + if (testSettings(testFormat)) + typez.append(QAudioFormat::Float); + + // Check channel counts > 2 + testFormat = defaultTestFormat; + for (int i = 3; i < 19; ++i) { // <mmreg.h> defines 18 different channels + testFormat.setChannelCount(i); + if (testSettings(testFormat)) + channelz.append(i); + } + + // Check more sample sizes + testFormat = defaultTestFormat; + QList<int> testSampleSizes = QList<int>() << 24 << 32 << 48 << 64; + Q_FOREACH (int s, testSampleSizes) { + testFormat.setSampleSize(s); + if (testSettings(testFormat)) + sizez.append(s); + } + + // Check more sample rates + testFormat = defaultTestFormat; + QList<int> testSampleRates = QList<int>() << 8000 << 16000 << 32000 << 88200 << 192000; + Q_FOREACH (int r, testSampleRates) { + testFormat.setSampleRate(r); + if (testSettings(testFormat)) + sampleRatez.append(r); + } + std::sort(sampleRatez.begin(), sampleRatez.end()); } - if (sampleRatez.count() > 0) - sampleRatez.prepend(8000); } QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode) |