From: Mylione Anadarajah Date: Tue, 17 Jul 2012 09:15:13 +0000 (+1000) Subject: Added data driven integration tests for qaudioinput. X-Git-Tag: upstream/5.2.95+rc1~238 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27a7559c7e87dd0c38a4b8aa1248689c1f95b216;p=platform%2Fupstream%2Fqtmultimedia.git Added data driven integration tests for qaudioinput. Change-Id: I42256833173e9ca94931ff35210802457d407e39 Reviewed-by: Michael Goddard --- diff --git a/tests/auto/integration/qaudioinput/tst_qaudioinput.cpp b/tests/auto/integration/qaudioinput/tst_qaudioinput.cpp index 9c57fd7..7d767f3 100755 --- a/tests/auto/integration/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/integration/qaudioinput/tst_qaudioinput.cpp @@ -91,7 +91,6 @@ private slots: void invalidFormat(); void bufferSize(); - void notifyInterval(); void disableNotifyInterval(); @@ -99,14 +98,22 @@ private slots: void suspendWhileStopped(); void resumeWhileStopped(); + void pull_data(){generate_audiofile_testrows();} void pull(); + + void pullSuspendResume_data(){generate_audiofile_testrows();} void pullSuspendResume(); + void push_data(){generate_audiofile_testrows();} void push(); + + void pushSuspendResume_data(){generate_audiofile_testrows();} void pushSuspendResume(); + void reset_data(){generate_audiofile_testrows();} void reset(); + void volume_data(){generate_audiofile_testrows();} void volume(); private: @@ -114,6 +121,8 @@ private: QString formatToFileName(const QAudioFormat &format); + void generate_audiofile_testrows(); + QAudioDeviceInfo audioDevice; QList testFormats; QList audioFiles; @@ -125,6 +134,21 @@ private: bool m_inCISystem; }; +void tst_QAudioInput::generate_audiofile_testrows() +{ + QTest::addColumn("audioFile"); + QTest::addColumn("audioFormat"); + + for (int i=0; iclose(); - audioFile->open(QIODevice::WriteOnly); - WavHeader wavHeader(testFormats.at(i)); - QVERIFY(wavHeader.write(*audioFile)); + // 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()"); + QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation"); - audioInput.start(audioFile); + audioFile->close(); + audioFile->open(QIODevice::WriteOnly); + WavHeader wavHeader(audioFormat); + QVERIFY(wavHeader.write(*audioFile)); - // Check that QAudioInput immediately transitions to ActiveState or IdleState - QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()"); - QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), - "didn't transition to ActiveState or IdleState after start()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - QVERIFY(audioInput.periodSize() > 0); - stateSignal.clear(); + audioInput.start(audioFile.data()); - // Check that 'elapsed' increases - QTest::qWait(40); - QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); + // Check that QAudioInput immediately transitions to ActiveState or IdleState + QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()"); + QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), + "didn't transition to ActiveState or IdleState after start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + QVERIFY(audioInput.periodSize() > 0); + stateSignal.clear(); - // Allow some recording to happen - QTest::qWait(3000); // 3 seconds should be plenty + // Check that 'elapsed' increases + QTest::qWait(40); + QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); - stateSignal.clear(); + // Allow some recording to happen + QTest::qWait(3000); // 3 seconds should be plenty - qint64 processedUs = audioInput.processedUSecs(); + stateSignal.clear(); - audioInput.stop(); - QTest::qWait(40); - QTRY_VERIFY2((stateSignal.count() == 1), - QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); + qint64 processedUs = audioInput.processedUSecs(); - QVERIFY2(qTolerantCompare(processedUs, 3040000LL), - QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData()); - QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); - QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); - QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + audioInput.stop(); + QTest::qWait(40); + QTRY_VERIFY2((stateSignal.count() == 1), + QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); - WavHeader::writeDataLength(*audioFile, audioFile->pos() - WavHeader::headerLength()); - audioFile->close(); + QVERIFY2(qTolerantCompare(processedUs, 3040000LL), + QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData()); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); + QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); + QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + + WavHeader::writeDataLength(*audioFile, audioFile->pos() - WavHeader::headerLength()); + audioFile->close(); - // Only run first format in CI system to reduce test times - if (m_inCISystem) - break; - } } void tst_QAudioInput::pullSuspendResume() @@ -496,191 +517,307 @@ void tst_QAudioInput::pullSuspendResume() if (m_inCISystem) QSKIP("QTBUG-26504 Fails 20% of time with pulseaudio backend"); #endif - for(int i=0; iclose(); - audioFiles.at(i)->open(QIODevice::WriteOnly); - WavHeader wavHeader(testFormats.at(i)); - QVERIFY(wavHeader.write(*audioFiles.at(i))); + // 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()"); + QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation"); - audioInput.start(audioFile); + audioFile->close(); + audioFile->open(QIODevice::WriteOnly); + WavHeader wavHeader(audioFormat); + QVERIFY(wavHeader.write(*audioFile)); - // Check that QAudioInput immediately transitions to ActiveState or IdleState - QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()"); - QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), - "didn't transition to ActiveState or IdleState after start()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - QVERIFY(audioInput.periodSize() > 0); - stateSignal.clear(); + audioInput.start(audioFile.data()); - // Check that 'elapsed' increases - QTest::qWait(40); - QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); + // Check that QAudioInput immediately transitions to ActiveState or IdleState + QTRY_VERIFY2((stateSignal.count() > 0),"didn't emit signals on start()"); + QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), + "didn't transition to ActiveState or IdleState after start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + QVERIFY(audioInput.periodSize() > 0); + stateSignal.clear(); - // Allow some recording to happen - QTest::qWait(3000); // 3 seconds should be plenty + // Check that 'elapsed' increases + QTest::qWait(40); + QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); - QVERIFY2((audioInput.state() == QAudio::ActiveState), - "didn't transition to ActiveState after some recording"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after some recording"); + // Allow some recording to happen + QTest::qWait(3000); // 3 seconds should be plenty - stateSignal.clear(); + QVERIFY2((audioInput.state() == QAudio::ActiveState), + "didn't transition to ActiveState after some recording"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after some recording"); - audioInput.suspend(); + stateSignal.clear(); - // Give backends running in separate threads a chance to suspend. - QTest::qWait(100); + audioInput.suspend(); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); - stateSignal.clear(); + // Give backends running in separate threads a chance to suspend. + QTest::qWait(100); - // Check that only 'elapsed', and not 'processed' increases while suspended - qint64 elapsedUs = audioInput.elapsedUSecs(); - qint64 processedUs = audioInput.processedUSecs(); - QTest::qWait(1000); - QVERIFY(audioInput.elapsedUSecs() > elapsedUs); - QVERIFY(audioInput.processedUSecs() == processedUs); + QVERIFY2((stateSignal.count() == 1), + QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); + stateSignal.clear(); - audioInput.resume(); + // Check that only 'elapsed', and not 'processed' increases while suspended + qint64 elapsedUs = audioInput.elapsedUSecs(); + qint64 processedUs = audioInput.processedUSecs(); + QTest::qWait(1000); + QVERIFY(audioInput.elapsedUSecs() > elapsedUs); + QVERIFY(audioInput.processedUSecs() == processedUs); - // Give backends running in separate threads a chance to resume. - QTest::qWait(100); + audioInput.resume(); - // Check that QAudioInput immediately transitions to ActiveState - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()"); - stateSignal.clear(); + // Give backends running in separate threads a chance to resume. + QTest::qWait(100); - processedUs = audioInput.processedUSecs(); + // Check that QAudioInput immediately transitions to ActiveState + QVERIFY2((stateSignal.count() == 1), + QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()"); + stateSignal.clear(); - audioInput.stop(); - QTest::qWait(40); - QTRY_VERIFY2((stateSignal.count() == 1), - QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); + processedUs = audioInput.processedUSecs(); - QVERIFY2(qTolerantCompare(processedUs, 3040000LL), - QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData()); - QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); - QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); - QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + audioInput.stop(); + QTest::qWait(40); + QTRY_VERIFY2((stateSignal.count() == 1), + QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); + + QVERIFY2(qTolerantCompare(processedUs, 3040000LL), + QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData()); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); + QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); + QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + + WavHeader::writeDataLength(*audioFile,audioFile->pos()-WavHeader::headerLength()); + audioFile->close(); +} - WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength()); - audioFile->close(); +void tst_QAudioInput::push() +{ + QFETCH(FilePtr, audioFile); + QFETCH(QAudioFormat, audioFormat); - // Only run first format in CI system to reduce test times - if (m_inCISystem) - break; + QAudioInput audioInput(audioFormat, this); + + audioInput.setNotifyInterval(100); + + QSignalSpy notifySignal(&audioInput, SIGNAL(notify())); + QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State))); + + // 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()"); + QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation"); + + audioFile->close(); + audioFile->open(QIODevice::WriteOnly); + WavHeader wavHeader(audioFormat); + QVERIFY(wavHeader.write(*audioFile)); + + QIODevice* feed = audioInput.start(); + + // Check that QAudioInput immediately transitions to IdleState + QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()"); + QVERIFY2((audioInput.state() == QAudio::IdleState), + "didn't transition to IdleState after start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + QVERIFY(audioInput.periodSize() > 0); + stateSignal.clear(); + + // Check that 'elapsed' increases + QTest::qWait(40); + QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); + + qint64 totalBytesRead = 0; + bool firstBuffer = true; + QByteArray buffer(AUDIO_BUFFER, 0); + qint64 len = (audioFormat.sampleRate()*audioFormat.channelCount()*(audioFormat.sampleSize()/8)*2); // 2 seconds + while (totalBytesRead < len) { + if (audioInput.bytesReady() >= audioInput.periodSize()) { + qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); + audioFile->write(buffer.constData(),bytesRead); + totalBytesRead+=bytesRead; + if (firstBuffer && bytesRead) { + // Check for transition to ActiveState when data is provided + QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data"); + QVERIFY2((audioInput.state() == QAudio::ActiveState), + "didn't transition to ActiveState after data"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + firstBuffer = false; + } + } else + QTest::qWait(20); } + + QTest::qWait(1000); + + stateSignal.clear(); + + qint64 processedUs = audioInput.processedUSecs(); + + audioInput.stop(); + QTest::qWait(40); + QTRY_VERIFY2((stateSignal.count() == 1), + QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); + + QVERIFY2(qTolerantCompare(processedUs, 2040000LL), + QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData()); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); + QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); + QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + + WavHeader::writeDataLength(*audioFile,audioFile->pos()-WavHeader::headerLength()); + audioFile->close(); } -void tst_QAudioInput::push() +void tst_QAudioInput::pushSuspendResume() { - for(int i=0; iclose(); + audioFile->open(QIODevice::WriteOnly); + WavHeader wavHeader(audioFormat); + QVERIFY(wavHeader.write(*audioFile)); + + QIODevice* feed = audioInput.start(); + + // Check that QAudioInput immediately transitions to IdleState + QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()"); + QVERIFY2((audioInput.state() == QAudio::IdleState), + "didn't transition to IdleState after start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + QVERIFY(audioInput.periodSize() > 0); + stateSignal.clear(); + + // Check that 'elapsed' increases + QTest::qWait(40); + QTRY_VERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); + + qint64 totalBytesRead = 0; + bool firstBuffer = true; + QByteArray buffer(AUDIO_BUFFER, 0); + qint64 len = (audioFormat.sampleRate()*audioFormat.channelCount()*(audioFormat.sampleSize()/8)); // 1 seconds + while (totalBytesRead < len) { + if (audioInput.bytesReady() >= audioInput.periodSize()) { + qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); + audioFile->write(buffer.constData(),bytesRead); + totalBytesRead+=bytesRead; + if (firstBuffer && bytesRead) { + // Check for transition to ActiveState when data is provided + QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data"); + QVERIFY2((audioInput.state() == QAudio::ActiveState), + "didn't transition to ActiveState after data"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); + firstBuffer = false; + } + } else + QTest::qWait(20); + } + stateSignal.clear(); - audioFiles.at(i)->close(); - audioFiles.at(i)->open(QIODevice::WriteOnly); - WavHeader wavHeader(testFormats.at(i)); - QVERIFY(wavHeader.write(*audioFiles.at(i))); + audioInput.suspend(); - QIODevice* feed = audioInput.start(); + // Give backends running in separate threads a chance to suspend + QTest::qWait(100); - // Check that QAudioInput immediately transitions to IdleState - QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()"); - QVERIFY2((audioInput.state() == QAudio::IdleState), - "didn't transition to IdleState after start()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - QVERIFY(audioInput.periodSize() > 0); - stateSignal.clear(); + QVERIFY2((stateSignal.count() == 1), + QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); + stateSignal.clear(); - // Check that 'elapsed' increases - QTest::qWait(40); - QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); - - qint64 totalBytesRead = 0; - bool firstBuffer = true; - QByteArray buffer(AUDIO_BUFFER, 0); - qint64 len = (testFormats.at(i).sampleRate()*testFormats.at(i).channelCount()*(testFormats.at(i).sampleSize()/8)*2); // 2 seconds - while (totalBytesRead < len) { - if (audioInput.bytesReady() >= audioInput.periodSize()) { - qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); - audioFiles.at(i)->write(buffer.constData(),bytesRead); - totalBytesRead+=bytesRead; - if (firstBuffer && bytesRead) { - // Check for transition to ActiveState when data is provided - QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data"); - QVERIFY2((audioInput.state() == QAudio::ActiveState), - "didn't transition to ActiveState after data"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - firstBuffer = false; - } - } else - QTest::qWait(20); - } - - QTest::qWait(1000); + // Check that only 'elapsed', and not 'processed' increases while suspended + qint64 elapsedUs = audioInput.elapsedUSecs(); + qint64 processedUs = audioInput.processedUSecs(); + QTest::qWait(1000); + QVERIFY(audioInput.elapsedUSecs() > elapsedUs); + QVERIFY(audioInput.processedUSecs() == processedUs); - stateSignal.clear(); + audioInput.resume(); - qint64 processedUs = audioInput.processedUSecs(); + // Give backends running in separate threads a chance to resume. + QTest::qWait(100); + + // Check that QAudioInput immediately transitions to Active or IdleState + QVERIFY2((stateSignal.count() > 0),"didn't emit signals on resume()"); + QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), + "didn't transition to ActiveState or IdleState after resume()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()"); + QVERIFY(audioInput.periodSize() > 0); + + // Let it play out what is in buffer and go to Idle before continue + QTest::qWait(1000); + stateSignal.clear(); + + // Read another seconds worth + totalBytesRead = 0; + firstBuffer = true; + while (totalBytesRead < len) { + if (audioInput.bytesReady() >= audioInput.periodSize()) { + qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); + audioFile->write(buffer.constData(),bytesRead); + totalBytesRead+=bytesRead; + } else + QTest::qWait(20); + } + stateSignal.clear(); - audioInput.stop(); - QTest::qWait(40); - QTRY_VERIFY2((stateSignal.count() == 1), - QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); + processedUs = audioInput.processedUSecs(); - QVERIFY2(qTolerantCompare(processedUs, 2040000LL), - QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData()); - QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); - QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); - QVERIFY2(notifySignal.count() > 0, "not emitting notify() signal"); + audioInput.stop(); + QTest::qWait(40); + QVERIFY2((stateSignal.count() == 1), + QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); - WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength()); - audioFiles.at(i)->close(); + QVERIFY2(qTolerantCompare(processedUs, 2040000LL), + QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData()); + QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); - // Only run first format in CI system to reduce test times - if (m_inCISystem) - break; - } + WavHeader::writeDataLength(*audioFile,audioFile->pos()-WavHeader::headerLength()); + audioFile->close(); } -void tst_QAudioInput::pushSuspendResume() +void tst_QAudioInput::reset() { -#ifdef Q_OS_LINUX - if (m_inCISystem) - QSKIP("QTBUG-26504 Fails 20% of time with pulseaudio backend"); -#endif - for(int i=0; iclose(); - audioFiles.at(i)->open(QIODevice::WriteOnly); - WavHeader wavHeader(testFormats.at(i)); - QVERIFY(wavHeader.write(*audioFiles.at(i))); - - QIODevice* feed = audioInput.start(); - + QIODevice* device = audioInput.start(); // Check that QAudioInput immediately transitions to IdleState QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()"); - QVERIFY2((audioInput.state() == QAudio::IdleState), - "didn't transition to IdleState after start()"); + QVERIFY2((audioInput.state() == QAudio::IdleState), "didn't transition to IdleState after start()"); QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); QVERIFY(audioInput.periodSize() > 0); - stateSignal.clear(); + QTRY_VERIFY2((audioInput.bytesReady() > audioInput.periodSize()), "no bytes available after starting"); - // Check that 'elapsed' increases - QTest::qWait(40); - QTRY_VERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()"); - - qint64 totalBytesRead = 0; - bool firstBuffer = true; - QByteArray buffer(AUDIO_BUFFER, 0); - qint64 len = (testFormats.at(i).sampleRate()*testFormats.at(i).channelCount()*(testFormats.at(i).sampleSize()/8)); // 1 seconds - while (totalBytesRead < len) { - if (audioInput.bytesReady() >= audioInput.periodSize()) { - qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); - audioFiles.at(i)->write(buffer.constData(),bytesRead); - totalBytesRead+=bytesRead; - if (firstBuffer && bytesRead) { - // Check for transition to ActiveState when data is provided - QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data"); - QVERIFY2((audioInput.state() == QAudio::ActiveState), - "didn't transition to ActiveState after data"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - firstBuffer = false; - } - } else - QTest::qWait(20); - } + // Trigger a read + QByteArray data = device->read(audioInput.periodSize()); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); stateSignal.clear(); - audioInput.suspend(); + audioInput.reset(); + QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit StoppedState signal after reset()"); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after reset()"); + QVERIFY2((audioInput.bytesReady() == 0), "buffer not cleared after reset()"); + } - // Give backends running in separate threads a chance to suspend - QTest::qWait(100); + { + QAudioInput audioInput(audioFormat, this); + QBuffer buffer; - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()"); - stateSignal.clear(); + audioInput.setNotifyInterval(100); - // Check that only 'elapsed', and not 'processed' increases while suspended - qint64 elapsedUs = audioInput.elapsedUSecs(); - qint64 processedUs = audioInput.processedUSecs(); - QTest::qWait(1000); - QVERIFY(audioInput.elapsedUSecs() > elapsedUs); - QVERIFY(audioInput.processedUSecs() == processedUs); + QSignalSpy notifySignal(&audioInput, SIGNAL(notify())); + QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State))); - audioInput.resume(); + // 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()"); + QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation"); - // Give backends running in separate threads a chance to resume. - QTest::qWait(100); + audioInput.start(&buffer); - // Check that QAudioInput immediately transitions to Active or IdleState - QVERIFY2((stateSignal.count() > 0),"didn't emit signals on resume()"); - QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState), - "didn't transition to ActiveState or IdleState after resume()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()"); + // Check that QAudioInput immediately transitions to ActiveState + QTRY_VERIFY2((stateSignal.count() >= 1),"didn't emit state changed signal on start()"); + QTRY_VERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); QVERIFY(audioInput.periodSize() > 0); - - // Let it play out what is in buffer and go to Idle before continue - QTest::qWait(1000); stateSignal.clear(); - // Read another seconds worth - totalBytesRead = 0; - firstBuffer = true; - while (totalBytesRead < len) { - if (audioInput.bytesReady() >= audioInput.periodSize()) { - qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize()); - audioFiles.at(i)->write(buffer.constData(),bytesRead); - totalBytesRead+=bytesRead; - } else - QTest::qWait(20); - } - stateSignal.clear(); - - processedUs = audioInput.processedUSecs(); - - audioInput.stop(); - QTest::qWait(40); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()"); - - QVERIFY2(qTolerantCompare(processedUs, 2040000LL), - QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData()); - QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState"); - - WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength()); - audioFiles.at(i)->close(); - - // Only run first format in CI system to reduce test times - if (m_inCISystem) - break; - } -} - -void tst_QAudioInput::reset() -{ - for(int i=0; i 0); - QTRY_VERIFY2((audioInput.bytesReady() > audioInput.periodSize()), "no bytes available after starting"); - - // Trigger a read - QByteArray data = device->read(audioInput.periodSize()); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - stateSignal.clear(); - - audioInput.reset(); - QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit StoppedState signal after reset()"); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after reset()"); - QVERIFY2((audioInput.bytesReady() == 0), "buffer not cleared after reset()"); - } - - { - QAudioInput audioInput(testFormats.at(i), this); - QBuffer buffer; - - audioInput.setNotifyInterval(100); - - QSignalSpy notifySignal(&audioInput, SIGNAL(notify())); - QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State))); - - // 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()"); - QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation"); - - audioInput.start(&buffer); - - // Check that QAudioInput immediately transitions to ActiveState - QTRY_VERIFY2((stateSignal.count() >= 1),"didn't emit state changed signal on start()"); - QTRY_VERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after start()"); - QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()"); - QVERIFY(audioInput.periodSize() > 0); - stateSignal.clear(); - - audioInput.reset(); - QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit StoppedState signal after reset()"); - QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after reset()"); - QVERIFY2((audioInput.bytesReady() == 0), "buffer not cleared after reset()"); - } - // Only run first format in CI system to reduce test times - if (m_inCISystem) - break; + audioInput.reset(); + QTRY_VERIFY2((stateSignal.count() == 1),"didn't emit StoppedState signal after reset()"); + QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after reset()"); + QVERIFY2((audioInput.bytesReady() == 0), "buffer not cleared after reset()"); } } void tst_QAudioInput::volume() { + QFETCH(QAudioFormat, audioFormat); + const qreal half(0.5f); const qreal one(1.0f); - // Hard to automatically test, but we can test the get/set a little - for (int i=0; i < testFormats.count(); i++) { - QAudioInput audioInput(testFormats.at(i), this); - - qreal volume = audioInput.volume(); - audioInput.setVolume(half); - QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 5); - // Wait a while to see if this changes - QTest::qWait(500); - QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 5); - - audioInput.setVolume(one); - QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 10); - // Wait a while to see if this changes - QTest::qWait(500); - QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 10); - - audioInput.setVolume(volume); - } + + QAudioInput audioInput(audioFormat, this); + + qreal volume = audioInput.volume(); + audioInput.setVolume(half); + QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 5); + // Wait a while to see if this changes + QTest::qWait(500); + QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 5); + + audioInput.setVolume(one); + QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 10); + // Wait a while to see if this changes + QTest::qWait(500); + QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 10); + + audioInput.setVolume(volume); } QTEST_MAIN(tst_QAudioInput)