diff options
author | Doris Verria <doris.verria@qt.io> | 2021-08-20 15:20:54 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-08-25 08:51:08 +0000 |
commit | 71ab74d1629aefe2a1fab1c6e8620fdd3cf0c53b (patch) | |
tree | f1db737d7e1731546892833cdeeabc5d96abef78 /tests | |
parent | e01011f18226c10386a260ed294d8ff2f07028af (diff) |
QAudioDecoder: Re-add API for setting desired audio format
Re-add API for setting/getting desired format for the
decoded audio samples. Readd support on all backends with
the exception of Android.
- Add a warning in the docs for lack of support on Android.
- Make the behavior of audioFormat() consistent on all
platforms. It will return an invalid format if no
format is set. Change Windows implementation to do so.
- Fix the documentation for audioFormat(). The format
returned is the one set to the decoder, and the decoded
buffers may not have this format, in the case when it was
set to an invalid one.
- Some small fixes on darwin and Windows.
Partly reverts af1182b5e29afa0cd69f929d54da224019707214.
Fixes: QTBUG-95766
Change-Id: Id1d6b33a6b9d916e272d3b9d9cee78b6f63609f3
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 185ff0902181f29990c371d0b19b47915b172143)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
3 files changed, 181 insertions, 0 deletions
diff --git a/tests/auto/integration/qaudiodecoderbackend/tst_qaudiodecoderbackend.cpp b/tests/auto/integration/qaudiodecoderbackend/tst_qaudiodecoderbackend.cpp index 5e32efa16..f6ec6fe4b 100644 --- a/tests/auto/integration/qaudiodecoderbackend/tst_qaudiodecoderbackend.cpp +++ b/tests/auto/integration/qaudiodecoderbackend/tst_qaudiodecoderbackend.cpp @@ -105,6 +105,7 @@ void tst_QAudioDecoderBackend::fileTest() QVERIFY(!d.isDecoding()); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.source(), QString("")); + QVERIFY(d.audioFormat() == QAudioFormat()); // Test local file QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME)); @@ -140,6 +141,8 @@ void tst_QAudioDecoderBackend::fileTest() QCOMPARE(buffer.format().sampleFormat(), QAudioFormat::Int16); QCOMPARE(buffer.byteCount(), buffer.sampleCount() * 2); // 16bit mono + // The decoder should still have no format set + QVERIFY(d.audioFormat() == QAudioFormat()); QVERIFY(errorSpy.isEmpty()); duration += buffer.duration(); @@ -180,6 +183,90 @@ void tst_QAudioDecoderBackend::fileTest() QTRY_COMPARE(durationSpy.count(), 2); QCOMPARE(d.duration(), qint64(-1)); QVERIFY(!d.bufferAvailable()); + readySpy.clear(); + bufferChangedSpy.clear(); + isDecodingSpy.clear(); + durationSpy.clear(); + finishedSpy.clear(); + positionSpy.clear(); + + // change output audio format + QAudioFormat format; + format.setChannelCount(2); + format.setSampleRate(11050); + format.setSampleFormat(QAudioFormat::UInt8); + + d.setAudioFormat(format); + + // We expect 1 second still, at 11050 * 2 samples == 22k samples. + // (at 1 byte/sample -> 22kb) + + // Make sure it stuck + QVERIFY(d.audioFormat() == format); + + duration = 0; + sampleCount = 0; + byteCount = 0; + + d.start(); + QTRY_VERIFY(d.isDecoding()); + QTRY_VERIFY(!isDecodingSpy.isEmpty()); + QTRY_VERIFY(!readySpy.isEmpty()); + QTRY_VERIFY(!bufferChangedSpy.isEmpty()); + QVERIFY(d.bufferAvailable()); + QTRY_VERIFY(!durationSpy.isEmpty()); + QVERIFY(qAbs(d.duration() - 1000) < 20); + + buffer = d.read(); + QVERIFY(buffer.isValid()); + // See if we got the right format + QVERIFY(buffer.format() == format); + + // The decoder should still have the same format + QVERIFY(d.audioFormat() == format); + + QVERIFY(errorSpy.isEmpty()); + + duration += buffer.duration(); + sampleCount += buffer.sampleCount(); + byteCount += buffer.byteCount(); + + // Now drain the decoder + if (duration < 998000) { + QTRY_COMPARE(d.bufferAvailable(), true); + } + + while (d.bufferAvailable()) { + buffer = d.read(); + QVERIFY(buffer.isValid()); + QTRY_VERIFY(!positionSpy.isEmpty()); + QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000)); + QVERIFY(d.position() - (duration / 1000) < 20); + + duration += buffer.duration(); + sampleCount += buffer.sampleCount(); + byteCount += buffer.byteCount(); + + if (duration < 998000) { + QTRY_COMPARE(d.bufferAvailable(), true); + } + } + + // Resampling might end up with fewer or more samples + // so be a bit sloppy + QVERIFY(qAbs(sampleCount - 22047) < 100); + QVERIFY(qAbs(byteCount - 22047) < 100); + QVERIFY(qAbs(qint64(duration) - 1000000) < 20000); + QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20); + QTRY_COMPARE(finishedSpy.count(), 1); + QVERIFY(!d.bufferAvailable()); + QVERIFY(!d.isDecoding()); + + d.stop(); + QTRY_VERIFY(!d.isDecoding()); + QTRY_COMPARE(durationSpy.count(), 2); + QCOMPARE(d.duration(), qint64(-1)); + QVERIFY(!d.bufferAvailable()); } /* @@ -195,6 +282,7 @@ void tst_QAudioDecoderBackend::unsupportedFileTest() QVERIFY(!d.isDecoding()); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.source(), QString("")); + QVERIFY(d.audioFormat() == QAudioFormat()); // Test local file QFileInfo fileInfo(QFINDTESTDATA(TEST_UNSUPPORTED_FILE_NAME)); @@ -215,6 +303,7 @@ void tst_QAudioDecoderBackend::unsupportedFileTest() d.start(); QTRY_VERIFY(!d.isDecoding()); QVERIFY(!d.bufferAvailable()); + QCOMPARE(d.audioFormat(), QAudioFormat()); QCOMPARE(d.duration(), qint64(-1)); QCOMPARE(d.position(), qint64(-1)); @@ -272,6 +361,7 @@ void tst_QAudioDecoderBackend::corruptedFileTest() QVERIFY(!d.isDecoding()); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.source(), QUrl()); + QVERIFY(d.audioFormat() == QAudioFormat()); // Test local file QFileInfo fileInfo(QFINDTESTDATA(TEST_CORRUPTED_FILE_NAME)); @@ -292,6 +382,7 @@ void tst_QAudioDecoderBackend::corruptedFileTest() d.start(); QTRY_VERIFY(!d.isDecoding()); QVERIFY(!d.bufferAvailable()); + QCOMPARE(d.audioFormat(), QAudioFormat()); QCOMPARE(d.duration(), qint64(-1)); QCOMPARE(d.position(), qint64(-1)); @@ -345,6 +436,7 @@ void tst_QAudioDecoderBackend::invalidSource() QVERIFY(!d.isDecoding()); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.source(), QUrl()); + QVERIFY(d.audioFormat() == QAudioFormat()); // Test invalid file source QFileInfo fileInfo(TEST_INVALID_SOURCE); @@ -365,6 +457,7 @@ void tst_QAudioDecoderBackend::invalidSource() d.start(); QTRY_VERIFY(!d.isDecoding()); QVERIFY(!d.bufferAvailable()); + QCOMPARE(d.audioFormat(), QAudioFormat()); QCOMPARE(d.duration(), qint64(-1)); QCOMPARE(d.position(), qint64(-1)); @@ -399,6 +492,7 @@ void tst_QAudioDecoderBackend::invalidSource() d.start(); QTRY_VERIFY(!d.isDecoding()); QVERIFY(!d.bufferAvailable()); + QCOMPARE(d.audioFormat(), QAudioFormat()); QCOMPARE(d.duration(), qint64(-1)); QCOMPARE(d.position(), qint64(-1)); @@ -447,6 +541,7 @@ void tst_QAudioDecoderBackend::deviceTest() QVERIFY(!d.isDecoding()); QVERIFY(d.bufferAvailable() == false); QCOMPARE(d.source(), QString("")); + QVERIFY(d.audioFormat() == QAudioFormat()); QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME)); QFile file(fileInfo.absoluteFilePath()); @@ -456,6 +551,9 @@ void tst_QAudioDecoderBackend::deviceTest() QVERIFY(d.sourceDevice() == &file); QVERIFY(d.source().isEmpty()); + // We haven't set the format yet + QVERIFY(d.audioFormat() == QAudioFormat()); + d.start(); QTRY_VERIFY(d.isDecoding()); @@ -511,6 +609,48 @@ void tst_QAudioDecoderBackend::deviceTest() QVERIFY(!d.bufferAvailable()); QTRY_COMPARE(durationSpy.count(), 2); QCOMPARE(d.duration(), qint64(-1)); + readySpy.clear(); + bufferChangedSpy.clear(); + isDecodingSpy.clear(); + durationSpy.clear(); + finishedSpy.clear(); + positionSpy.clear(); + + // Now try changing formats + QAudioFormat format; + format.setChannelCount(2); + format.setSampleRate(8000); + format.setSampleFormat(QAudioFormat::UInt8); + + d.setAudioFormat(format); + + // Make sure it stuck + QVERIFY(d.audioFormat() == format); + + d.start(); + QTRY_VERIFY(d.isDecoding()); + QTRY_VERIFY(!isDecodingSpy.isEmpty()); + QTRY_VERIFY(!readySpy.isEmpty()); + QTRY_VERIFY(!bufferChangedSpy.isEmpty()); + QVERIFY(d.bufferAvailable()); + QTRY_VERIFY(!durationSpy.isEmpty()); + QVERIFY(qAbs(d.duration() - 1000) < 20); + + buffer = d.read(); + QVERIFY(buffer.isValid()); + // See if we got the right format + QVERIFY(buffer.format() == format); + + // The decoder should still have the same format + QVERIFY(d.audioFormat() == format); + + QVERIFY(errorSpy.isEmpty()); + + d.stop(); + QTRY_VERIFY(!d.isDecoding()); + QVERIFY(!d.bufferAvailable()); + QTRY_COMPARE(durationSpy.count(), 2); + QCOMPARE(d.duration(), qint64(-1)); } QTEST_MAIN(tst_QAudioDecoderBackend) diff --git a/tests/auto/unit/mockbackend/qmockaudiodecoder.h b/tests/auto/unit/mockbackend/qmockaudiodecoder.h index 15c95b9df..b31bd29a6 100644 --- a/tests/auto/unit/mockbackend/qmockaudiodecoder.h +++ b/tests/auto/unit/mockbackend/qmockaudiodecoder.h @@ -82,6 +82,19 @@ public: stop(); } + QAudioFormat audioFormat() const override + { + return mFormat; + } + + void setAudioFormat(const QAudioFormat &format) override + { + if (mFormat != format) { + mFormat = format; + emit formatChanged(mFormat); + } + } + // When decoding we decode to first buffer, then second buffer // we then stop until the first is read again and so on, for // 5 buffers diff --git a/tests/auto/unit/multimedia/qaudiodecoder/tst_qaudiodecoder.cpp b/tests/auto/unit/multimedia/qaudiodecoder/tst_qaudiodecoder.cpp index 1c200cb21..6049bd4a2 100644 --- a/tests/auto/unit/multimedia/qaudiodecoder/tst_qaudiodecoder.cpp +++ b/tests/auto/unit/multimedia/qaudiodecoder/tst_qaudiodecoder.cpp @@ -219,6 +219,28 @@ void tst_QAudioDecoder::format() b = d.read(); QVERIFY(b.format().isValid()); + QVERIFY(d.audioFormat() == b.format()); + + // Setting format while decoding is forbidden + QAudioFormat f(d.audioFormat()); + f.setChannelCount(2); + + d.setAudioFormat(f); + QVERIFY(d.audioFormat() != f); + QVERIFY(d.audioFormat() == b.format()); + + // Now stop, and set something specific + d.stop(); + d.setAudioFormat(f); + QVERIFY(d.audioFormat() == f); + + // Decode again + d.start(); + QTRY_VERIFY(d.bufferAvailable()); + + b = d.read(); + QVERIFY(d.audioFormat() == f); + QVERIFY(b.format() == f); } void tst_QAudioDecoder::source() @@ -314,6 +336,12 @@ void tst_QAudioDecoder::nullControl() d.setSourceDevice(&f); QVERIFY(d.sourceDevice() == nullptr); + QAudioFormat format; + format.setChannelCount(2); + QVERIFY(!d.audioFormat().isValid()); + d.setAudioFormat(format); + QVERIFY(!d.audioFormat().isValid()); + QVERIFY(!d.read().isValid()); QVERIFY(!d.bufferAvailable()); |