summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVaL Doroshchuk <valentyn.doroshchuk@qt.io>2017-09-27 17:37:25 +0200
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2018-03-22 11:00:10 +0000
commitefbb769b24e1a3b88326578042029876b09b4dea (patch)
treedaa935dbd2e5b0c9a29c7ffd9940bb0a43c4d9e6
parenta429fb971beccf174f2df7f1ae8551a10d17d696 (diff)
downloadqtmultimedia-efbb769b24e1a3b88326578042029876b09b4dea.tar.gz
Support changing of volume in 24-bit audio samples
Introduced a fix to support changing of volume for 3 bytes samples audio stream. Task-number: QTBUG-60579 Change-Id: I4ba4a9a1cf65812ccbc46b40c78546875d5e4d73 Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/multimedia/audio/qaudiohelpers.cpp49
-rw-r--r--tests/auto/integration/qsoundeffect/test24.wavbin0 -> 16482 bytes
-rw-r--r--tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp27
3 files changed, 76 insertions, 0 deletions
diff --git a/src/multimedia/audio/qaudiohelpers.cpp b/src/multimedia/audio/qaudiohelpers.cpp
index 8aa4c090b..fae591477 100644
--- a/src/multimedia/audio/qaudiohelpers.cpp
+++ b/src/multimedia/audio/qaudiohelpers.cpp
@@ -43,6 +43,49 @@
QT_BEGIN_NAMESPACE
+// Base implementation of 24 bits number.
+// Used to adjust 3 bytes values by a factor.
+// TODO: Uses little-endian only.
+class Int24
+{
+public:
+ quint8 data[3];
+ Int24(qint32 v) {
+ data[0] = v & 0xFF;
+ data[1] = (v & 0xFF00) >> 8;
+ data[2] = (v & 0xFF0000) >> 16;
+ }
+ template<class T>
+ T multiply(qreal factor, T v = 0) const {
+ v |= data[0];
+ v |= data[1] << 8;
+ v |= data[2] << 16;
+ v *= factor;
+ return v;
+ }
+};
+
+class qint24: public Int24
+{
+public:
+ qint24(qint32 v): Int24(v) {}
+ qint24 operator*(qreal factor) const {
+ // Checks if it is a signed value.
+ qint32 v = (data[2] & 0x80) ? 0xFF000000 : 0;
+ return multiply(factor, v);
+ }
+};
+
+class quint24: public Int24
+{
+public:
+ quint24(quint32 v): Int24(v) {}
+ quint24 operator*(qreal factor) const {
+ return multiply<quint32>(factor);
+ }
+};
+
+
namespace QAudioHelperInternal
{
@@ -101,6 +144,12 @@ void qMultiplySamples(qreal factor, const QAudioFormat &format, const void* src,
else if (format.sampleType() == QAudioFormat::UnSignedInt)
QAudioHelperInternal::adjustUnsignedSamples<quint16>(factor,src,dest,samplesCount);
break;
+ case 24:
+ if (format.sampleType() == QAudioFormat::SignedInt)
+ QAudioHelperInternal::adjustSamples<qint24>(factor,src,dest,samplesCount);
+ else if (format.sampleType() == QAudioFormat::UnSignedInt)
+ QAudioHelperInternal::adjustSamples<quint24>(factor,src,dest,samplesCount);
+ break;
default:
if (format.sampleType() == QAudioFormat::SignedInt)
QAudioHelperInternal::adjustSamples<qint32>(factor,src,dest,samplesCount);
diff --git a/tests/auto/integration/qsoundeffect/test24.wav b/tests/auto/integration/qsoundeffect/test24.wav
new file mode 100644
index 000000000..9575aaaee
--- /dev/null
+++ b/tests/auto/integration/qsoundeffect/test24.wav
Binary files differ
diff --git a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp
index 5be889096..fa98c8b16 100644
--- a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp
+++ b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp
@@ -62,12 +62,14 @@ private slots:
void testSetSourceWhilePlaying();
void testSupportedMimeTypes();
void testCorruptFile();
+ void testPlaying24Bits();
private:
QSoundEffect* sound;
QUrl url; // test.wav: pcm_s16le, 48000 Hz, stereo, s16
QUrl url2; // test_tone.wav: pcm_s16le, 44100 Hz, mono
QUrl urlCorrupted; // test_corrupted.wav: corrupted
+ QUrl url24Bits; // test24.wav pcm_s24le, 44100 Hz, mono
};
void tst_QSoundEffect::init()
@@ -105,6 +107,11 @@ void tst_QSoundEffect::initTestCase()
QVERIFY2(!fullPath.isEmpty(), qPrintable(QStringLiteral("Unable to locate ") + testFileName));
urlCorrupted = QUrl::fromLocalFile(fullPath);
+ testFileName = QStringLiteral("test24.wav");
+ fullPath = QFINDTESTDATA(testFileName);
+ QVERIFY2(!fullPath.isEmpty(), qPrintable(QStringLiteral("Unable to locate ") + testFileName));
+ url24Bits = QUrl::fromLocalFile(fullPath);
+
sound = new QSoundEffect(this);
QVERIFY(sound->source().isEmpty());
@@ -409,6 +416,26 @@ void tst_QSoundEffect::testCorruptFile()
}
}
+void tst_QSoundEffect::testPlaying24Bits()
+{
+ sound->setLoopCount(QSoundEffect::Infinite);
+ sound->setSource(url24Bits);
+ QTestEventLoop::instance().enterLoop(1);
+ sound->play();
+ QTestEventLoop::instance().enterLoop(1);
+ QTRY_COMPARE(sound->isPlaying(), true);
+ sound->stop();
+
+ QSignalSpy readSignal(sound, SIGNAL(volumeChanged()));
+ sound->setVolume(0.5);
+ QCOMPARE(sound->volume(), 0.5);
+ sound->play();
+ QTestEventLoop::instance().enterLoop(1);
+ QTRY_COMPARE(sound->isPlaying(), true);
+ QCOMPARE(readSignal.count(), 1);
+ sound->stop();
+}
+
QTEST_MAIN(tst_QSoundEffect)
#include "tst_qsoundeffect.moc"