Add AudioEngine with new implementation
Change-Id: I5eebe662ecbce9814ed3e763db56df9be737d11f Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
47
config.tests/openal/main.cpp
Normal file
47
config.tests/openal/main.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 <AL/al.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
11
config.tests/openal/openal.pro
Normal file
11
config.tests/openal/openal.pro
Normal file
@@ -0,0 +1,11 @@
|
||||
TEMPLATE = app
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
win32 {
|
||||
LIBS += -lOpenAL32
|
||||
}else {
|
||||
LIBS += -lopenal
|
||||
}
|
||||
7
examples/audioengine/audioengine.pro
Normal file
7
examples/audioengine/audioengine.pro
Normal file
@@ -0,0 +1,7 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
# These examples contain no C++ and can simply be copied
|
||||
SUBDIRS =
|
||||
sources.files = qml/*
|
||||
sources.path = $$[QT_INSTALL_EXAMPLES]/qtmultimedia/declarative/audioengine
|
||||
INSTALLS += sources
|
||||
193
examples/audioengine/qml/audioengine.qml
Normal file
193
examples/audioengine/qml/audioengine.qml
Normal file
@@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the examples 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtAudioEngine 1.0
|
||||
import QtQuick 2.0
|
||||
import "content"
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
id: root
|
||||
width: 300
|
||||
height: 500
|
||||
property int radius : 100
|
||||
property real twoPi : Math.PI + Math.PI
|
||||
|
||||
MyAudioEngine {
|
||||
id:audioEngine
|
||||
listener.position : Qt.vector3d(observer.x, observer.y, 0);
|
||||
}
|
||||
|
||||
Item {
|
||||
id: circle
|
||||
x: root.width / 2
|
||||
y: root.height / 2
|
||||
property real percent: 0
|
||||
SequentialAnimation on percent {
|
||||
id: circleAnim1
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
NumberAnimation {
|
||||
duration: 8000
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: holder
|
||||
x: circle.x - Math.sin(circle.percent * root.twoPi) * root.radius - 50
|
||||
y: circle.y + Math.cos(circle.percent * root.twoPi) * root.radius + 50
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color:"green"
|
||||
id: observer
|
||||
width: 16
|
||||
height: 16
|
||||
x: circle.x - width / 2
|
||||
y: circle.y - height / 2
|
||||
}
|
||||
Rectangle {
|
||||
color:"red"
|
||||
id: starship
|
||||
width: 32
|
||||
height: 32
|
||||
x: holder.x - width / 2
|
||||
y: holder.y - height / 2
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
audioEngine.sounds["effects"].play(Qt.vector3d(holder.x, holder.y, 0));
|
||||
}
|
||||
}
|
||||
|
||||
SoundInstance {
|
||||
id: shipSound
|
||||
engine:audioEngine
|
||||
sound:"shipengine"
|
||||
position: Qt.vector3d(holder.x, holder.y, 0)
|
||||
direction: {
|
||||
var a = (starship.rotation / 360) * root.twoPi;
|
||||
return Qt.vector3d(Math.sin(a), -Math.cos(a), 0);
|
||||
}
|
||||
velocity: {
|
||||
var speed = root.twoPi * root.radius / 4;
|
||||
return shipSound.direction * speed;
|
||||
}
|
||||
|
||||
Component.onCompleted: shipSound.play()
|
||||
}
|
||||
|
||||
//Category Volume Control
|
||||
Rectangle {
|
||||
property variant volumeCtrl: audioEngine.categories["sfx"];
|
||||
id: volumeBar
|
||||
x: 10
|
||||
y: 10
|
||||
width: 280
|
||||
height: 22
|
||||
color: "darkgray"
|
||||
Rectangle {
|
||||
id: volumeTracker
|
||||
x: 0
|
||||
y: 0
|
||||
width: volumeBar.volumeCtrl.volume * parent.width;
|
||||
height: parent.height
|
||||
color: "lightgreen"
|
||||
}
|
||||
Text {
|
||||
text: " volume:" + volumeBar.volumeCtrl.volume * 100 +"%";
|
||||
font.pointSize: 16;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
property bool m:false
|
||||
onPressed: {
|
||||
m = true;
|
||||
updateVolume(mouse);
|
||||
}
|
||||
onReleased: {
|
||||
m = false;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (m) {
|
||||
updateVolume(mouse);
|
||||
}
|
||||
}
|
||||
function updateVolume(mouse) {
|
||||
volumeBar.volumeCtrl.volume = Math.min(1, Math.max(0, mouse.x / (volumeBar.width - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Information display
|
||||
Item {
|
||||
x:10
|
||||
y:32
|
||||
Text {
|
||||
text: " [live instances] = " + audioEngine.liveInstances;
|
||||
font.pointSize: 14;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
x:10
|
||||
y:60
|
||||
Text {
|
||||
text: " [loading]=" + (audioEngine.loading ? "true" : "false");
|
||||
font.pointSize: 16;
|
||||
font.italic: true;
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
16
examples/audioengine/qml/audioengine.qmlproject
Normal file
16
examples/audioengine/qml/audioengine.qmlproject
Normal file
@@ -0,0 +1,16 @@
|
||||
import QmlProject 1.1
|
||||
|
||||
Project {
|
||||
mainFile: "audioengine.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
}
|
||||
131
examples/audioengine/qml/content/MyAudioEngine.qml
Normal file
131
examples/audioengine/qml/content/MyAudioEngine.qml
Normal file
@@ -0,0 +1,131 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the examples 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtAudioEngine 1.0
|
||||
import QtQuick 2.0
|
||||
|
||||
AudioEngine {
|
||||
|
||||
AudioCategory {
|
||||
name:"sfx"
|
||||
volume: 1
|
||||
}
|
||||
|
||||
AudioCategory {
|
||||
name:"music"
|
||||
volume: 1
|
||||
}
|
||||
|
||||
|
||||
AttenuationModelInverse {
|
||||
name:"default"
|
||||
start: 20
|
||||
end: 1000
|
||||
rolloff: 1
|
||||
}
|
||||
|
||||
AttenuationModelLinear {
|
||||
name:"shipengine"
|
||||
start: 20
|
||||
end: 180
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"fire"
|
||||
source: "fire-03-loop.wav"
|
||||
preloaded:true
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
AudioSample {
|
||||
name:"lava"
|
||||
source: "lava-bubbling-01.wav"
|
||||
}
|
||||
AudioSample {
|
||||
name:"water"
|
||||
source: "running-water-01.wav"
|
||||
}
|
||||
Sound {
|
||||
name:"shipengine"
|
||||
attenuationModel:"shipengine"
|
||||
category:"sfx"
|
||||
PlayVariation {
|
||||
looping:true
|
||||
sample:"fire"
|
||||
maxGain:0.9
|
||||
minGain:0.8
|
||||
}
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"effects"
|
||||
category:"sfx"
|
||||
PlayVariation {
|
||||
sample:"lava"
|
||||
maxGain:1.5
|
||||
minGain:1.2
|
||||
maxPitch:2.0
|
||||
minPitch:0.5
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
maxGain:1.1
|
||||
minGain:0.7
|
||||
maxPitch:1.5
|
||||
minPitch:0.5
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"water"
|
||||
maxGain:1.5
|
||||
minGain:1.2
|
||||
}
|
||||
}
|
||||
|
||||
dopplerFactor: 1
|
||||
speedOfSound: 343.33
|
||||
|
||||
listener.up:"0,0,1"
|
||||
listener.position:"0,0,0"
|
||||
listener.velocity:"0,0,0"
|
||||
listener.direction:"0,1,0"
|
||||
}
|
||||
@@ -24,3 +24,4 @@ TEMPLATE = subdirs
|
||||
QT += widgets
|
||||
}
|
||||
|
||||
contains(config_test_openal, yes): SUBDIRS += audioengine
|
||||
|
||||
85
src/imports/audioengine/audioengine.cpp
Normal file
85
src/imports/audioengine/audioengine.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 <QtDeclarative/qdeclarativeextensionplugin.h>
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativeengine.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qdeclarative_soundinstance_p.h"
|
||||
#include "qdeclarative_sound_p.h"
|
||||
#include "qdeclarative_playvariation_p.h"
|
||||
#include "qdeclarative_audiocategory_p.h"
|
||||
#include "qdeclarative_audiolistener_p.h"
|
||||
#include "qdeclarative_audiosample_p.h"
|
||||
#include "qdeclarative_attenuationmodel_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAudioEngineDeclarativeModule : public QDeclarativeExtensionPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual void registerTypes(const char *uri)
|
||||
{
|
||||
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtAudioEngine"));
|
||||
|
||||
qmlRegisterType<QDeclarativeAudioEngine>(uri, 1, 0, "AudioEngine");
|
||||
qmlRegisterType<QDeclarativeAudioSample>(uri, 1, 0, "AudioSample");
|
||||
qmlRegisterType<QDeclarativeAudioCategory>(uri, 1, 0, "AudioCategory");
|
||||
qmlRegisterType<QDeclarativeSoundCone>(uri, 1, 0, "");
|
||||
qmlRegisterType<QDeclarativeSound>(uri, 1, 0, "Sound");
|
||||
qmlRegisterType<QDeclarativePlayVariation>(uri, 1, 0, "PlayVariation");
|
||||
qmlRegisterType<QDeclarativeAudioListener>(uri, 1, 0, "AudioListener");
|
||||
qmlRegisterType<QDeclarativeSoundInstance>(uri, 1, 0, "SoundInstance");
|
||||
|
||||
qmlRegisterType<QDeclarativeAttenuationModelLinear>(uri, 1, 0, "AttenuationModelLinear");
|
||||
qmlRegisterType<QDeclarativeAttenuationModelInverse>(uri, 1, 0, "AttenuationModelInverse");
|
||||
}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "audioengine.moc"
|
||||
|
||||
Q_EXPORT_PLUGIN2("QtAudioEngine", QT_PREPEND_NAMESPACE(QAudioEngineDeclarativeModule));
|
||||
|
||||
51
src/imports/audioengine/audioengine.pro
Normal file
51
src/imports/audioengine/audioengine.pro
Normal file
@@ -0,0 +1,51 @@
|
||||
TARGET = declarative_audioengine
|
||||
TARGETPATH = QtAudioEngine
|
||||
|
||||
include(../qimportbase.pri)
|
||||
QT += declarative quick multimedia-private
|
||||
|
||||
win32 {
|
||||
LIBS += -lOpenAL32
|
||||
}else {
|
||||
LIBS += -lopenal
|
||||
}
|
||||
|
||||
DESTDIR = $$QT.multimedia.imports/$$TARGETPATH
|
||||
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
|
||||
|
||||
INCLUDEPATH += ../../multimedia/audio
|
||||
|
||||
HEADERS += \
|
||||
qdeclarative_attenuationmodel_p.h \
|
||||
qdeclarative_audioengine_p.h \
|
||||
qdeclarative_soundinstance_p.h \
|
||||
qdeclarative_audiocategory_p.h \
|
||||
qdeclarative_audiolistener_p.h \
|
||||
qdeclarative_playvariation_p.h \
|
||||
qdeclarative_audiosample_p.h \
|
||||
qdeclarative_sound_p.h \
|
||||
qsoundinstance_p.h \
|
||||
qaudioengine_p.h \
|
||||
qsoundsource_p.h \
|
||||
qsoundbuffer_p.h \
|
||||
qaudioengine_openal_p.h
|
||||
|
||||
SOURCES += \
|
||||
audioengine.cpp \
|
||||
qdeclarative_attenuationmodel_p.cpp \
|
||||
qdeclarative_audioengine_p.cpp \
|
||||
qdeclarative_soundinstance_p.cpp \
|
||||
qdeclarative_audiocategory_p.cpp \
|
||||
qdeclarative_audiolistener_p.cpp \
|
||||
qdeclarative_playvariation_p.cpp \
|
||||
qdeclarative_audiosample_p.cpp \
|
||||
qdeclarative_sound_p.cpp \
|
||||
qsoundinstance_p.cpp \
|
||||
qaudioengine_p.cpp \
|
||||
qsoundsource_openal_p.cpp \
|
||||
qaudioengine_openal_p.cpp
|
||||
|
||||
qmldir.files += $$PWD/qmldir
|
||||
qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
|
||||
|
||||
INSTALLS += target qmldir
|
||||
448
src/imports/audioengine/qaudioengine_openal_p.cpp
Normal file
448
src/imports/audioengine/qaudioengine_openal_p.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 <QtCore/QThread>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
#include "qsamplecache_p.h"
|
||||
#include "qaudioengine_openal_p.h"
|
||||
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class StaticSoundBufferAL : public QSoundBufferPrivateAL
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StaticSoundBufferAL(QObject *parent, const QUrl& url, QSampleCache *sampleLoader)
|
||||
: QSoundBufferPrivateAL(parent)
|
||||
, m_ref(1)
|
||||
, m_url(url)
|
||||
, m_alBuffer(0)
|
||||
, m_isReady(false)
|
||||
, m_sample(0)
|
||||
, m_sampleLoader(sampleLoader)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "creating new StaticSoundBufferOpenAL";
|
||||
#endif
|
||||
}
|
||||
|
||||
void load()
|
||||
{
|
||||
if (m_sample)
|
||||
return;
|
||||
m_sample = m_sampleLoader->requestSample(m_url);
|
||||
connect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
|
||||
connect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
|
||||
switch (m_sample->state()) {
|
||||
case QSample::Ready:
|
||||
sampleReady();
|
||||
break;
|
||||
case QSample::Error:
|
||||
decoderError();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
~StaticSoundBufferAL()
|
||||
{
|
||||
if (m_sample)
|
||||
m_sample->release();
|
||||
alDeleteBuffers(1, &m_alBuffer);
|
||||
}
|
||||
|
||||
void bindToSource(ALuint alSource)
|
||||
{
|
||||
Q_ASSERT(m_alBuffer != 0);
|
||||
alSourcei(alSource, AL_BUFFER, m_alBuffer);
|
||||
}
|
||||
|
||||
void unbindFromSource(ALuint alSource)
|
||||
{
|
||||
alSourcei(alSource, AL_BUFFER, 0);
|
||||
}
|
||||
|
||||
//called in application
|
||||
bool isReady() const
|
||||
{
|
||||
return m_isReady;
|
||||
}
|
||||
|
||||
long addRef()
|
||||
{
|
||||
return ++m_ref;
|
||||
}
|
||||
|
||||
long release()
|
||||
{
|
||||
return --m_ref;
|
||||
}
|
||||
|
||||
long refCount() const
|
||||
{
|
||||
return m_ref;
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
void sampleReady()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "StaticSoundBufferOpenAL:sample[" << m_url << "] loaded";
|
||||
#endif
|
||||
|
||||
disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
|
||||
disconnect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
|
||||
|
||||
if (m_sample->data().size() > 1024 * 1024 * 4) {
|
||||
qWarning() << "source [" << m_url << "] size too large!";
|
||||
decoderError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_sample->format().channelCount() > 2) {
|
||||
qWarning() << "source [" << m_url << "] channel > 2!";
|
||||
decoderError();
|
||||
return;
|
||||
}
|
||||
|
||||
ALenum alFormat = 0;
|
||||
if (m_sample->format().sampleSize() == 8) {
|
||||
alFormat = m_sample->format().channelCount() == 1 ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8;
|
||||
} else if (m_sample->format().sampleSize() == 16) {
|
||||
alFormat = m_sample->format().channelCount() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||
} else {
|
||||
qWarning() << "source [" << m_url << "] invalid sample size:"
|
||||
<< m_sample->format().sampleSize() << "(should be 8 or 16)";
|
||||
decoderError();
|
||||
return;
|
||||
}
|
||||
|
||||
alGenBuffers(1, &m_alBuffer);
|
||||
if (!QAudioEnginePrivate::checkNoError("create buffer")) {
|
||||
return;
|
||||
}
|
||||
alBufferData(m_alBuffer, alFormat, m_sample->data().data(),
|
||||
m_sample->data().size(), m_sample->format().frequency());
|
||||
|
||||
if (!QAudioEnginePrivate::checkNoError("fill buffer")) {
|
||||
return;
|
||||
}
|
||||
m_isReady = true;
|
||||
emit ready();
|
||||
|
||||
m_sample->release();
|
||||
m_sample = 0;
|
||||
}
|
||||
|
||||
void decoderError()
|
||||
{
|
||||
qWarning() << "loading [" << m_url << "] failed";
|
||||
disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
|
||||
emit error();
|
||||
}
|
||||
|
||||
private:
|
||||
long m_ref;
|
||||
QUrl m_url;
|
||||
ALuint m_alBuffer;
|
||||
bool m_isReady;
|
||||
QSample *m_sample;
|
||||
QSampleCache *m_sampleLoader;
|
||||
};
|
||||
|
||||
QSoundBufferPrivateAL::QSoundBufferPrivateAL(QObject *parent)
|
||||
: QSoundBuffer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
QAudioEnginePrivate::QAudioEnginePrivate(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_updateTimer.setInterval(200);
|
||||
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateSoundSources()));
|
||||
|
||||
m_sampleLoader = new QSampleCache(this);
|
||||
m_sampleLoader->setCapacity(0);
|
||||
connect(m_sampleLoader, SIGNAL(isLoadingChanged()), this, SIGNAL(isLoadingChanged()));
|
||||
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "default openal device = " << alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
|
||||
const ALCchar* devNames = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
int cc = 0;
|
||||
qDebug() << "device list:";
|
||||
while (true) {
|
||||
qDebug() << " " << devNames + cc;
|
||||
while (devNames[cc] != 0)
|
||||
++cc;
|
||||
++cc;
|
||||
if (devNames[cc] == 0)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
ALCdevice *device = alcOpenDevice(0);
|
||||
if (!device) {
|
||||
qWarning() << "Can not create openal device!";
|
||||
return;
|
||||
}
|
||||
|
||||
ALCcontext* context = alcCreateContext(device, 0);
|
||||
if (!context) {
|
||||
qWarning() << "Can not create openal context!";
|
||||
return;
|
||||
}
|
||||
alcMakeContextCurrent(context);
|
||||
alDistanceModel(AL_NONE);
|
||||
alDopplerFactor(0);
|
||||
}
|
||||
|
||||
QAudioEnginePrivate::~QAudioEnginePrivate()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QAudioEnginePrivate::dtor";
|
||||
#endif
|
||||
delete m_sampleLoader;
|
||||
QObjectList children = this->children();
|
||||
foreach (QObject *child, children) {
|
||||
QSoundSourcePrivate* s = qobject_cast<QSoundSourcePrivate*>(child);
|
||||
if (!s)
|
||||
continue;
|
||||
s->release();
|
||||
}
|
||||
|
||||
foreach (QSoundBufferPrivateAL *buffer, m_staticBufferPool) {
|
||||
delete buffer;
|
||||
}
|
||||
m_staticBufferPool.clear();
|
||||
|
||||
ALCcontext* context = alcGetCurrentContext();
|
||||
ALCdevice *device = alcGetContextsDevice(context);
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QAudioEnginePrivate::dtor: all done";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QAudioEnginePrivate::isLoading() const
|
||||
{
|
||||
return m_sampleLoader->isLoading();
|
||||
}
|
||||
|
||||
QSoundSource* QAudioEnginePrivate::createSoundSource()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QAudioEnginePrivate::createSoundSource()";
|
||||
#endif
|
||||
QSoundSourcePrivate *instance = NULL;
|
||||
if (m_instancePool.count() == 0) {
|
||||
instance = new QSoundSourcePrivate(this);
|
||||
} else {
|
||||
instance = m_instancePool.front();
|
||||
m_instancePool.pop_front();
|
||||
}
|
||||
connect(instance, SIGNAL(activate(QObject*)), this, SLOT(soundSourceActivate(QObject*)));
|
||||
return instance;
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::releaseSoundSource(QSoundSource *soundInstance)
|
||||
{
|
||||
QSoundSourcePrivate *privInstance = static_cast<QSoundSourcePrivate*>(soundInstance);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "recycle soundInstance" << privInstance;
|
||||
#endif
|
||||
privInstance->unbindBuffer();
|
||||
m_instancePool.push_front(privInstance);
|
||||
m_activeInstances.removeOne(privInstance);
|
||||
}
|
||||
|
||||
QSoundBuffer* QAudioEnginePrivate::getStaticSoundBuffer(const QUrl& url)
|
||||
{
|
||||
StaticSoundBufferAL *staticBuffer = NULL;
|
||||
QMap<QUrl, QSoundBufferPrivateAL*>::iterator it = m_staticBufferPool.find(url);
|
||||
if (it == m_staticBufferPool.end()) {
|
||||
staticBuffer = new StaticSoundBufferAL(this, url, m_sampleLoader);
|
||||
m_staticBufferPool.insert(url, staticBuffer);
|
||||
} else {
|
||||
staticBuffer = static_cast<StaticSoundBufferAL*>(*it);
|
||||
staticBuffer->addRef();
|
||||
}
|
||||
return staticBuffer;
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::releaseSoundBuffer(QSoundBuffer *buffer)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QAudioEnginePrivate: recycle sound buffer";
|
||||
#endif
|
||||
if (buffer->inherits("StaticSoundBufferOpenAL")) {
|
||||
StaticSoundBufferAL *staticBuffer = static_cast<StaticSoundBufferAL*>(buffer);
|
||||
//decrement the reference count, still kept in memory for reuse
|
||||
staticBuffer->release();
|
||||
//TODO implement some resource recycle strategy
|
||||
} else {
|
||||
//TODO
|
||||
Q_ASSERT(0);
|
||||
qWarning() << "Unknown soundbuffer type for recycle" << buffer;
|
||||
}
|
||||
}
|
||||
|
||||
bool QAudioEnginePrivate::checkNoError(const char *msg)
|
||||
{
|
||||
ALenum error = alGetError();
|
||||
if (error != AL_NO_ERROR) {
|
||||
qWarning() << "Failed on" << msg << "[OpenAL error code =" << error << "]";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector3D QAudioEnginePrivate::listenerPosition() const
|
||||
{
|
||||
ALfloat x, y, z;
|
||||
alGetListener3f(AL_POSITION, &x, &y, &z);
|
||||
checkNoError("get listener position");
|
||||
return QVector3D(x, y, z);
|
||||
}
|
||||
|
||||
QVector3D QAudioEnginePrivate::listenerVelocity() const
|
||||
{
|
||||
ALfloat x, y, z;
|
||||
alGetListener3f(AL_VELOCITY, &x, &y, &z);
|
||||
checkNoError("get listener velocity");
|
||||
return QVector3D(x, y, z);
|
||||
}
|
||||
|
||||
qreal QAudioEnginePrivate::listenerGain() const
|
||||
{
|
||||
ALfloat gain;
|
||||
alGetListenerf(AL_GAIN, &gain);
|
||||
checkNoError("get listener gain");
|
||||
return gain;
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setListenerPosition(const QVector3D& position)
|
||||
{
|
||||
alListener3f(AL_POSITION, position.x(), position.y(), position.z());
|
||||
checkNoError("set listener position");
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setListenerOrientation(const QVector3D& direction, const QVector3D& up)
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
orientation[0] = direction.x();
|
||||
orientation[1] = direction.y();
|
||||
orientation[2] = direction.z();
|
||||
orientation[3] = up.x();
|
||||
orientation[4] = up.y();
|
||||
orientation[5] = up.z();
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
checkNoError("set listener orientation");
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setListenerVelocity(const QVector3D& velocity)
|
||||
{
|
||||
alListener3f(AL_VELOCITY, velocity.x(), velocity.y(), velocity.z());
|
||||
checkNoError("set listener velocity");
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setListenerGain(qreal gain)
|
||||
{
|
||||
alListenerf(AL_GAIN, gain);
|
||||
checkNoError("set listener gain");
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setDopplerFactor(qreal dopplerFactor)
|
||||
{
|
||||
alDopplerFactor(dopplerFactor);
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::setSpeedOfSound(qreal speedOfSound)
|
||||
{
|
||||
alSpeedOfSound(speedOfSound);
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::soundSourceActivate(QObject *soundSource)
|
||||
{
|
||||
QSoundSourcePrivate *ss = qobject_cast<QSoundSourcePrivate*>(soundSource);
|
||||
ss->checkState();
|
||||
if (ss->isLooping())
|
||||
return;
|
||||
if (!m_activeInstances.contains(ss))
|
||||
m_activeInstances.push_back(ss);
|
||||
if (!m_updateTimer.isActive())
|
||||
m_updateTimer.start();
|
||||
}
|
||||
|
||||
void QAudioEnginePrivate::updateSoundSources()
|
||||
{
|
||||
for (QList<QSoundSourcePrivate*>::Iterator it = m_activeInstances.begin();
|
||||
it != m_activeInstances.end();) {
|
||||
QSoundSourcePrivate *instance = *it;
|
||||
instance->checkState();
|
||||
if (instance->state() == QSoundSource::StoppedState) {
|
||||
it = m_activeInstances.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_activeInstances.count() == 0) {
|
||||
m_updateTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
#include "qaudioengine_openal_p.moc"
|
||||
//#include "moc_qaudioengine_openal_p.cpp"
|
||||
168
src/imports/audioengine/qaudioengine_openal_p.h
Normal file
168
src/imports/audioengine/qaudioengine_openal_p.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QAUDIOENGINE_OPENAL_P_H
|
||||
#define QAUDIOENGINE_OPENAL_P_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QTimer>
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
#include "qsoundsource_p.h"
|
||||
#include "qsoundbuffer_p.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSoundBufferPrivateAL : public QSoundBuffer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSoundBufferPrivateAL(QObject* parent);
|
||||
virtual void bindToSource(ALuint alSource) = 0;
|
||||
virtual void unbindFromSource(ALuint alSource) = 0;
|
||||
};
|
||||
|
||||
class QSoundSourcePrivate : public QSoundSource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSoundSourcePrivate(QObject *parent);
|
||||
~QSoundSourcePrivate();
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
QSoundSource::State state() const;
|
||||
|
||||
bool isLooping() const;
|
||||
void setLooping(bool looping);
|
||||
void setPosition(const QVector3D& position);
|
||||
void setDirection(const QVector3D& direction);
|
||||
void setVelocity(const QVector3D& velocity);
|
||||
|
||||
QVector3D velocity() const;
|
||||
QVector3D position() const;
|
||||
QVector3D direction() const;
|
||||
|
||||
void setGain(qreal gain);
|
||||
void setPitch(qreal pitch);
|
||||
void setCone(qreal innerAngle, qreal outerAngle, qreal outerGain);
|
||||
|
||||
void bindBuffer(QSoundBuffer*);
|
||||
void unbindBuffer();
|
||||
|
||||
void checkState();
|
||||
|
||||
void release();
|
||||
|
||||
Q_SIGNALS:
|
||||
void activate(QObject*);
|
||||
|
||||
private:
|
||||
void sourcePlay();
|
||||
void sourcePause();
|
||||
|
||||
ALuint m_alSource;
|
||||
QSoundBufferPrivateAL *m_bindBuffer;
|
||||
bool m_isReady; //true if the sound source is already bound to some sound buffer
|
||||
QSoundSource::State m_state;
|
||||
qreal m_gain;
|
||||
qreal m_pitch;
|
||||
qreal m_coneInnerAngle;
|
||||
qreal m_coneOuterAngle;
|
||||
qreal m_coneOuterGain;
|
||||
};
|
||||
|
||||
class QSampleCache;
|
||||
class QAudioEnginePrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QAudioEnginePrivate(QObject *parent);
|
||||
~QAudioEnginePrivate();
|
||||
|
||||
bool isLoading() const;
|
||||
|
||||
QSoundSource* createSoundSource();
|
||||
void releaseSoundSource(QSoundSource *soundInstance);
|
||||
QSoundBuffer* getStaticSoundBuffer(const QUrl& url);
|
||||
void releaseSoundBuffer(QSoundBuffer *buffer);
|
||||
|
||||
QVector3D listenerPosition() const;
|
||||
QVector3D listenerVelocity() const;
|
||||
qreal listenerGain() const;
|
||||
void setListenerPosition(const QVector3D& position);
|
||||
void setListenerVelocity(const QVector3D& velocity);
|
||||
void setListenerOrientation(const QVector3D& direction, const QVector3D& up);
|
||||
void setListenerGain(qreal gain);
|
||||
void setDopplerFactor(qreal dopplerFactor);
|
||||
void setSpeedOfSound(qreal speedOfSound);
|
||||
|
||||
static bool checkNoError(const char *msg);
|
||||
|
||||
Q_SIGNALS:
|
||||
void isLoadingChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateSoundSources();
|
||||
void soundSourceActivate(QObject *soundSource);
|
||||
|
||||
private:
|
||||
QList<QSoundSourcePrivate*> m_activeInstances;
|
||||
QList<QSoundSourcePrivate*> m_instancePool;
|
||||
QMap<QUrl, QSoundBufferPrivateAL*> m_staticBufferPool;
|
||||
|
||||
QSampleCache *m_sampleLoader;
|
||||
QTimer m_updateTimer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
198
src/imports/audioengine/qaudioengine_p.cpp
Normal file
198
src/imports/audioengine/qaudioengine_p.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qaudioengine_p.h"
|
||||
#include "qsoundsource_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#include "qaudioengine_openal_p.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QSoundSource::QSoundSource(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QSoundBuffer::QSoundBuffer(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QAudioEngine* QAudioEngine::create(QObject *parent)
|
||||
{
|
||||
return new QAudioEngine(parent);
|
||||
}
|
||||
|
||||
QAudioEngine::QAudioEngine(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_listenerUp(0, 0, 1)
|
||||
, m_listenerDirection(0, 1, 0)
|
||||
{
|
||||
d = new QAudioEnginePrivate(this);
|
||||
connect(d, SIGNAL(isLoadingChanged()), this, SIGNAL(isLoadingChanged()));
|
||||
setDopplerFactor(1);
|
||||
setSpeedOfSound(qreal(343.33));
|
||||
updateListenerOrientation();
|
||||
}
|
||||
|
||||
QAudioEngine::~QAudioEngine()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QAudioEngine::dtor";
|
||||
#endif
|
||||
}
|
||||
|
||||
QSoundBuffer* QAudioEngine::getStaticSoundBuffer(const QUrl& url)
|
||||
{
|
||||
return d->getStaticSoundBuffer(url);
|
||||
}
|
||||
|
||||
void QAudioEngine::releaseSoundBuffer(QSoundBuffer *buffer)
|
||||
{
|
||||
d->releaseSoundBuffer(buffer);
|
||||
}
|
||||
|
||||
QSoundSource* QAudioEngine::createSoundSource()
|
||||
{
|
||||
return d->createSoundSource();
|
||||
}
|
||||
|
||||
void QAudioEngine::releaseSoundSource(QSoundSource *soundInstance)
|
||||
{
|
||||
d->releaseSoundSource(soundInstance);
|
||||
}
|
||||
|
||||
bool QAudioEngine::isLoading() const
|
||||
{
|
||||
return d->isLoading();
|
||||
}
|
||||
|
||||
QVector3D QAudioEngine::listenerPosition() const
|
||||
{
|
||||
return d->listenerPosition();
|
||||
}
|
||||
|
||||
QVector3D QAudioEngine::listenerDirection() const
|
||||
{
|
||||
return m_listenerDirection;
|
||||
}
|
||||
|
||||
QVector3D QAudioEngine::listenerUp() const
|
||||
{
|
||||
return m_listenerUp;
|
||||
}
|
||||
|
||||
qreal QAudioEngine::listenerGain() const
|
||||
{
|
||||
return d->listenerGain();
|
||||
}
|
||||
|
||||
QVector3D QAudioEngine::listenerVelocity() const
|
||||
{
|
||||
return d->listenerVelocity();
|
||||
}
|
||||
|
||||
void QAudioEngine::setListenerPosition(const QVector3D& position)
|
||||
{
|
||||
d->setListenerPosition(position);
|
||||
}
|
||||
|
||||
void QAudioEngine::setListenerVelocity(const QVector3D& velocity)
|
||||
{
|
||||
d->setListenerVelocity(velocity);
|
||||
}
|
||||
|
||||
void QAudioEngine::setListenerDirection(const QVector3D& direction)
|
||||
{
|
||||
if (m_listenerDirection == direction)
|
||||
return;
|
||||
m_listenerDirection = direction;
|
||||
updateListenerOrientation();
|
||||
}
|
||||
|
||||
void QAudioEngine::setListenerUp(const QVector3D& up)
|
||||
{
|
||||
if (m_listenerUp == up)
|
||||
return;
|
||||
m_listenerUp = up;
|
||||
updateListenerOrientation();
|
||||
}
|
||||
|
||||
void QAudioEngine::updateListenerOrientation()
|
||||
{
|
||||
QVector3D dir = m_listenerDirection;
|
||||
QVector3D up = m_listenerUp;
|
||||
dir.normalize();
|
||||
up.normalize();
|
||||
QVector3D u = up - dir * QVector3D::dotProduct(dir, up);
|
||||
u.normalize();
|
||||
d->setListenerOrientation(dir, u);
|
||||
}
|
||||
|
||||
void QAudioEngine::setListenerGain(qreal gain)
|
||||
{
|
||||
d->setListenerGain(gain);
|
||||
}
|
||||
|
||||
qreal QAudioEngine::dopplerFactor() const
|
||||
{
|
||||
return m_dopplerFactor;
|
||||
}
|
||||
|
||||
void QAudioEngine::setDopplerFactor(qreal dopplerFactor)
|
||||
{
|
||||
m_dopplerFactor = dopplerFactor;
|
||||
d->setDopplerFactor(dopplerFactor);
|
||||
}
|
||||
|
||||
qreal QAudioEngine::speedOfSound() const
|
||||
{
|
||||
return m_speedOfSound;
|
||||
}
|
||||
|
||||
void QAudioEngine::setSpeedOfSound(qreal speedOfSound)
|
||||
{
|
||||
m_speedOfSound = speedOfSound;
|
||||
d->setSpeedOfSound(speedOfSound);
|
||||
}
|
||||
110
src/imports/audioengine/qaudioengine_p.h
Normal file
110
src/imports/audioengine/qaudioengine_p.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QAUDIOENGINE_P_H
|
||||
#define QAUDIOENGINE_P_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtGui/qvector3d.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSoundSource;
|
||||
class QSoundBuffer;
|
||||
class QAudioEnginePrivate;
|
||||
|
||||
class QAudioEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~QAudioEngine();
|
||||
|
||||
virtual QSoundSource* createSoundSource();
|
||||
virtual void releaseSoundSource(QSoundSource *soundInstance);
|
||||
|
||||
virtual QSoundBuffer* getStaticSoundBuffer(const QUrl& url);
|
||||
virtual void releaseSoundBuffer(QSoundBuffer *buffer);
|
||||
|
||||
virtual bool isLoading() const;
|
||||
|
||||
virtual QVector3D listenerPosition() const;
|
||||
virtual QVector3D listenerDirection() const;
|
||||
virtual QVector3D listenerVelocity() const;
|
||||
virtual QVector3D listenerUp() const;
|
||||
virtual qreal listenerGain() const;
|
||||
virtual void setListenerPosition(const QVector3D& position);
|
||||
virtual void setListenerDirection(const QVector3D& direction);
|
||||
virtual void setListenerVelocity(const QVector3D& velocity);
|
||||
virtual void setListenerUp(const QVector3D& up);
|
||||
virtual void setListenerGain(qreal gain);
|
||||
|
||||
virtual qreal dopplerFactor() const;
|
||||
virtual void setDopplerFactor(qreal dopplerFactor);
|
||||
|
||||
virtual qreal speedOfSound() const;
|
||||
virtual void setSpeedOfSound(qreal speedOfSound);
|
||||
|
||||
static QAudioEngine* create(QObject *parent);
|
||||
|
||||
Q_SIGNALS:
|
||||
void isLoadingChanged();
|
||||
|
||||
private:
|
||||
QAudioEngine(QObject *parent);
|
||||
QAudioEnginePrivate *d;
|
||||
|
||||
void updateListenerOrientation();
|
||||
|
||||
qreal m_dopplerFactor;
|
||||
qreal m_speedOfSound;
|
||||
QVector3D m_listenerUp;
|
||||
QVector3D m_listenerDirection;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
379
src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp
Normal file
379
src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_attenuationmodel_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QDeclarativeAttenuationModel::QDeclarativeAttenuationModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
{
|
||||
}
|
||||
|
||||
QDeclarativeAttenuationModel::~QDeclarativeAttenuationModel()
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModel::classBegin()
|
||||
{
|
||||
if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) {
|
||||
qWarning("AttenuationModel must be defined inside AudioEngine!");
|
||||
//TODO: COMPILE_EXCEPTION ?
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModel::componentComplete()
|
||||
{
|
||||
if (m_name.isEmpty()) {
|
||||
qWarning("AttenuationModel must have a name!");
|
||||
return;
|
||||
}
|
||||
m_complete = true;
|
||||
}
|
||||
|
||||
QString QDeclarativeAttenuationModel::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModel::setName(const QString& name)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AttenuationModel: you can not change name after initialization.");
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
\qmlclass AttenuationModelLinear QDeclarativeAttenuationModelLinear
|
||||
\since 5.0
|
||||
\brief The AttenuationModelLinear element allows you to define a linear attenuation curve for
|
||||
Sound element.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
AttenuationModelLinear must be defined inside AudioEngine.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AttenuationModelLinear {
|
||||
name:"linear"
|
||||
start: 20
|
||||
end: 180
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
attenuationModel: "linear"
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty string AttenuationModelLinear::name
|
||||
|
||||
This property holds the name of AttenuationModelLinear, must be unique among all attenuation
|
||||
models and only defined once.
|
||||
*/
|
||||
QDeclarativeAttenuationModelLinear::QDeclarativeAttenuationModelLinear(QObject *parent)
|
||||
: QDeclarativeAttenuationModel(parent)
|
||||
, m_start(0)
|
||||
, m_end(1)
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelLinear::componentComplete()
|
||||
{
|
||||
if (m_start > m_end) {
|
||||
qSwap(m_start, m_end);
|
||||
qWarning() << "AttenuationModelLinear[" << m_name << "]: start must be less or equal than end.";
|
||||
}
|
||||
QDeclarativeAttenuationModel::componentComplete();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AttenuationModelLinear::start
|
||||
|
||||
This property holds the start distance. There will be no attenuation if the distance from sound
|
||||
to listener is within this range.
|
||||
The default value is 0.
|
||||
*/
|
||||
qreal QDeclarativeAttenuationModelLinear::startDistance() const
|
||||
{
|
||||
return m_start;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelLinear::setStartDistance(qreal startDist)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning() << "AttenuationModelLinear[" << m_name << "]: you can not change properties after initialization.";
|
||||
return;
|
||||
}
|
||||
if (startDist < 0) {
|
||||
qWarning() << "AttenuationModelLinear[" << m_name << "]: start must be no less than 0.";
|
||||
return;
|
||||
}
|
||||
m_start = startDist;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AttenuationModelLinear::end
|
||||
|
||||
This property holds the end distance. There will be no sound hearable if the distance from sound
|
||||
to listener is larger than this.
|
||||
The default value is 1.
|
||||
*/
|
||||
qreal QDeclarativeAttenuationModelLinear::endDistance() const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelLinear::setEndDistance(qreal endDist)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning() << "AttenuationModelLinear[" << m_name << "]: you can not change properties after initialization.";
|
||||
return;
|
||||
}
|
||||
if (endDist < 0) {
|
||||
qWarning() << "AttenuationModelLinear[" << m_name << "]: end must be no greater than 0.";
|
||||
return;
|
||||
}
|
||||
m_end = endDist;
|
||||
}
|
||||
|
||||
qreal QDeclarativeAttenuationModelLinear::calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const
|
||||
{
|
||||
qreal md = m_end - m_start;
|
||||
if (md == 0)
|
||||
return 1;
|
||||
qreal d = qBound(qreal(0), (listenerPosition - sourcePosition).length() - m_start, md);
|
||||
return qreal(1) - (d / md);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
\qmlclass AttenuationModelInverse QDeclarativeAttenuationModelInverse
|
||||
\since 5.0
|
||||
\brief The AttenuationModelInverse element allows you to define a non-linear attenuation curve
|
||||
for Sound element.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
AttenuationModelInverse must be defined inside AudioEngine.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AttenuationModelInverse {
|
||||
name:"linear"
|
||||
start: 20
|
||||
end: 500
|
||||
rolloff: 1.5
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
attenuationModel: "linear"
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Attenuation factor is calculated as below:
|
||||
|
||||
distance: distance from sound to listener
|
||||
d = min(max(distance, start), end);
|
||||
attenuation = start / (start + (d - start) * rolloff);
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty string AttenuationModelInverse::name
|
||||
|
||||
This property holds the name of AttenuationModelInverse, must be unique among all attenuation
|
||||
models and only defined once.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty real AttenuationModelInverse::start
|
||||
|
||||
This property holds the start distance. There will be no attenuation if the distance from sound
|
||||
to listener is within this range.
|
||||
The default value is 1.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty real AttenuationModelInverse::end
|
||||
|
||||
This property holds the end distance. There will be no further attenuation if the distance from
|
||||
sound to listener is larger than this.
|
||||
The default value is 1000.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty real AttenuationModelInverse::rolloff
|
||||
|
||||
This property holds the rolloff factor. The bigger the value is, the faster the sound attenuates.
|
||||
The default value is 1.
|
||||
*/
|
||||
|
||||
QDeclarativeAttenuationModelInverse::QDeclarativeAttenuationModelInverse(QObject *parent)
|
||||
: QDeclarativeAttenuationModel(parent)
|
||||
, m_ref(1)
|
||||
, m_max(1000)
|
||||
, m_rolloff(1)
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelInverse::componentComplete()
|
||||
{
|
||||
if (m_ref > m_max) {
|
||||
qSwap(m_ref, m_max);
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: referenceDistance must be less or equal than maxDistance.";
|
||||
}
|
||||
QDeclarativeAttenuationModel::componentComplete();
|
||||
}
|
||||
|
||||
qreal QDeclarativeAttenuationModelInverse::referenceDistance() const
|
||||
{
|
||||
return m_ref;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelInverse::setReferenceDistance(qreal referenceDistance)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization.";
|
||||
return;
|
||||
}
|
||||
if (referenceDistance <= 0) {
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: referenceDistance must be greater than 0.";
|
||||
return;
|
||||
}
|
||||
m_ref = referenceDistance;
|
||||
}
|
||||
|
||||
qreal QDeclarativeAttenuationModelInverse::maxDistance() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelInverse::setMaxDistance(qreal maxDistance)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization.";
|
||||
return;
|
||||
}
|
||||
if (maxDistance <= 0) {
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: maxDistance must be greater than 0.";
|
||||
return;
|
||||
}
|
||||
m_max = maxDistance;
|
||||
}
|
||||
|
||||
qreal QDeclarativeAttenuationModelInverse::rolloffFactor() const
|
||||
{
|
||||
return m_rolloff;
|
||||
}
|
||||
|
||||
void QDeclarativeAttenuationModelInverse::setRolloffFactor(qreal rolloffFactor)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization.";
|
||||
return;
|
||||
}
|
||||
m_rolloff = rolloffFactor;
|
||||
}
|
||||
|
||||
qreal QDeclarativeAttenuationModelInverse::calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const
|
||||
{
|
||||
Q_ASSERT(m_ref > 0);
|
||||
return m_ref / (m_ref + (qBound(m_ref, (listenerPosition - sourcePosition).length(), m_max) - m_ref) * m_rolloff);
|
||||
}
|
||||
|
||||
138
src/imports/audioengine/qdeclarative_attenuationmodel_p.h
Normal file
138
src/imports/audioengine/qdeclarative_attenuationmodel_p.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEATTENUATIONMODEL_P_H
|
||||
#define QDECLARATIVEATTENUATIONMODEL_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
#include <QVector3D>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeAttenuationModel : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
|
||||
public:
|
||||
QDeclarativeAttenuationModel(QObject *parent = 0);
|
||||
~QDeclarativeAttenuationModel();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
|
||||
virtual qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const = 0;
|
||||
|
||||
protected:
|
||||
bool m_complete;
|
||||
QString m_name;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAttenuationModel);
|
||||
};
|
||||
|
||||
class QDeclarativeAttenuationModelLinear : public QDeclarativeAttenuationModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal start READ startDistance WRITE setStartDistance CONSTANT)
|
||||
Q_PROPERTY(qreal end READ endDistance WRITE setEndDistance CONSTANT)
|
||||
|
||||
public:
|
||||
QDeclarativeAttenuationModelLinear(QObject *parent = 0);
|
||||
|
||||
void componentComplete();
|
||||
|
||||
qreal startDistance() const;
|
||||
void setStartDistance(qreal startDist);
|
||||
|
||||
qreal endDistance() const;
|
||||
void setEndDistance(qreal endDist);
|
||||
|
||||
qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAttenuationModelLinear);
|
||||
qreal m_start;
|
||||
qreal m_end;
|
||||
};
|
||||
|
||||
class QDeclarativeAttenuationModelInverse : public QDeclarativeAttenuationModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal start READ referenceDistance WRITE setReferenceDistance CONSTANT)
|
||||
Q_PROPERTY(qreal end READ maxDistance WRITE setMaxDistance CONSTANT)
|
||||
Q_PROPERTY(qreal rolloff READ rolloffFactor WRITE setRolloffFactor CONSTANT)
|
||||
|
||||
public:
|
||||
QDeclarativeAttenuationModelInverse(QObject *parent = 0);
|
||||
|
||||
void componentComplete();
|
||||
|
||||
qreal referenceDistance() const;
|
||||
void setReferenceDistance(qreal referenceDistance);
|
||||
|
||||
qreal maxDistance() const;
|
||||
void setMaxDistance(qreal maxDistance);
|
||||
|
||||
qreal rolloffFactor() const;
|
||||
void setRolloffFactor(qreal rolloffFactor);
|
||||
|
||||
qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAttenuationModelInverse);
|
||||
qreal m_ref;
|
||||
qreal m_max;
|
||||
qreal m_rolloff;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
207
src/imports/audioengine/qdeclarative_audiocategory_p.cpp
Normal file
207
src/imports/audioengine/qdeclarative_audiocategory_p.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_audiocategory_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass AudioCategory QDeclarativeAudioCategory
|
||||
\since 5.0
|
||||
\brief The AudioCategory element allows you to control all active sound instances by group
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
AudioCategory element can be accessed through AudioEngine::categories with its unique name and
|
||||
must be defined inside AudioEngine.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioCategory {
|
||||
name: "sfx"
|
||||
volume: 0.8
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
category: "sfx"
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: {
|
||||
audioengine.categories["sfx"].volume = 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Sound elements can be grouped togather by specifying the category property. When you change the
|
||||
volume of a category, all audio output from related elements will be affected as well.
|
||||
|
||||
Note: there will always be an AudioCategory named \c default whether you explicitly define it or
|
||||
not. If you do not specify any category for a Sound element, it will be grouped into the \c default
|
||||
category.
|
||||
|
||||
*/
|
||||
QDeclarativeAudioCategory::QDeclarativeAudioCategory(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
, m_volume(1)
|
||||
{
|
||||
}
|
||||
|
||||
QDeclarativeAudioCategory::~QDeclarativeAudioCategory()
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeAudioCategory::classBegin()
|
||||
{
|
||||
if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) {
|
||||
qWarning("AudioCategory must be defined inside AudioEngine!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativeAudioCategory::componentComplete()
|
||||
{
|
||||
if (m_name.isEmpty()) {
|
||||
qWarning("AudioCategory must have a name!");
|
||||
return;
|
||||
}
|
||||
m_complete = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AudioCategory::volume
|
||||
|
||||
This property holds the volume of the category and will modulate all audio output from the
|
||||
element which belongs to this category.
|
||||
*/
|
||||
qreal QDeclarativeAudioCategory::volume() const
|
||||
{
|
||||
return m_volume;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioCategory::setVolume(qreal volume)
|
||||
{
|
||||
if (m_volume == volume)
|
||||
return;
|
||||
m_volume = volume;
|
||||
emit volumeChanged(m_volume);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioCategory[" << m_name << "] setVolume(" << volume << ")";
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string AudioCategory::name
|
||||
|
||||
This property holds the name of AudioCategory. The name must be unique among all categories and only
|
||||
defined once.
|
||||
*/
|
||||
void QDeclarativeAudioCategory::setName(const QString& name)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AudioCategory: you can not change name after initialization.");
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString QDeclarativeAudioCategory::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod AudioCategory::stop()
|
||||
|
||||
Stops all active sound instances which belong to this category.
|
||||
*/
|
||||
void QDeclarativeAudioCategory::stop()
|
||||
{
|
||||
emit stopped();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod AudioCategory::pause()
|
||||
|
||||
Pauses all active sound instances which belong to this category.
|
||||
*/
|
||||
void QDeclarativeAudioCategory::pause()
|
||||
{
|
||||
emit paused();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod AudioCategory::pause()
|
||||
|
||||
Resumes all active sound instances from paused state which belong to this category.
|
||||
*/
|
||||
void QDeclarativeAudioCategory::resume()
|
||||
{
|
||||
emit resumed();
|
||||
}
|
||||
94
src/imports/audioengine/qdeclarative_audiocategory_p.h
Normal file
94
src/imports/audioengine/qdeclarative_audiocategory_p.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEAUDIOCATEGORY_P_H
|
||||
#define QDECLARATIVEAUDIOCATEGORY_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeAudioCategory : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
|
||||
public:
|
||||
QDeclarativeAudioCategory(QObject *parent = 0);
|
||||
~QDeclarativeAudioCategory();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
qreal volume() const;
|
||||
void setVolume(qreal volume);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
|
||||
Q_SIGNALS:
|
||||
void volumeChanged(qreal newVolume);
|
||||
void stopped();
|
||||
void paused();
|
||||
void resumed();
|
||||
|
||||
public Q_SLOTS:
|
||||
void stop();
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAudioCategory);
|
||||
bool m_complete;
|
||||
QString m_name;
|
||||
qreal m_volume;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
519
src/imports/audioengine/qdeclarative_audioengine_p.cpp
Normal file
519
src/imports/audioengine/qdeclarative_audioengine_p.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_audioengine_p.h"
|
||||
#include "qdeclarative_audiolistener_p.h"
|
||||
#include "qdeclarative_audiocategory_p.h"
|
||||
#include "qdeclarative_audiosample_p.h"
|
||||
#include "qdeclarative_sound_p.h"
|
||||
#include "qdeclarative_playvariation_p.h"
|
||||
#include "qdeclarative_attenuationmodel_p.h"
|
||||
#include "qdeclarative_soundinstance_p.h"
|
||||
#include "qsoundinstance_p.h"
|
||||
#include <QtDeclarative/qdeclarativeengine.h>
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass AudioEngine QDeclarativeAudioEngine
|
||||
\since 5.0
|
||||
\brief The AudioEngine element allows you to organize all your 3d audio content in one place.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
PlayVariation {
|
||||
sample:"explosion"
|
||||
}
|
||||
}
|
||||
|
||||
dopplerFactor: 1
|
||||
speedOfSound: 343.33
|
||||
|
||||
listener.up:"0,0,1"
|
||||
listener.position:"0,0,0"
|
||||
listener.velocity:"0,0,0"
|
||||
listener.direction:"0,1,0"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: {
|
||||
audioengine.sounds["explosion"].play();
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
The \c AudioEngine element acts as a central library for configuring all 3d audio content in an
|
||||
app, so you should define only one such element in your app.
|
||||
|
||||
It is mostly used as a container to access other elements such as AudioCategory, AudioSample and
|
||||
Sound.
|
||||
|
||||
\sa AudioCategory, AudioSample, Sound, SoundInstance, AttenuationModelLinear, AttenuationModelInverse
|
||||
*/
|
||||
|
||||
QDeclarativeAudioEngine::QDeclarativeAudioEngine(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
, m_defaultCategory(0)
|
||||
, m_defaultAttenuationModel(0)
|
||||
, m_audioEngine(0)
|
||||
{
|
||||
m_audioEngine = QAudioEngine::create(this);
|
||||
connect(m_audioEngine, SIGNAL(isLoadingChanged()), this, SIGNAL(isLoadingChanged()));
|
||||
connect(m_audioEngine, SIGNAL(isLoadingChanged()), this, SLOT(handleLoadingChanged()));
|
||||
m_listener = new QDeclarativeAudioListener(this);
|
||||
m_updateTimer.setInterval(100);
|
||||
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateSoundInstances()));
|
||||
}
|
||||
|
||||
QDeclarativeAudioEngine::~QDeclarativeAudioEngine()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioEngine::dtor"
|
||||
<< "active = " << m_activeSoundInstances.count()
|
||||
<< "pool = " << m_soundInstancePool.count();
|
||||
#endif
|
||||
qDeleteAll(m_activeSoundInstances);
|
||||
m_activeSoundInstances.clear();
|
||||
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "for pool";
|
||||
#endif
|
||||
qDeleteAll(m_soundInstancePool);
|
||||
m_soundInstancePool.clear();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::classBegin()
|
||||
{
|
||||
}
|
||||
|
||||
bool QDeclarativeAudioEngine::isReady() const
|
||||
{
|
||||
return m_complete;
|
||||
}
|
||||
|
||||
QAudioEngine* QDeclarativeAudioEngine::engine() const
|
||||
{
|
||||
return m_audioEngine;
|
||||
}
|
||||
|
||||
QDeclarativeSoundInstance* QDeclarativeAudioEngine::newDeclarativeSoundInstance(bool managed)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioEngine::newDeclarativeSoundInstance(" << managed << ")";
|
||||
#endif
|
||||
QDeclarativeSoundInstance *instance = 0;
|
||||
if (managed) {
|
||||
if (m_managedDeclSndInstancePool.count() > 0) {
|
||||
instance = m_managedDeclSndInstancePool.last();
|
||||
m_managedDeclSndInstancePool.pop_back();
|
||||
} else {
|
||||
instance = new QDeclarativeSoundInstance(this);
|
||||
qmlEngine(instance)->setObjectOwnership(instance, QDeclarativeEngine::CppOwnership);
|
||||
instance->setEngine(this);
|
||||
}
|
||||
m_managedDeclSoundInstances.push_back(instance);
|
||||
} else {
|
||||
instance = new QDeclarativeSoundInstance();
|
||||
instance->setEngine(this);
|
||||
qmlEngine(instance)->setObjectOwnership(instance, QDeclarativeEngine::JavaScriptOwnership);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::releaseManagedDeclarativeSoundInstance(QDeclarativeSoundInstance* declSndInstance)
|
||||
{
|
||||
declSndInstance->setSound(QString());
|
||||
m_managedDeclSndInstancePool.push_back(declSndInstance);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty int AudioEngine::liveInstances
|
||||
|
||||
This property indicates how many live sound instances there are at the moment.
|
||||
*/
|
||||
int QDeclarativeAudioEngine::liveInstanceCount() const
|
||||
{
|
||||
return m_activeSoundInstances.count();
|
||||
}
|
||||
|
||||
QSoundInstance* QDeclarativeAudioEngine::newSoundInstance(const QString &name)
|
||||
{
|
||||
QSoundInstance *instance = 0;
|
||||
if (m_soundInstancePool.count() > 0) {
|
||||
instance = m_soundInstancePool.last();
|
||||
m_soundInstancePool.pop_back();
|
||||
} else {
|
||||
instance = new QSoundInstance(this);
|
||||
}
|
||||
instance->bindSoundDescription(qobject_cast<QDeclarativeSound*>(qvariant_cast<QObject*>(m_sounds.value(name))));
|
||||
m_activeSoundInstances.push_back(instance);
|
||||
if (!m_updateTimer.isActive())
|
||||
m_updateTimer.start();
|
||||
emit liveInstanceCountChanged();
|
||||
return instance;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::releaseSoundInstance(QSoundInstance* instance)
|
||||
{
|
||||
instance->bindSoundDescription(0);
|
||||
m_activeSoundInstances.removeOne(instance);
|
||||
m_soundInstancePool.push_back(instance);
|
||||
emit liveInstanceCountChanged();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::componentComplete()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "AudioEngine begin initialization";
|
||||
#endif
|
||||
if (!m_defaultCategory) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "creating default category";
|
||||
#endif
|
||||
m_defaultCategory = new QDeclarativeAudioCategory(this);
|
||||
m_defaultCategory->classBegin();
|
||||
m_defaultCategory->setName(QString::fromLatin1("default"));
|
||||
m_defaultCategory->setVolume(1);
|
||||
m_defaultCategory->componentComplete();
|
||||
}
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "init samples" << m_samples.keys().count();
|
||||
#endif
|
||||
foreach (const QString& key, m_samples.keys()) {
|
||||
QDeclarativeAudioSample *sample = qobject_cast<QDeclarativeAudioSample*>(
|
||||
qvariant_cast<QObject*>(m_samples[key]));
|
||||
if (!sample) {
|
||||
qWarning() << "accessing invalid sample[" << key << "]";
|
||||
continue;
|
||||
}
|
||||
sample->init();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "init sounds" << m_sounds.keys().count();
|
||||
#endif
|
||||
foreach (const QString& key, m_sounds.keys()) {
|
||||
QDeclarativeSound *sound = qobject_cast<QDeclarativeSound*>(
|
||||
qvariant_cast<QObject*>(m_sounds[key]));
|
||||
|
||||
if (!sound) {
|
||||
qWarning() << "accessing invalid sound[" << key << "]";
|
||||
continue;
|
||||
}
|
||||
QDeclarativeAudioCategory *category = m_defaultCategory;
|
||||
if (m_categories.contains(sound->category())) {
|
||||
category = qobject_cast<QDeclarativeAudioCategory*>(
|
||||
qvariant_cast<QObject*>(m_categories[sound->category()]));
|
||||
}
|
||||
sound->setCategoryObject(category);
|
||||
|
||||
QDeclarativeAttenuationModel *attenuationModel = 0;
|
||||
if (sound->attenuationModel().isEmpty()) {
|
||||
if (m_defaultAttenuationModel)
|
||||
attenuationModel = m_defaultAttenuationModel;
|
||||
} else if (m_attenuationModels.contains(sound->attenuationModel())){
|
||||
attenuationModel = m_attenuationModels[sound->attenuationModel()];
|
||||
} else {
|
||||
qWarning() << "Sound[" << sound->name() << "] contains invalid attenuationModel["
|
||||
<< sound->attenuationModel() << "]";
|
||||
}
|
||||
sound->setAttenuationModelObject(attenuationModel);
|
||||
|
||||
foreach (QDeclarativePlayVariation* playVariation, sound->playlist()) {
|
||||
if (m_samples.contains(playVariation->sample())) {
|
||||
playVariation->setSampleObject(
|
||||
qobject_cast<QDeclarativeAudioSample*>(
|
||||
qvariant_cast<QObject*>(m_samples[playVariation->sample()])));
|
||||
} else {
|
||||
qWarning() << "Sound[" << sound->name() << "] contains invalid sample["
|
||||
<< playVariation->sample() << "] for its playVarations";
|
||||
}
|
||||
}
|
||||
}
|
||||
m_complete = true;
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "AudioEngine ready.";
|
||||
#endif
|
||||
emit ready();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::updateSoundInstances()
|
||||
{
|
||||
for (QList<QDeclarativeSoundInstance*>::Iterator it = m_managedDeclSoundInstances.begin();
|
||||
it != m_managedDeclSoundInstances.end();) {
|
||||
QDeclarativeSoundInstance *declSndInstance = *it;
|
||||
if (declSndInstance->state() == QDeclarativeSoundInstance::StopppedState) {
|
||||
it = m_managedDeclSoundInstances.erase(it);
|
||||
releaseManagedDeclarativeSoundInstance(declSndInstance);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "AudioEngine removed managed sounce instance";
|
||||
#endif
|
||||
} else {
|
||||
declSndInstance->updatePosition(qreal(0.1));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
QVector3D listenerPosition = this->listener()->position();
|
||||
foreach (QSoundInstance *instance, m_activeSoundInstances) {
|
||||
if (instance->state() == QSoundInstance::PlayingState
|
||||
&& instance->attenuationEnabled()) {
|
||||
instance->update3DVolume(listenerPosition);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_activeSoundInstances.count() == 0)
|
||||
m_updateTimer.stop();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::appendFunction(QDeclarativeListProperty<QObject> *property, QObject *value)
|
||||
{
|
||||
QDeclarativeAudioEngine* engine = static_cast<QDeclarativeAudioEngine*>(property->object);
|
||||
if (engine->m_complete) {
|
||||
qWarning("AudioEngine: cannot add child after initialization!");
|
||||
return;
|
||||
}
|
||||
|
||||
QDeclarativeSound *sound = qobject_cast<QDeclarativeSound*>(value);
|
||||
if (sound) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "add QDeclarativeSound[" << sound->name() << "]";
|
||||
#endif
|
||||
if (engine->m_sounds.contains(sound->name())) {
|
||||
qWarning() << "Failed to add Sound[" << sound->name() << "], already exists!";
|
||||
return;
|
||||
}
|
||||
engine->m_sounds.insert(sound->name(), QVariant::fromValue(value));
|
||||
return;
|
||||
}
|
||||
|
||||
QDeclarativeAudioSample *sample = qobject_cast<QDeclarativeAudioSample*>(value);
|
||||
if (sample) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "add QDeclarativeAudioSample[" << sample->name() << "]";
|
||||
#endif
|
||||
if (engine->m_samples.contains(sample->name())) {
|
||||
qWarning() << "Failed to add AudioSample[" << sample->name() << "], already exists!";
|
||||
return;
|
||||
}
|
||||
engine->m_samples.insert(sample->name(), QVariant::fromValue(value));
|
||||
return;
|
||||
}
|
||||
|
||||
QDeclarativeAudioCategory *category = qobject_cast<QDeclarativeAudioCategory*>(value);
|
||||
if (category) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "add QDeclarativeAudioCategory[" << category->name() << "]";
|
||||
#endif
|
||||
if (engine->m_categories.contains(category->name())) {
|
||||
qWarning() << "Failed to add AudioCategory[" << category->name() << "], already exists!";
|
||||
return;
|
||||
}
|
||||
engine->m_categories.insert(category->name(), QVariant::fromValue(value));
|
||||
if (category->name() == QLatin1String("default")) {
|
||||
engine->m_defaultCategory = category;
|
||||
}
|
||||
}
|
||||
|
||||
QDeclarativeAttenuationModel *attenModel = qobject_cast<QDeclarativeAttenuationModel*>(value);
|
||||
if (attenModel) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "add AttenuationModel[" << attenModel->name() << "]";
|
||||
#endif
|
||||
if (attenModel->name() == QLatin1String("default")) {
|
||||
engine->m_defaultAttenuationModel = attenModel;
|
||||
}
|
||||
if (engine->m_attenuationModels.contains(attenModel->name())) {
|
||||
qWarning() << "Failed to add AttenuationModel[" << attenModel->name() << "], already exists!";
|
||||
return;
|
||||
}
|
||||
engine->m_attenuationModels.insert(attenModel->name(), attenModel);
|
||||
return;
|
||||
}
|
||||
|
||||
qWarning("Unknown child type for AudioEngine!");
|
||||
}
|
||||
|
||||
QDeclarativeListProperty<QObject> QDeclarativeAudioEngine::bank()
|
||||
{
|
||||
return QDeclarativeListProperty<QObject>(this, 0, appendFunction);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty map AudioEngine::categories
|
||||
|
||||
Container of all AudioCategory elements.
|
||||
*/
|
||||
QObject* QDeclarativeAudioEngine::categories()
|
||||
{
|
||||
return &m_categories;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty map AudioEngine::samples
|
||||
|
||||
Container of all AudioSample elements.
|
||||
*/
|
||||
QObject* QDeclarativeAudioEngine::samples()
|
||||
{
|
||||
return &m_samples;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty map AudioEngine::sounds
|
||||
|
||||
Container of all Sound elements.
|
||||
*/
|
||||
QObject* QDeclarativeAudioEngine::sounds()
|
||||
{
|
||||
return &m_sounds;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty AudioListener AudioEngine::listener
|
||||
|
||||
This property holds the listener object. You can change various
|
||||
properties to affect the 3D positioning of sounds.
|
||||
|
||||
\sa AudioListener
|
||||
*/
|
||||
QDeclarativeAudioListener* QDeclarativeAudioEngine::listener() const
|
||||
{
|
||||
return m_listener;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AudioEngine::dopplerFactor
|
||||
|
||||
This property holds a simple scaling for the effect of doppler shift.
|
||||
*/
|
||||
qreal QDeclarativeAudioEngine::dopplerFactor() const
|
||||
{
|
||||
return m_audioEngine->dopplerFactor();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::setDopplerFactor(qreal dopplerFactor)
|
||||
{
|
||||
m_audioEngine->setDopplerFactor(dopplerFactor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AudioEngine::speedOfSound
|
||||
|
||||
This property holds the reference value of the sound speed which will be used in doppler shift
|
||||
calculation.
|
||||
*/
|
||||
qreal QDeclarativeAudioEngine::speedOfSound() const
|
||||
{
|
||||
return m_audioEngine->speedOfSound();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::setSpeedOfSound(qreal speedOfSound)
|
||||
{
|
||||
m_audioEngine->setSpeedOfSound(speedOfSound);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AudioEngine::loading
|
||||
|
||||
This property indicates if the audio engine is loading any audio sample at the moment. This may
|
||||
be useful if you specified the preloaded property in AudioSample and would like to show a loading screen
|
||||
to the user before all audio samples are loaded.
|
||||
|
||||
/sa finishedLoading, AudioSample::preloaded
|
||||
*/
|
||||
bool QDeclarativeAudioEngine::isLoading() const
|
||||
{
|
||||
return m_audioEngine->isLoading();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioEngine::handleLoadingChanged()
|
||||
{
|
||||
if (!isLoading())
|
||||
emit finishedLoading();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal AudioEngine::onLiveInstancesChanged()
|
||||
|
||||
This handler is called when \l liveInstances is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal AudioEngine::onLoadingChanged()
|
||||
|
||||
This handler is called when \l loading is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal AudioEngine::finishedLoading()
|
||||
|
||||
This handler is called when \l loading is finished
|
||||
*/
|
||||
QT_END_NAMESPACE
|
||||
|
||||
168
src/imports/audioengine/qdeclarative_audioengine_p.h
Normal file
168
src/imports/audioengine/qdeclarative_audioengine_p.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEAUDIOENGINE_P_H
|
||||
#define QDECLARATIVEAUDIOENGINE_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
#include <QtDeclarative/qdeclarativepropertymap.h>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QTimer>
|
||||
#include "qaudioengine_p.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeSoundInstance;
|
||||
class QDeclarativeAudioListener;
|
||||
class QDeclarativeAudioCategory;
|
||||
class QDeclarativeAudioSample;
|
||||
class QDeclarativeSound;
|
||||
class QDeclarativePlayVariation;
|
||||
class QAudioCategory;
|
||||
class QDeclarativeAttenuationModel;
|
||||
class QSoundInstance;
|
||||
|
||||
class QDeclarativeAudioEngine : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(QDeclarativeListProperty<QObject> bank READ bank CONSTANT)
|
||||
Q_PROPERTY(QObject* categories READ categories CONSTANT)
|
||||
Q_PROPERTY(QObject* samples READ samples CONSTANT)
|
||||
Q_PROPERTY(QObject* sounds READ sounds CONSTANT)
|
||||
Q_PROPERTY(bool loading READ isLoading NOTIFY isLoadingChanged)
|
||||
Q_PROPERTY(int liveInstances READ liveInstanceCount NOTIFY liveInstanceCountChanged)
|
||||
Q_PROPERTY(QDeclarativeAudioListener* listener READ listener CONSTANT)
|
||||
Q_PROPERTY(qreal dopplerFactor READ dopplerFactor WRITE setDopplerFactor)
|
||||
Q_PROPERTY(qreal speedOfSound READ speedOfSound WRITE setSpeedOfSound)
|
||||
Q_CLASSINFO("DefaultProperty", "bank")
|
||||
|
||||
public:
|
||||
QDeclarativeAudioEngine(QObject *parent = 0);
|
||||
~QDeclarativeAudioEngine();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
//This is used for tracking all objects declared inside AudioEngine
|
||||
//see appendFunction
|
||||
QDeclarativeListProperty<QObject> bank();
|
||||
|
||||
QObject* categories();
|
||||
QObject* samples();
|
||||
QObject* sounds();
|
||||
|
||||
QDeclarativeAudioListener* listener() const;
|
||||
|
||||
qreal dopplerFactor() const;
|
||||
void setDopplerFactor(qreal dopplerFactor);
|
||||
|
||||
qreal speedOfSound() const;
|
||||
void setSpeedOfSound(qreal speedOfSound);
|
||||
|
||||
bool isLoading() const;
|
||||
|
||||
int liveInstanceCount() const;
|
||||
|
||||
//for child elements
|
||||
bool isReady() const;
|
||||
QAudioEngine* engine() const;
|
||||
|
||||
//if managed, then the instance should start playing immediately and will be collected
|
||||
//when the playback finished
|
||||
QDeclarativeSoundInstance* newDeclarativeSoundInstance(bool managed);
|
||||
|
||||
//internal sound instance is different from declarativeSoundInstance
|
||||
//declarative instance is more like a soundInstance helper which can
|
||||
//switch to different sound instance conveniently while sound instance
|
||||
//must be mapped to one sound definition.
|
||||
QSoundInstance* newSoundInstance(const QString &name);
|
||||
void releaseSoundInstance(QSoundInstance* instance);
|
||||
|
||||
Q_SIGNALS:
|
||||
void ready();
|
||||
void liveInstanceCountChanged();
|
||||
void isLoadingChanged();
|
||||
void finishedLoading();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateSoundInstances();
|
||||
void handleLoadingChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAudioEngine);
|
||||
bool m_complete;
|
||||
|
||||
//see bank()
|
||||
static void appendFunction(QDeclarativeListProperty<QObject> *property, QObject *value);
|
||||
|
||||
QDeclarativeAudioListener *m_listener;
|
||||
QDeclarativeAudioCategory* m_defaultCategory;
|
||||
QDeclarativePropertyMap m_categories;
|
||||
QDeclarativePropertyMap m_samples;
|
||||
QDeclarativePropertyMap m_sounds;
|
||||
|
||||
//Use strong type here since no need to for AttenuationModel to be accessible directly by user
|
||||
//after config stage
|
||||
QDeclarativeAttenuationModel *m_defaultAttenuationModel;
|
||||
QMap<QString, QDeclarativeAttenuationModel*> m_attenuationModels;
|
||||
|
||||
QAudioEngine *m_audioEngine;
|
||||
|
||||
//for execution stage management
|
||||
QList<QSoundInstance*> m_soundInstancePool;
|
||||
QList<QSoundInstance*> m_activeSoundInstances;
|
||||
|
||||
QTimer m_updateTimer;
|
||||
QList<QDeclarativeSoundInstance*> m_managedDeclSoundInstances;
|
||||
QList<QDeclarativeSoundInstance*> m_managedDeclSndInstancePool;
|
||||
void releaseManagedDeclarativeSoundInstance(QDeclarativeSoundInstance* declSndInstance);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
263
src/imports/audioengine/qdeclarative_audiolistener_p.cpp
Normal file
263
src/imports/audioengine/qdeclarative_audiolistener_p.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_audiolistener_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass AudioListener QDeclarativeAudioListener
|
||||
\since 5.0
|
||||
\brief The AudioListener element allows you to control global listener parameters.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
AudioListener will have only one global instance and you can either access it through the
|
||||
listener property of AudioEngine:
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
listener.up:"0,0,1"
|
||||
listener.velocity:"0,0,0"
|
||||
listener.direction:"0,1,0"
|
||||
listener.position:Qt.vector3d(observer.x, observer.y, 0);
|
||||
}
|
||||
|
||||
Item {
|
||||
id: observer
|
||||
x: 10 + observer.percent * 100
|
||||
y: 20 + observer.percent * 80
|
||||
property real percent: 0
|
||||
SequentialAnimation on percent {
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
NumberAnimation {
|
||||
duration: 8000
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
or alternatively, by defining an AudioListener element outside AudioEngine:
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
listener.up:"0,0,1"
|
||||
listener.velocity:"0,0,0"
|
||||
listener.direction:"0,1,0"
|
||||
}
|
||||
|
||||
AudioListener {
|
||||
engine:audioengine
|
||||
position: Qt.vector3d(observer.x, observer.y, 0);
|
||||
}
|
||||
|
||||
Item {
|
||||
id: observer
|
||||
x: 10 + observer.percent * 100
|
||||
y: 20 + observer.percent * 80
|
||||
property real percent: 0
|
||||
SequentialAnimation on percent {
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
NumberAnimation {
|
||||
duration: 8000
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
This separate AudioListener definition is allowed to make qml bindings easier in some case.
|
||||
*/
|
||||
|
||||
QDeclarativeAudioListener::QDeclarativeAudioListener(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_engine(0)
|
||||
{
|
||||
m_engine = qobject_cast<QDeclarativeAudioEngine*>(parent);
|
||||
}
|
||||
|
||||
QDeclarativeAudioListener::~QDeclarativeAudioListener()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty AudioEngine AudioListener::engine
|
||||
|
||||
This property holds the reference to AudioEngine, must be set only once.
|
||||
*/
|
||||
QDeclarativeAudioEngine* QDeclarativeAudioListener::engine() const
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setEngine(QDeclarativeAudioEngine *engine)
|
||||
{
|
||||
setParent(engine);
|
||||
m_engine = engine;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d AudioListener::position
|
||||
|
||||
This property holds the 3d position of the listener.
|
||||
*/
|
||||
QVector3D QDeclarativeAudioListener::position() const
|
||||
{
|
||||
return m_engine->engine()->listenerPosition();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setPosition(const QVector3D &position)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioListener::setPosition";
|
||||
#endif
|
||||
m_engine->engine()->setListenerPosition(position);
|
||||
emit positionChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d AudioListener::direction
|
||||
|
||||
This property holds the normalized 3d direction vector of the listener.
|
||||
*/
|
||||
QVector3D QDeclarativeAudioListener::direction() const
|
||||
{
|
||||
return m_engine->engine()->listenerDirection();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setDirection(const QVector3D &direction)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioListener::setDirection";
|
||||
#endif
|
||||
m_engine->engine()->setListenerDirection(direction);
|
||||
emit directionChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d AudioListener::velocity
|
||||
|
||||
This property holds the 3d velocity vector of the listener.
|
||||
*/
|
||||
QVector3D QDeclarativeAudioListener::velocity() const
|
||||
{
|
||||
return m_engine->engine()->listenerVelocity();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setVelocity(const QVector3D &velocity)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioListener::setVelocity";
|
||||
#endif
|
||||
m_engine->engine()->setListenerVelocity(velocity);
|
||||
emit velocityChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d AudioListener::up
|
||||
|
||||
This property holds the normalized 3d up vector of the listener.
|
||||
*/
|
||||
QVector3D QDeclarativeAudioListener::up() const
|
||||
{
|
||||
return m_engine->engine()->listenerUp();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setUp(const QVector3D &up)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioListener::setUp";
|
||||
#endif
|
||||
m_engine->engine()->setListenerUp(up);
|
||||
emit upChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real AudioListener::gain
|
||||
|
||||
This property will modulate all audio output from audio engine elements.
|
||||
*/
|
||||
qreal QDeclarativeAudioListener::gain() const
|
||||
{
|
||||
return m_engine->engine()->listenerGain();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioListener::setGain(qreal gain)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeAudioListener::setGain";
|
||||
#endif
|
||||
m_engine->engine()->setListenerGain(gain);
|
||||
emit gainChanged();
|
||||
}
|
||||
102
src/imports/audioengine/qdeclarative_audiolistener_p.h
Normal file
102
src/imports/audioengine/qdeclarative_audiolistener_p.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEAUDIOLISTENER_P_H
|
||||
#define QDECLARATIVEAUDIOLISTENER_P_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/qvector3d.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeAudioEngine;
|
||||
|
||||
class QDeclarativeAudioListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QDeclarativeAudioEngine* engine READ engine WRITE setEngine)
|
||||
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||
Q_PROPERTY(QVector3D direction READ direction WRITE setDirection NOTIFY directionChanged)
|
||||
Q_PROPERTY(QVector3D velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
|
||||
Q_PROPERTY(QVector3D up READ up WRITE setUp NOTIFY upChanged)
|
||||
Q_PROPERTY(qreal gain READ gain WRITE setGain NOTIFY gainChanged)
|
||||
|
||||
public:
|
||||
QDeclarativeAudioListener(QObject *parent = 0);
|
||||
~QDeclarativeAudioListener();
|
||||
|
||||
QDeclarativeAudioEngine* engine() const;
|
||||
void setEngine(QDeclarativeAudioEngine *engine);
|
||||
|
||||
QVector3D position() const;
|
||||
void setPosition(const QVector3D &position);
|
||||
|
||||
QVector3D direction() const;
|
||||
void setDirection(const QVector3D &direction);
|
||||
|
||||
QVector3D up() const;
|
||||
void setUp(const QVector3D &up);
|
||||
|
||||
QVector3D velocity() const;
|
||||
void setVelocity(const QVector3D &velocity);
|
||||
|
||||
qreal gain() const;
|
||||
void setGain(qreal gain);
|
||||
|
||||
Q_SIGNALS:
|
||||
void positionChanged();
|
||||
void directionChanged();
|
||||
void velocityChanged();
|
||||
void upChanged();
|
||||
void gainChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAudioListener);
|
||||
QDeclarativeAudioEngine *m_engine;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
242
src/imports/audioengine/qdeclarative_audiosample_p.cpp
Normal file
242
src/imports/audioengine/qdeclarative_audiosample_p.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_audiosample_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qdebug.h"
|
||||
#include "qsoundbuffer_p.h"
|
||||
#include "qaudioengine_p.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass AudioSample QDeclarativeAudioSample
|
||||
\since 5.0
|
||||
\brief The AudioSample element allows you to load audio samples, mostly wav file.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
AudioSample element can be accessed through AudioEngine::samples with its unique name and must
|
||||
be defined inside AudioEngine.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
QDeclarativeAudioSample::QDeclarativeAudioSample(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
, m_streaming(false)
|
||||
, m_preloaded(false)
|
||||
, m_soundBuffer(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDeclarativeAudioSample::~QDeclarativeAudioSample()
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::classBegin()
|
||||
{
|
||||
if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) {
|
||||
qWarning("AudioSample must be defined inside AudioEngine!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::componentComplete()
|
||||
{
|
||||
if (m_name.isEmpty()) {
|
||||
qWarning("AudioSample must have a name!");
|
||||
return;
|
||||
}
|
||||
m_complete = true;
|
||||
}
|
||||
|
||||
QUrl QDeclarativeAudioSample::source() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::setSource(const QUrl& url)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AudioSample: source not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_url = url;
|
||||
}
|
||||
|
||||
bool QDeclarativeAudioSample::isStreaming() const
|
||||
{
|
||||
return m_streaming;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty bool AudioSample::preloaded
|
||||
|
||||
This property holds indicates whether this sample needs to be preloaded or not.
|
||||
If true, the audio engine will start loading the sample file immediately when the app started,
|
||||
otherwise the sample will not be loaded untill be used by other element.
|
||||
*/
|
||||
|
||||
bool QDeclarativeAudioSample::isPreloaded() const
|
||||
{
|
||||
return m_preloaded;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty bool AudioSample::isLoaded
|
||||
|
||||
This property holds indicates whether this sample has been loaded into memory or not.
|
||||
*/
|
||||
bool QDeclarativeAudioSample::isLoaded() const
|
||||
{
|
||||
if (!m_soundBuffer)
|
||||
return false;
|
||||
return m_soundBuffer->isReady();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty AudioSample::load()
|
||||
|
||||
Starts loading the sample into memory if not loaded.
|
||||
*/
|
||||
void QDeclarativeAudioSample::load()
|
||||
{
|
||||
if (isLoaded())
|
||||
return;
|
||||
if (!m_soundBuffer) {
|
||||
m_preloaded = true;
|
||||
return;
|
||||
}
|
||||
m_soundBuffer->load();
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::setPreloaded(bool preloaded)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AudioSample: preloaded not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_preloaded = preloaded;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::setStreaming(bool streaming)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AudioSample: streaming not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_streaming = streaming;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string AudioSample::name
|
||||
|
||||
This property holds the name of AudioSample, must be unique among all samples and only
|
||||
defined once.
|
||||
*/
|
||||
QString QDeclarativeAudioSample::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::setName(const QString& name)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("AudioSample: name not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void QDeclarativeAudioSample::init()
|
||||
{
|
||||
if (m_streaming) {
|
||||
//TODO
|
||||
|
||||
} else {
|
||||
m_soundBuffer =
|
||||
qobject_cast<QDeclarativeAudioEngine*>(parent())->engine()->getStaticSoundBuffer(m_url);
|
||||
if (m_soundBuffer->isReady()) {
|
||||
emit loadedChanged();
|
||||
} else {
|
||||
connect(m_soundBuffer, SIGNAL(ready()), this, SIGNAL(loadedChanged()));
|
||||
}
|
||||
if (m_preloaded) {
|
||||
m_soundBuffer->load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSoundBuffer* QDeclarativeAudioSample::soundBuffer() const
|
||||
{
|
||||
return m_soundBuffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal AudioSample::onLoadedChanged()
|
||||
|
||||
This handler is called when \l loaded is changed
|
||||
*/
|
||||
|
||||
|
||||
111
src/imports/audioengine/qdeclarative_audiosample_p.h
Normal file
111
src/imports/audioengine/qdeclarative_audiosample_p.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEAUDIOSAMPLE_P_H
|
||||
#define QDECLARATIVEAUDIOSAMPLE_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSoundBuffer;
|
||||
|
||||
class QDeclarativeAudioSample : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
Q_PROPERTY(QUrl source READ source WRITE setSource)
|
||||
Q_PROPERTY(bool preloaded READ isPreloaded WRITE setPreloaded)
|
||||
Q_PROPERTY(bool streaming READ isStreaming WRITE setStreaming)
|
||||
Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)
|
||||
|
||||
public:
|
||||
QDeclarativeAudioSample(QObject *parent = 0);
|
||||
~QDeclarativeAudioSample();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
|
||||
QUrl source() const;
|
||||
void setSource(const QUrl& url);
|
||||
|
||||
bool isStreaming() const;
|
||||
void setStreaming(bool streaming);
|
||||
|
||||
bool isPreloaded() const;
|
||||
void setPreloaded(bool preloaded);
|
||||
|
||||
bool isLoaded() const;
|
||||
|
||||
QSoundBuffer* soundBuffer() const;
|
||||
|
||||
//called by QDeclarativeAudioEngine
|
||||
void init();
|
||||
|
||||
Q_SIGNALS:
|
||||
void loadedChanged();
|
||||
|
||||
public Q_SLOTS:
|
||||
void load();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeAudioSample);
|
||||
bool m_complete;
|
||||
QString m_name;
|
||||
QUrl m_url;
|
||||
bool m_streaming;
|
||||
bool m_preloaded;
|
||||
|
||||
QSoundBuffer *m_soundBuffer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
287
src/imports/audioengine/qdeclarative_playvariation_p.cpp
Normal file
287
src/imports/audioengine/qdeclarative_playvariation_p.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_playvariation_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qsoundinstance_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass PlayVariation QDeclarativePlayVariation
|
||||
\since 5.0
|
||||
\brief The PlayVariation element allows you to define a playback variation for \l Sound element.
|
||||
So each time the playback of the same sound can be a slightly different even with the same
|
||||
AudioSample.
|
||||
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
PlayVariation must be defined inside \l Sound element.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion01"
|
||||
source: "explosion-01.wav"
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion02"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
minPitch: 0.8
|
||||
maxPitch: 1.1
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
minGain: 1.1
|
||||
maxGain: 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
*/
|
||||
QDeclarativePlayVariation::QDeclarativePlayVariation(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
, m_looping(false)
|
||||
, m_maxGain(1)
|
||||
, m_minGain(1)
|
||||
, m_maxPitch(1)
|
||||
, m_minPitch(1)
|
||||
, m_sampleObject(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDeclarativePlayVariation::~QDeclarativePlayVariation()
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::classBegin()
|
||||
{
|
||||
if (!parent() || !parent()->inherits("QDeclarativeSound")) {
|
||||
qWarning("PlayVariation must be defined inside Sound!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::componentComplete()
|
||||
{
|
||||
if (m_maxGain < m_minGain) {
|
||||
qWarning("PlayVariation: maxGain must be no less than minGain");
|
||||
qSwap(m_minGain, m_maxGain);
|
||||
}
|
||||
if (m_maxPitch < m_minPitch) {
|
||||
qWarning("PlayVariation: maxPitch must be no less than minPitch");
|
||||
qSwap(m_minPitch, m_maxPitch);
|
||||
}
|
||||
m_complete = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string PlayVariation::sample
|
||||
|
||||
This property specifies which \l AudioSample this variation will use.
|
||||
*/
|
||||
QString QDeclarativePlayVariation::sample() const
|
||||
{
|
||||
return m_sample;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setSample(const QString& sample)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
m_sample = sample;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty bool PlayVariation::looping
|
||||
|
||||
This property indicates whether the playback will be looped or not.
|
||||
*/
|
||||
bool QDeclarativePlayVariation::isLooping() const
|
||||
{
|
||||
return m_looping;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setLooping(bool looping)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
m_looping = looping;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real PlayVariation::maxGain
|
||||
|
||||
This property specifies the maximum gain adjustment that can be applied in any playback.
|
||||
*/
|
||||
qreal QDeclarativePlayVariation::maxGain() const
|
||||
{
|
||||
return m_maxGain;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setMaxGain(qreal maxGain)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
if (maxGain <= 0) {
|
||||
qWarning("PlayVariation: maxGain must be greater than 0");
|
||||
return;
|
||||
}
|
||||
m_maxGain = maxGain;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real PlayVariation::minGain
|
||||
|
||||
This property specifies the minimum gain adjustment that can be applied in any playback.
|
||||
*/
|
||||
qreal QDeclarativePlayVariation::minGain() const
|
||||
{
|
||||
return m_minGain;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setMinGain(qreal minGain)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
if (minGain < 0) {
|
||||
qWarning("PlayVariation: minGain must be no less than 0");
|
||||
return;
|
||||
}
|
||||
m_minGain = minGain;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real PlayVariation::maxPitch
|
||||
|
||||
This property specifies the maximum pitch adjustment that can be applied in any playback.
|
||||
*/
|
||||
qreal QDeclarativePlayVariation::maxPitch() const
|
||||
{
|
||||
return m_maxPitch;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setMaxPitch(qreal maxPitch)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
if (maxPitch < 0) {
|
||||
qWarning("PlayVariation: maxPitch must be no less than 0");
|
||||
return;
|
||||
}
|
||||
m_maxPitch = maxPitch;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real PlayVariation::minPitch
|
||||
|
||||
This property specifies the minimum pitch adjustment that can be applied in any playback.
|
||||
*/
|
||||
qreal QDeclarativePlayVariation::minPitch() const
|
||||
{
|
||||
return m_minPitch;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setMinPitch(qreal minPitch)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("PlayVariation: cannot change properties after initialization.");
|
||||
return;
|
||||
}
|
||||
if (m_minPitch < 0) {
|
||||
qWarning("PlayVariation: m_minPitch must be no less than 0");
|
||||
return;
|
||||
}
|
||||
m_minPitch = minPitch;
|
||||
}
|
||||
|
||||
QDeclarativeAudioSample* QDeclarativePlayVariation::sampleObject() const
|
||||
{
|
||||
return m_sampleObject;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::setSampleObject(QDeclarativeAudioSample *sampleObject)
|
||||
{
|
||||
m_sampleObject = sampleObject;
|
||||
}
|
||||
|
||||
void QDeclarativePlayVariation::applyParameters(QSoundInstance *soundInstance)
|
||||
{
|
||||
qreal pitch = qreal(qrand() % 1001) * 0.001f * (m_maxPitch - m_minPitch) + m_minPitch;
|
||||
qreal gain = qreal(qrand() % 1001) * 0.001f * (m_maxGain - m_minGain) + m_minGain;
|
||||
soundInstance->updateVariationParameters(pitch, gain, m_looping);
|
||||
}
|
||||
111
src/imports/audioengine/qdeclarative_playvariation_p.h
Normal file
111
src/imports/audioengine/qdeclarative_playvariation_p.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVEPLAYVARIATION_P_H
|
||||
#define QDECLARATIVEPLAYVARIATION_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeAudioSample;
|
||||
class QSoundInstance;
|
||||
|
||||
class QDeclarativePlayVariation : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(QString sample READ sample WRITE setSample)
|
||||
Q_PROPERTY(bool looping READ isLooping WRITE setLooping)
|
||||
Q_PROPERTY(qreal maxGain READ maxGain WRITE setMaxGain)
|
||||
Q_PROPERTY(qreal minGain READ minGain WRITE setMinGain)
|
||||
Q_PROPERTY(qreal maxPitch READ maxPitch WRITE setMaxPitch)
|
||||
Q_PROPERTY(qreal minPitch READ minPitch WRITE setMinPitch)
|
||||
|
||||
public:
|
||||
QDeclarativePlayVariation(QObject *parent = 0);
|
||||
~QDeclarativePlayVariation();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
QString sample() const;
|
||||
void setSample(const QString& sample);
|
||||
|
||||
bool isLooping() const;
|
||||
void setLooping(bool looping);
|
||||
|
||||
qreal maxGain() const;
|
||||
void setMaxGain(qreal maxGain);
|
||||
qreal minGain() const;
|
||||
void setMinGain(qreal minGain);
|
||||
|
||||
qreal maxPitch() const;
|
||||
void setMaxPitch(qreal maxPitch);
|
||||
qreal minPitch() const;
|
||||
void setMinPitch(qreal minPitch);
|
||||
|
||||
//called by QDeclarativeAudioEngine
|
||||
void setSampleObject(QDeclarativeAudioSample *sampleObject);
|
||||
QDeclarativeAudioSample* sampleObject() const;
|
||||
|
||||
void applyParameters(QSoundInstance *soundInstance);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativePlayVariation);
|
||||
bool m_complete;
|
||||
QString m_sample;
|
||||
bool m_looping;
|
||||
qreal m_maxGain;
|
||||
qreal m_minGain;
|
||||
qreal m_maxPitch;
|
||||
qreal m_minPitch;
|
||||
QDeclarativeAudioSample *m_sampleObject;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
558
src/imports/audioengine/qdeclarative_sound_p.cpp
Normal file
558
src/imports/audioengine/qdeclarative_sound_p.cpp
Normal file
@@ -0,0 +1,558 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_sound_p.h"
|
||||
#include "qdeclarative_audiocategory_p.h"
|
||||
#include "qdeclarative_attenuationmodel_p.h"
|
||||
#include "qdeclarative_soundinstance_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QDeclarativeSoundCone::QDeclarativeSoundCone(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_innerAngle(360)
|
||||
, m_outerAngle(360)
|
||||
, m_outerGain(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real Sound::cone.innerAngle
|
||||
|
||||
This property holds the innerAngle for Sound definition.
|
||||
The range is [0, 360] degree. There is no directional attenuation within innerAngle.
|
||||
*/
|
||||
qreal QDeclarativeSoundCone::innerAngle() const
|
||||
{
|
||||
return m_innerAngle;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundCone::setInnerAngle(qreal innerAngle)
|
||||
{
|
||||
QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent());
|
||||
if (s && s->m_complete)
|
||||
return;
|
||||
if (innerAngle < 0 || innerAngle > 360) {
|
||||
qWarning() << "innerAngle should be within[0, 360] degrees";
|
||||
return;
|
||||
}
|
||||
m_innerAngle = innerAngle;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real Sound::cone.outerAngle
|
||||
|
||||
This property holds the outerAngle for Sound definition.
|
||||
The range is [0, 360] degree. All audio output from this sound will be attenuated by \l outerGain
|
||||
outside outerAngle.
|
||||
*/
|
||||
qreal QDeclarativeSoundCone::outerAngle() const
|
||||
{
|
||||
return m_outerAngle;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundCone::setOuterAngle(qreal outerAngle)
|
||||
{
|
||||
QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent());
|
||||
if (s && s->m_complete)
|
||||
return;
|
||||
if (outerAngle < 0 || outerAngle > 360) {
|
||||
qWarning() << "outerAngle should be within[0, 360] degrees";
|
||||
return;
|
||||
}
|
||||
m_outerAngle = outerAngle;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real Sound::cone.outerGain
|
||||
|
||||
This property holds attenuation value for directional attenuation of this sound.
|
||||
The range is [0, 1]. All audio output from this sound will be attenuated by outerGain
|
||||
outside \l outerAngle.
|
||||
*/
|
||||
qreal QDeclarativeSoundCone::outerGain() const
|
||||
{
|
||||
return m_outerGain;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundCone::setOuterGain(qreal outerGain)
|
||||
{
|
||||
QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent());
|
||||
if (s && s->m_complete)
|
||||
return;
|
||||
if (outerGain < 0 || outerGain > 1) {
|
||||
qWarning() << "outerGain should no less than 0 and no more than 1";
|
||||
return;
|
||||
}
|
||||
m_outerGain = outerGain;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundCone::componentComplete()
|
||||
{
|
||||
if (m_outerAngle < m_innerAngle) {
|
||||
m_outerAngle = m_innerAngle;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
\qmlclass Sound QDeclarativeSound
|
||||
\since 5.0
|
||||
\brief The Sound element allows you to define a variety of samples and parameters to be used for
|
||||
SoundInstance.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
Sound element can be accessed through AudioEngine::sounds with its unique name and must be
|
||||
defined inside AudioEngine.
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion01"
|
||||
source: "explosion-01.wav"
|
||||
}
|
||||
|
||||
AudioSample {
|
||||
name:"explosion02"
|
||||
source: "explosion-02.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
minPitch: 0.8
|
||||
maxPitch: 1.1
|
||||
}
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
minGain: 1.1
|
||||
maxGain: 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: {
|
||||
audioengine.sounds["explosion"].play();
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
QDeclarativeSound::QDeclarativeSound(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_complete(false)
|
||||
, m_playType(Random)
|
||||
, m_attenuationModelObject(0)
|
||||
, m_categoryObject(0)
|
||||
{
|
||||
m_cone = new QDeclarativeSoundCone(this);
|
||||
}
|
||||
|
||||
QDeclarativeSound::~QDeclarativeSound()
|
||||
{
|
||||
}
|
||||
|
||||
void QDeclarativeSound::classBegin()
|
||||
{
|
||||
if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) {
|
||||
qWarning("Sound must be defined inside AudioEngine!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativeSound::componentComplete()
|
||||
{
|
||||
m_complete = true;
|
||||
m_cone->componentComplete();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty enueration Sound::playType
|
||||
|
||||
This property holds the playType. It can be one of:
|
||||
|
||||
\list
|
||||
\o Random - randomly picks up a play variation when playback is triggered
|
||||
\o Sequential - plays each variation in sequence when playback is triggered
|
||||
\endlist
|
||||
|
||||
The default value is Random.
|
||||
*/
|
||||
QDeclarativeSound::PlayType QDeclarativeSound::playType() const
|
||||
{
|
||||
return m_playType;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setPlayType(PlayType playType)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("Sound: playType not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_playType = playType;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string Sound::category
|
||||
|
||||
This property specifies which AudioCategory this sound belongs to.
|
||||
*/
|
||||
QString QDeclarativeSound::category() const
|
||||
{
|
||||
return m_category;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setCategory(const QString& category)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("Sound: category not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_category = category;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string Sound::name
|
||||
|
||||
This property holds the name of Sound, must be unique among all sounds and only
|
||||
defined once.
|
||||
*/
|
||||
QString QDeclarativeSound::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setName(const QString& name)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("Sound: category not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string Sound::attenuationModel
|
||||
|
||||
This property specifies which attenuation model this sound will apply.
|
||||
*/
|
||||
QString QDeclarativeSound::attenuationModel() const
|
||||
{
|
||||
return m_attenuationModel;
|
||||
}
|
||||
|
||||
int QDeclarativeSound::genVariationIndex(int oldVariationIndex)
|
||||
{
|
||||
if (m_playlist.count() == 0)
|
||||
return -1;
|
||||
|
||||
if (m_playlist.count() == 1)
|
||||
return 0;
|
||||
|
||||
switch (m_playType) {
|
||||
case QDeclarativeSound::Random: {
|
||||
if (oldVariationIndex < 0)
|
||||
oldVariationIndex = 0;
|
||||
return (oldVariationIndex + (qrand() % (m_playlist.count() + 1))) % m_playlist.count();
|
||||
}
|
||||
default:
|
||||
return (oldVariationIndex + 1) % m_playlist.count();
|
||||
}
|
||||
}
|
||||
|
||||
QDeclarativePlayVariation* QDeclarativeSound::getVariation(int index)
|
||||
{
|
||||
Q_ASSERT(index >= 0 && index < m_playlist.count());
|
||||
return m_playlist[index];
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setAttenuationModel(QString attenuationModel)
|
||||
{
|
||||
if (m_complete) {
|
||||
qWarning("Sound: attenuationModel not changable after initialization.");
|
||||
return;
|
||||
}
|
||||
m_attenuationModel = attenuationModel;
|
||||
}
|
||||
|
||||
QDeclarativeSoundCone* QDeclarativeSound::cone() const
|
||||
{
|
||||
return m_cone;
|
||||
}
|
||||
|
||||
QDeclarativeAttenuationModel* QDeclarativeSound::attenuationModelObject() const
|
||||
{
|
||||
return m_attenuationModelObject;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setAttenuationModelObject(QDeclarativeAttenuationModel *attenuationModelObject)
|
||||
{
|
||||
m_attenuationModelObject = attenuationModelObject;
|
||||
}
|
||||
|
||||
QDeclarativeAudioCategory* QDeclarativeSound::categoryObject() const
|
||||
{
|
||||
return m_categoryObject;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::setCategoryObject(QDeclarativeAudioCategory *categoryObject)
|
||||
{
|
||||
m_categoryObject = categoryObject;
|
||||
}
|
||||
|
||||
QDeclarativeListProperty<QDeclarativePlayVariation> QDeclarativeSound::playVariationlist()
|
||||
{
|
||||
return QDeclarativeListProperty<QDeclarativePlayVariation>(this, 0, appendFunction);
|
||||
}
|
||||
|
||||
QList<QDeclarativePlayVariation*>& QDeclarativeSound::playlist()
|
||||
{
|
||||
return m_playlist;
|
||||
}
|
||||
|
||||
void QDeclarativeSound::appendFunction(QDeclarativeListProperty<QDeclarativePlayVariation> *property, QDeclarativePlayVariation *value)
|
||||
{
|
||||
QDeclarativeSound *sound = static_cast<QDeclarativeSound*>(property->object);
|
||||
if (sound->m_complete) {
|
||||
qWarning("Sound: PlayVariation not addable after initialization.");
|
||||
return;
|
||||
}
|
||||
sound->m_playlist.append(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play()
|
||||
|
||||
Creates a new \l SoundInstance and starts playing.
|
||||
Position, direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play()
|
||||
{
|
||||
play(QVector3D(), QVector3D(), QVector3D(), 1, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(gain)
|
||||
|
||||
Creates a new SoundInstance and starts playing with the adjusted \a gain.
|
||||
Position, direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(qreal gain)
|
||||
{
|
||||
play(QVector3D(), QVector3D(), QVector3D(), gain, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(gain, pitch)
|
||||
|
||||
Creates a new SoundInstance and starts playing with the adjusted \a gain and \a pitch.
|
||||
Position, direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(qreal gain, qreal pitch)
|
||||
{
|
||||
play(QVector3D(), QVector3D(), QVector3D(), gain, pitch);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position.
|
||||
Direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position)
|
||||
{
|
||||
play(position, QVector3D(), QVector3D(), 1, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position and \a velocity.
|
||||
Direction is set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity)
|
||||
{
|
||||
play(position, velocity, QVector3D(), 1, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity, direction)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, \a velocity and
|
||||
\a direction.
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity,
|
||||
const QVector3D& direction)
|
||||
{
|
||||
play(position, velocity, direction, 1, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, gain)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position and adjusted \a gain.
|
||||
Direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, qreal gain)
|
||||
{
|
||||
play(position, QVector3D(), QVector3D(), gain, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity, gain)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, \a velocity and
|
||||
adjusted \a gain.
|
||||
Direction is set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity, qreal gain)
|
||||
{
|
||||
play(position, velocity, QVector3D(), gain, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity, direction, gain)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, \a velocity,
|
||||
\a direction and adjusted \a gain.
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction, qreal gain)
|
||||
{
|
||||
play(position, velocity, direction, gain, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, gain, pitch)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, adjusted \a gain and
|
||||
\a pitch.
|
||||
Direction and velocity are all set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, qreal gain, qreal pitch)
|
||||
{
|
||||
play(position, QVector3D(), QVector3D(), gain, pitch);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity, gain, pitch)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, \a velocity,
|
||||
adjusted \a gain and \a pitch.
|
||||
Direction is set to \c "0,0,0".
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity, qreal gain, qreal pitch)
|
||||
{
|
||||
play(position, velocity, QVector3D(), gain, pitch);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod Sound::play(position, velocity, direction, gain, pitch)
|
||||
|
||||
Creates a new SoundInstance and starts playing with specified \a position, \a velocity,
|
||||
\a direction, adjusted \a gain and \a pitch.
|
||||
*/
|
||||
void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction, qreal gain, qreal pitch)
|
||||
{
|
||||
if (!m_complete) {
|
||||
qWarning() << "AudioEngine::play not ready!";
|
||||
return;
|
||||
}
|
||||
QDeclarativeSoundInstance *instance = this->newInstance(true);
|
||||
if (!instance)
|
||||
return;
|
||||
instance->setPosition(position);
|
||||
instance->setVelocity(velocity);
|
||||
instance->setDirection(direction);
|
||||
instance->setGain(gain);
|
||||
instance->setPitch(pitch);
|
||||
instance->setConeInnerAngle(cone()->innerAngle());
|
||||
instance->setConeOuterAngle(cone()->outerAngle());
|
||||
instance->setConeOuterGain(cone()->outerGain());
|
||||
instance->play();
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "Sound[" << m_name << "] play ("
|
||||
<< position << ","
|
||||
<< velocity <<","
|
||||
<< direction << ","
|
||||
<< gain << ","
|
||||
<< pitch << ")triggered";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod SoundInstance Sound::newInstance()
|
||||
|
||||
Returns a new \l SoundInstance.
|
||||
*/
|
||||
QDeclarativeSoundInstance* QDeclarativeSound::newInstance()
|
||||
{
|
||||
return newInstance(false);
|
||||
}
|
||||
|
||||
QDeclarativeSoundInstance* QDeclarativeSound::newInstance(bool managed)
|
||||
{
|
||||
QDeclarativeSoundInstance *instance =
|
||||
qobject_cast<QDeclarativeAudioEngine*>(this->parent())->newDeclarativeSoundInstance(managed);
|
||||
instance->setSound(m_name);
|
||||
return instance;
|
||||
}
|
||||
|
||||
176
src/imports/audioengine/qdeclarative_sound_p.h
Normal file
176
src/imports/audioengine/qdeclarative_sound_p.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVESOUND_P_H
|
||||
#define QDECLARATIVESOUND_P_H
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/qdeclarativecomponent.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include "qdeclarative_playvariation_p.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeAudioCategory;
|
||||
class QDeclarativeAttenuationModel;
|
||||
class QDeclarativeSoundInstance;
|
||||
|
||||
class QDeclarativeSoundCone : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal innerAngle READ innerAngle WRITE setInnerAngle)
|
||||
Q_PROPERTY(qreal outerAngle READ outerAngle WRITE setOuterAngle)
|
||||
Q_PROPERTY(qreal outerGain READ outerGain WRITE setOuterGain)
|
||||
public:
|
||||
QDeclarativeSoundCone(QObject *parent = 0);
|
||||
|
||||
//by degree
|
||||
qreal innerAngle() const;
|
||||
void setInnerAngle(qreal innerAngle);
|
||||
|
||||
//by degree
|
||||
qreal outerAngle() const;
|
||||
void setOuterAngle(qreal outerAngle);
|
||||
|
||||
qreal outerGain() const;
|
||||
void setOuterGain(qreal outerGain);
|
||||
|
||||
void componentComplete();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeSoundCone)
|
||||
qreal m_innerAngle;
|
||||
qreal m_outerAngle;
|
||||
qreal m_outerGain;
|
||||
};
|
||||
|
||||
class QDeclarativeSound : public QObject, public QDeclarativeParserStatus
|
||||
{
|
||||
friend class QDeclarativeSoundCone;
|
||||
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDeclarativeParserStatus)
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
Q_PROPERTY(PlayType playType READ playType WRITE setPlayType)
|
||||
Q_PROPERTY(QString category READ category WRITE setCategory)
|
||||
Q_PROPERTY(QDeclarativeSoundCone* cone READ cone CONSTANT)
|
||||
Q_PROPERTY(QString attenuationModel READ attenuationModel WRITE setAttenuationModel)
|
||||
Q_PROPERTY(QDeclarativeListProperty<QDeclarativePlayVariation> playVariationlist READ playVariationlist CONSTANT)
|
||||
Q_CLASSINFO("DefaultProperty", "playVariationlist")
|
||||
|
||||
Q_ENUMS(PlayType)
|
||||
public:
|
||||
enum PlayType
|
||||
{
|
||||
Random,
|
||||
Sequential
|
||||
};
|
||||
|
||||
QDeclarativeSound(QObject *parent = 0);
|
||||
~QDeclarativeSound();
|
||||
|
||||
void classBegin();
|
||||
void componentComplete();
|
||||
|
||||
PlayType playType() const;
|
||||
void setPlayType(PlayType playType);
|
||||
|
||||
QString category() const;
|
||||
void setCategory(const QString& category);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
|
||||
QString attenuationModel() const;
|
||||
void setAttenuationModel(QString attenuationModel);
|
||||
|
||||
QDeclarativeSoundCone* cone() const;
|
||||
|
||||
QDeclarativeAttenuationModel* attenuationModelObject() const;
|
||||
void setAttenuationModelObject(QDeclarativeAttenuationModel *attenuationModelObject);
|
||||
QDeclarativeAudioCategory* categoryObject() const;
|
||||
void setCategoryObject(QDeclarativeAudioCategory *categoryObject);
|
||||
|
||||
int genVariationIndex(int oldVariationIndex);
|
||||
QDeclarativePlayVariation* getVariation(int index);
|
||||
|
||||
//This is used for tracking new PlayVariation declared inside Sound
|
||||
QDeclarativeListProperty<QDeclarativePlayVariation> playVariationlist();
|
||||
QList<QDeclarativePlayVariation*>& playlist();
|
||||
|
||||
public Q_SLOTS:
|
||||
void play();
|
||||
void play(qreal gain);
|
||||
void play(qreal gain, qreal pitch);
|
||||
void play(const QVector3D& position);
|
||||
void play(const QVector3D& position, const QVector3D& velocity);
|
||||
void play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction);
|
||||
void play(const QVector3D& position, qreal gain);
|
||||
void play(const QVector3D& position, const QVector3D& velocity, qreal gain);
|
||||
void play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction, qreal gain);
|
||||
void play(const QVector3D& position, qreal gain, qreal pitch);
|
||||
void play(const QVector3D& position, const QVector3D& velocity, qreal gain, qreal pitch);
|
||||
void play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction, qreal gain, qreal pitch);
|
||||
QDeclarativeSoundInstance* newInstance();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeSound)
|
||||
QDeclarativeSoundInstance* newInstance(bool managed);
|
||||
static void appendFunction(QDeclarativeListProperty<QDeclarativePlayVariation> *property, QDeclarativePlayVariation *value);
|
||||
bool m_complete;
|
||||
PlayType m_playType;
|
||||
QString m_name;
|
||||
QString m_category;
|
||||
QString m_attenuationModel;
|
||||
QList<QDeclarativePlayVariation*> m_playlist;
|
||||
QDeclarativeSoundCone *m_cone;
|
||||
|
||||
QDeclarativeAttenuationModel *m_attenuationModelObject;
|
||||
QDeclarativeAudioCategory *m_categoryObject;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
560
src/imports/audioengine/qdeclarative_soundinstance_p.cpp
Normal file
560
src/imports/audioengine/qdeclarative_soundinstance_p.cpp
Normal file
@@ -0,0 +1,560 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qdeclarative_soundinstance_p.h"
|
||||
#include "qdeclarative_sound_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qaudioengine_p.h"
|
||||
#include "qsoundinstance_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
/*!
|
||||
\qmlclass SoundInstance QDeclarativeSoundInstance
|
||||
\since 5.0
|
||||
\brief The SoundInstance element allows you to play 3d audio content.
|
||||
\ingroup qml-multimedia
|
||||
\inherits Item
|
||||
|
||||
This element is part of the \bold{QtAudioEngine 1.0} module.
|
||||
|
||||
There are two ways to create SoundInstance objects. You can obtain it by calling newInstance
|
||||
method of Sound element:
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
id:root
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion01"
|
||||
source: "explosion-01.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property variant soundEffect: audioengine.sounds["explosion"].newInstance();
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: {
|
||||
root.soundEffect.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Or alternatively, you can explicitly define SoundInstance element outside of AudioEngine for
|
||||
easier qml bindings:
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtAudioEngine 1.0
|
||||
|
||||
Rectangle {
|
||||
id:root
|
||||
color:"white"
|
||||
width: 300
|
||||
height: 500
|
||||
|
||||
AudioEngine {
|
||||
id:audioengine
|
||||
|
||||
AudioSample {
|
||||
name:"explosion01"
|
||||
source: "explosion-01.wav"
|
||||
}
|
||||
|
||||
Sound {
|
||||
name:"explosion"
|
||||
PlayVariation {
|
||||
sample:"explosion01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: animator
|
||||
x: 10 + observer.percent * 100
|
||||
y: 20 + observer.percent * 80
|
||||
property real percent: 0
|
||||
SequentialAnimation on percent {
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
NumberAnimation {
|
||||
duration: 8000
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SoundInstance {
|
||||
id:soundEffect
|
||||
engine:audioengine
|
||||
sound:"explosion"
|
||||
position:Qt.vector3d(animator.x, animator.y, 0);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: {
|
||||
soundEffect.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
QDeclarativeSoundInstance::QDeclarativeSoundInstance(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_position(0, 0, 0)
|
||||
, m_direction(0, 1, 0)
|
||||
, m_velocity(0, 0, 0)
|
||||
, m_gain(1)
|
||||
, m_pitch(1)
|
||||
, m_requestState(QDeclarativeSoundInstance::StopppedState)
|
||||
, m_coneInnerAngle(360)
|
||||
, m_coneOuterAngle(360)
|
||||
, m_coneOuterGain(0)
|
||||
, m_instance(0)
|
||||
, m_engine(0)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::ctor()";
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty AudioEngine SoundInstance::engine
|
||||
|
||||
This property holds the reference to AudioEngine, must be set only once.
|
||||
*/
|
||||
QDeclarativeAudioEngine* QDeclarativeSoundInstance::engine() const
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setEngine(QDeclarativeAudioEngine *engine)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::setEngine(" << engine << ")";
|
||||
#endif
|
||||
if (!engine)
|
||||
return;
|
||||
|
||||
if (m_engine) {
|
||||
qWarning("SoundInstance: you can not set different value for engine property");
|
||||
return;
|
||||
}
|
||||
m_engine = engine;
|
||||
if (!m_engine->isReady()) {
|
||||
connect(m_engine, SIGNAL(ready()), this, SLOT(engineComplete()));
|
||||
} else {
|
||||
engineComplete();
|
||||
}
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::engineComplete()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::engineComplete()";
|
||||
#endif
|
||||
disconnect(m_engine, SIGNAL(ready()), this, SLOT(engineComplete()));
|
||||
if (m_sound.isEmpty())
|
||||
return;
|
||||
|
||||
//rebind to actual engine resource
|
||||
QString sound = m_sound;
|
||||
m_sound.clear();
|
||||
setSound(sound);
|
||||
}
|
||||
|
||||
QDeclarativeSoundInstance::~QDeclarativeSoundInstance()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty string SoundInstance::sound
|
||||
|
||||
This property specifies which Sound this SoundInstance will use. Unlike some properties in
|
||||
other elements, this property can be changed dynamically.
|
||||
*/
|
||||
QString QDeclarativeSoundInstance::sound() const
|
||||
{
|
||||
return m_sound;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setSound(const QString& sound)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::setSound(" << sound << ")";
|
||||
#endif
|
||||
if (m_sound == sound)
|
||||
return;
|
||||
|
||||
if (!m_engine || !m_engine->isReady()) {
|
||||
m_sound = sound;
|
||||
emit soundChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "SoundInstance Element switch sound from [" << m_sound << "] to [" << sound << "]";
|
||||
#endif
|
||||
|
||||
stop();
|
||||
dropInstance();
|
||||
|
||||
m_sound = sound;
|
||||
if (!m_sound.isEmpty()) {
|
||||
m_instance = m_engine->newSoundInstance(m_sound);
|
||||
connect(m_instance, SIGNAL(stateChanged(QSoundInstance::State)), this, SLOT(handleStateChanged()));
|
||||
m_instance->setPosition(m_position);
|
||||
m_instance->setDirection(m_direction);
|
||||
m_instance->setVelocity(m_velocity);
|
||||
m_instance->setGain(m_gain);
|
||||
m_instance->setPitch(m_pitch);
|
||||
m_instance->setCone(m_coneInnerAngle, m_coneOuterAngle, m_coneOuterGain);
|
||||
if (m_requestState == QDeclarativeSoundInstance::PlayingState) {
|
||||
m_instance->play();
|
||||
} else if (m_requestState == QDeclarativeSoundInstance::PausedState) {
|
||||
m_instance->pause();
|
||||
}
|
||||
}
|
||||
emit soundChanged();
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::dropInstance()
|
||||
{
|
||||
if (m_instance) {
|
||||
disconnect(m_instance, SIGNAL(stateChanged(QSoundInstance::State)), this, SLOT(handleStateChanged()));
|
||||
m_engine->releaseSoundInstance(m_instance);
|
||||
m_instance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration SoundInstance::state
|
||||
|
||||
This property holds the current playback state. It can be one of:
|
||||
|
||||
\list
|
||||
\o StopppedState
|
||||
\o PlayingState
|
||||
\o PausedState
|
||||
\endlist
|
||||
*/
|
||||
QDeclarativeSoundInstance::State QDeclarativeSoundInstance::state() const
|
||||
{
|
||||
if (m_instance)
|
||||
return State(m_instance->state());
|
||||
return m_requestState;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod SoundInstance::play()
|
||||
|
||||
Starts playback.
|
||||
*/
|
||||
void QDeclarativeSoundInstance::play()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::play()";
|
||||
#endif
|
||||
if (!m_instance) {
|
||||
m_requestState = QDeclarativeSoundInstance::PlayingState;
|
||||
return;
|
||||
}
|
||||
m_instance->play();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod SoundInstance::play()
|
||||
|
||||
Stops current playback.
|
||||
*/
|
||||
void QDeclarativeSoundInstance::stop()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::stop()";
|
||||
#endif
|
||||
m_requestState = QDeclarativeSoundInstance::StopppedState;
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->stop();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod SoundInstance::play()
|
||||
|
||||
Pauses current playback.
|
||||
*/
|
||||
void QDeclarativeSoundInstance::pause()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QDeclarativeSoundInstance::pause()";
|
||||
#endif
|
||||
if (!m_instance) {
|
||||
m_requestState = QDeclarativeSoundInstance::PausedState;
|
||||
return;
|
||||
}
|
||||
m_instance->pause();
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::updatePosition(qreal deltaTime)
|
||||
{
|
||||
if (!m_instance || deltaTime == 0 || m_velocity.lengthSquared() == 0)
|
||||
return;
|
||||
setPosition(m_position + m_velocity * deltaTime);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d SoundInstance::position
|
||||
|
||||
This property holds the current 3d position.
|
||||
*/
|
||||
QVector3D QDeclarativeSoundInstance::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setPosition(const QVector3D& position)
|
||||
{
|
||||
if (m_position == position)
|
||||
return;
|
||||
m_position = position;
|
||||
emit positionChanged();
|
||||
if (!m_instance) {
|
||||
return;
|
||||
}
|
||||
m_instance->setPosition(m_position);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d SoundInstance::direction
|
||||
|
||||
This property holds the current 3d direction.
|
||||
*/
|
||||
QVector3D QDeclarativeSoundInstance::direction() const
|
||||
{
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setDirection(const QVector3D& direction)
|
||||
{
|
||||
if (m_direction == direction)
|
||||
return;
|
||||
m_direction = direction;
|
||||
emit directionChanged();
|
||||
if (!m_instance) {
|
||||
return;
|
||||
}
|
||||
m_instance->setDirection(m_direction);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d SoundInstance::velocity
|
||||
|
||||
This property holds the current 3d velocity.
|
||||
*/
|
||||
QVector3D QDeclarativeSoundInstance::velocity() const
|
||||
{
|
||||
return m_velocity;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setVelocity(const QVector3D& velocity)
|
||||
{
|
||||
if (m_velocity == velocity)
|
||||
return;
|
||||
m_velocity = velocity;
|
||||
emit velocityChanged();
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setVelocity(m_velocity);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d SoundInstance::gain
|
||||
|
||||
This property holds the gain adjustment which will be used to modulate the audio ouput level
|
||||
from this SoundInstance.
|
||||
*/
|
||||
qreal QDeclarativeSoundInstance::gain() const
|
||||
{
|
||||
return m_gain;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setGain(qreal gain)
|
||||
{
|
||||
if (gain == m_gain)
|
||||
return;
|
||||
if (gain < 0) {
|
||||
qWarning("gain must be a positive value!");
|
||||
return;
|
||||
}
|
||||
m_gain = gain;
|
||||
emit gainChanged();
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setGain(m_gain);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty vector3d SoundInstance::gain
|
||||
|
||||
This property holds the pitch adjustment which will be used to modulate the audio pitch
|
||||
from this SoundInstance.
|
||||
*/
|
||||
qreal QDeclarativeSoundInstance::pitch() const
|
||||
{
|
||||
return m_pitch;
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setPitch(qreal pitch)
|
||||
{
|
||||
if (pitch == m_pitch)
|
||||
return;
|
||||
if (pitch < 0) {
|
||||
qWarning("pitch must be a positive value!");
|
||||
return;
|
||||
}
|
||||
m_pitch = pitch;
|
||||
emit pitchChanged();
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setPitch(m_pitch);
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setConeInnerAngle(qreal innerAngle)
|
||||
{
|
||||
if (m_coneInnerAngle == innerAngle)
|
||||
return;
|
||||
m_coneInnerAngle = innerAngle;
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setCone(m_coneInnerAngle, m_coneOuterAngle, m_coneOuterGain);
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setConeOuterAngle(qreal outerAngle)
|
||||
{
|
||||
if (m_coneOuterAngle == outerAngle)
|
||||
return;
|
||||
m_coneOuterAngle = outerAngle;
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setCone(m_coneInnerAngle, m_coneOuterAngle, m_coneOuterGain);
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::setConeOuterGain(qreal outerGain)
|
||||
{
|
||||
if (m_coneOuterGain == outerGain)
|
||||
return;
|
||||
m_coneOuterGain = outerGain;
|
||||
if (!m_instance)
|
||||
return;
|
||||
m_instance->setCone(m_coneInnerAngle, m_coneOuterAngle, m_coneOuterGain);
|
||||
}
|
||||
|
||||
void QDeclarativeSoundInstance::handleStateChanged()
|
||||
{
|
||||
emit stateChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onStateChanged(state)
|
||||
|
||||
This handler is called when \l state is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onPositionChanged()
|
||||
|
||||
This handler is called when \l position is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onDirectionChanged()
|
||||
|
||||
This handler is called when \l direction is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onVelocityChanged()
|
||||
|
||||
This handler is called when \l velocity is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onGainChanged()
|
||||
|
||||
This handler is called when \l gain is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onPitchChanged()
|
||||
|
||||
This handler is called when \l pitch is changed
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlsignal SoundInstance::onSoundChanged()
|
||||
|
||||
This handler is called when \l sound is changed
|
||||
*/
|
||||
155
src/imports/audioengine/qdeclarative_soundinstance_p.h
Normal file
155
src/imports/audioengine/qdeclarative_soundinstance_p.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QDECLARATIVE_SOUNDINSTANCE_P_H
|
||||
#define QDECLARATIVE_SOUNDINSTANCE_P_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/qvector3d.h>
|
||||
#include "qsoundinstance_p.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeSound;
|
||||
class QAudioEngine;
|
||||
class QDeclarativeAudioEngine;
|
||||
|
||||
class QDeclarativeSoundInstance : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QDeclarativeAudioEngine* engine READ engine WRITE setEngine)
|
||||
Q_PROPERTY(QString sound READ sound WRITE setSound NOTIFY soundChanged)
|
||||
Q_PROPERTY(State state READ state NOTIFY stateChanged)
|
||||
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||
Q_PROPERTY(QVector3D direction READ direction WRITE setDirection NOTIFY directionChanged)
|
||||
Q_PROPERTY(QVector3D velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
|
||||
Q_PROPERTY(qreal gain READ gain WRITE setGain NOTIFY gainChanged)
|
||||
Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged)
|
||||
|
||||
Q_ENUMS(State)
|
||||
|
||||
public:
|
||||
enum State
|
||||
{
|
||||
StopppedState = QSoundInstance::StopppedState,
|
||||
PlayingState = QSoundInstance::PlayingState,
|
||||
PausedState = QSoundInstance::PausedState
|
||||
};
|
||||
|
||||
QDeclarativeSoundInstance(QObject *parent = 0);
|
||||
~QDeclarativeSoundInstance();
|
||||
|
||||
QDeclarativeAudioEngine* engine() const;
|
||||
void setEngine(QDeclarativeAudioEngine *engine);
|
||||
|
||||
QString sound() const;
|
||||
void setSound(const QString& sound);
|
||||
|
||||
State state() const;
|
||||
|
||||
QVector3D position() const;
|
||||
void setPosition(const QVector3D& position);
|
||||
|
||||
QVector3D direction() const;
|
||||
void setDirection(const QVector3D& direction);
|
||||
|
||||
QVector3D velocity() const;
|
||||
void setVelocity(const QVector3D& velocity);
|
||||
|
||||
qreal gain() const;
|
||||
void setGain(qreal gain);
|
||||
|
||||
qreal pitch() const;
|
||||
void setPitch(qreal pitch);
|
||||
|
||||
void setConeInnerAngle(qreal innerAngle);
|
||||
void setConeOuterAngle(qreal outerAngle);
|
||||
void setConeOuterGain(qreal outerGain);
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged();
|
||||
void positionChanged();
|
||||
void directionChanged();
|
||||
void velocityChanged();
|
||||
void gainChanged();
|
||||
void pitchChanged();
|
||||
void soundChanged();
|
||||
|
||||
public Q_SLOTS:
|
||||
void play();
|
||||
void stop();
|
||||
void pause();
|
||||
void updatePosition(qreal deltaTime);
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleStateChanged();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QDeclarativeSoundInstance);
|
||||
QString m_sound;
|
||||
QVector3D m_position;
|
||||
QVector3D m_direction;
|
||||
QVector3D m_velocity;
|
||||
qreal m_gain;
|
||||
qreal m_pitch;
|
||||
State m_requestState;
|
||||
|
||||
qreal m_coneInnerAngle;
|
||||
qreal m_coneOuterAngle;
|
||||
qreal m_coneOuterGain;
|
||||
|
||||
void dropInstance();
|
||||
|
||||
QSoundInstance *m_instance;
|
||||
QDeclarativeAudioEngine *m_engine;
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void engineComplete();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
1
src/imports/audioengine/qmldir
Normal file
1
src/imports/audioengine/qmldir
Normal file
@@ -0,0 +1 @@
|
||||
plugin declarative_audioengine
|
||||
70
src/imports/audioengine/qsoundbuffer_p.h
Normal file
70
src/imports/audioengine/qsoundbuffer_p.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QSOUNDBUFFER_P_H
|
||||
#define QSOUNDBUFFER_P_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSoundBuffer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual bool isReady() const = 0;
|
||||
virtual void load() = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void ready();
|
||||
void error();
|
||||
|
||||
protected:
|
||||
QSoundBuffer(QObject *parent);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QSOUNDBUFFER_P_H
|
||||
387
src/imports/audioengine/qsoundinstance_p.cpp
Normal file
387
src/imports/audioengine/qsoundinstance_p.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qsoundinstance_p.h"
|
||||
#include "qsoundsource_p.h"
|
||||
#include "qsoundbuffer_p.h"
|
||||
#include "qdeclarative_sound_p.h"
|
||||
#include "qdeclarative_audiocategory_p.h"
|
||||
#include "qdeclarative_audiosample_p.h"
|
||||
#include "qdeclarative_attenuationmodel_p.h"
|
||||
#include "qdeclarative_playvariation_p.h"
|
||||
#include "qdeclarative_audioengine_p.h"
|
||||
#include "qdeclarative_audiolistener_p.h"
|
||||
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QSoundInstance::QSoundInstance(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_soundSource(0)
|
||||
, m_bindBuffer(0)
|
||||
, m_sound(0)
|
||||
, m_variationIndex(-1)
|
||||
, m_isReady(false)
|
||||
, m_gain(1)
|
||||
, m_attenuationGain(1)
|
||||
, m_varGain(1)
|
||||
, m_pitch(1)
|
||||
, m_varPitch(1)
|
||||
, m_state(QSoundInstance::StopppedState)
|
||||
, m_coneOuterGain(0)
|
||||
, m_engine(0)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "creating new QSoundInstance";
|
||||
#endif
|
||||
m_engine = qobject_cast<QDeclarativeAudioEngine*>(parent);
|
||||
}
|
||||
|
||||
void QSoundInstance::bindSoundDescription(QDeclarativeSound *sound)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance::bindSoundDescription" << sound;
|
||||
#endif
|
||||
if (m_sound == sound)
|
||||
return;
|
||||
|
||||
if (m_sound && m_sound->categoryObject()) {
|
||||
disconnect(m_sound->categoryObject(), SIGNAL(volumeChanged(qreal)), this, SLOT(categoryVolumeChanged()));
|
||||
disconnect(m_sound->categoryObject(), SIGNAL(paused()), this, SLOT(pause()));
|
||||
disconnect(m_sound->categoryObject(), SIGNAL(stopped()), this, SLOT(stop()));
|
||||
disconnect(m_sound->categoryObject(), SIGNAL(resumed()), this, SLOT(resume()));
|
||||
}
|
||||
m_attenuationGain = 1;
|
||||
m_gain = 1;
|
||||
|
||||
m_sound = sound;
|
||||
|
||||
if (sound) {
|
||||
if (!m_soundSource) {
|
||||
m_soundSource = m_engine->engine()->createSoundSource();
|
||||
connect(m_soundSource, SIGNAL(stateChanged(QSoundSource::State)),
|
||||
this, SLOT(handleSourceStateChanged(QSoundSource::State)));
|
||||
}
|
||||
} else {
|
||||
if (m_soundSource) {
|
||||
detach();
|
||||
m_engine->engine()->releaseSoundSource(m_soundSource);
|
||||
m_soundSource = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sound) {
|
||||
if (m_sound->categoryObject()) {
|
||||
connect(m_sound->categoryObject(), SIGNAL(volumeChanged(qreal)), this, SLOT(categoryVolumeChanged()));
|
||||
connect(m_sound->categoryObject(), SIGNAL(paused()), this, SLOT(pause()));
|
||||
connect(m_sound->categoryObject(), SIGNAL(stopped()), this, SLOT(stop()));
|
||||
connect(m_sound->categoryObject(), SIGNAL(resumed()), this, SLOT(resume()));
|
||||
}
|
||||
prepareNewVariation();
|
||||
} else {
|
||||
m_variationIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
QSoundInstance::~QSoundInstance()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance::dtor()";
|
||||
#endif
|
||||
if (m_soundSource) {
|
||||
detach();
|
||||
m_engine->engine()->releaseSoundSource(m_soundSource);
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundInstance::prepareNewVariation()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance::prepareNewVariation()";
|
||||
#endif
|
||||
int newVariationIndex = m_sound->genVariationIndex(m_variationIndex);
|
||||
if (newVariationIndex == m_variationIndex)
|
||||
return;
|
||||
QDeclarativePlayVariation *playVar = m_sound->getVariation(newVariationIndex);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance: generate new play variation [old:" << m_variationIndex << ", new:" << newVariationIndex << "-" << playVar->sample() << "]";
|
||||
#endif
|
||||
m_variationIndex = newVariationIndex;
|
||||
playVar->applyParameters(this);
|
||||
detach();
|
||||
|
||||
m_bindBuffer = playVar->sampleObject()->soundBuffer();
|
||||
if (m_bindBuffer->isReady()) {
|
||||
Q_ASSERT(m_soundSource);
|
||||
m_soundSource->bindBuffer(m_bindBuffer);
|
||||
m_isReady = true;
|
||||
} else {
|
||||
m_bindBuffer->load();
|
||||
connect(m_bindBuffer, SIGNAL(ready()), this, SLOT(bufferReady()));
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundInstance::bufferReady()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance::bufferReady()";
|
||||
#endif
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->bindBuffer(m_bindBuffer);
|
||||
disconnect(m_bindBuffer, SIGNAL(ready()), this, SLOT(bufferReady()));
|
||||
m_isReady = true;
|
||||
|
||||
if (m_state == QSoundInstance::PlayingState) {
|
||||
sourcePlay();
|
||||
} else if (m_state == QSoundInstance::PausedState) {
|
||||
sourcePause();
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundInstance::categoryVolumeChanged()
|
||||
{
|
||||
updateGain();
|
||||
}
|
||||
|
||||
void QSoundInstance::handleSourceStateChanged(QSoundSource::State newState)
|
||||
{
|
||||
State ns = State(newState);
|
||||
if (ns == m_state)
|
||||
return;
|
||||
if (ns == QSoundInstance::StopppedState) {
|
||||
prepareNewVariation();
|
||||
}
|
||||
setState(ns);
|
||||
}
|
||||
|
||||
void QSoundInstance::setState(State state)
|
||||
{
|
||||
if (state == m_state)
|
||||
return;
|
||||
m_state = state;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
qreal QSoundInstance::categoryVolume() const
|
||||
{
|
||||
if (!m_sound)
|
||||
return 1;
|
||||
if (!m_sound->categoryObject())
|
||||
return 1;
|
||||
return m_sound->categoryObject()->volume();
|
||||
}
|
||||
|
||||
void QSoundInstance::sourceStop()
|
||||
{
|
||||
Q_ASSERT(m_soundSource);
|
||||
m_soundSource->stop();
|
||||
setState(QSoundInstance::StopppedState);
|
||||
}
|
||||
|
||||
void QSoundInstance::detach()
|
||||
{
|
||||
sourceStop();
|
||||
m_isReady = false;
|
||||
if (m_soundSource)
|
||||
m_soundSource->unbindBuffer();
|
||||
if (m_bindBuffer) {
|
||||
disconnect(m_bindBuffer, SIGNAL(ready()), this, SLOT(bufferReady()));
|
||||
m_engine->engine()->releaseSoundBuffer(m_bindBuffer);
|
||||
m_bindBuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundInstance::play()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstancePrivate::play()";
|
||||
#endif
|
||||
if (!m_soundSource || m_state == QSoundInstance::PlayingState)
|
||||
return;
|
||||
if (!m_isReady) {
|
||||
setState(QSoundInstance::PlayingState);
|
||||
return;
|
||||
}
|
||||
sourcePlay();
|
||||
setState(QSoundInstance::PlayingState);
|
||||
}
|
||||
|
||||
void QSoundInstance::sourcePlay()
|
||||
{
|
||||
update3DVolume(m_engine->listener()->position());
|
||||
Q_ASSERT(m_soundSource);
|
||||
m_soundSource->play();
|
||||
}
|
||||
|
||||
void QSoundInstance::resume()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstancePrivate::resume()";
|
||||
#endif
|
||||
if (m_state != QSoundInstance::PausedState)
|
||||
return;
|
||||
play();
|
||||
}
|
||||
|
||||
void QSoundInstance::pause()
|
||||
{
|
||||
if (!m_soundSource || m_state == QSoundInstance::PausedState)
|
||||
return;
|
||||
if (!m_isReady) {
|
||||
setState(QSoundInstance::PausedState);
|
||||
return;
|
||||
}
|
||||
sourcePause();
|
||||
setState(QSoundInstance::PausedState);
|
||||
}
|
||||
|
||||
void QSoundInstance::sourcePause()
|
||||
{
|
||||
Q_ASSERT(m_soundSource);
|
||||
m_soundSource->pause();
|
||||
}
|
||||
|
||||
void QSoundInstance::stop()
|
||||
{
|
||||
if (!m_isReady || !m_soundSource || m_state == QSoundInstance::StopppedState) {
|
||||
setState(QSoundInstance::StopppedState);
|
||||
return;
|
||||
}
|
||||
sourceStop();
|
||||
prepareNewVariation();
|
||||
}
|
||||
|
||||
QSoundInstance::State QSoundInstance::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void QSoundInstance::setPosition(const QVector3D& position)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->setPosition(position);
|
||||
}
|
||||
|
||||
void QSoundInstance::setDirection(const QVector3D& direction)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->setDirection(direction);
|
||||
}
|
||||
|
||||
void QSoundInstance::setVelocity(const QVector3D& velocity)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->setVelocity(velocity);
|
||||
}
|
||||
|
||||
void QSoundInstance::setGain(qreal gain)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_gain = gain;
|
||||
updateGain();
|
||||
}
|
||||
|
||||
void QSoundInstance::setPitch(qreal pitch)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_pitch = pitch;
|
||||
updatePitch();
|
||||
}
|
||||
|
||||
void QSoundInstance::setCone(qreal innerAngle, qreal outerAngle, qreal outerGain)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->setCone(innerAngle, outerAngle, outerGain);
|
||||
}
|
||||
|
||||
bool QSoundInstance::attenuationEnabled() const
|
||||
{
|
||||
if (!m_sound || !m_sound->attenuationModelObject())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QSoundInstance::update3DVolume(const QVector3D& listenerPosition)
|
||||
{
|
||||
if (!m_sound || !m_soundSource)
|
||||
return;
|
||||
QDeclarativeAttenuationModel *attenModel = m_sound->attenuationModelObject();
|
||||
if (!attenModel)
|
||||
return;
|
||||
m_attenuationGain = attenModel->calculateGain(listenerPosition, m_soundSource->position());
|
||||
updateGain();
|
||||
}
|
||||
|
||||
void QSoundInstance::updateVariationParameters(qreal varPitch, qreal varGain, bool looping)
|
||||
{
|
||||
if (!m_soundSource)
|
||||
return;
|
||||
m_soundSource->setLooping(looping);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundInstance::updateVariationParameters" << varPitch << varGain << looping;
|
||||
#endif
|
||||
m_varPitch = varPitch;
|
||||
m_varGain = varGain;
|
||||
updatePitch();
|
||||
updateGain();
|
||||
}
|
||||
|
||||
void QSoundInstance::updatePitch()
|
||||
{
|
||||
m_soundSource->setPitch(m_pitch * m_varPitch);
|
||||
}
|
||||
|
||||
void QSoundInstance::updateGain()
|
||||
{
|
||||
m_soundSource->setGain(m_gain * m_varGain * m_attenuationGain * categoryVolume());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
139
src/imports/audioengine/qsoundinstance_p.h
Normal file
139
src/imports/audioengine/qsoundinstance_p.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QSOUNDINSTANCE_P_H
|
||||
#define QSOUNDINSTANCE_P_H
|
||||
|
||||
#include <QVector3D>
|
||||
#include <QObject>
|
||||
#include "qsoundsource_p.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDeclarativeSound;
|
||||
class QDeclarativeAudioEngine;
|
||||
|
||||
class QSoundInstance : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QSoundInstance(QObject *parent);
|
||||
~QSoundInstance();
|
||||
|
||||
void play();
|
||||
|
||||
enum State
|
||||
{
|
||||
StopppedState = QSoundSource::StoppedState,
|
||||
PlayingState = QSoundSource::PlayingState,
|
||||
PausedState = QSoundSource::PausedState
|
||||
};
|
||||
State state() const;
|
||||
|
||||
void setPosition(const QVector3D& position);
|
||||
void setDirection(const QVector3D& direction);
|
||||
void setVelocity(const QVector3D& velocity);
|
||||
|
||||
//this gain and pitch is used for dynamic user control during execution
|
||||
void setGain(qreal gain);
|
||||
void setPitch(qreal pitch);
|
||||
void setCone(qreal innerAngle, qreal outerAngle, qreal outerGain);
|
||||
|
||||
//this varPitch and varGain is calculated from config in PlayVariation
|
||||
void updateVariationParameters(qreal varPitch, qreal varGain, bool looping);
|
||||
|
||||
void bindSoundDescription(QDeclarativeSound *sound);
|
||||
|
||||
void update3DVolume(const QVector3D& listenerPosition);
|
||||
|
||||
bool attenuationEnabled() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged(QSoundInstance::State state);
|
||||
|
||||
public Q_SLOTS:
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
private Q_SLOTS:
|
||||
void resume();
|
||||
void bufferReady();
|
||||
void categoryVolumeChanged();
|
||||
void handleSourceStateChanged(QSoundSource::State);
|
||||
|
||||
private:
|
||||
void setState(State state);
|
||||
void prepareNewVariation();
|
||||
void detach();
|
||||
qreal categoryVolume() const;
|
||||
void updatePitch();
|
||||
void updateGain();
|
||||
void updateConeOuterGain();
|
||||
|
||||
void sourcePlay();
|
||||
void sourcePause();
|
||||
void sourceStop();
|
||||
|
||||
QSoundSource *m_soundSource;
|
||||
QSoundBuffer *m_bindBuffer;
|
||||
|
||||
QDeclarativeSound *m_sound;
|
||||
int m_variationIndex;
|
||||
|
||||
bool m_isReady; //true if the sound source is already bound to some sound buffer
|
||||
qreal m_gain;
|
||||
qreal m_attenuationGain;
|
||||
qreal m_varGain;
|
||||
qreal m_pitch;
|
||||
qreal m_varPitch;
|
||||
State m_state;
|
||||
qreal m_coneOuterGain;
|
||||
|
||||
QDeclarativeAudioEngine *m_engine;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QSOUNDINSTANCE_P_H
|
||||
314
src/imports/audioengine/qsoundsource_openal_p.cpp
Normal file
314
src/imports/audioengine/qsoundsource_openal_p.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 "qaudioengine_openal_p.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#define DEBUG_AUDIOENGINE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QSoundSourcePrivate::QSoundSourcePrivate(QObject *parent)
|
||||
: QSoundSource(parent)
|
||||
, m_alSource(0)
|
||||
, m_bindBuffer(0)
|
||||
, m_isReady(false)
|
||||
, m_state(QSoundSource::StoppedState)
|
||||
, m_gain(0)
|
||||
, m_pitch(0)
|
||||
, m_coneInnerAngle(0)
|
||||
, m_coneOuterAngle(0)
|
||||
, m_coneOuterGain(1)
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "creating new QSoundSourcePrivate";
|
||||
#endif
|
||||
alGenSources(1, &m_alSource);
|
||||
QAudioEnginePrivate::checkNoError("create source");
|
||||
setGain(1);
|
||||
setPitch(1);
|
||||
setCone(360, 360, 0);
|
||||
}
|
||||
|
||||
QSoundSourcePrivate::~QSoundSourcePrivate()
|
||||
{
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundSourcePrivate::dtor";
|
||||
#endif
|
||||
release();
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::release()
|
||||
{
|
||||
if (m_alSource) {
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
qDebug() << "QSoundSourcePrivate::release";
|
||||
#endif
|
||||
stop();
|
||||
unbindBuffer();
|
||||
alDeleteSources(1, &m_alSource);
|
||||
QAudioEnginePrivate::checkNoError("delete source");
|
||||
m_alSource = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::bindBuffer(QSoundBuffer* soundBuffer)
|
||||
{
|
||||
unbindBuffer();
|
||||
Q_ASSERT(soundBuffer->isReady());
|
||||
m_bindBuffer = qobject_cast<QSoundBufferPrivateAL*>(soundBuffer);
|
||||
m_bindBuffer->bindToSource(m_alSource);
|
||||
m_isReady = true;
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::unbindBuffer()
|
||||
{
|
||||
if (m_bindBuffer) {
|
||||
m_bindBuffer->unbindFromSource(m_alSource);
|
||||
m_bindBuffer = 0;
|
||||
}
|
||||
m_isReady = false;
|
||||
if (m_state != QSoundSource::StoppedState) {
|
||||
m_state = QSoundSource::StoppedState;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::play()
|
||||
{
|
||||
if (!m_alSource || !m_isReady)
|
||||
return;
|
||||
alSourcePlay(m_alSource);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("play");
|
||||
#endif
|
||||
emit activate(this);
|
||||
}
|
||||
|
||||
bool QSoundSourcePrivate::isLooping() const
|
||||
{
|
||||
if (!m_alSource)
|
||||
return false;
|
||||
ALint looping = 0;
|
||||
alGetSourcei(m_alSource, AL_LOOPING, &looping);
|
||||
return looping == AL_TRUE ? true : false;
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::pause()
|
||||
{
|
||||
if (!m_alSource || !m_isReady)
|
||||
return;
|
||||
alSourcePause(m_alSource);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("pause");
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::stop()
|
||||
{
|
||||
if (!m_alSource)
|
||||
return;
|
||||
alSourceStop(m_alSource);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("stop");
|
||||
#endif
|
||||
}
|
||||
|
||||
QSoundSource::State QSoundSourcePrivate::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::checkState()
|
||||
{
|
||||
QSoundSource::State st;
|
||||
st = QSoundSource::StoppedState;
|
||||
if (m_alSource && m_isReady) {
|
||||
ALint s;
|
||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &s);
|
||||
switch (s) {
|
||||
case AL_PLAYING:
|
||||
st = QSoundSource::PlayingState;
|
||||
break;
|
||||
case AL_PAUSED:
|
||||
st = QSoundSource::PausedState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (st == m_state)
|
||||
return;
|
||||
m_state = st;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setLooping(bool looping)
|
||||
{
|
||||
if (!m_alSource)
|
||||
return;
|
||||
alSourcei(m_alSource, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setPosition(const QVector3D& position)
|
||||
{
|
||||
if (!m_alSource)
|
||||
return;
|
||||
alSource3f(m_alSource, AL_POSITION, position.x(), position.y(), position.z());
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set position");
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setDirection(const QVector3D& direction)
|
||||
{
|
||||
if (!m_alSource)
|
||||
return;
|
||||
alSource3f(m_alSource, AL_DIRECTION, direction.x(), direction.y(), direction.z());
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set direction");
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setVelocity(const QVector3D& velocity)
|
||||
{
|
||||
if (!m_alSource)
|
||||
return;
|
||||
alSource3f(m_alSource, AL_VELOCITY, velocity.x(), velocity.y(), velocity.z());
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set velocity");
|
||||
#endif
|
||||
}
|
||||
|
||||
QVector3D QSoundSourcePrivate::velocity() const
|
||||
{
|
||||
if (!m_alSource)
|
||||
return QVector3D(0, 0, 0);
|
||||
ALfloat x, y, z;
|
||||
alGetSource3f(m_alSource, AL_VELOCITY, &x, &y, &z);
|
||||
return QVector3D(x, y, z);
|
||||
}
|
||||
|
||||
QVector3D QSoundSourcePrivate::position() const
|
||||
{
|
||||
if (!m_alSource)
|
||||
return QVector3D(0, 0, 0);
|
||||
ALfloat x, y, z;
|
||||
alGetSource3f(m_alSource, AL_POSITION, &x, &y, &z);
|
||||
return QVector3D(x, y, z);
|
||||
}
|
||||
|
||||
QVector3D QSoundSourcePrivate::direction() const
|
||||
{
|
||||
if (!m_alSource)
|
||||
return QVector3D(0, 1, 0);
|
||||
ALfloat x, y, z;
|
||||
alGetSource3f(m_alSource, AL_DIRECTION, &x, &y, &z);
|
||||
return QVector3D(x, y, z);
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setGain(qreal gain)
|
||||
{
|
||||
if (!m_alSource || gain == m_gain)
|
||||
return;
|
||||
alSourcef(m_alSource, AL_GAIN, gain);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set gain");
|
||||
#endif
|
||||
m_gain = gain;
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setPitch(qreal pitch)
|
||||
{
|
||||
if (!m_alSource || m_pitch == pitch)
|
||||
return;
|
||||
alSourcef(m_alSource, AL_PITCH, pitch);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set pitch");
|
||||
#endif
|
||||
m_pitch = pitch;
|
||||
}
|
||||
|
||||
void QSoundSourcePrivate::setCone(qreal innerAngle, qreal outerAngle, qreal outerGain)
|
||||
{
|
||||
if (innerAngle > outerAngle)
|
||||
outerAngle = innerAngle;
|
||||
Q_ASSERT(outerAngle <= 360 && innerAngle >= 0);
|
||||
|
||||
//make sure the setting order will always keep outerAngle >= innerAngle in openAL
|
||||
if (outerAngle >= m_coneInnerAngle) {
|
||||
if (m_coneOuterAngle != outerAngle) {
|
||||
alSourcef(m_alSource, AL_CONE_OUTER_ANGLE, outerAngle);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set cone outerAngle");
|
||||
#endif
|
||||
m_coneOuterAngle = outerAngle;
|
||||
}
|
||||
if (m_coneInnerAngle != innerAngle) {
|
||||
alSourcef(m_alSource, AL_CONE_INNER_ANGLE, innerAngle);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set cone innerAngle");
|
||||
#endif
|
||||
m_coneInnerAngle = innerAngle;
|
||||
}
|
||||
} else {
|
||||
if (m_coneInnerAngle != innerAngle) {
|
||||
alSourcef(m_alSource, AL_CONE_INNER_ANGLE, innerAngle);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set cone innerAngle");
|
||||
#endif
|
||||
m_coneInnerAngle = innerAngle;
|
||||
}
|
||||
if (m_coneOuterAngle != outerAngle) {
|
||||
alSourcef(m_alSource, AL_CONE_OUTER_ANGLE, outerAngle);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set cone outerAngle");
|
||||
#endif
|
||||
m_coneOuterAngle = outerAngle;
|
||||
}
|
||||
}
|
||||
|
||||
if (outerGain != m_coneOuterGain) {
|
||||
alSourcef(m_alSource, AL_CONE_OUTER_GAIN, outerGain);
|
||||
#ifdef DEBUG_AUDIOENGINE
|
||||
QAudioEnginePrivate::checkNoError("source set cone outerGain");
|
||||
#endif
|
||||
m_coneOuterGain = outerGain;
|
||||
}
|
||||
}
|
||||
98
src/imports/audioengine/qsoundsource_p.h
Normal file
98
src/imports/audioengine/qsoundsource_p.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins 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 QSOUNDSOURCE_P_H
|
||||
#define QSOUNDSOURCE_P_H
|
||||
|
||||
#include <QVector3D>
|
||||
#include <QObject>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSoundBuffer;
|
||||
|
||||
class QSoundSource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State
|
||||
{
|
||||
StoppedState,
|
||||
PlayingState,
|
||||
PausedState
|
||||
};
|
||||
|
||||
virtual void play() = 0;
|
||||
virtual void pause() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
virtual QSoundSource::State state() const = 0;
|
||||
|
||||
virtual void setLooping(bool looping) = 0;
|
||||
virtual void setDirection(const QVector3D& direction) = 0;
|
||||
virtual void setPosition(const QVector3D& position) = 0;
|
||||
virtual void setVelocity(const QVector3D& velocity) = 0;
|
||||
|
||||
virtual QVector3D velocity() const = 0;
|
||||
virtual QVector3D position() const = 0;
|
||||
virtual QVector3D direction() const = 0;
|
||||
|
||||
virtual void setGain(qreal gain) = 0;
|
||||
virtual void setPitch(qreal pitch) = 0;
|
||||
virtual void setCone(qreal innerAngle, qreal outerAngle, qreal outerGain) = 0;
|
||||
|
||||
virtual void bindBuffer(QSoundBuffer*) = 0;
|
||||
virtual void unbindBuffer() = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged(QSoundSource::State newState);
|
||||
|
||||
protected:
|
||||
QSoundSource(QObject *parent);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += multimedia
|
||||
contains(config_test_openal, yes): SUBDIRS += audioengine
|
||||
|
||||
|
||||
@@ -93,13 +93,17 @@ QT_BEGIN_NAMESPACE
|
||||
\endcode
|
||||
*/
|
||||
|
||||
QSampleCache::QSampleCache()
|
||||
: m_networkAccessManager(0)
|
||||
QSampleCache::QSampleCache(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_networkAccessManager(0)
|
||||
, m_mutex(QMutex::Recursive)
|
||||
, m_capacity(0)
|
||||
, m_usage(0)
|
||||
, m_loadingRefCount(0)
|
||||
{
|
||||
m_loadingThread.setObjectName(QLatin1String("QSampleCache::LoadingThread"));
|
||||
connect(&m_loadingThread, SIGNAL(finished()), this, SIGNAL(isLoadingChanged()));
|
||||
connect(&m_loadingThread, SIGNAL(started()), this, SIGNAL(isLoadingChanged()));
|
||||
}
|
||||
|
||||
QNetworkAccessManager& QSampleCache::networkAccessManager()
|
||||
@@ -128,10 +132,31 @@ QSampleCache::~QSampleCache()
|
||||
delete m_networkAccessManager;
|
||||
}
|
||||
|
||||
void QSampleCache::loadingRelease()
|
||||
{
|
||||
QMutexLocker locker(&m_loadingMutex);
|
||||
m_loadingRefCount--;
|
||||
if (m_loadingRefCount == 0) {
|
||||
if (m_loadingThread.isRunning())
|
||||
m_loadingThread.exit();
|
||||
}
|
||||
}
|
||||
|
||||
bool QSampleCache::isLoading() const
|
||||
{
|
||||
return m_loadingThread.isRunning();
|
||||
}
|
||||
|
||||
QSample* QSampleCache::requestSample(const QUrl& url)
|
||||
{
|
||||
//lock and add first to make sure live loadingThread will not be killed during this function call
|
||||
m_loadingMutex.lock();
|
||||
m_loadingRefCount++;
|
||||
m_loadingMutex.unlock();
|
||||
|
||||
if (!m_loadingThread.isRunning())
|
||||
m_loadingThread.start();
|
||||
|
||||
#ifdef QT_SAMPLECACHE_DEBUG
|
||||
qDebug() << "QSampleCache: request sample [" << url << "]";
|
||||
#endif
|
||||
@@ -250,6 +275,8 @@ void QSample::loadIfNecessary()
|
||||
if (m_state == QSample::Error || m_state == QSample::Creating) {
|
||||
m_state = QSample::Loading;
|
||||
QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
|
||||
} else {
|
||||
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +394,7 @@ void QSample::decoderError()
|
||||
#endif
|
||||
cleanup();
|
||||
m_state = QSample::Error;
|
||||
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||
emit error();
|
||||
}
|
||||
|
||||
@@ -380,6 +408,7 @@ void QSample::onReady()
|
||||
m_audioFormat = m_waveDecoder->audioFormat();
|
||||
cleanup();
|
||||
m_state = QSample::Ready;
|
||||
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||
emit ready();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class QSampleCache;
|
||||
class QWaveDecoder;
|
||||
|
||||
// Lives in application thread
|
||||
class QSample : public QObject
|
||||
class Q_MULTIMEDIA_EXPORT QSample : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -127,17 +127,23 @@ private:
|
||||
int m_ref;
|
||||
};
|
||||
|
||||
class QSampleCache
|
||||
class Q_MULTIMEDIA_EXPORT QSampleCache : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend class QSample;
|
||||
|
||||
QSampleCache();
|
||||
QSampleCache(QObject *parent = 0);
|
||||
~QSampleCache();
|
||||
|
||||
QSample* requestSample(const QUrl& url);
|
||||
void setCapacity(qint64 capacity);
|
||||
|
||||
bool isLoading() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void isLoadingChanged();
|
||||
|
||||
private:
|
||||
QMap<QUrl, QSample*> m_samples;
|
||||
QSet<QSample*> m_staleSamples;
|
||||
@@ -152,6 +158,10 @@ private:
|
||||
bool notifyUnreferencedSample(QSample* sample);
|
||||
void removeUnreferencedSample(QSample* sample);
|
||||
void unloadSample(QSample* sample);
|
||||
|
||||
void loadingRelease();
|
||||
int m_loadingRefCount;
|
||||
QMutex m_loadingMutex;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -52,4 +52,6 @@
|
||||
"pulseaudio" => {},
|
||||
"resourcepolicy" => {},
|
||||
"xvideo" => {},
|
||||
|
||||
"openal" => {},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user