qtmobility/tests/auto/qaudioinput/tst_qaudioinput.cpp
changeset 14 6fbed849b4f4
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtTest/QtTest>
       
    43 #include <QtCore/qlocale.h>
       
    44 
       
    45 #include <qaudioinput.h>
       
    46 #include <qaudiodeviceinfo.h>
       
    47 #include <qaudioformat.h>
       
    48 #include <qaudio.h>
       
    49 
       
    50 #include "wavheader.h"
       
    51 
       
    52 #define AUDIO_BUFFER 192000
       
    53 
       
    54 #if defined(Q_OS_SYMBIAN)
       
    55 #define SRCDIR ""
       
    56 #endif
       
    57 
       
    58 class tst_QAudioInput : public QObject
       
    59 {
       
    60     Q_OBJECT
       
    61 public:
       
    62     tst_QAudioInput(QObject* parent=0) : QObject(parent) {}
       
    63 
       
    64 private slots:
       
    65     void initTestCase();
       
    66 
       
    67     void format();
       
    68     void invalidFormat();
       
    69 
       
    70     void bufferSize();
       
    71 
       
    72     void notifyInterval();
       
    73     void disableNotifyInterval();
       
    74 
       
    75     void stopWhileStopped();
       
    76     void suspendWhileStopped();
       
    77     void resumeWhileStopped();
       
    78 
       
    79     void pull();
       
    80     void pullSuspendResume();
       
    81 
       
    82     void push();
       
    83     void pushSuspendResume();
       
    84 
       
    85     void cleanupTestCase();
       
    86 
       
    87 private:
       
    88     QString formatToFileName(const QAudioFormat &format);
       
    89     QString workingDir();
       
    90 
       
    91     QAudioDeviceInfo audioDevice;
       
    92     QList<QAudioFormat> testFormats;
       
    93     QList<QFile*> audioFiles;
       
    94 
       
    95     QScopedPointer<QByteArray> m_byteArray;
       
    96     QScopedPointer<QBuffer> m_buffer;
       
    97 };
       
    98 
       
    99 QString tst_QAudioInput::formatToFileName(const QAudioFormat &format)
       
   100 {
       
   101     const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
       
   102         ?   QString("LE") : QString("BE");
       
   103 
       
   104     const QString formatSigned = (format.sampleType() == QAudioFormat::SignedInt)
       
   105         ?   QString("signed") : QString("unsigned");
       
   106 
       
   107     return QString("%1_%2_%3_%4_%5")
       
   108         .arg(format.frequency())
       
   109         .arg(format.sampleSize())
       
   110         .arg(formatSigned)
       
   111         .arg(formatEndian)
       
   112         .arg(format.channels());
       
   113 }
       
   114 
       
   115 
       
   116 QString tst_QAudioInput::workingDir()
       
   117 {
       
   118     QDir working(QString(SRCDIR));
       
   119 
       
   120     if (working.exists())
       
   121         return QString(SRCDIR);
       
   122 
       
   123     return QDir::currentPath();
       
   124 }
       
   125 
       
   126 void tst_QAudioInput::initTestCase()
       
   127 {
       
   128     // Only perform tests if audio output device exists
       
   129     const QList<QAudioDeviceInfo> devices =
       
   130         QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
       
   131     QVERIFY(devices.size() > 0);
       
   132 
       
   133     audioDevice = QAudioDeviceInfo::defaultInputDevice();
       
   134 
       
   135 
       
   136     QAudioFormat format;
       
   137 
       
   138     format.setCodec("audio/pcm");
       
   139 
       
   140     if (audioDevice.isFormatSupported(audioDevice.preferredFormat()))
       
   141         testFormats.append(audioDevice.preferredFormat());
       
   142 
       
   143     // PCM 8000  mono S8
       
   144     format.setFrequency(8000);
       
   145     format.setSampleSize(8);
       
   146     format.setSampleType(QAudioFormat::SignedInt);
       
   147     format.setByteOrder(QAudioFormat::LittleEndian);
       
   148     format.setChannels(1);
       
   149     if (audioDevice.isFormatSupported(format))
       
   150         testFormats.append(format);
       
   151 
       
   152     // PCM 11025 mono S16LE
       
   153     format.setFrequency(11025);
       
   154     format.setSampleSize(16);
       
   155     if (audioDevice.isFormatSupported(format))
       
   156         testFormats.append(format);
       
   157 
       
   158     // PCM 22050 mono S16LE
       
   159     format.setFrequency(22050);
       
   160     if (audioDevice.isFormatSupported(format))
       
   161         testFormats.append(format);
       
   162 
       
   163     // PCM 22050 stereo S16LE
       
   164     format.setChannels(2);
       
   165     if (audioDevice.isFormatSupported(format))
       
   166         testFormats.append(format);
       
   167 
       
   168     // PCM 44100 stereo S16LE
       
   169     format.setFrequency(44100);
       
   170     if (audioDevice.isFormatSupported(format))
       
   171         testFormats.append(format);
       
   172 
       
   173     // PCM 48000 stereo S16LE
       
   174     format.setFrequency(48000);
       
   175     if (audioDevice.isFormatSupported(format))
       
   176         testFormats.append(format);
       
   177 
       
   178     QVERIFY(testFormats.size());
       
   179 
       
   180     foreach (format, testFormats) {
       
   181         QFile* file = new QFile(workingDir() + formatToFileName(format) + QString(".wav"));
       
   182         audioFiles.append(file);
       
   183     }
       
   184 }
       
   185 
       
   186 void tst_QAudioInput::format()
       
   187 {
       
   188     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   189 
       
   190     QAudioFormat requested = audioDevice.preferredFormat();
       
   191     QAudioFormat actual    = audioInput.format();
       
   192 
       
   193     QVERIFY2((requested.channels() == actual.channels()),
       
   194             QString("channels: requested=%1, actual=%2").arg(requested.channels()).arg(actual.channels()).toLocal8Bit().constData());
       
   195     QVERIFY2((requested.frequency() == actual.frequency()),
       
   196             QString("frequency: requested=%1, actual=%2").arg(requested.frequency()).arg(actual.frequency()).toLocal8Bit().constData());
       
   197     QVERIFY2((requested.sampleSize() == actual.sampleSize()),
       
   198             QString("sampleSize: requested=%1, actual=%2").arg(requested.sampleSize()).arg(actual.sampleSize()).toLocal8Bit().constData());
       
   199     QVERIFY2((requested.codec() == actual.codec()),
       
   200             QString("codec: requested=%1, actual=%2").arg(requested.codec()).arg(actual.codec()).toLocal8Bit().constData());
       
   201     QVERIFY2((requested.byteOrder() == actual.byteOrder()),
       
   202             QString("byteOrder: requested=%1, actual=%2").arg(requested.byteOrder()).arg(actual.byteOrder()).toLocal8Bit().constData());
       
   203     QVERIFY2((requested.sampleType() == actual.sampleType()),
       
   204             QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData());
       
   205 }
       
   206 
       
   207 void tst_QAudioInput::invalidFormat()
       
   208 {
       
   209     QAudioFormat invalidFormat;
       
   210     invalidFormat.setFrequency(0);
       
   211 
       
   212     QVERIFY2(!audioDevice.isFormatSupported(invalidFormat),
       
   213             "isFormatSupported() is returning true on an invalid format");
       
   214 
       
   215     QAudioInput audioInput(invalidFormat, this);
       
   216 
       
   217     // Check that we are in the default state before calling start
       
   218     QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   219     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   220 
       
   221     audioInput.start();
       
   222 
       
   223     // Check that error is raised
       
   224     QVERIFY2((audioInput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()");
       
   225 }
       
   226 
       
   227 void tst_QAudioInput::bufferSize()
       
   228 {
       
   229     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   230 
       
   231     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
       
   232 
       
   233     audioInput.setBufferSize(512);
       
   234     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(512)");
       
   235     QVERIFY2((audioInput.bufferSize() == 512),
       
   236             QString("bufferSize: requested=512, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
       
   237 
       
   238     audioInput.setBufferSize(4096);
       
   239     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(4096)");
       
   240     QVERIFY2((audioInput.bufferSize() == 4096),
       
   241             QString("bufferSize: requested=4096, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
       
   242 
       
   243     audioInput.setBufferSize(8192);
       
   244     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(8192)");
       
   245     QVERIFY2((audioInput.bufferSize() == 8192),
       
   246             QString("bufferSize: requested=8192, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
       
   247 }
       
   248 
       
   249 void tst_QAudioInput::notifyInterval()
       
   250 {
       
   251     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   252 
       
   253     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
       
   254 
       
   255     audioInput.setNotifyInterval(50);
       
   256     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(50)");
       
   257     QVERIFY2((audioInput.notifyInterval() == 50),
       
   258             QString("notifyInterval: requested=50, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
       
   259 
       
   260     audioInput.setNotifyInterval(100);
       
   261     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(100)");
       
   262     QVERIFY2((audioInput.notifyInterval() == 100),
       
   263             QString("notifyInterval: requested=100, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
       
   264 
       
   265     audioInput.setNotifyInterval(250);
       
   266     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(250)");
       
   267     QVERIFY2((audioInput.notifyInterval() == 250),
       
   268             QString("notifyInterval: requested=250, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
       
   269 
       
   270     audioInput.setNotifyInterval(1000);
       
   271     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(1000)");
       
   272     QVERIFY2((audioInput.notifyInterval() == 1000),
       
   273             QString("notifyInterval: requested=1000, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
       
   274 }
       
   275 
       
   276 void tst_QAudioInput::disableNotifyInterval()
       
   277 {
       
   278     // Sets an invalid notification interval (QAudioInput::setNotifyInterval(0))
       
   279     // Checks that
       
   280     //  - No error is raised (QAudioInput::error() returns QAudio::NoError)
       
   281     //  - if <= 0, set to zero and disable notify signal
       
   282 
       
   283     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   284 
       
   285     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");
       
   286 
       
   287     audioInput.setNotifyInterval(0);
       
   288     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(0)");
       
   289     QVERIFY2((audioInput.notifyInterval() == 0),
       
   290             "notifyInterval() is not zero after setNotifyInterval(0)");
       
   291 
       
   292     audioInput.setNotifyInterval(-1);
       
   293     QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(-1)");
       
   294     QVERIFY2((audioInput.notifyInterval() == 0),
       
   295             "notifyInterval() is not zero after setNotifyInterval(-1)");
       
   296 
       
   297     //start and run to check if notify() is emitted
       
   298     if (audioFiles.size() > 0) {
       
   299         QAudioInput audioInputCheck(testFormats.at(0), this);
       
   300         audioInputCheck.setNotifyInterval(0);
       
   301         QSignalSpy notifySignal(&audioInputCheck, SIGNAL(notify()));
       
   302         audioFiles.at(0)->open(QIODevice::WriteOnly);
       
   303         audioInputCheck.start(audioFiles.at(0));
       
   304         QTest::qWait(3000); // 3 seconds should be plenty
       
   305         audioInputCheck.stop();
       
   306         QVERIFY2((notifySignal.count() == 0),
       
   307                 QString("didn't disable notify interval: shouldn't have got any but got %1").arg(notifySignal.count()).toLocal8Bit().constData());
       
   308         audioFiles.at(0)->close();
       
   309     }
       
   310 }
       
   311 
       
   312 void tst_QAudioInput::stopWhileStopped()
       
   313 {
       
   314     // Calls QAudioInput::stop() when object is already in StoppedState
       
   315     // Checks that
       
   316     //  - No state change occurs
       
   317     //  - No error is raised (QAudioInput::error() returns QAudio::NoError)
       
   318 
       
   319     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   320 
       
   321     QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   322     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   323 
       
   324     QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   325     audioInput.stop();
       
   326 
       
   327     // Check that no state transition occurred
       
   328     QVERIFY2((stateSignal.count() == 0), "stop() while stopped is emitting a signal and it shouldn't");
       
   329     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
       
   330 }
       
   331 
       
   332 void tst_QAudioInput::suspendWhileStopped()
       
   333 {
       
   334     // Calls QAudioInput::suspend() when object is already in StoppedState
       
   335     // Checks that
       
   336     //  - No state change occurs
       
   337     //  - No error is raised (QAudioInput::error() returns QAudio::NoError)
       
   338 
       
   339     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   340 
       
   341     QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   342     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   343 
       
   344     QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   345     audioInput.suspend();
       
   346 
       
   347     // Check that no state transition occurred
       
   348     QVERIFY2((stateSignal.count() == 0), "stop() while suspended is emitting a signal and it shouldn't");
       
   349     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
       
   350 }
       
   351 
       
   352 void tst_QAudioInput::resumeWhileStopped()
       
   353 {
       
   354     // Calls QAudioInput::resume() when object is already in StoppedState
       
   355     // Checks that
       
   356     //  - No state change occurs
       
   357     //  - No error is raised (QAudioInput::error() returns QAudio::NoError)
       
   358 
       
   359     QAudioInput audioInput(audioDevice.preferredFormat(), this);
       
   360 
       
   361     QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   362     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   363 
       
   364     QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   365     audioInput.resume();
       
   366 
       
   367     // Check that no state transition occurred
       
   368     QVERIFY2((stateSignal.count() == 0), "resume() while stopped is emitting a signal and it shouldn't");
       
   369     QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after resume()");
       
   370 }
       
   371 
       
   372 void tst_QAudioInput::pull()
       
   373 {
       
   374     for(int i=0; i<audioFiles.count(); i++) {
       
   375         QAudioInput audioInput(testFormats.at(i), this);
       
   376 
       
   377         audioInput.setNotifyInterval(100);
       
   378 
       
   379         QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
       
   380         QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   381 
       
   382         // Check that we are in the default state before calling start
       
   383         QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   384         QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   385         QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
       
   386 
       
   387         audioFiles.at(i)->close();
       
   388         audioFiles.at(i)->open(QIODevice::WriteOnly);
       
   389         WavHeader wavHeader(testFormats.at(i));
       
   390         QVERIFY(wavHeader.write(*audioFiles.at(i)));
       
   391 
       
   392         audioInput.start(audioFiles.at(i));
       
   393 
       
   394         // Check that QAudioInput immediately transitions to ActiveState or IdleState
       
   395         QVERIFY2((stateSignal.count() > 0),"didn't emit signals on start()");
       
   396         QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
       
   397                 "didn't transition to ActiveState or IdleState after start()");
       
   398         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   399         QVERIFY(audioInput.periodSize() > 0);
       
   400         stateSignal.clear();
       
   401 
       
   402         // Check that 'elapsed' increases
       
   403         QTest::qWait(40);
       
   404         QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
       
   405 
       
   406         // Allow some recording to happen
       
   407         QTest::qWait(3000); // 3 seconds should be plenty
       
   408 
       
   409         stateSignal.clear();
       
   410 
       
   411         qint64 processedUs = audioInput.processedUSecs();
       
   412 
       
   413         audioInput.stop();
       
   414         QTest::qWait(40);
       
   415         QVERIFY2((stateSignal.count() == 1),
       
   416             QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   417         QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
       
   418 
       
   419         QVERIFY2((processedUs > 2800000 && processedUs < 3200000),
       
   420                 QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData());
       
   421         QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
       
   422         QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
       
   423         QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
       
   424                 QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
       
   425 
       
   426         WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
       
   427         audioFiles.at(i)->close();
       
   428     }
       
   429 }
       
   430 
       
   431 void tst_QAudioInput::pullSuspendResume()
       
   432 {
       
   433     for(int i=0; i<audioFiles.count(); i++) {
       
   434         QAudioInput audioInput(testFormats.at(i), this);
       
   435 
       
   436         audioInput.setNotifyInterval(100);
       
   437 
       
   438         QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
       
   439         QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   440 
       
   441         // Check that we are in the default state before calling start
       
   442         QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   443         QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   444         QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
       
   445 
       
   446         audioFiles.at(i)->close();
       
   447         audioFiles.at(i)->open(QIODevice::WriteOnly);
       
   448         WavHeader wavHeader(testFormats.at(i));
       
   449         QVERIFY(wavHeader.write(*audioFiles.at(i)));
       
   450 
       
   451         audioInput.start(audioFiles.at(i));
       
   452 
       
   453         // Check that QAudioInput immediately transitions to ActiveState or IdleState
       
   454         QVERIFY2((stateSignal.count() > 0),"didn't emit signals on start()");
       
   455         QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
       
   456                 "didn't transition to ActiveState or IdleState after start()");
       
   457         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   458         QVERIFY(audioInput.periodSize() > 0);
       
   459         stateSignal.clear();
       
   460 
       
   461         // Check that 'elapsed' increases
       
   462         QTest::qWait(40);
       
   463         QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
       
   464 
       
   465         // Allow some recording to happen
       
   466         QTest::qWait(3000); // 3 seconds should be plenty
       
   467 
       
   468         QVERIFY2((audioInput.state() == QAudio::ActiveState),
       
   469                 "didn't transition to ActiveState after some recording");
       
   470         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after some recording");
       
   471 
       
   472         stateSignal.clear();
       
   473 
       
   474         audioInput.suspend();
       
   475 
       
   476         // Give backends running in separate threads a chance to suspend.
       
   477         QTest::qWait(100);
       
   478 
       
   479         QVERIFY2((stateSignal.count() == 1),
       
   480             QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   481         QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()");
       
   482         QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
       
   483         stateSignal.clear();
       
   484 
       
   485         // Check that only 'elapsed', and not 'processed' increases while suspended
       
   486         qint64 elapsedUs = audioInput.elapsedUSecs();
       
   487         qint64 processedUs = audioInput.processedUSecs();
       
   488         QTest::qWait(1000);
       
   489         QVERIFY(audioInput.elapsedUSecs() > elapsedUs);
       
   490         QVERIFY(audioInput.processedUSecs() == processedUs);
       
   491 
       
   492         audioInput.resume();
       
   493 
       
   494         // Give backends running in separate threads a chance to resume.
       
   495         QTest::qWait(100);
       
   496 
       
   497         // Check that QAudioInput immediately transitions to ActiveState
       
   498         QVERIFY2((stateSignal.count() == 1),
       
   499                 QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   500         QVERIFY2((audioInput.state() == QAudio::ActiveState), "didn't transition to ActiveState after resume()");
       
   501         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
       
   502         stateSignal.clear();
       
   503 
       
   504         processedUs = audioInput.processedUSecs();
       
   505 
       
   506         audioInput.stop();
       
   507         QTest::qWait(40);
       
   508         QVERIFY2((stateSignal.count() == 1),
       
   509             QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   510         QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
       
   511 
       
   512         QVERIFY2((processedUs > 2800000 && processedUs < 3200000),
       
   513                 QString("processedUSecs() doesn't fall in acceptable range, should be 3040000 (%1)").arg(processedUs).toLocal8Bit().constData());
       
   514         QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
       
   515         QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
       
   516         QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
       
   517                 QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
       
   518 
       
   519         WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
       
   520         audioFiles.at(i)->close();
       
   521     }
       
   522 }
       
   523 
       
   524 void tst_QAudioInput::push()
       
   525 {
       
   526     for(int i=0; i<audioFiles.count(); i++) {
       
   527         QAudioInput audioInput(testFormats.at(i), this);
       
   528 
       
   529         audioInput.setNotifyInterval(100);
       
   530 
       
   531         QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
       
   532         QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   533 
       
   534         // Check that we are in the default state before calling start
       
   535         QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   536         QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   537         QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
       
   538 
       
   539         audioFiles.at(i)->close();
       
   540         audioFiles.at(i)->open(QIODevice::WriteOnly);
       
   541         WavHeader wavHeader(testFormats.at(i));
       
   542         QVERIFY(wavHeader.write(*audioFiles.at(i)));
       
   543 
       
   544         QIODevice* feed = audioInput.start();
       
   545 
       
   546         // Check that QAudioInput immediately transitions to IdleState
       
   547         QVERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()");
       
   548         QVERIFY2((audioInput.state() == QAudio::IdleState),
       
   549                 "didn't transition to IdleState after start()");
       
   550         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   551         QVERIFY(audioInput.periodSize() > 0);
       
   552         stateSignal.clear();
       
   553 
       
   554         // Check that 'elapsed' increases
       
   555         QTest::qWait(40);
       
   556         QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
       
   557 
       
   558         qint64 totalBytesRead = 0;
       
   559         bool firstBuffer = true;
       
   560         char buffer[AUDIO_BUFFER];
       
   561         qint64 len = (testFormats.at(i).frequency()*testFormats.at(i).channels()*(testFormats.at(i).sampleSize()/8)*2); // 2 seconds
       
   562         while (totalBytesRead < len) {
       
   563             if (audioInput.bytesReady() > audioInput.periodSize()) {
       
   564                 qint64 bytesRead = feed->read(buffer, audioInput.periodSize());
       
   565                 audioFiles.at(i)->write(buffer,bytesRead);
       
   566                 totalBytesRead+=bytesRead;
       
   567                 if (firstBuffer && bytesRead) {
       
   568                     // Check for transition to ActiveState when data is provided
       
   569                     QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data");
       
   570                     QVERIFY2((audioInput.state() == QAudio::ActiveState),
       
   571                             "didn't transition to ActiveState after data");
       
   572                     QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   573                     firstBuffer = false;
       
   574                 }
       
   575             } else
       
   576                 QTest::qWait(20);
       
   577         }
       
   578 
       
   579         QTest::qWait(1000);
       
   580 
       
   581         stateSignal.clear();
       
   582 
       
   583         qint64 processedUs = audioInput.processedUSecs();
       
   584 
       
   585         audioInput.stop();
       
   586         QTest::qWait(40);
       
   587         QVERIFY2((stateSignal.count() == 1),
       
   588             QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   589         QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
       
   590 
       
   591         QVERIFY2((processedUs > 1800000 && processedUs < 2200000),
       
   592                 QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData());
       
   593         QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
       
   594         QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
       
   595         QVERIFY2((notifySignal.count() > 20 && notifySignal.count() < 40),
       
   596                 QString("notify() signals emitted (%1) should be 30").arg(notifySignal.count()).toLocal8Bit().constData());
       
   597 
       
   598         WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
       
   599         audioFiles.at(i)->close();
       
   600     }
       
   601 }
       
   602 
       
   603 void tst_QAudioInput::pushSuspendResume()
       
   604 {
       
   605     for(int i=0; i<audioFiles.count(); i++) {
       
   606         QAudioInput audioInput(testFormats.at(i), this);
       
   607 
       
   608         audioInput.setNotifyInterval(100);
       
   609 
       
   610         QSignalSpy notifySignal(&audioInput, SIGNAL(notify()));
       
   611         QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
       
   612 
       
   613         // Check that we are in the default state before calling start
       
   614         QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()");
       
   615         QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()");
       
   616         QVERIFY2((audioInput.elapsedUSecs() == qint64(0)),"elapsedUSecs() not zero on creation");
       
   617 
       
   618         audioFiles.at(i)->close();
       
   619         audioFiles.at(i)->open(QIODevice::WriteOnly);
       
   620         WavHeader wavHeader(testFormats.at(i));
       
   621         QVERIFY(wavHeader.write(*audioFiles.at(i)));
       
   622 
       
   623         QIODevice* feed = audioInput.start();
       
   624 
       
   625         // Check that QAudioInput immediately transitions to IdleState
       
   626         QVERIFY2((stateSignal.count() == 1),"didn't emit IdleState signal on start()");
       
   627         QVERIFY2((audioInput.state() == QAudio::IdleState),
       
   628                 "didn't transition to IdleState after start()");
       
   629         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   630         QVERIFY(audioInput.periodSize() > 0);
       
   631         stateSignal.clear();
       
   632 
       
   633         // Check that 'elapsed' increases
       
   634         QTest::qWait(40);
       
   635         QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");
       
   636 
       
   637         qint64 totalBytesRead = 0;
       
   638         bool firstBuffer = true;
       
   639         char buffer[AUDIO_BUFFER];
       
   640         qint64 len = (testFormats.at(i).frequency()*testFormats.at(i).channels()*(testFormats.at(i).sampleSize()/8)); // 1 seconds
       
   641         while (totalBytesRead < len) {
       
   642             if (audioInput.bytesReady() > audioInput.periodSize()) {
       
   643                 qint64 bytesRead = feed->read(buffer, audioInput.periodSize());
       
   644                 audioFiles.at(i)->write(buffer,bytesRead);
       
   645                 totalBytesRead+=bytesRead;
       
   646                 if (firstBuffer && bytesRead) {
       
   647                     // Check for transition to ActiveState when data is provided
       
   648                     QVERIFY2((stateSignal.count() == 1),"didn't emit ActiveState signal on data");
       
   649                     QVERIFY2((audioInput.state() == QAudio::ActiveState),
       
   650                             "didn't transition to ActiveState after data");
       
   651                     QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
       
   652                     firstBuffer = false;
       
   653                 }
       
   654             } else
       
   655                 QTest::qWait(20);
       
   656         }
       
   657         stateSignal.clear();
       
   658 
       
   659         audioInput.suspend();
       
   660 
       
   661         // Give backends running in separate threads a chance to suspend
       
   662         QTest::qWait(100);
       
   663 
       
   664         QVERIFY2((stateSignal.count() == 1),
       
   665             QString("didn't emit SuspendedState signal after suspend(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   666         QVERIFY2((audioInput.state() == QAudio::SuspendedState), "didn't transitions to SuspendedState after stop()");
       
   667         QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after stop()");
       
   668         stateSignal.clear();
       
   669 
       
   670         // Check that only 'elapsed', and not 'processed' increases while suspended
       
   671         qint64 elapsedUs = audioInput.elapsedUSecs();
       
   672         qint64 processedUs = audioInput.processedUSecs();
       
   673         QTest::qWait(1000);
       
   674         QVERIFY(audioInput.elapsedUSecs() > elapsedUs);
       
   675         QVERIFY(audioInput.processedUSecs() == processedUs);
       
   676 
       
   677         audioInput.resume();
       
   678 
       
   679         // Give backends running in separate threads a chance to resume.
       
   680         QTest::qWait(100);
       
   681 
       
   682         // Check that QAudioInput immediately transitions to Active or IdleState
       
   683         QVERIFY2((stateSignal.count() > 0),"didn't emit signals on resume()");
       
   684         QVERIFY2((audioInput.state() == QAudio::ActiveState || audioInput.state() == QAudio::IdleState),
       
   685                 "didn't transition to ActiveState or IdleState after resume()");
       
   686         QVERIFY2((audioInput.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after resume()");
       
   687         QVERIFY(audioInput.periodSize() > 0);
       
   688 
       
   689         // Let it play out what is in buffer and go to Idle before continue
       
   690         QTest::qWait(1000);
       
   691         stateSignal.clear();
       
   692 
       
   693         // Read another seconds worth
       
   694         totalBytesRead = 0;
       
   695         firstBuffer = true;
       
   696         while (totalBytesRead < len) {
       
   697             if (audioInput.bytesReady() >= audioInput.periodSize()) {
       
   698                 qint64 bytesRead = feed->read(buffer, audioInput.periodSize());
       
   699                 audioFiles.at(i)->write(buffer,bytesRead);
       
   700                 totalBytesRead+=bytesRead;
       
   701             } else
       
   702                 QTest::qWait(20);
       
   703         }
       
   704         stateSignal.clear();
       
   705 
       
   706         processedUs = audioInput.processedUSecs();
       
   707 
       
   708         audioInput.stop();
       
   709         QTest::qWait(40);
       
   710         QVERIFY2((stateSignal.count() == 1),
       
   711             QString("didn't emit StoppedState signal after stop(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData());
       
   712         QVERIFY2((audioInput.state() == QAudio::StoppedState), "didn't transitions to StoppedState after stop()");
       
   713 
       
   714         QVERIFY2((processedUs > 1800000 && processedUs < 2200000),
       
   715                 QString("processedUSecs() doesn't fall in acceptable range, should be 2040000 (%1)").arg(processedUs).toLocal8Bit().constData());
       
   716         QVERIFY2((audioInput.elapsedUSecs() == (qint64)0), "elapsedUSecs() not equal to zero in StoppedState");
       
   717 
       
   718         WavHeader::writeDataLength(*audioFiles.at(i),audioFiles.at(i)->pos()-WavHeader::headerLength());
       
   719         audioFiles.at(i)->close();
       
   720     }
       
   721 }
       
   722 
       
   723 void tst_QAudioInput::cleanupTestCase()
       
   724 {
       
   725     QFile* file;
       
   726 
       
   727     foreach (file, audioFiles) {
       
   728         file->remove();
       
   729         delete file;
       
   730     }
       
   731 }
       
   732 
       
   733 QTEST_MAIN(tst_QAudioInput)
       
   734 
       
   735 #include "tst_qaudioinput.moc"