QSoundEffect: fix changing the loop count while playing.
authorYoann Lopes <yoann.lopes@digia.com>
Thu, 20 Feb 2014 18:42:20 +0000 (19:42 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 25 Feb 2014 14:00:44 +0000 (15:00 +0100)
The running count was not updated with the new value.

Auto-test added and documentation updated to be more clear about this
behavior.

Task-number: QTBUG-36643

Change-Id: I29e98ca4679f950a75133b21873738bcb72d23d4
Reviewed-by: Christian Stromme <christian.stromme@digia.com>
src/multimedia/audio/qsoundeffect.cpp
src/multimedia/audio/qsoundeffect_pulse_p.cpp
src/multimedia/audio/qsoundeffect_qaudio_p.cpp
tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp

index 83b28c4..cdf5ab3 100644 (file)
@@ -184,16 +184,20 @@ void QSoundEffect::setSource(const QUrl &url)
 /*!
     \qmlproperty int QtMultimedia::SoundEffect::loops
 
-    This property provides a way to control the number of times to repeat the sound on each play().
+    This property holds the number of times the sound is played. A value of 0 or 1 means
+    the sound will be played only once; set to SoundEffect.Infinite to enable infinite looping.
 
-    Set to SoundEffect.Infinite to enable infinite looping.
+    The value can be changed while the sound effect is playing, in which case it will update
+    the remaining loops to the new value.
 */
 
 /*!
     \property QSoundEffect::loops
-    This property provides a way to control the number of times to repeat the sound on each play().
+    This property holds the number of times the sound is played. A value of 0 or 1 means
+    the sound will be played only once; set to SoundEffect.Infinite to enable infinite looping.
 
-    Set to QSoundEffect::Infinite to enable infinite looping.
+    The value can be changed while the sound effect is playing, in which case it will update
+    the remaining loops to the new value.
 */
 
 /*!
@@ -213,8 +217,14 @@ int QSoundEffect::loopCount() const
 */
 
 /*!
-    Set the total number of times to repeat playing this sound effect on each play() call to \a loopCount.
-    Pass \c QSoundEffect::Infinite to repeat until stop() is called.
+    Set the total number of times to play this sound effect to \a loopCount.
+
+    Setting the loop count to 0 or 1 means the sound effect will be played only once;
+    pass \c QSoundEffect::Infinite to repeat indefinitely. The loop count can be changed while
+    the sound effect is playing, in which case it will update the remaining loops to
+    the new \a loopCount.
+
+    \sa loopsRemaining()
 */
 void QSoundEffect::setLoopCount(int loopCount)
 {
index ef09cd9..570870f 100644 (file)
@@ -516,6 +516,8 @@ void QSoundEffectPrivate::setLoopCount(int loopCount)
     if (loopCount == 0)
         loopCount = 1;
     m_loopCount = loopCount;
+    if (m_playing)
+        setLoopsRemaining(loopCount);
 }
 
 qreal QSoundEffectPrivate::volume() const
@@ -647,7 +649,7 @@ void QSoundEffectPrivate::play()
             emptyStream();
             return;
         }
-        m_runningCount = m_loopCount;
+        setLoopsRemaining(m_loopCount);
         playSample();
     }
 
index aed8a7a..2b4359c 100644 (file)
@@ -172,7 +172,8 @@ void QSoundEffectPrivate::setLoopCount(int loopCount)
     if (loopCount == 0)
         loopCount = 1;
     d->m_loopCount = loopCount;
-    d->m_runningCount = loopCount;
+    if (d->m_playing)
+        setLoopsRemaining(loopCount);
 }
 
 qreal QSoundEffectPrivate::volume() const
@@ -228,7 +229,7 @@ QSoundEffect::Status QSoundEffectPrivate::status() const
 void QSoundEffectPrivate::play()
 {
     d->m_offset = 0;
-    d->m_runningCount = d->m_loopCount;
+    setLoopsRemaining(d->m_loopCount);
 #ifdef QT_QAUDIO_DEBUG
     qDebug() << this << "play";
 #endif
@@ -283,7 +284,7 @@ void QSoundEffectPrivate::setPlaying(bool playing)
 
 void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining)
 {
-    if (!d->m_runningCount && loopsRemaining)
+    if (d->m_runningCount == loopsRemaining)
         return;
 #ifdef QT_QAUDIO_DEBUG
     qDebug() << this << "setLoopsRemaining " << loopsRemaining;
index d113d59..c56b08d 100644 (file)
@@ -152,16 +152,86 @@ void tst_QSoundEffect::testLooping()
 
     sound->setLoopCount(5);
     sound->setVolume(0.1f);
-    QCOMPARE(sound->loopCount(),5);
-    QCOMPARE(readSignal_Count.count(),1);
+    QCOMPARE(sound->loopCount(), 5);
+    QCOMPARE(readSignal_Count.count(), 1);
+    QCOMPARE(sound->loopsRemaining(), 0);
+    QCOMPARE(readSignal_Remaining.count(), 0);
 
     sound->play();
+    QCOMPARE(sound->loopsRemaining(), 5);
+    QCOMPARE(readSignal_Remaining.count(), 1);
 
     // test.wav is about 200ms, wait until it has finished playing 5 times
     QTestEventLoop::instance().enterLoop(3);
 
     QTRY_COMPARE(sound->loopsRemaining(), 0);
-    QCOMPARE(readSignal_Remaining.count(),5);
+    QVERIFY(readSignal_Remaining.count() >= 6);
+    QTRY_VERIFY(!sound->isPlaying());
+
+    // QTBUG-36643 (setting the loop count while playing should work)
+    {
+        readSignal_Count.clear();
+        readSignal_Remaining.clear();
+
+        sound->setLoopCount(30);
+        QCOMPARE(sound->loopCount(), 30);
+        QCOMPARE(readSignal_Count.count(), 1);
+        QCOMPARE(sound->loopsRemaining(), 0);
+        QCOMPARE(readSignal_Remaining.count(), 0);
+
+        sound->play();
+        QCOMPARE(sound->loopsRemaining(), 30);
+        QCOMPARE(readSignal_Remaining.count(), 1);
+
+        // wait for the sound to be played several times
+        QTRY_COMPARE(sound->loopsRemaining(), 20);
+        QVERIFY(readSignal_Remaining.count() >= 10);
+        readSignal_Count.clear();
+        readSignal_Remaining.clear();
+
+        // change the loop count while playing
+        sound->setLoopCount(5);
+        QCOMPARE(sound->loopCount(), 5);
+        QCOMPARE(readSignal_Count.count(), 1);
+        QCOMPARE(sound->loopsRemaining(), 5);
+        QCOMPARE(readSignal_Remaining.count(), 1);
+
+        // wait for all the loops to be completed
+        QTRY_COMPARE(sound->loopsRemaining(), 0);
+        QVERIFY(readSignal_Remaining.count() >= 6);
+        QTRY_VERIFY(!sound->isPlaying());
+    }
+
+    {
+        readSignal_Count.clear();
+        readSignal_Remaining.clear();
+
+        sound->setLoopCount(QSoundEffect::Infinite);
+        QCOMPARE(sound->loopCount(), int(QSoundEffect::Infinite));
+        QCOMPARE(readSignal_Count.count(), 1);
+        QCOMPARE(sound->loopsRemaining(), 0);
+        QCOMPARE(readSignal_Remaining.count(), 0);
+
+        sound->play();
+        QCOMPARE(sound->loopsRemaining(), int(QSoundEffect::Infinite));
+        QCOMPARE(readSignal_Remaining.count(), 1);
+
+        QTest::qWait(1500);
+        QVERIFY(sound->isPlaying());
+        readSignal_Count.clear();
+        readSignal_Remaining.clear();
+
+        // Setting the loop count to 0 should play it one last time
+        sound->setLoopCount(0);
+        QCOMPARE(sound->loopCount(), 1);
+        QCOMPARE(readSignal_Count.count(), 1);
+        QCOMPARE(sound->loopsRemaining(), 1);
+        QCOMPARE(readSignal_Remaining.count(), 1);
+
+        QTRY_COMPARE(sound->loopsRemaining(), 0);
+        QVERIFY(readSignal_Remaining.count() >= 2);
+        QTRY_VERIFY(!sound->isPlaying());
+    }
 }
 
 void tst_QSoundEffect::testVolume()