From d964388b38ec4762e315d86aacb779604bcdca1b Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 20 Feb 2014 19:42:20 +0100 Subject: QSoundEffect: fix changing the loop count while playing. 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 --- src/multimedia/audio/qsoundeffect.cpp | 22 +++++-- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 4 +- src/multimedia/audio/qsoundeffect_qaudio_p.cpp | 7 +- .../integration/qsoundeffect/tst_qsoundeffect.cpp | 76 +++++++++++++++++++++- 4 files changed, 96 insertions(+), 13 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect.cpp b/src/multimedia/audio/qsoundeffect.cpp index 83b28c453..cdf5ab300 100644 --- a/src/multimedia/audio/qsoundeffect.cpp +++ b/src/multimedia/audio/qsoundeffect.cpp @@ -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) { diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index ef09cd90a..570870fc9 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -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(); } diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp index aed8a7aea..2b4359ccf 100644 --- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp +++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp @@ -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; diff --git a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp index d113d595a..c56b08dfd 100644 --- a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp +++ b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp @@ -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() -- cgit v1.2.3