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
|
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
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += multimedia
|
SUBDIRS += multimedia
|
||||||
|
contains(config_test_openal, yes): SUBDIRS += audioengine
|
||||||
|
|
||||||
|
|||||||
@@ -93,13 +93,17 @@ QT_BEGIN_NAMESPACE
|
|||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QSampleCache::QSampleCache()
|
QSampleCache::QSampleCache(QObject *parent)
|
||||||
: m_networkAccessManager(0)
|
: QObject(parent)
|
||||||
|
, m_networkAccessManager(0)
|
||||||
, m_mutex(QMutex::Recursive)
|
, m_mutex(QMutex::Recursive)
|
||||||
, m_capacity(0)
|
, m_capacity(0)
|
||||||
, m_usage(0)
|
, m_usage(0)
|
||||||
|
, m_loadingRefCount(0)
|
||||||
{
|
{
|
||||||
m_loadingThread.setObjectName(QLatin1String("QSampleCache::LoadingThread"));
|
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()
|
QNetworkAccessManager& QSampleCache::networkAccessManager()
|
||||||
@@ -128,10 +132,31 @@ QSampleCache::~QSampleCache()
|
|||||||
delete m_networkAccessManager;
|
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)
|
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())
|
if (!m_loadingThread.isRunning())
|
||||||
m_loadingThread.start();
|
m_loadingThread.start();
|
||||||
|
|
||||||
#ifdef QT_SAMPLECACHE_DEBUG
|
#ifdef QT_SAMPLECACHE_DEBUG
|
||||||
qDebug() << "QSampleCache: request sample [" << url << "]";
|
qDebug() << "QSampleCache: request sample [" << url << "]";
|
||||||
#endif
|
#endif
|
||||||
@@ -250,6 +275,8 @@ void QSample::loadIfNecessary()
|
|||||||
if (m_state == QSample::Error || m_state == QSample::Creating) {
|
if (m_state == QSample::Error || m_state == QSample::Creating) {
|
||||||
m_state = QSample::Loading;
|
m_state = QSample::Loading;
|
||||||
QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
|
||||||
|
} else {
|
||||||
|
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,6 +394,7 @@ void QSample::decoderError()
|
|||||||
#endif
|
#endif
|
||||||
cleanup();
|
cleanup();
|
||||||
m_state = QSample::Error;
|
m_state = QSample::Error;
|
||||||
|
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||||
emit error();
|
emit error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +408,7 @@ void QSample::onReady()
|
|||||||
m_audioFormat = m_waveDecoder->audioFormat();
|
m_audioFormat = m_waveDecoder->audioFormat();
|
||||||
cleanup();
|
cleanup();
|
||||||
m_state = QSample::Ready;
|
m_state = QSample::Ready;
|
||||||
|
qobject_cast<QSampleCache*>(m_parent)->loadingRelease();
|
||||||
emit ready();
|
emit ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class QSampleCache;
|
|||||||
class QWaveDecoder;
|
class QWaveDecoder;
|
||||||
|
|
||||||
// Lives in application thread
|
// Lives in application thread
|
||||||
class QSample : public QObject
|
class Q_MULTIMEDIA_EXPORT QSample : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -127,17 +127,23 @@ private:
|
|||||||
int m_ref;
|
int m_ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSampleCache
|
class Q_MULTIMEDIA_EXPORT QSampleCache : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
friend class QSample;
|
friend class QSample;
|
||||||
|
|
||||||
QSampleCache();
|
QSampleCache(QObject *parent = 0);
|
||||||
~QSampleCache();
|
~QSampleCache();
|
||||||
|
|
||||||
QSample* requestSample(const QUrl& url);
|
QSample* requestSample(const QUrl& url);
|
||||||
void setCapacity(qint64 capacity);
|
void setCapacity(qint64 capacity);
|
||||||
|
|
||||||
|
bool isLoading() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void isLoadingChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QUrl, QSample*> m_samples;
|
QMap<QUrl, QSample*> m_samples;
|
||||||
QSet<QSample*> m_staleSamples;
|
QSet<QSample*> m_staleSamples;
|
||||||
@@ -152,6 +158,10 @@ private:
|
|||||||
bool notifyUnreferencedSample(QSample* sample);
|
bool notifyUnreferencedSample(QSample* sample);
|
||||||
void removeUnreferencedSample(QSample* sample);
|
void removeUnreferencedSample(QSample* sample);
|
||||||
void unloadSample(QSample* sample);
|
void unloadSample(QSample* sample);
|
||||||
|
|
||||||
|
void loadingRelease();
|
||||||
|
int m_loadingRefCount;
|
||||||
|
QMutex m_loadingMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -52,4 +52,6 @@
|
|||||||
"pulseaudio" => {},
|
"pulseaudio" => {},
|
||||||
"resourcepolicy" => {},
|
"resourcepolicy" => {},
|
||||||
"xvideo" => {},
|
"xvideo" => {},
|
||||||
|
|
||||||
|
"openal" => {},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user