diff --git a/src/multimedia/audio/qaudiohelpers.cpp b/src/multimedia/audio/qaudiohelpers.cpp
index 8aa4c090bc55e98c6538562ed38e00a7591bf28e..fae5914773fcad9f1595e419fe442d7ff0f7ebde 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 0000000000000000000000000000000000000000..9575aaaee3bc7563a0ec8a2157afe6037eca10ad
Binary files /dev/null and b/tests/auto/integration/qsoundeffect/test24.wav differ
diff --git a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp
index 5be889096dc022788ad12c24f3606a073971e12c..fa98c8b1656c85775318b077c6e5637064f8b712 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"