Add new implementation of QSound class
Added a re-implementation of QSound, using functionality derived from QSoundEffect. QSound API remains the same as the original 4.x version. It offers both a static interface (with auto resource cleanup on sound completion), as well as an object instance interface for more detailed control. Change-Id: I85c00dd88547f8dea9b1e1ef2da31d2f2e28a172 Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
c13a13c486
commit
f9ec11a25e
49
doc/src/snippets/multimedia-snippets/qsound.cpp
Normal file
49
doc/src/snippets/multimedia-snippets/qsound.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//! [0]
|
||||||
|
QSound::play("mysounds/bells.wav");
|
||||||
|
//! [0]
|
||||||
|
|
||||||
|
|
||||||
|
//! [1]
|
||||||
|
QSound bells("mysounds/bells.wav");
|
||||||
|
bells.play();
|
||||||
|
//! [1]
|
||||||
@@ -21,7 +21,8 @@ unix:!mac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC_HEADERS += \
|
PUBLIC_HEADERS += \
|
||||||
effects/qsoundeffect.h
|
effects/qsoundeffect.h \
|
||||||
|
effects/qsound.h
|
||||||
|
|
||||||
PRIVATE_HEADERS += \
|
PRIVATE_HEADERS += \
|
||||||
effects/qwavedecoder_p.h \
|
effects/qwavedecoder_p.h \
|
||||||
@@ -30,6 +31,7 @@ PRIVATE_HEADERS += \
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
effects/qsoundeffect.cpp \
|
effects/qsoundeffect.cpp \
|
||||||
effects/qwavedecoder_p.cpp \
|
effects/qwavedecoder_p.cpp \
|
||||||
effects/qsamplecache_p.cpp
|
effects/qsamplecache_p.cpp \
|
||||||
|
effects/qsound.cpp
|
||||||
|
|
||||||
HEADERS +=
|
HEADERS +=
|
||||||
|
|||||||
236
src/multimedia/effects/qsound.cpp
Normal file
236
src/multimedia/effects/qsound.cpp
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qsound.h"
|
||||||
|
#include "qsoundeffect.h"
|
||||||
|
#include "qcoreapplication.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QSound
|
||||||
|
\brief The QSound class provides a way to play .wav sound files.
|
||||||
|
|
||||||
|
\ingroup multimedia
|
||||||
|
|
||||||
|
|
||||||
|
Qt provides the most commonly required audio operation in GUI
|
||||||
|
applications: asynchronously playing a sound file. This is most
|
||||||
|
easily accomplished using the static play() function:
|
||||||
|
|
||||||
|
\snippet doc/src/snippets/multimedia-snippets/qsound.cpp 0
|
||||||
|
|
||||||
|
Alternatively, create a QSound object from the sound file first
|
||||||
|
and then call the play() slot:
|
||||||
|
|
||||||
|
\snippet doc/src/snippets/multimedia-snippets/qsound.cpp 1
|
||||||
|
|
||||||
|
Once created a QSound object can be queried for its fileName() and
|
||||||
|
total number of loops() (i.e. the number of times the sound will
|
||||||
|
play). The number of repetitions can be altered using the
|
||||||
|
setLoops() function. While playing the sound, the loopsRemaining()
|
||||||
|
function returns the remaining number of repetitions. Use the
|
||||||
|
isFinished() function to determine whether the sound has finished
|
||||||
|
playing.
|
||||||
|
|
||||||
|
Sounds played using a QSound object may use more memory than the
|
||||||
|
static play() function, but it may also play more immediately
|
||||||
|
(depending on the underlying platform audio facilities).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Plays the sound stored in the file specified by the given \a filename.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa stop(), loopsRemaining(), isFinished()
|
||||||
|
*/
|
||||||
|
void QSound::play(const QString& filename)
|
||||||
|
{
|
||||||
|
// Object destruction is generaly handled via deleteOnComplete
|
||||||
|
// Unexpected cases will be handled via parenting of QSound objects to qApp
|
||||||
|
QSound *sound = new QSound(filename, qApp);
|
||||||
|
sound->connect(sound->m_soundEffect, SIGNAL(playingChanged()), SLOT(deleteOnComplete()));
|
||||||
|
sound->play();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QSound object from the file specified by the given \a
|
||||||
|
filename and with the given \a parent.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa play()
|
||||||
|
*/
|
||||||
|
QSound::QSound(const QString& filename, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_soundEffect = new QSoundEffect(this);
|
||||||
|
m_soundEffect->setSource(QUrl::fromLocalFile(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys this sound object. If the sound is not finished playing,
|
||||||
|
the stop() function is called before the sound object is
|
||||||
|
destroyed.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa stop(), isFinished()
|
||||||
|
*/
|
||||||
|
QSound::~QSound()
|
||||||
|
{
|
||||||
|
if (!isFinished())
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if the sound has finished playing; otherwise returns false.
|
||||||
|
*/
|
||||||
|
bool QSound::isFinished() const
|
||||||
|
{
|
||||||
|
return !m_soundEffect->isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
|
||||||
|
Starts playing the sound specified by this QSound object.
|
||||||
|
|
||||||
|
The function returns immediately. Depending on the platform audio
|
||||||
|
facilities, other sounds may stop or be mixed with the new
|
||||||
|
sound. The sound can be played again at any time, possibly mixing
|
||||||
|
or replacing previous plays of the sound.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa fileName()
|
||||||
|
*/
|
||||||
|
void QSound::play()
|
||||||
|
{
|
||||||
|
m_soundEffect->play();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the number of times the sound will play.
|
||||||
|
Return value of \c QSound::Infinite indicates infinite number of loops
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa loopsRemaining(), setLoops()
|
||||||
|
*/
|
||||||
|
int QSound::loops() const
|
||||||
|
{
|
||||||
|
// retain old API value for infite loops
|
||||||
|
int loopCount = m_soundEffect->loopCount();
|
||||||
|
if (loopCount == QSoundEffect::Infinite)
|
||||||
|
loopCount = Infinite;
|
||||||
|
|
||||||
|
return loopCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the remaining number of times the sound will loop (for all
|
||||||
|
positive values this value decreases each time the sound is played).
|
||||||
|
Return value of \c QSound::Infinite indicates infinite number of loops
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa loops(), isFinished()
|
||||||
|
*/
|
||||||
|
int QSound::loopsRemaining() const
|
||||||
|
{
|
||||||
|
// retain old API value for infite loops
|
||||||
|
int loopsRemaining = m_soundEffect->loopsRemaining();
|
||||||
|
if (loopsRemaining == QSoundEffect::Infinite)
|
||||||
|
loopsRemaining = Infinite;
|
||||||
|
|
||||||
|
return loopsRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QSound::setLoops(int number)
|
||||||
|
|
||||||
|
Sets the sound to repeat the given \a number of times when it is
|
||||||
|
played.
|
||||||
|
|
||||||
|
Note that passing the value \c QSound::Infinite will cause the sound to loop
|
||||||
|
indefinitely.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa loops()
|
||||||
|
*/
|
||||||
|
void QSound::setLoops(int n)
|
||||||
|
{
|
||||||
|
if (n == Infinite)
|
||||||
|
n = QSoundEffect::Infinite;
|
||||||
|
|
||||||
|
m_soundEffect->setLoopCount(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the filename associated with this QSound object.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa QSound()
|
||||||
|
*/
|
||||||
|
QString QSound::fileName() const
|
||||||
|
{
|
||||||
|
return m_soundEffect->source().toLocalFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Stops the sound playing.
|
||||||
|
|
||||||
|
\since 5.0
|
||||||
|
\sa play()
|
||||||
|
*/
|
||||||
|
void QSound::stop()
|
||||||
|
{
|
||||||
|
m_soundEffect->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
\since 5.0
|
||||||
|
*/
|
||||||
|
void QSound::deleteOnComplete()
|
||||||
|
{
|
||||||
|
if (!m_soundEffect->isPlaying())
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_qsound.cpp"
|
||||||
93
src/multimedia/effects/qsound.h
Normal file
93
src/multimedia/effects/qsound.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSOUND_H
|
||||||
|
#define QSOUND_H
|
||||||
|
|
||||||
|
#include <qtmultimediadefs.h>
|
||||||
|
#include <QtCore/qobject.h>
|
||||||
|
|
||||||
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QT_MODULE(Multimedia)
|
||||||
|
|
||||||
|
class QSoundEffect;
|
||||||
|
|
||||||
|
class Q_MULTIMEDIA_EXPORT QSound : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Loop
|
||||||
|
{
|
||||||
|
Infinite = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void play(const QString& filename);
|
||||||
|
|
||||||
|
explicit QSound(const QString& filename, QObject* parent = 0);
|
||||||
|
~QSound();
|
||||||
|
|
||||||
|
int loops() const;
|
||||||
|
int loopsRemaining() const;
|
||||||
|
void setLoops(int);
|
||||||
|
QString fileName() const;
|
||||||
|
|
||||||
|
bool isFinished() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void play();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void deleteOnComplete();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSoundEffect *m_soundEffect;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_HEADER
|
||||||
|
|
||||||
|
|
||||||
|
#endif // QSOUND_H
|
||||||
@@ -121,10 +121,17 @@ QT_BEGIN_NAMESPACE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlsignal SoundEffect::loopsChanged()
|
\qmlsignal SoundEffect::loopCountChanged()
|
||||||
\since 1.0
|
\since 1.0
|
||||||
|
|
||||||
This handler is called when the number of loops has changed.
|
This handler is called when the initial number of loops has changed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlsignal SoundEffect::loopsRemainingChanged()
|
||||||
|
\since 1.0
|
||||||
|
|
||||||
|
This handler is called when the remaining number of loops has changed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -164,6 +171,7 @@ QSoundEffect::QSoundEffect(QObject *parent) :
|
|||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
d = new QSoundEffectPrivate(this);
|
d = new QSoundEffectPrivate(this);
|
||||||
|
connect(d, SIGNAL(loopsRemainingChanged()), SIGNAL(loopsRemainingChanged()));
|
||||||
connect(d, SIGNAL(volumeChanged()), SIGNAL(volumeChanged()));
|
connect(d, SIGNAL(volumeChanged()), SIGNAL(volumeChanged()));
|
||||||
connect(d, SIGNAL(mutedChanged()), SIGNAL(mutedChanged()));
|
connect(d, SIGNAL(mutedChanged()), SIGNAL(mutedChanged()));
|
||||||
connect(d, SIGNAL(loadedChanged()), SIGNAL(loadedChanged()));
|
connect(d, SIGNAL(loadedChanged()), SIGNAL(loadedChanged()));
|
||||||
@@ -201,6 +209,11 @@ int QSoundEffect::loopCount() const
|
|||||||
return d->loopCount();
|
return d->loopCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QSoundEffect::loopsRemaining() const
|
||||||
|
{
|
||||||
|
return d->loopsRemaining();
|
||||||
|
}
|
||||||
|
|
||||||
void QSoundEffect::setLoopCount(int loopCount)
|
void QSoundEffect::setLoopCount(int loopCount)
|
||||||
{
|
{
|
||||||
if (loopCount < 0 && loopCount != Infinite) {
|
if (loopCount < 0 && loopCount != Infinite) {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject
|
|||||||
Q_CLASSINFO("DefaultMethod", "play()")
|
Q_CLASSINFO("DefaultMethod", "play()")
|
||||||
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
|
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(int loops READ loopCount WRITE setLoopCount NOTIFY loopCountChanged)
|
Q_PROPERTY(int loops READ loopCount WRITE setLoopCount NOTIFY loopCountChanged)
|
||||||
|
Q_PROPERTY(int loopsRemaining READ loopsRemaining NOTIFY loopsRemainingChanged)
|
||||||
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||||
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
|
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
|
||||||
Q_PROPERTY(bool playing READ isPlaying NOTIFY playingChanged)
|
Q_PROPERTY(bool playing READ isPlaying NOTIFY playingChanged)
|
||||||
@@ -93,6 +94,7 @@ public:
|
|||||||
void setSource(const QUrl &url);
|
void setSource(const QUrl &url);
|
||||||
|
|
||||||
int loopCount() const;
|
int loopCount() const;
|
||||||
|
int loopsRemaining() const;
|
||||||
void setLoopCount(int loopCount);
|
void setLoopCount(int loopCount);
|
||||||
|
|
||||||
qreal volume() const;
|
qreal volume() const;
|
||||||
@@ -109,6 +111,7 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
void loopCountChanged();
|
void loopCountChanged();
|
||||||
|
void loopsRemainingChanged();
|
||||||
void volumeChanged();
|
void volumeChanged();
|
||||||
void mutedChanged();
|
void mutedChanged();
|
||||||
void loadedChanged();
|
void loadedChanged();
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ void QSoundEffectPrivate::setSource(const QUrl &url)
|
|||||||
m_sampleReady = false;
|
m_sampleReady = false;
|
||||||
|
|
||||||
PulseDaemonLocker locker;
|
PulseDaemonLocker locker;
|
||||||
m_runningCount = 0;
|
setLoopsRemaining(0);
|
||||||
if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) {
|
if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) {
|
||||||
pa_stream_set_write_callback(m_pulseStream, 0, 0);
|
pa_stream_set_write_callback(m_pulseStream, 0, 0);
|
||||||
pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
|
pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
|
||||||
@@ -444,6 +444,11 @@ int QSoundEffectPrivate::loopCount() const
|
|||||||
return m_loopCount;
|
return m_loopCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QSoundEffectPrivate::loopsRemaining() const
|
||||||
|
{
|
||||||
|
return m_runningCount;
|
||||||
|
}
|
||||||
|
|
||||||
void QSoundEffectPrivate::setLoopCount(int loopCount)
|
void QSoundEffectPrivate::setLoopCount(int loopCount)
|
||||||
{
|
{
|
||||||
if (loopCount == 0)
|
if (loopCount == 0)
|
||||||
@@ -542,6 +547,17 @@ void QSoundEffectPrivate::setStatus(QSoundEffect::Status status)
|
|||||||
emit loadedChanged();
|
emit loadedChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining)
|
||||||
|
{
|
||||||
|
#ifdef QT_PA_DEBUG
|
||||||
|
qDebug() << this << "setLoopsRemaining " << loopsRemaining;
|
||||||
|
#endif
|
||||||
|
if (m_runningCount == loopsRemaining)
|
||||||
|
return;
|
||||||
|
m_runningCount = loopsRemaining;
|
||||||
|
emit loopsRemainingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void QSoundEffectPrivate::play()
|
void QSoundEffectPrivate::play()
|
||||||
{
|
{
|
||||||
#ifdef QT_PA_DEBUG
|
#ifdef QT_PA_DEBUG
|
||||||
@@ -561,7 +577,7 @@ void QSoundEffectPrivate::play()
|
|||||||
#ifdef QT_PA_DEBUG
|
#ifdef QT_PA_DEBUG
|
||||||
qDebug() << this << "restart playing";
|
qDebug() << this << "restart playing";
|
||||||
#endif
|
#endif
|
||||||
m_runningCount = 0;
|
setLoopsRemaining(0);
|
||||||
m_playQueued = true;
|
m_playQueued = true;
|
||||||
Q_ASSERT(m_pulseStream);
|
Q_ASSERT(m_pulseStream);
|
||||||
emptyStream();
|
emptyStream();
|
||||||
@@ -708,7 +724,7 @@ void QSoundEffectPrivate::prepare()
|
|||||||
}
|
}
|
||||||
if (m_playQueued) {
|
if (m_playQueued) {
|
||||||
m_playQueued = false;
|
m_playQueued = false;
|
||||||
m_runningCount = m_loopCount;
|
setLoopsRemaining(m_loopCount);
|
||||||
playSample();
|
playSample();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -727,7 +743,7 @@ void QSoundEffectPrivate::uploadSample()
|
|||||||
if (m_position == m_sample->data().size()) {
|
if (m_position == m_sample->data().size()) {
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
if (m_runningCount > 0)
|
if (m_runningCount > 0)
|
||||||
m_runningCount--;
|
setLoopsRemaining(m_runningCount - 1);
|
||||||
if (m_runningCount == 0) {
|
if (m_runningCount == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -745,7 +761,7 @@ void QSoundEffectPrivate::uploadSample()
|
|||||||
if (m_position == m_sample->data().size()) {
|
if (m_position == m_sample->data().size()) {
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
if (m_runningCount > 0)
|
if (m_runningCount > 0)
|
||||||
m_runningCount--;
|
setLoopsRemaining(m_runningCount - 1);
|
||||||
if (m_runningCount != 0 && firstPartLength < writableSize)
|
if (m_runningCount != 0 && firstPartLength < writableSize)
|
||||||
{
|
{
|
||||||
while (writtenBytes < writableSize) {
|
while (writtenBytes < writableSize) {
|
||||||
@@ -760,7 +776,7 @@ void QSoundEffectPrivate::uploadSample()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (m_runningCount > 0)
|
if (m_runningCount > 0)
|
||||||
m_runningCount--;
|
setLoopsRemaining(m_runningCount - 1);
|
||||||
if (m_runningCount == 0)
|
if (m_runningCount == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -793,7 +809,7 @@ void QSoundEffectPrivate::stop()
|
|||||||
m_stopping = true;
|
m_stopping = true;
|
||||||
if (m_pulseStream)
|
if (m_pulseStream)
|
||||||
emptyStream();
|
emptyStream();
|
||||||
m_runningCount = 0;
|
setLoopsRemaining(0);
|
||||||
m_position = 0;
|
m_position = 0;
|
||||||
m_playQueued = false;
|
m_playQueued = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public:
|
|||||||
QUrl source() const;
|
QUrl source() const;
|
||||||
void setSource(const QUrl &url);
|
void setSource(const QUrl &url);
|
||||||
int loopCount() const;
|
int loopCount() const;
|
||||||
|
int loopsRemaining() const;
|
||||||
void setLoopCount(int loopCount);
|
void setLoopCount(int loopCount);
|
||||||
int volume() const;
|
int volume() const;
|
||||||
void setVolume(int volume);
|
void setVolume(int volume);
|
||||||
@@ -98,6 +99,7 @@ public Q_SLOTS:
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void loopsRemainingChanged();
|
||||||
void volumeChanged();
|
void volumeChanged();
|
||||||
void mutedChanged();
|
void mutedChanged();
|
||||||
void loadedChanged();
|
void loadedChanged();
|
||||||
@@ -125,6 +127,7 @@ private:
|
|||||||
|
|
||||||
void setPlaying(bool playing);
|
void setPlaying(bool playing);
|
||||||
void setStatus(QSoundEffect::Status status);
|
void setStatus(QSoundEffect::Status status);
|
||||||
|
void setLoopsRemaining(int loopsRemaining);
|
||||||
|
|
||||||
static void stream_write_callback(pa_stream *s, size_t length, void *userdata);
|
static void stream_write_callback(pa_stream *s, size_t length, void *userdata);
|
||||||
static void stream_state_callback(pa_stream *s, void *userdata);
|
static void stream_state_callback(pa_stream *s, void *userdata);
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ int QSoundEffectPrivate::loopCount() const
|
|||||||
return m_loopCount;
|
return m_loopCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QSoundEffectPrivate::loopsRemaining() const
|
||||||
|
{
|
||||||
|
return m_runningCount;
|
||||||
|
}
|
||||||
|
|
||||||
void QSoundEffectPrivate::setLoopCount(int loopCount)
|
void QSoundEffectPrivate::setLoopCount(int loopCount)
|
||||||
{
|
{
|
||||||
m_loopCount = loopCount;
|
m_loopCount = loopCount;
|
||||||
@@ -150,19 +155,19 @@ void QSoundEffectPrivate::play()
|
|||||||
if (m_status == QSoundEffect::Null || m_status == QSoundEffect::Error)
|
if (m_status == QSoundEffect::Null || m_status == QSoundEffect::Error)
|
||||||
return;
|
return;
|
||||||
if (m_loopCount < 0) {
|
if (m_loopCount < 0) {
|
||||||
m_runningCount = -1;
|
setLoopsRemaining(-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_runningCount < 0)
|
if (m_runningCount < 0)
|
||||||
m_runningCount = 0;
|
setLoopsRemaining(0);
|
||||||
m_runningCount += m_loopCount;
|
setLoopsRemaining(m_runningCount + m_loopCount);
|
||||||
}
|
}
|
||||||
m_player->play();
|
m_player->play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSoundEffectPrivate::stop()
|
void QSoundEffectPrivate::stop()
|
||||||
{
|
{
|
||||||
m_runningCount = 0;
|
setLoopsRemaining(0);
|
||||||
m_player->stop();
|
m_player->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,11 +179,14 @@ void QSoundEffectPrivate::stateChanged(QMediaPlayer::State state)
|
|||||||
} else if (m_runningCount == 0) {
|
} else if (m_runningCount == 0) {
|
||||||
setPlaying(false);
|
setPlaying(false);
|
||||||
return;
|
return;
|
||||||
} else if (--m_runningCount > 0) {
|
} else {
|
||||||
|
setLoopsRemaining(m_runningCount - 1);
|
||||||
|
if (m_runningCount > 0) {
|
||||||
m_player->play();
|
m_player->play();
|
||||||
} else {
|
} else {
|
||||||
setPlaying(false);
|
setPlaying(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setPlaying(true);
|
setPlaying(true);
|
||||||
}
|
}
|
||||||
@@ -233,6 +241,14 @@ void QSoundEffectPrivate::setPlaying(bool playing)
|
|||||||
emit playingChanged();
|
emit playingChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining)
|
||||||
|
{
|
||||||
|
if (m_runningCount == loopsRemaining)
|
||||||
|
return;
|
||||||
|
m_runningCount = loopsRemaining;
|
||||||
|
emit loopsRemainingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "moc_qsoundeffect_qmedia_p.cpp"
|
#include "moc_qsoundeffect_qmedia_p.cpp"
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ public:
|
|||||||
QUrl source() const;
|
QUrl source() const;
|
||||||
void setSource(const QUrl &url);
|
void setSource(const QUrl &url);
|
||||||
int loopCount() const;
|
int loopCount() const;
|
||||||
|
int loopsRemaining() const;
|
||||||
void setLoopCount(int loopCount);
|
void setLoopCount(int loopCount);
|
||||||
int volume() const;
|
int volume() const;
|
||||||
void setVolume(int volume);
|
void setVolume(int volume);
|
||||||
@@ -95,6 +96,7 @@ public Q_SLOTS:
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void loopsRemainingChanged();
|
||||||
void volumeChanged();
|
void volumeChanged();
|
||||||
void mutedChanged();
|
void mutedChanged();
|
||||||
void loadedChanged();
|
void loadedChanged();
|
||||||
@@ -109,6 +111,7 @@ private Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
void setStatus(QSoundEffect::Status status);
|
void setStatus(QSoundEffect::Status status);
|
||||||
void setPlaying(bool playing);
|
void setPlaying(bool playing);
|
||||||
|
void setLoopsRemaining(int loopsRemaining);
|
||||||
|
|
||||||
int m_loopCount;
|
int m_loopCount;
|
||||||
int m_runningCount;
|
int m_runningCount;
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ SUBDIRS += \
|
|||||||
qaudiooutput \
|
qaudiooutput \
|
||||||
qmediaplayerbackend \
|
qmediaplayerbackend \
|
||||||
qcamerabackend \
|
qcamerabackend \
|
||||||
qsoundeffect
|
qsoundeffect \
|
||||||
|
qsound
|
||||||
|
|
||||||
|
|||||||
12
tests/auto/integration/qsound/qsound.pro
Normal file
12
tests/auto/integration/qsound/qsound.pro
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
TARGET = tst_qsound
|
||||||
|
|
||||||
|
QT += core declarative multimedia-private testlib
|
||||||
|
CONFIG += no_private_qt_headers_warning
|
||||||
|
|
||||||
|
# This is more of a system test
|
||||||
|
# CONFIG += testcase
|
||||||
|
|
||||||
|
SOURCES += tst_qsound.cpp
|
||||||
|
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||||
|
|
||||||
BIN
tests/auto/integration/qsound/test.wav
Normal file
BIN
tests/auto/integration/qsound/test.wav
Normal file
Binary file not shown.
BIN
tests/auto/integration/qsound/test2.wav
Normal file
BIN
tests/auto/integration/qsound/test2.wav
Normal file
Binary file not shown.
129
tests/auto/integration/qsound/tst_qsound.cpp
Normal file
129
tests/auto/integration/qsound/tst_qsound.cpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||||||
|
** License version 2.1 as published by the Free Software Foundation and
|
||||||
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU Lesser
|
||||||
|
** General Public License version 2.1 requirements will be met:
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License version 3.0 as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||||
|
** file. Please review the following information to ensure the GNU General
|
||||||
|
** Public License version 3.0 requirements will be met:
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** Other Usage
|
||||||
|
** Alternatively, this file may be used in accordance with the terms and
|
||||||
|
** conditions contained in a signed written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QSound>
|
||||||
|
|
||||||
|
class tst_QSound : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
tst_QSound( QObject* parent=0) : QObject(parent) {}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void cleanupTestCase();
|
||||||
|
void testLooping();
|
||||||
|
void testPlay();
|
||||||
|
void testStop();
|
||||||
|
|
||||||
|
void testStaticPlay();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSound* sound;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void tst_QSound::initTestCase()
|
||||||
|
{
|
||||||
|
sound = new QSound(QString(SRCDIR "test.wav"), this);
|
||||||
|
|
||||||
|
QVERIFY(!sound->fileName().isEmpty());
|
||||||
|
QCOMPARE(sound->loops(),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSound::cleanupTestCase()
|
||||||
|
{
|
||||||
|
if (sound)
|
||||||
|
{
|
||||||
|
delete sound;
|
||||||
|
sound = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSound::testLooping()
|
||||||
|
{
|
||||||
|
sound->setLoops(5);
|
||||||
|
QCOMPARE(sound->loops(),5);
|
||||||
|
|
||||||
|
sound->play();
|
||||||
|
QVERIFY(!sound->isFinished());
|
||||||
|
|
||||||
|
// test.wav is about 200ms, wait until it has finished playing 5 times
|
||||||
|
QTest::qWait(3000);
|
||||||
|
|
||||||
|
QVERIFY(sound->isFinished());
|
||||||
|
QCOMPARE(sound->loopsRemaining(),0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSound::testPlay()
|
||||||
|
{
|
||||||
|
sound->setLoops(1);
|
||||||
|
sound->play();
|
||||||
|
QVERIFY(!sound->isFinished());
|
||||||
|
QTest::qWait(1000);
|
||||||
|
QVERIFY(sound->isFinished());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSound::testStop()
|
||||||
|
{
|
||||||
|
sound->setLoops(10);
|
||||||
|
sound->play();
|
||||||
|
QVERIFY(!sound->isFinished());
|
||||||
|
QTest::qWait(1000);
|
||||||
|
sound->stop();
|
||||||
|
QTest::qWait(1000);
|
||||||
|
QVERIFY(sound->isFinished());
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSound::testStaticPlay()
|
||||||
|
{
|
||||||
|
// Check that you hear sound with static play also.
|
||||||
|
QSound::play(QString(SRCDIR "test2.wav"));
|
||||||
|
|
||||||
|
QTest::qWait(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_QSound);
|
||||||
|
#include "tst_qsound.moc"
|
||||||
@@ -106,16 +106,20 @@ void tst_QSoundEffect::testSource()
|
|||||||
|
|
||||||
void tst_QSoundEffect::testLooping()
|
void tst_QSoundEffect::testLooping()
|
||||||
{
|
{
|
||||||
QSignalSpy readSignal(sound, SIGNAL(loopCountChanged()));
|
QSignalSpy readSignal_Count(sound, SIGNAL(loopCountChanged()));
|
||||||
|
QSignalSpy readSignal_Remaining(sound, SIGNAL(loopsRemainingChanged()));
|
||||||
|
|
||||||
sound->setLoopCount(5);
|
sound->setLoopCount(5);
|
||||||
QCOMPARE(sound->loopCount(),5);
|
QCOMPARE(sound->loopCount(),5);
|
||||||
|
QCOMPARE(readSignal_Count.count(),1);
|
||||||
|
|
||||||
sound->play();
|
sound->play();
|
||||||
|
|
||||||
// test.wav is about 200ms, wait until it has finished playing 5 times
|
// test.wav is about 200ms, wait until it has finished playing 5 times
|
||||||
QTest::qWait(3000);
|
QTest::qWait(3000);
|
||||||
|
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(),5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QSoundEffect::testVolume()
|
void tst_QSoundEffect::testVolume()
|
||||||
|
|||||||
Reference in New Issue
Block a user