diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-04 11:14:19 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-04 11:14:19 (GMT) |
commit | 739cf93e212c27a5880ef4cb50ddf4d238ab236d (patch) | |
tree | da6db393ef3c8699d1a2dd3346f21990d84d322f | |
parent | 8cbc34de67d52d5923b3a70bf84aadfe3aa94f24 (diff) | |
parent | abcea22c5ba45d00c713d25a77773efbf6d941f7 (diff) | |
download | Qt-739cf93e212c27a5880ef4cb50ddf4d238ab236d.zip Qt-739cf93e212c27a5880ef4cb50ddf4d238ab236d.tar.gz Qt-739cf93e212c27a5880ef4cb50ddf4d238ab236d.tar.bz2 |
Merge branch 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration into 4.7-integration
* 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration:
Build fix for -qtnamespace.
Fix compile failure in QtMultimedia.
Verify the audio format before trying to open an audio device.
-rw-r--r-- | src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 23 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 8 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 11 | ||||
-rw-r--r-- | src/multimedia/audio/qaudioinput_alsa_p.cpp | 24 | ||||
-rw-r--r-- | src/multimedia/audio/qaudioinput_mac_p.cpp | 2 | ||||
-rw-r--r-- | src/multimedia/audio/qaudioinput_win32_p.cpp | 46 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput_alsa_p.cpp | 23 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput_mac_p.cpp | 6 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput_mac_p.h | 2 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput_win32_p.cpp | 36 | ||||
-rw-r--r-- | tests/auto/qaudioinput/tst_qaudioinput.cpp | 47 | ||||
-rw-r--r-- | tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 47 |
12 files changed, 235 insertions, 40 deletions
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 633b309..25622a4 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -257,37 +257,40 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + + err = -1; + switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index ecd03e5..d3dfa5f 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -78,7 +78,13 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAu bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { - return format.codec() == QString::fromLatin1("audio/pcm"); + QAudioDeviceInfoInternal *self = const_cast<QAudioDeviceInfoInternal*>(this); + + return format.isValid() + && format.codec() == QString::fromLatin1("audio/pcm") + && self->frequencyList().contains(format.frequency()) + && self->channelsList().contains(format.channels()) + && self->sampleSizeList().contains(format.sampleSize()); } QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index 9e8b1bf..4ff6a21 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -196,8 +196,9 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } - if (!match) failed = true; // check frequency match = false; @@ -208,6 +209,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample size @@ -219,6 +222,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check byte order @@ -230,6 +235,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample type @@ -241,6 +248,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } if(!failed) { diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 58669b3..ddafa3d 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -152,7 +152,7 @@ int QAudioInputPrivate::xrun_recovery(int err) int QAudioInputPrivate::setFormat() { - snd_pcm_format_t format = SND_PCM_FORMAT_S16; + snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { format = SND_PCM_FORMAT_U8; @@ -204,7 +204,9 @@ int QAudioInputPrivate::setFormat() format = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, format); + return format != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, format) + : -1; } QIODevice* QAudioInputPrivate::start(QIODevice* device) @@ -259,10 +261,26 @@ bool QAudioInputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.frequency() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.frequency()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + return false; + } + + QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index 5897e75..c3d2ae2 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -717,7 +717,7 @@ QIODevice* QAudioInputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index ece1c26..1cde159 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -214,18 +214,44 @@ bool QAudioInputPrivate::open() qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif header = 0; - if(buffer_size == 0) { - // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; - period_size = buffer_size/5; + period_size = 0; + + if (!settings.isValid()) { + qWarning("QAudioInput: open error, invalid format."); + } else if (settings.channels() <= 0) { + qWarning("QAudioInput: open error, invalid number of channels (%d).", + settings.channels()); + } else if (settings.sampleSize() <= 0) { + qWarning("QAudioInput: open error, invalid sample size (%d).", + settings.sampleSize()); + } else if (settings.frequency() < 8000 || settings.frequency() > 48000) { + qWarning("QAudioInput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + + buffer_size + = (settings.frequency() + * settings.channels() + * settings.sampleSize() +#ifndef Q_OS_WINCE // Default buffer size, 200ms, default period size is 40ms + + 39) / 40; + period_size = buffer_size / 5; } else { - period_size = buffer_size/5; - } -#ifdef Q_OS_WINCE - // For wince reduce size to 40ms for buffer size and 20ms period - buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.04; - period_size = buffer_size/2; + period_size = buffer_size / 5; +#else // For wince reduce size to 40ms for buffer size and 20ms period + + 199) / 200; + period_size = buffer_size / 2; + } else { + period_size = buffer_size / 2; #endif + } + + if (period_size == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + emit stateChanged(deviceState); + return false; + } + timeStamp.restart(); elapsedTimeOffset = 0; wfx.nSamplesPerSec = settings.frequency(); diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 49b32c0..ecf3215 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -155,7 +155,7 @@ int QAudioOutputPrivate::xrun_recovery(int err) int QAudioOutputPrivate::setFormat() { - snd_pcm_format_t pcmformat = SND_PCM_FORMAT_S16; + snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { pcmformat = SND_PCM_FORMAT_U8; @@ -208,7 +208,9 @@ int QAudioOutputPrivate::setFormat() pcmformat = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); + return pcmformat != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat) + : -1; } QIODevice* QAudioOutputPrivate::start(QIODevice* device) @@ -275,10 +277,25 @@ bool QAudioOutputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.frequency() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.frequency()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + return false; + } + QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index cc52d90..86a2e31 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -60,11 +60,11 @@ #include <QtCore/qtimer.h> #include <QtCore/qdebug.h> -#include <QtMultimedia/qaudiodeviceinfo.h> #include <QtMultimedia/qaudiooutput.h> #include "qaudio_mac_p.h" #include "qaudiooutput_mac_p.h" +#include "qaudiodeviceinfo_mac_p.h" QT_BEGIN_NAMESPACE @@ -278,6 +278,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device, const QAudioF if (QAudio::Mode(mode) == QAudio::AudioInput) errorCode = QAudio::OpenError; else { + audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioOutput); isOpen = false; audioDeviceId = AudioDeviceID(did); audioUnit = 0; @@ -299,6 +300,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device, const QAudioF QAudioOutputPrivate::~QAudioOutputPrivate() { + delete audioDeviceInfo; close(); } @@ -424,7 +426,7 @@ QIODevice* QAudioOutputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h index 752905c..7013961 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.h +++ b/src/multimedia/audio/qaudiooutput_mac_p.h @@ -73,6 +73,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QIODevice; +class QAbstractAudioDeviceInfo; namespace QtMultimediaInternal { @@ -101,6 +102,7 @@ public: QWaitCondition threadFinished; QMutex mutex; QTimer* intervalTimer; + QAbstractAudioDeviceInfo *audioDeviceInfo; QAudio::Error errorCode; QAudio::State stateCode; diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 99bada2..1f304e3 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -251,20 +251,38 @@ bool QAudioOutputPrivate::open() QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif - if (!(settings.frequency() >= 8000 && settings.frequency() <= 48000)) { + + period_size = 0; + + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.channels() <= 0) { + qWarning("QAudioOutput: open error, invalid number of channels (%d).", + settings.channels()); + } else if (settings.sampleSize() <= 0) { + qWarning("QAudioOutput: open error, invalid sample size (%d).", + settings.sampleSize()); + } else if (settings.frequency() < 8000 || settings.frequency() > 48000) { + qWarning("QAudioOutput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + // Default buffer size, 200ms, default period size is 40ms + buffer_size + = (settings.frequency() + * settings.channels() + * settings.sampleSize() + + 39) / 40; + period_size = buffer_size / 5; + } else { + period_size = buffer_size / 5; + } + + if (period_size == 0) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); - qWarning("QAudioOutput: open error, frequency out of range."); return false; } - if(buffer_size == 0) { - // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; - period_size = buffer_size/5; - } else { - period_size = buffer_size/5; - } + waveBlocks = allocateBlocks(period_size, buffer_size/period_size); mutex.lock(); diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index 84c3874..1808b1d 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -50,6 +50,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioInput : public QObject { Q_OBJECT @@ -58,6 +60,8 @@ public: private slots: void initTestCase(); + void invalidFormat_data(); + void invalidFormat(); void settings(); void buffers(); void notifyInterval(); @@ -71,6 +75,8 @@ private: void tst_QAudioInput::initTestCase() { + qRegisterMetaType<QAudioFormat>(); + format.setFrequency(8000); format.setChannels(1); format.setSampleSize(8); @@ -91,6 +97,47 @@ void tst_QAudioInput::initTestCase() audio = new QAudioInput(format, this); } +void tst_QAudioInput::invalidFormat_data() +{ + QTest::addColumn<QAudioFormat>("invalidFormat"); + + QAudioFormat audioFormat; + + QTest::newRow("Null Format") + << audioFormat; + + audioFormat = format; + audioFormat.setChannels(0); + QTest::newRow("Channel count 0") + << audioFormat; + + audioFormat = format; + audioFormat.setFrequency(0); + QTest::newRow("Sample rate 0") + << audioFormat; + + audioFormat = format; + audioFormat.setSampleSize(0); + QTest::newRow("Sample size 0") + << audioFormat; +} + +void tst_QAudioInput::invalidFormat() +{ + QFETCH(QAudioFormat, invalidFormat); + + QAudioInput audioInput(invalidFormat, this); + + // Check that we are in the default state before calling start + QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()"); + + audioInput.start(); + + // Check that error is raised + QVERIFY2((audioInput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()"); +} + void tst_QAudioInput::settings() { if(available) { diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index 437ef5e..e6d11a6 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -52,6 +52,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioOutput : public QObject { Q_OBJECT @@ -60,6 +62,8 @@ public: private slots: void initTestCase(); + void invalidFormat_data(); + void invalidFormat(); void settings(); void buffers(); void notifyInterval(); @@ -74,6 +78,8 @@ private: void tst_QAudioOutput::initTestCase() { + qRegisterMetaType<QAudioFormat>(); + format.setFrequency(8000); format.setChannels(1); format.setSampleSize(8); @@ -92,6 +98,47 @@ void tst_QAudioOutput::initTestCase() audio = new QAudioOutput(format, this); } +void tst_QAudioOutput::invalidFormat_data() +{ + QTest::addColumn<QAudioFormat>("invalidFormat"); + + QAudioFormat audioFormat; + + QTest::newRow("Null Format") + << audioFormat; + + audioFormat = format; + audioFormat.setChannels(0); + QTest::newRow("Channel count 0") + << audioFormat; + + audioFormat = format; + audioFormat.setFrequency(0); + QTest::newRow("Sample rate 0") + << audioFormat; + + audioFormat = format; + audioFormat.setSampleSize(0); + QTest::newRow("Sample size 0") + << audioFormat; +} + +void tst_QAudioOutput::invalidFormat() +{ + QFETCH(QAudioFormat, invalidFormat); + + QAudioOutput audioOutput(invalidFormat, this); + + // Check that we are in the default state before calling start + QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()"); + QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()"); + + audioOutput.start(); + + // Check that error is raised + QVERIFY2((audioOutput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()"); +} + void tst_QAudioOutput::settings() { if(available) { |