/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtCore/qlocale.h>
#include <QtCore/QTemporaryDir>
#include <QtCore/QSharedPointer>
#include <QtCore/QScopedPointer>

#include <qaudioinput.h>
#include <qaudiodeviceinfo.h>
#include <qaudioformat.h>
#include <qaudio.h>

#include "wavheader.h"

//TESTED_COMPONENT=src/multimedia

#define AUDIO_BUFFER 192000
#define RANGE_ERR 0.5

template<typename T> inline bool qTolerantCompare(T value, T expected)
{
    return qAbs(value - expected) < (RANGE_ERR * expected);
}

#ifndef QTRY_VERIFY2
#define QTRY_VERIFY2(__expr,__msg) \
    do { \
        const int __step = 50; \
        const int __timeout = 5000; \
        if (!(__expr)) { \
            QTest::qWait(0); \
        } \
        for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
            QTest::qWait(__step); \
        } \
        QVERIFY2(__expr,__msg); \
    } while(0)
#endif

class tst_QAudioInput : public QObject
{
    Q_OBJECT
public:
    tst_QAudioInput(QObject* parent=0) : QObject(parent) {}

private slots:
    void initTestCase();

    void format();
    void invalidFormat_data();
    void invalidFormat();

    void bufferSize();
    void notifyInterval();
    void disableNotifyInterval();

    void stopWhileStopped();
    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:
    typedef QSharedPointer<QFile> FilePtr;

    QString formatToFileName(const QAudioFormat &format);

    void generate_audiofile_testrows();

    QAudioDeviceInfo audioDevice;
    QList<QAudioFormat> testFormats;
    QList<FilePtr> audioFiles;
    QScopedPointer<QTemporaryDir> m_temporaryDir;

    QScopedPointer<QByteArray> m_byteArray;
    QScopedPointer<QBuffer> m_buffer;

    bool m_inCISystem;
};

void tst_QAudioInput::generate_audiofile_testrows()
{
    QTest::addColumn<FilePtr>("audioFile");
    QTest::addColumn<QAudioFormat>("audioFormat");

    for (int i=0; i<audioFiles.count(); i++) {
        QTest::newRow(QString("Audio File %1").arg(i).toLocal8Bit().constData())
                << audioFiles.at(i) << testFormats.at(i);

        // Only run first format in CI system to reduce test times
        if (m_inCISystem)
            break;
    }
}

QString tst_QAudioInput::formatToFileName(const QAudioFormat &format)
{
    const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
        ?   QString("LE") : QString("BE");

    const QString formatSigned = (format.sampleType() == QAudioFormat::SignedInt)
        ?   QString("signed") : QString("unsigned");

    return QString("%1_%2_%3_%4_%5")
        .arg(format.sampleRate())
        .arg(format.sampleSize())
        .arg(formatSigned)
        .arg(formatEndian)
        .arg(format.channelCount());
}

void tst_QAudioInput::initTestCase()
{
    qRegisterMetaType<QAudioFormat>();

    // Only perform tests if audio output device exists
    const QList<QAudioDeviceInfo> devices =
        QAudioDeviceInfo::availableDevices(QAudio::AudioInput);

    if (devices.size() <= 0)
        QSKIP("No audio backend");

    audioDevice = QAudioDeviceInfo::defaultInputDevice();


    QAudioFormat format;

    format.setCodec("audio/pcm");

    if (audioDevice.isFormatSupported(audioDevice.preferredFormat()))
        testFormats.append(audioDevice.preferredFormat());

    // PCM 8000  mono S8
    format.setSampleRate(8000);
    format.setSampleSize(8);
    format.setSampleType(QAudioFormat::SignedInt);
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setChannelCount(1);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    // PCM 11025 mono S16LE
    format.setSampleRate(11025);
    format.setSampleSize(16);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    // PCM 22050 mono S16LE
    format.setSampleRate(22050);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    // PCM 22050 stereo S16LE
    format.setChannelCount(2);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    // PCM 44100 stereo S16LE
    format.setSampleRate(44100);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    // PCM 48000 stereo S16LE
    format.setSampleRate(48000);
    if (audioDevice.isFormatSupported(format))
        testFormats.append(format);

    QVERIFY(testFormats.size());

    const QChar slash = QLatin1Char('/');
    QString temporaryPattern = QDir::tempPath();
    if (!temporaryPattern.endsWith(slash))
        temporaryPattern += slash;
    temporaryPattern += "tst_qaudioinputXXXXXX";
    m_temporaryDir.reset(new QTemporaryDir(temporaryPattern));
    m_temporaryDir->setAutoRemove(true);
    QVERIFY(m_temporaryDir->isValid());

    const QString temporaryAudioPath = m_temporaryDir->path() + slash;
    for (const QAudioFormat &format : qAsConst(testFormats)) {
        const QString fileName = temporaryAudioPath + formatToFileName(format) + QStringLiteral(".wav");
        audioFiles.append(FilePtr::create(fileName));
    }
    qgetenv("QT_TEST_CI").toInt(&m_inCISystem,10);
}

void tst_QAudioInput::format()
{
    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    QAudioFormat requested = audioDevice.preferredFormat();
    QAudioFormat actual    = audioInput.format();

    QVERIFY2((requested.channelCount() == actual.channelCount()),
            QString("channels: requested=%1, actual=%2").arg(requested.channelCount()).arg(actual.channelCount()).toLocal8Bit().constData());
    QVERIFY2((requested.sampleRate() == actual.sampleRate()),
            QString("sampleRate: requested=%1, actual=%2").arg(requested.sampleRate()).arg(actual.sampleRate()).toLocal8Bit().constData());
    QVERIFY2((requested.sampleSize() == actual.sampleSize()),
            QString("sampleSize: requested=%1, actual=%2").arg(requested.sampleSize()).arg(actual.sampleSize()).toLocal8Bit().constData());
    QVERIFY2((requested.codec() == actual.codec()),
            QString("codec: requested=%1, actual=%2").arg(requested.codec()).arg(actual.codec()).toLocal8Bit().constData());
    QVERIFY2((requested.byteOrder() == actual.byteOrder()),
            QString("byteOrder: requested=%1, actual=%2").arg(requested.byteOrder()).arg(actual.byteOrder()).toLocal8Bit().constData());
    QVERIFY2((requested.sampleType() == actual.sampleType()),
            QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData());
}

void tst_QAudioInput::invalidFormat_data()
{
    QTest::addColumn<QAudioFormat>("invalidFormat");

    QAudioFormat format;

    QTest::newRow("Null Format")
            << format;

    format = audioDevice.preferredFormat();
    format.setChannelCount(0);
    QTest::newRow("Channel count 0")
            << format;

    format = audioDevice.preferredFormat();
    format.setSampleRate(0);
    QTest::newRow("Sample rate 0")
            << format;

    format = audioDevice.preferredFormat();
    format.setSampleSize(0);
    QTest::newRow("Sample size 0")
            << format;
}

void tst_QAudioInput::invalidFormat()
{
    QFETCH(QAudioFormat, invalidFormat);

    QVERIFY2(!audioDevice.isFormatSupported(invalidFormat),
            "isFormatSupported() is returning true on an invalid format");

    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
    QTRY_VERIFY2((audioInput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()");
}

void tst_QAudioInput::bufferSize()
{
    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");

    audioInput.setBufferSize(512);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(512)");
    QVERIFY2((audioInput.bufferSize() == 512),
            QString("bufferSize: requested=512, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());

    audioInput.setBufferSize(4096);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(4096)");
    QVERIFY2((audioInput.bufferSize() == 4096),
            QString("bufferSize: requested=4096, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());

    audioInput.setBufferSize(8192);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setBufferSize(8192)");
    QVERIFY2((audioInput.bufferSize() == 8192),
            QString("bufferSize: requested=8192, actual=%2").arg(audioInput.bufferSize()).toLocal8Bit().constData());
}

void tst_QAudioInput::notifyInterval()
{
    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");

    audioInput.setNotifyInterval(50);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(50)");
    QVERIFY2((audioInput.notifyInterval() == 50),
            QString("notifyInterval: requested=50, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());

    audioInput.setNotifyInterval(100);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(100)");
    QVERIFY2((audioInput.notifyInterval() == 100),
            QString("notifyInterval: requested=100, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());

    audioInput.setNotifyInterval(250);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(250)");
    QVERIFY2((audioInput.notifyInterval() == 250),
            QString("notifyInterval: requested=250, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());

    audioInput.setNotifyInterval(1000);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(1000)");
    QVERIFY2((audioInput.notifyInterval() == 1000),
            QString("notifyInterval: requested=1000, actual=%2").arg(audioInput.notifyInterval()).toLocal8Bit().constData());
}

void tst_QAudioInput::disableNotifyInterval()
{
    // Sets an invalid notification interval (QAudioInput::setNotifyInterval(0))
    // Checks that
    //  - No error is raised (QAudioInput::error() returns QAudio::NoError)
    //  - if <= 0, set to zero and disable notify signal

    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError on creation");

    audioInput.setNotifyInterval(0);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(0)");
    QVERIFY2((audioInput.notifyInterval() == 0),
            "notifyInterval() is not zero after setNotifyInterval(0)");

    audioInput.setNotifyInterval(-1);
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() is not QAudio::NoError after setNotifyInterval(-1)");
    QVERIFY2((audioInput.notifyInterval() == 0),
            "notifyInterval() is not zero after setNotifyInterval(-1)");

    //start and run to check if notify() is emitted
    if (audioFiles.size() > 0) {
        QAudioInput audioInputCheck(testFormats.at(0), this);
        audioInputCheck.setNotifyInterval(0);
        QSignalSpy notifySignal(&audioInputCheck, SIGNAL(notify()));
        QFile *audioFile = audioFiles.at(0).data();
        audioFile->open(QIODevice::WriteOnly);
        audioInputCheck.start(audioFile);
        QTest::qWait(3000); // 3 seconds should be plenty
        audioInputCheck.stop();
        QVERIFY2((notifySignal.count() == 0),
                QString("didn't disable notify interval: shouldn't have got any but got %1").arg(notifySignal.count()).toLocal8Bit().constData());
        audioFile->close();
    }
}

void tst_QAudioInput::stopWhileStopped()
{
    // Calls QAudioInput::stop() when object is already in StoppedState
    // Checks that
    //  - No state change occurs
    //  - No error is raised (QAudioInput::error() returns QAudio::NoError)

    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    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()");

    QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
    audioInput.stop();

    // Check that no state transition occurred
    QVERIFY2((stateSignal.count() == 0), "stop() while stopped is emitting a signal and it shouldn't");
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
}

void tst_QAudioInput::suspendWhileStopped()
{
    // Calls QAudioInput::suspend() when object is already in StoppedState
    // Checks that
    //  - No state change occurs
    //  - No error is raised (QAudioInput::error() returns QAudio::NoError)

    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    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()");

    QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
    audioInput.suspend();

    // Check that no state transition occurred
    QVERIFY2((stateSignal.count() == 0), "stop() while suspended is emitting a signal and it shouldn't");
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after stop()");
}

void tst_QAudioInput::resumeWhileStopped()
{
    // Calls QAudioInput::resume() when object is already in StoppedState
    // Checks that
    //  - No state change occurs
    //  - No error is raised (QAudioInput::error() returns QAudio::NoError)

    QAudioInput audioInput(audioDevice.preferredFormat(), this);

    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()");

    QSignalSpy stateSignal(&audioInput, SIGNAL(stateChanged(QAudio::State)));
    audioInput.resume();

    // Check that no state transition occurred
    QVERIFY2((stateSignal.count() == 0), "resume() while stopped is emitting a signal and it shouldn't");
    QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError after resume()");
}

void tst_QAudioInput::pull()
{
    QFETCH(FilePtr, audioFile);
    QFETCH(QAudioFormat, audioFormat);

    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));

    audioInput.start(audioFile.data());

    // 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();

    // Check that 'elapsed' increases
    QTest::qWait(40);
    QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");

    // Allow some recording to happen
    QTest::qWait(3000); // 3 seconds should be plenty

    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, 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();

}

void tst_QAudioInput::pullSuspendResume()
{
#ifdef Q_OS_LINUX
    if (m_inCISystem)
        QSKIP("QTBUG-26504 Fails 20% of time with pulseaudio backend");
#endif
    QFETCH(FilePtr, audioFile);
    QFETCH(QAudioFormat, audioFormat);

    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));

    audioInput.start(audioFile.data());

    // 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();

    // Check that 'elapsed' increases
    QTest::qWait(40);
    QVERIFY2((audioInput.elapsedUSecs() > 0), "elapsedUSecs() is still zero after start()");

    // Allow some recording to happen
    QTest::qWait(3000); // 3 seconds should be plenty

    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");

    stateSignal.clear();

    audioInput.suspend();

    // Give backends running in separate threads a chance to suspend.
    QTest::qWait(100);

    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 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);

    audioInput.resume();

    // Give backends running in separate threads a chance to resume.
    QTest::qWait(100);

    // 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();

    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, 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();
}

void tst_QAudioInput::push()
{
    QFETCH(FilePtr, audioFile);
    QFETCH(QAudioFormat, audioFormat);

    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));

    // Set a large buffer to avoid underruns during QTest::qWaits
    audioInput.setBufferSize(audioFormat.bytesForDuration(1000000));

    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) {
        QTRY_VERIFY_WITH_TIMEOUT(audioInput.bytesReady() >= audioInput.periodSize(), 10000);
        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
            QTRY_VERIFY2((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;
        }
    }

    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::pushSuspendResume()
{
#ifdef Q_OS_LINUX
    if (m_inCISystem)
        QSKIP("QTBUG-26504 Fails 20% of time with pulseaudio backend");
#endif
    QFETCH(FilePtr, audioFile);
    QFETCH(QAudioFormat, audioFormat);
    QAudioInput audioInput(audioFormat, this);

    audioInput.setNotifyInterval(100);
    audioInput.setBufferSize(audioFormat.bytesForDuration(1000000));

    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);
    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) {
        QTRY_VERIFY_WITH_TIMEOUT(audioInput.bytesReady() >= audioInput.periodSize(), 10000);
        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
            QTRY_VERIFY2((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;
        }
    }
    stateSignal.clear();

    audioInput.suspend();

    // Give backends running in separate threads a chance to suspend
    QTest::qWait(100);

    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 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);

    // Drain any data, in case we run out of space when resuming
    const int reads = audioInput.bytesReady() / audioInput.periodSize();
    for (int r = 0; r < reads; ++r)
        feed->read(buffer.data(), audioInput.periodSize());

    audioInput.resume();

    // Check that QAudioInput immediately transitions to Active or IdleState
    QTRY_VERIFY2((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 && audioInput.state() != QAudio::StoppedState) {
        QTRY_VERIFY_WITH_TIMEOUT(audioInput.bytesReady() >= audioInput.periodSize(), 10000);
        qint64 bytesRead = feed->read(buffer.data(), audioInput.periodSize());
        audioFile->write(buffer.constData(),bytesRead);
        totalBytesRead+=bytesRead;
    }
    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(*audioFile,audioFile->pos()-WavHeader::headerLength());
    audioFile->close();
}

void tst_QAudioInput::reset()
{
    QFETCH(QAudioFormat, audioFormat);

    // Try both push/pull.. the vagaries of Active vs Idle are tested elsewhere
    {
        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");

        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.error() == QAudio::NoError), "error state is not equal to QAudio::NoError after start()");
        QVERIFY(audioInput.periodSize() > 0);
        QTRY_VERIFY2_WITH_TIMEOUT((audioInput.bytesReady() > audioInput.periodSize()), "no bytes available after starting", 10000);

        // 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(audioFormat, 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()");
    }
}

void tst_QAudioInput::volume()
{
    QFETCH(QAudioFormat, audioFormat);

    const qreal half(0.5f);
    const qreal one(1.0f);

    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(half);
    audioInput.start();
    QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 5);
    audioInput.setVolume(one);
    QTRY_VERIFY(qRound(audioInput.volume()*10.0f) == 10);

    audioInput.setVolume(volume);
}

QTEST_MAIN(tst_QAudioInput)

#include "tst_qaudioinput.moc"
