summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTitta Heikkala <titta.heikkala@theqtcompany.com>2015-11-06 10:57:30 +0200
committerSean Harmer <sean.harmer@kdab.com>2016-01-22 09:52:16 +0000
commita203ce0742105557a7e4641f6a37e462f231d0b0 (patch)
treec7db18c9c4017af908f2ed3b1ff4a2402cdfd6e9
parent44c743c90cf51eddbf5b0bb3cf957c58fa0ef94f (diff)
Added Audio Visualizer example
Example visualizes the magnitude of music played as animated bars. The music is played using media player. Implementation combines the use of Qt 3D rendering with Qt Quick 2D elements. Change-Id: I945d50d0dbd26151f274269649cca793a5ad4d27 Reviewed-by: Tomi Korpipää <tomi.korpipaa@theqtcompany.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@theqtcompany.com> Reviewed-by: Pasi Keränen <pasi.keranen@theqtcompany.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--examples/qt3d/audio-visualizer-qml/BarEntity.qml187
-rw-r--r--examples/qt3d/audio-visualizer-qml/Visualizer.qml294
-rw-r--r--examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.pro20
-rw-r--r--examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.qrc22
-rw-r--r--examples/qt3d/audio-visualizer-qml/doc/src/audio-visualizer-qml.qdoc97
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/albumcover.pngbin0 -> 627138 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/demotitle.pngbin0 -> 20912 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/normalmap.pngbin0 -> 533 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/pausehoverpressed.pngbin0 -> 2017 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/pausenormal.pngbin0 -> 1948 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/playhoverpressed.pngbin0 -> 2243 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/playnormal.pngbin0 -> 2172 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/songtitle.pngbin0 -> 7438 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/stopdisabled.pngbin0 -> 1938 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/stophoverpressed.pngbin0 -> 2013 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/images/stopnormal.pngbin0 -> 1939 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/main.cpp80
-rw-r--r--examples/qt3d/audio-visualizer-qml/main.qml280
-rw-r--r--examples/qt3d/audio-visualizer-qml/meshes/circle.obj72
-rw-r--r--examples/qt3d/audio-visualizer-qml/meshes/progressbar.obj478
-rw-r--r--examples/qt3d/audio-visualizer-qml/music/tiltshifted_lost_neon_sun.mp3bin0 -> 1014097 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/music/visualization.rawbin0 -> 3178 bytes
-rw-r--r--examples/qt3d/audio-visualizer-qml/touchsettings.cpp64
-rw-r--r--examples/qt3d/audio-visualizer-qml/touchsettings.h52
-rw-r--r--examples/qt3d/qt3d.pro2
-rw-r--r--src/doc/qt3d.qdocconf3
26 files changed, 1650 insertions, 1 deletions
diff --git a/examples/qt3d/audio-visualizer-qml/BarEntity.qml b/examples/qt3d/audio-visualizer-qml/BarEntity.qml
new file mode 100644
index 000000000..b9c8857ae
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/BarEntity.qml
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import QtQuick 2.4 as QQ2
+
+Entity {
+ property int rotationTimeMs: 0
+ property int entityIndex: 0
+ property int entityCount: 0
+ property int startAngle: 0 + 360 / entityCount * entityIndex
+ property bool needsNewMagnitude: true
+ property real magnitude: 0
+ property real animWeight: 0
+
+ property color lowColor: "black"
+ property color highColor: "#b3b3b3"
+ property color barColor: lowColor
+
+ property string entityAnimationsState: "stopped"
+ property bool entityAnimationsPlaying: true
+
+ property var entityMesh: null
+
+ onEntityAnimationsStateChanged: {
+ if (animationState == "paused") {
+ if (angleAnimation.running)
+ angleAnimation.pause()
+ if (barColorAnimations.running)
+ barColorAnimations.pause()
+ } else if (animationState == "playing"){
+ needsNewMagnitude = true;
+ if (heightDecreaseAnimation.running)
+ heightDecreaseAnimation.stop()
+ if (angleAnimation.paused) {
+ angleAnimation.resume()
+ } else if (!entityAnimationsPlaying) {
+ magnitude = 0
+ angleAnimation.start()
+ entityAnimationsPlaying = true
+ }
+ if (barColorAnimations.paused)
+ barColorAnimations.resume()
+ } else {
+ if (animWeight != 0)
+ heightDecreaseAnimation.start()
+ needsNewMagnitude = true
+ angleAnimation.stop()
+ barColorAnimations.stop()
+ entityAnimationsPlaying = false
+ }
+ }
+
+ property Material barMaterial: PhongMaterial {
+ diffuse: barColor
+ ambient: Qt.darker(barColor)
+ specular: "black"
+ shininess: 1
+ }
+
+ property Transform angleTransform: Transform {
+ property real heightIncrease: magnitude * animWeight
+ property real barAngle: startAngle
+
+ matrix: {
+ var m = Qt.matrix4x4()
+ m.rotate(barAngle, Qt.vector3d(0, 1, 0))
+ m.translate(Qt.vector3d(1.1, heightIncrease / 2 - heightIncrease * 0.05, 0))
+ m.scale(Qt.vector3d(0.5, heightIncrease * 15, 0.5))
+ return m;
+ }
+
+ property real compareAngle: barAngle
+ onBarAngleChanged: {
+ compareAngle = barAngle
+
+ if (compareAngle > 360)
+ compareAngle = barAngle - 360
+
+ if (compareAngle > 180) {
+ parent.enabled = false
+ animWeight = 0
+ if (needsNewMagnitude) {
+ // Calculate the ms offset where the bar will be at the center point of the
+ // visualization and fetch the correct magnitude for that point in time.
+ var offset = (90.0 + 360.0 - compareAngle) * (rotationTimeMs / 360.0)
+ magnitude = mediaPlayer.getNextAudioLevel(offset)
+ needsNewMagnitude = false
+ }
+ } else {
+ parent.enabled = true
+ // Calculate a power of 2 curve for the bar animation that peaks at 90 degrees
+ animWeight = Math.min((compareAngle / 90), (180 - compareAngle) / 90)
+ animWeight = animWeight * animWeight
+ if (!needsNewMagnitude) {
+ needsNewMagnitude = true
+ barColorAnimations.start()
+ }
+ }
+ }
+ }
+
+ components: [entityMesh, barMaterial, angleTransform]
+
+ //![0]
+ QQ2.NumberAnimation {
+ id: angleAnimation
+ target: angleTransform
+ property: "barAngle"
+ duration: rotationTimeMs
+ loops: QQ2.Animation.Infinite
+ running: true
+ from: startAngle
+ to: 360 + startAngle
+ }
+ //![0]
+
+ QQ2.NumberAnimation {
+ id: heightDecreaseAnimation
+ target: angleTransform
+ property: "heightIncrease"
+ duration: 400
+ running: false
+ from: angleTransform.heightIncrease
+ to: 0
+ onStopped: barColor = lowColor
+ }
+
+ property int animationDuration: angleAnimation.duration / 6
+
+ //![1]
+ QQ2.SequentialAnimation on barColor {
+ id: barColorAnimations
+ running: false
+
+ QQ2.ColorAnimation {
+ from: lowColor
+ to: highColor
+ duration: animationDuration
+ }
+
+ QQ2.PauseAnimation {
+ duration: animationDuration
+ }
+
+ QQ2.ColorAnimation {
+ from: highColor
+ to: lowColor
+ duration: animationDuration
+ }
+ }
+ //![1]
+}
diff --git a/examples/qt3d/audio-visualizer-qml/Visualizer.qml b/examples/qt3d/audio-visualizer-qml/Visualizer.qml
new file mode 100644
index 000000000..26bb48fc9
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/Visualizer.qml
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import QtQuick 2.2 as QQ2
+
+Entity {
+ id: sceneRoot
+ property int barRotationTimeMs: 1
+ property int numberOfBars: 1
+ property string animationState: "stopped"
+ property real titleStartAngle: 95
+ property real titleStopAngle: 5
+
+ onAnimationStateChanged: {
+ if (animationState == "playing") {
+ mediaPlayer.play()
+ if (progressTransformAnimation.paused)
+ progressTransformAnimation.resume()
+ else
+ progressTransformAnimation.start()
+ } else if (animationState == "paused") {
+ mediaPlayer.pause()
+ if (progressTransformAnimation.running)
+ progressTransformAnimation.pause()
+ } else {
+ mediaPlayer.stop()
+ progressTransformAnimation.stop()
+ progressTransform.progressAngle = progressTransform.defaultStartAngle
+ }
+ }
+
+ QQ2.Item {
+ id: stateItem
+
+ state: animationState
+ states: [
+ QQ2.State {
+ name: "playing"
+ QQ2.PropertyChanges {
+ target: titlePrism
+ titleAngle: titleStopAngle
+ }
+ },
+ QQ2.State {
+ name: "paused"
+ QQ2.PropertyChanges {
+ target: titlePrism
+ titleAngle: titleStopAngle
+ }
+ },
+ QQ2.State {
+ name: "stopped"
+ QQ2.PropertyChanges {
+ target: titlePrism
+ titleAngle: titleStartAngle
+ }
+ }
+ ]
+
+ transitions: QQ2.Transition {
+ QQ2.NumberAnimation {
+ property: "titleAngle"
+ duration: 2000
+ running: false
+ }
+ }
+ }
+
+ function startVisualization() {
+ progressTransformAnimation.duration = mediaPlayer.duration
+ mainview.state = "playing"
+ progressTransformAnimation.start()
+ }
+
+ //![0]
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 1820 / 1080
+ nearPlane: 0.1
+ farPlane: 1000.0
+ position: Qt.vector3d(0.014, 0.956, 2.178)
+ upVector: Qt.vector3d(0.0, 1.0, 0.0)
+ viewCenter: Qt.vector3d(0.0, 0.7, 0.0)
+ }
+ //![0]
+
+ Configuration {
+ controlledCamera: camera
+ }
+
+ Entity {
+ components: [
+ DirectionalLight {
+ intensity: 0.9
+ direction: Qt.vector3d(0, 0.6, -1)
+ }
+ ]
+ }
+
+ FrameGraph {
+ id: external_forward_renderer
+ activeFrameGraph: ForwardRenderer {
+ camera: camera
+ clearColor: "transparent"
+ }
+ }
+
+ components: [external_forward_renderer]
+
+ //![1]
+ // Bars
+ CuboidMesh {
+ id: barMesh
+ xExtent: 0.1
+ yExtent: 0.1
+ zExtent: 0.1
+ }
+
+ NodeInstantiator {
+ id: collection
+ property int maxCount: parent.numberOfBars
+ model: maxCount
+
+ delegate: BarEntity {
+ id: cubicEntity
+ entityMesh: barMesh
+ rotationTimeMs: sceneRoot.barRotationTimeMs
+ entityIndex: index
+ entityCount: sceneRoot.numberOfBars
+ entityAnimationsState: animationState
+ magnitude: 0
+ }
+ }
+ //![1]
+
+ // TitlePrism
+ Entity {
+ id: titlePrism
+ property real titleAngle: titleStartAngle
+
+ Entity {
+ id: titlePlane
+
+ PlaneMesh {
+ id: titlePlaneMesh
+ width: 550
+ height: 100
+ }
+
+ Transform {
+ id: titlePlaneTransform
+ scale: 0.003
+ translation: Qt.vector3d(0, 0.11, 0)
+ }
+
+ NormalDiffuseMapAlphaMaterial {
+ id: titlePlaneMaterial
+ diffuse: "qrc:/images/demotitle.png"
+ normal: "qrc:/images/normalmap.png"
+ shininess: 1.0
+ }
+
+ components: [titlePlaneMesh, titlePlaneMaterial, titlePlaneTransform]
+ }
+
+ // Song title
+ Entity {
+ id: songTitlePlane
+
+ PlaneMesh {
+ id: songPlaneMesh
+ width: 550
+ height: 100
+ }
+
+ Transform {
+ id: songPlaneTransform
+ scale: 0.003
+ rotationX: 90
+ translation: Qt.vector3d(0, -0.03, 0.13)
+ }
+
+ property Material songPlaneMaterial: NormalDiffuseMapAlphaMaterial {
+ diffuse: "qrc:/images/songtitle.png"
+ normal: "qrc:/images/normalmap.png"
+ shininess: 1.0
+ }
+
+ components: [songPlaneMesh, songPlaneMaterial, songPlaneTransform]
+ }
+
+ property Transform titlePrismPlaneTransform: Transform {
+ matrix: {
+ var m = Qt.matrix4x4()
+ m.translate(Qt.vector3d(-0.5, 1.3, -0.4))
+ m.rotate(titlePrism.titleAngle, Qt.vector3d(1, 0, 0))
+ return m;
+ }
+ }
+
+ components: [titlePlane, songTitlePlane, titlePrismPlaneTransform]
+ }
+
+ // Circle to create the reflection effect
+ Mesh {
+ id: circleMesh
+ source: "qrc:/meshes/circle.obj"
+ }
+
+ Entity {
+ id: circleEntity
+ property Material circleMaterial: PhongAlphaMaterial {
+ alpha: 0.4
+ ambient: "black"
+ diffuse: "black"
+ specular: "black"
+ shininess: 10000
+ }
+
+ components: [circleMesh, circleMaterial]
+ }
+
+ //![2]
+ // Progress
+ Mesh {
+ id: progressMesh
+ source: "qrc:/meshes/progressbar.obj"
+ }
+
+ Transform {
+ id: progressTransform
+ property real defaultStartAngle: -90
+ property real progressAngle: defaultStartAngle
+ rotationY: progressAngle
+ }
+
+ Entity {
+ property Material progressMaterial: PhongMaterial {
+ ambient: "#80C342"
+ diffuse: "black"
+ }
+
+ components: [progressMesh, progressMaterial, progressTransform]
+ }
+ //![2]
+
+ QQ2.NumberAnimation {
+ id: progressTransformAnimation
+ target: progressTransform
+ property: "progressAngle"
+ duration: 0
+ running: false
+ from: progressTransform.defaultStartAngle
+ to: -270
+ onStopped: if (animationState != "stopped") animationState = "stopped"
+ }
+}
diff --git a/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.pro b/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.pro
new file mode 100644
index 000000000..b2c3c7f2e
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.pro
@@ -0,0 +1,20 @@
+requires(qtHaveModule(multimedia))
+
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += 3dcore 3dquick qml quick multimedia
+
+SOURCES += \
+ main.cpp \
+ touchsettings.cpp
+
+HEADERS += \
+ touchsettings.h
+
+OTHER_FILES += \
+ *.qml
+
+RESOURCES += \
+ audio-visualizer-qml.qrc
diff --git a/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.qrc b/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.qrc
new file mode 100644
index 000000000..fb8324cb6
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/audio-visualizer-qml.qrc
@@ -0,0 +1,22 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>Visualizer.qml</file>
+ <file>BarEntity.qml</file>
+ <file>meshes/circle.obj</file>
+ <file>meshes/progressbar.obj</file>
+ <file>images/pausenormal.png</file>
+ <file>images/playnormal.png</file>
+ <file>images/stopdisabled.png</file>
+ <file>images/stopnormal.png</file>
+ <file>images/pausehoverpressed.png</file>
+ <file>images/playhoverpressed.png</file>
+ <file>images/stophoverpressed.png</file>
+ <file>music/tiltshifted_lost_neon_sun.mp3</file>
+ <file>images/demotitle.png</file>
+ <file>images/songtitle.png</file>
+ <file>images/normalmap.png</file>
+ <file>images/albumcover.png</file>
+ <file>music/visualization.raw</file>
+ </qresource>
+</RCC>
diff --git a/examples/qt3d/audio-visualizer-qml/doc/src/audio-visualizer-qml.qdoc b/examples/qt3d/audio-visualizer-qml/doc/src/audio-visualizer-qml.qdoc
new file mode 100644
index 000000000..ddd89de33
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/doc/src/audio-visualizer-qml.qdoc
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audio-visualizer-qml
+ \title Qt 3D: Audio Visualizer Example
+ \ingroup qt3d-examples-qml
+ \brief Demonstrates combining Qt 3D rendering and Qt Quick 2 elements.
+
+ \image audio-visualizer-qml-example.jpg
+
+ \e Audio Visualizer demonstrates how to implement an application that combines the use of
+ Qt 3D rendering with Qt Quick 2D elements. The example uses media player to play music and it
+ visualizes the magnitude of the music as animated bars.
+
+ \include examples-run.qdocinc
+
+ \section1 Qt Quick 2D Implementation
+
+ The Qt Quick Implementation \l{audio-visualizer-qml/main.qml}{main.qml} of the example uses
+ \c{MediaPlayer} to play audio content.
+
+ \snippet audio-visualizer-qml/main.qml 0
+
+ The player is controlled with the \c{playButton} and c\{stopButton}. Based on the clicked
+ buttons the \c{state} of the \c{mainview} changes.
+
+ The 3D content is rendered using the \c{Scene3D} type. The state of the Audio Visualizer is
+ maintained in the \c{mainview}. It's passed on to the \c{visualizer} as it's needed for the bar
+ animations.
+
+ \snippet audio-visualizer-qml/main.qml 1
+
+ \section1 Qt 3D Implementation
+
+ The 3D elements of the example are created in the
+ \l{audio-visualizer-qml/Visualizer.qml}{Visualizer.qml}. The camera is set to a fixed position
+ to show the visualized bars from a correct angle.
+
+ \snippet audio-visualizer-qml/Visualizer.qml 0
+
+ A \c{NodeInstatiator} is used to create the bars that visualize the magnitude of the music.
+
+ \snippet audio-visualizer-qml/Visualizer.qml 1
+
+ The \c{visualizer} also contains an \c{Entity} to show the progress. This element has a curve
+ shaped mesh and it's rotated on a level to show the progress based on the duration of the played
+ track.
+
+ \snippet audio-visualizer-qml/Visualizer.qml 2
+
+ In \l{audio-visualizer-qml/BarEntity.qml}{BarEntity.qml} there are animations for rotating the
+ bars and changing the bar color. The bars are rotated on a level following a ring form. At the
+ same time the color of the bars is animated.
+
+ \snippet audio-visualizer-qml/BarEntity.qml 0
+
+ \snippet audio-visualizer-qml/BarEntity.qml 1
+
+ The magnitude of each bar is read from a separate .raw file that is based on the track being
+ played. As the bars rotate around the ring the height is scaled to highlight currently played
+ position. After a full round of rotation, a new value is fetched for the bar.
+
+*/
diff --git a/examples/qt3d/audio-visualizer-qml/images/albumcover.png b/examples/qt3d/audio-visualizer-qml/images/albumcover.png
new file mode 100644
index 000000000..89872564f
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/albumcover.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/demotitle.png b/examples/qt3d/audio-visualizer-qml/images/demotitle.png
new file mode 100644
index 000000000..58816784e
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/demotitle.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/normalmap.png b/examples/qt3d/audio-visualizer-qml/images/normalmap.png
new file mode 100644
index 000000000..be522bbf9
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/normalmap.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/pausehoverpressed.png b/examples/qt3d/audio-visualizer-qml/images/pausehoverpressed.png
new file mode 100644
index 000000000..1a2c585fe
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/pausehoverpressed.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/pausenormal.png b/examples/qt3d/audio-visualizer-qml/images/pausenormal.png
new file mode 100644
index 000000000..50c46ab36
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/pausenormal.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/playhoverpressed.png b/examples/qt3d/audio-visualizer-qml/images/playhoverpressed.png
new file mode 100644
index 000000000..a65e74501
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/playhoverpressed.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/playnormal.png b/examples/qt3d/audio-visualizer-qml/images/playnormal.png
new file mode 100644
index 000000000..546bdd2b3
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/playnormal.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/songtitle.png b/examples/qt3d/audio-visualizer-qml/images/songtitle.png
new file mode 100644
index 000000000..1f47b971f
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/songtitle.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/stopdisabled.png b/examples/qt3d/audio-visualizer-qml/images/stopdisabled.png
new file mode 100644
index 000000000..06e3672f0
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/stopdisabled.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/stophoverpressed.png b/examples/qt3d/audio-visualizer-qml/images/stophoverpressed.png
new file mode 100644
index 000000000..67d2db299
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/stophoverpressed.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/images/stopnormal.png b/examples/qt3d/audio-visualizer-qml/images/stopnormal.png
new file mode 100644
index 000000000..ddb15509c
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/images/stopnormal.png
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/main.cpp b/examples/qt3d/audio-visualizer-qml/main.cpp
new file mode 100644
index 000000000..969be0a58
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/main.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "touchsettings.h"
+#include <QtGui/QGuiApplication>
+#include <QtGui/QOpenGLContext>
+#include <QtQuick/QQuickView>
+#include <QtQuick/QQuickItem>
+#include <Qt3DQuick/QQmlAspectEngine>
+#include <QtQml/QQmlContext>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QSurfaceFormat format;
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
+ format.setVersion(3, 2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ }
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+
+ QQuickView view;
+ view.setFormat(format);
+ view.create();
+
+ Qt3DCore::Quick::QQmlAspectEngine engine;
+
+ QVariantMap data;
+ data.insert(QStringLiteral("surface"), QVariant::fromValue(static_cast<QSurface *>(&view)));
+ data.insert(QStringLiteral("eventSource"), QVariant::fromValue(&view));
+ engine.aspectEngine()->setData(data);
+ engine.qmlEngine()->rootContext()->setContextProperty("_view", &view);
+
+ TouchSettings touchSettings;
+ view.rootContext()->setContextProperty("touchSettings", &touchSettings);
+
+ view.setSource(QUrl("qrc:/main.qml"));
+
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setMaximumSize(QSize(1820, 1080));
+ view.setMinimumSize(QSize(300, 150));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/qt3d/audio-visualizer-qml/main.qml b/examples/qt3d/audio-visualizer-qml/main.qml
new file mode 100644
index 000000000..10c624864
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/main.qml
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Scene3D 2.0
+import QtQuick.Layouts 1.2
+import QtMultimedia 5.0
+
+Item {
+ id: mainview
+ width: 1215
+ height: 720
+ visible: true
+ property bool isHoverEnabled: false
+
+ property variant magnitudeArray: null
+ property int millisecondsPerBar: 68
+ property string magnitudeDataSourceFile: "qrc:/music/visualization.raw"
+ property int mediaLatencyOffset: 68
+
+ state: "stopped"
+ states: [
+ State {
+ name: "playing"
+ PropertyChanges {
+ target: playButtonImage
+ source: {
+ if (playButtonMouseArea.containsMouse)
+ "qrc:/images/pausehoverpressed.png"
+ else
+ "qrc:/images/pausenormal.png"
+ }
+ }
+ PropertyChanges {
+ target: stopButtonImage
+ source: "qrc:/images/stopnormal.png"
+ }
+ },
+ State {
+ name: "paused"
+ PropertyChanges {
+ target: playButtonImage
+ source: {
+ if (playButtonMouseArea.containsMouse)
+ "qrc:/images/playhoverpressed.png"
+ else
+ "qrc:/images/playnormal.png"
+ }
+ }
+ PropertyChanges {
+ target: stopButtonImage
+ source: "qrc:/images/stopnormal.png"
+ }
+ },
+ State {
+ name: "stopped"
+ PropertyChanges {
+ target: playButtonImage
+ source: "qrc:/images/playnormal.png"
+ }
+ PropertyChanges {
+ target: stopButtonImage
+ source: "qrc:/images/stopdisabled.png"
+ }
+ }
+ ]
+
+ Component.onCompleted: isHoverEnabled = touchSettings.isHoverEnabled()
+
+ //![0]
+ MediaPlayer {
+ id: mediaPlayer
+ autoPlay: true
+ volume: 0.5
+ source: "qrc:/music/tiltshifted_lost_neon_sun.mp3"
+ //![0]
+
+ onStatusChanged: {
+ if (status == MediaPlayer.EndOfMedia) //{
+ state = "stopped"
+ }
+
+ onError: console.error("error with audio " + mediaPlayer.error)
+
+ onDurationChanged: {
+ // Load the pre-calculated magnitude data for the visualizer
+ var request = new XMLHttpRequest()
+ request.responseType = 'arraybuffer'
+ request.onreadystatechange = function() {
+ if (request.readyState === XMLHttpRequest.DONE) {
+ if (request.status == 200 || request.status == 0) {
+ var arrayBuffer = request.response
+ if (arrayBuffer) {
+ magnitudeArray = new Uint16Array(arrayBuffer)
+ visualizer.startVisualization()
+ }
+ } else {
+ console.warn("Couldn't load magnitude data for bars.")
+ }
+ request = null
+ }
+ };
+
+ request.open('GET', magnitudeDataSourceFile, true)
+ request.send(null)
+ }
+
+ function getNextAudioLevel(offsetMs) {
+ if (magnitudeArray === null)
+ return 0.0;
+
+ // Calculate the integer index position in to the magnitude array
+ var index = ((mediaPlayer.position + offsetMs) /
+ mainview.millisecondsPerBar) | 0;
+
+ if (index < 0 || index >= magnitudeArray.length)
+ return 0.0;
+
+ return (magnitudeArray[index] / 63274.0);
+ }
+ }
+
+ Image {
+ id: coverImage
+ anchors.fill: parent
+ source: "qrc:/images/albumcover.png"
+ }
+
+ //![1]
+ Scene3D {
+ anchors.fill: parent
+
+ Visualizer {
+ id: visualizer
+ animationState: mainview.state
+ numberOfBars: 120
+ barRotationTimeMs: 8160 // 68 ms per bar
+ }
+ }
+ //![1]
+
+ Rectangle {
+ id: blackBottomRect
+ color: "black"
+ width: parent.width
+ height: 0.14 * mainview.height
+ anchors.bottom: parent.bottom
+ }
+
+ // Duration of played content
+ Text {
+ text: formatDuration(mediaPlayer.position)
+ color: "#80C342"
+ x: parent.width / 6
+ y: mainview.height - mainview.height / 8
+ font.pixelSize: 12
+ }
+
+ // Duration of the content left
+ Text {
+ text: "-" + formatDuration(mediaPlayer.duration - mediaPlayer.position)
+ color: "#80C342"
+ x: parent.width - parent.width / 6
+ y: mainview.height - mainview.height / 8
+ font.pixelSize: 12
+ }
+
+ function formatDuration(milliseconds) {
+ var minutes = Math.floor(milliseconds / 60000)
+ milliseconds -= minutes * 60000
+ var seconds = milliseconds / 1000
+ seconds = Math.round(seconds)
+ if (seconds < 10)
+ return minutes + ":0" + seconds
+ else
+ return minutes + ":" + seconds
+ }
+
+ property int buttonHorizontalMargin: 10
+ Rectangle {
+ id: playButton
+ height: 54
+ width: 54
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: width
+ x: parent.width / 2 - width - buttonHorizontalMargin
+ color: "transparent"
+
+ Image {
+ id: playButtonImage
+ source: "qrc:/images/pausenormal.png"
+ }
+
+ MouseArea {
+ id: playButtonMouseArea
+ anchors.fill: parent
+ hoverEnabled: isHoverEnabled
+ onClicked: {
+ if (mainview.state == 'paused' || mainview.state == 'stopped')
+ mainview.state = 'playing'
+ else
+ mainview.state = 'paused'
+ }
+ onEntered: {
+ if (mainview.state == 'playing')
+ playButtonImage.source = "qrc:/images/pausehoverpressed.png"
+ else
+ playButtonImage.source = "qrc:/images/playhoverpressed.png"
+ }
+ onExited: {
+ if (mainview.state == 'playing')
+ playButtonImage.source = "qrc:/images/pausenormal.png"
+ else
+ playButtonImage.source = "qrc:/images/playnormal.png"
+ }
+ }
+ }
+
+ Rectangle {
+ id: stopButton
+ height: 54
+ width: 54
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: width
+ x: parent.width / 2 + buttonHorizontalMargin
+ color: "transparent"
+
+ Image {
+ id: stopButtonImage
+ source: "qrc:/images/stopnormal.png"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: isHoverEnabled
+ onClicked: mainview.state = 'stopped'
+ onEntered: {
+ if (mainview.state != 'stopped')
+ stopButtonImage.source = "qrc:/images/stophoverpressed.png"
+ }
+ onExited: {
+ if (mainview.state != 'stopped')
+ stopButtonImage.source = "qrc:/images/stopnormal.png"
+ }
+ }
+ }
+}
diff --git a/examples/qt3d/audio-visualizer-qml/meshes/circle.obj b/examples/qt3d/audio-visualizer-qml/meshes/circle.obj
new file mode 100644
index 000000000..e76bc8659
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/meshes/circle.obj
@@ -0,0 +1,72 @@
+# Blender v2.76 (sub 0) OBJ File: ''
+# www.blender.org
+mtllib circle.mtl
+o Circle
+v 0.000000 0.000000 0.000000
+v 0.000000 0.000000 -1.100000
+v -0.214599 0.000000 -1.078864
+v -0.420952 0.000000 -1.016267
+v -0.611127 0.000000 -0.914617
+v -0.777817 0.000000 -0.777817
+v -0.914617 0.000000 -0.611127
+v -1.016267 0.000000 -0.420952
+v -1.078864 0.000000 -0.214599
+v -1.100000 0.000000 -0.000000
+v -1.078864 0.000000 0.214599
+v -1.016268 0.000000 0.420952
+v -0.914617 0.000000 0.611127
+v -0.777817 0.000000 0.777817
+v -0.611127 0.000000 0.914617
+v -0.420952 0.000000 1.016268
+v -0.214599 0.000000 1.078864
+v 0.000000 0.000000 1.100000
+v 0.214600 0.000000 1.078864
+v 0.420952 0.000000 1.016267
+v 0.611128 0.000000 0.914616
+v 0.777818 0.000000 0.777817
+v 0.914617 0.000000 0.611127
+v 1.016268 0.000000 0.420951
+v 1.078864 0.000000 0.214598
+v 1.100000 0.000000 -0.000001
+v 1.078864 0.000000 -0.214600
+v 1.016267 0.000000 -0.420953
+v 0.914616 0.000000 -0.611128
+v 0.777816 0.000000 -0.777818
+v 0.611126 0.000000 -0.914617
+v 0.420950 0.000000 -1.016268
+v 0.214598 0.000000 -1.078864
+vn 0.000000 1.000000 0.000000
+usemtl None
+s off
+f 1//1 2//1 3//1
+f 1//1 3//1 4//1
+f 1//1 4//1 5//1
+f 1//1 5//1 6//1
+f 1//1 6//1 7//1
+f 1//1 7//1 8//1
+f 1//1 8//1 9//1
+f 1//1 9//1 10//1
+f 1//1 10//1 11//1
+f 1//1 11//1 12//1
+f 1//1 12//1 13//1
+f 1//1 13//1 14//1
+f 1//1 14//1 15//1
+f 1//1 15//1 16//1
+f 1//1 16//1 17//1
+f 1//1 17//1 18//1
+f 1//1 18//1 19//1
+f 1//1 19//1 20//1
+f 1//1 20//1 21//1
+f 1//1 21//1 22//1
+f 1//1 22//1 23//1
+f 1//1 23//1 24//1
+f 1//1 24//1 25//1
+f 1//1 25//1 26//1
+f 1//1 26//1 27//1
+f 1//1 27//1 28//1
+f 1//1 28//1 29//1
+f 1//1 29//1 30//1
+f 1//1 30//1 31//1
+f 1//1 31//1 32//1
+f 1//1 32//1 33//1
+f 1//1 33//1 2//1
diff --git a/examples/qt3d/audio-visualizer-qml/meshes/progressbar.obj b/examples/qt3d/audio-visualizer-qml/meshes/progressbar.obj
new file mode 100644
index 000000000..a48ad3540
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/meshes/progressbar.obj
@@ -0,0 +1,478 @@
+# Blender v2.70 (sub 0) OBJ File: ''
+# www.blender.org
+v 0.000000 -0.005000 -1.000000
+v 0.000000 0.005000 -1.000000
+v 0.049068 -0.005000 -0.998795
+v 0.049068 0.005000 -0.998795
+v 0.098017 -0.005000 -0.995185
+v 0.098017 0.005000 -0.995185
+v 0.146730 -0.005000 -0.989177
+v 0.146730 0.005000 -0.989177
+v 0.195090 -0.005000 -0.980785
+v 0.195090 0.005000 -0.980785
+v 0.242980 -0.005000 -0.970031
+v 0.242980 0.005000 -0.970031
+v 0.290285 -0.005000 -0.956940
+v 0.290285 0.005000 -0.956940
+v 0.336890 -0.005000 -0.941544
+v 0.336890 0.005000 -0.941544
+v 0.382683 -0.005000 -0.923880
+v 0.382683 0.005000 -0.923880
+v 0.427555 -0.005000 -0.903989
+v 0.427555 0.005000 -0.903989
+v 0.471397 -0.005000 -0.881921
+v 0.471397 0.005000 -0.881921
+v 0.514103 -0.005000 -0.857729
+v 0.514103 0.005000 -0.857729
+v 0.555570 -0.005000 -0.831470
+v 0.555570 0.005000 -0.831470
+v 0.595699 -0.005000 -0.803208
+v 0.595699 0.005000 -0.803208
+v 0.634393 -0.005000 -0.773010
+v 0.634393 0.005000 -0.773010
+v 0.671559 -0.005000 -0.740951
+v 0.671559 0.005000 -0.740951
+v 0.707107 -0.005000 -0.707107
+v 0.707107 0.005000 -0.707107
+v 0.740951 -0.005000 -0.671559
+v 0.740951 0.005000 -0.671559
+v 0.773011 -0.005000 -0.634393
+v 0.773011 0.005000 -0.634393
+v 0.803208 -0.005000 -0.595699
+v 0.803208 0.005000 -0.595699
+v 0.831470 -0.005000 -0.555570
+v 0.831470 0.005000 -0.555570
+v 0.857729 -0.005000 -0.514103
+v 0.857729 0.005000 -0.514103
+v 0.881921 -0.005000 -0.471397
+v 0.881921 0.005000 -0.471397
+v 0.903989 -0.005000 -0.427555
+v 0.903989 0.005000 -0.427555
+v 0.923880 -0.005000 -0.382683
+v 0.923880 0.005000 -0.382683
+v 0.941544 -0.005000 -0.336890
+v 0.941544 0.005000 -0.336890
+v 0.956940 -0.005000 -0.290284
+v 0.956940 0.005000 -0.290284
+v 0.970031 -0.005000 -0.242980
+v 0.970031 0.005000 -0.242980
+v 0.980785 -0.005000 -0.195090
+v 0.980785 0.005000 -0.195090
+v 0.989177 -0.005000 -0.146730
+v 0.989177 0.005000 -0.146730
+v 0.995185 -0.005000 -0.098017
+v 0.995185 0.005000 -0.098017
+v 0.998795 -0.005000 -0.049067
+v 0.998795 0.005000 -0.049067
+v 1.000000 -0.005000 0.000000
+v 1.000000 0.005000 0.000000
+v 0.998795 -0.005000 0.049068
+v 0.998795 0.005000 0.049068
+v 0.995185 -0.005000 0.098018
+v 0.995185 0.005000 0.098018
+v 0.989176 -0.005000 0.146731
+v 0.989176 0.005000 0.146731
+v 0.980785 -0.005000 0.195091
+v 0.980785 0.005000 0.195091
+v 0.970031 -0.005000 0.242981
+v 0.970031 0.005000 0.242981
+v 0.956940 -0.005000 0.290285
+v 0.956940 0.005000 0.290285
+v 0.941544 -0.005000 0.336890
+v 0.941544 0.005000 0.336890
+v 0.923879 -0.005000 0.382684
+v 0.923879 0.005000 0.382684
+v 0.903989 -0.005000 0.427556
+v 0.903989 0.005000 0.427556
+v 0.881921 -0.005000 0.471397
+v 0.881921 0.005000 0.471397
+v 0.857728 -0.005000 0.514103
+v 0.857728 0.005000 0.514103
+v 0.831470 -0.005000 0.555570
+v 0.831470 0.005000 0.555570
+v 0.803208 -0.005000 0.595699
+v 0.803208 0.005000 0.595699
+v 0.773010 -0.005000 0.634393
+v 0.773010 0.005000 0.634393
+v 0.740951 -0.005000 0.671559
+v 0.740951 0.005000 0.671559
+v 0.707107 -0.005000 0.707107
+v 0.707107 0.005000 0.707107
+v 0.671559 -0.005000 0.740951
+v 0.671559 0.005000 0.740951
+v 0.634394 -0.005000 0.773010
+v 0.634394 0.005000 0.773010
+v 0.595700 -0.005000 0.803207
+v 0.595700 0.005000 0.803207
+v 0.555571 -0.005000 0.831469
+v 0.555571 0.005000 0.831469
+v 0.514103 -0.005000 0.857728
+v 0.514103 0.005000 0.857728
+v 0.471397 -0.005000 0.881921
+v 0.471397 0.005000 0.881921
+v 0.427556 -0.005000 0.903989
+v 0.427556 0.005000 0.903989
+v 0.382684 -0.005000 0.923879
+v 0.382684 0.005000 0.923879
+v 0.336891 -0.005000 0.941544
+v 0.336891 0.005000 0.941544
+v 0.290286 -0.005000 0.956940
+v 0.290286 0.005000 0.956940
+v 0.242981 -0.005000 0.970031
+v 0.242981 0.005000 0.970031
+v 0.195092 -0.005000 0.980785
+v 0.195092 0.005000 0.980785
+v 0.146732 -0.005000 0.989176
+v 0.146732 0.005000 0.989176
+v 0.098019 -0.005000 0.995185
+v 0.098019 0.005000 0.995185
+v 0.049069 -0.005000 0.998795
+v 0.049069 0.005000 0.998795
+v 0.000002 -0.005000 1.000000
+v 0.000002 0.005000 1.000000
+vt 0.985992 0.001342
+vt 0.986125 0.004167
+vt 0.999986 0.003515
+vt 0.972125 0.001989
+vt 0.972257 0.004817
+vt 0.958240 0.002631
+vt 0.958371 0.005463
+vt 0.944323 0.003267
+vt 0.944453 0.006107
+vt 0.930368 0.003899
+vt 0.930498 0.006747
+vt 0.916365 0.004525
+vt 0.916493 0.007384
+vt 0.902304 0.005145
+vt 0.902431 0.008017
+vt 0.888174 0.005758
+vt 0.888300 0.008645
+vt 0.873967 0.006365
+vt 0.874091 0.009268
+vt 0.859676 0.006964
+vt 0.859799 0.009885
+vt 0.845299 0.007556
+vt 0.845420 0.010494
+vt 0.830832 0.008137
+vt 0.830952 0.011094
+vt 0.816275 0.008707
+vt 0.816392 0.011683
+vt 0.801624 0.009266
+vt 0.801738 0.012260
+vt 0.786881 0.009812
+vt 0.786993 0.012825
+vt 0.772049 0.010344
+vt 0.772158 0.013376
+vt 0.757127 0.010861
+vt 0.757232 0.013911
+vt 0.742113 0.011363
+vt 0.742215 0.014431
+vt 0.727008 0.011848
+vt 0.727107 0.014935
+vt 0.711815 0.012315
+vt 0.711910 0.015420
+vt 0.696532 0.012762
+vt 0.696622 0.015885
+vt 0.681160 0.013188
+vt 0.681246 0.016329
+vt 0.665700 0.013592
+vt 0.665782 0.016750
+vt 0.650157 0.013972
+vt 0.650233 0.017147
+vt 0.634534 0.014327
+vt 0.634606 0.017518
+vt 0.618838 0.014658
+vt 0.618904 0.017864
+vt 0.603071 0.014964
+vt 0.603132 0.018183
+vt 0.587239 0.015245
+vt 0.587295 0.018477
+vt 0.571347 0.015502
+vt 0.571399 0.018746
+vt 0.555400 0.015735
+vt 0.555446 0.018990
+vt 0.539400 0.015942
+vt 0.539441 0.019207
+vt 0.523351 0.016123
+vt 0.523386 0.019398
+vt 0.507255 0.016277
+vt 0.507284 0.019561
+vt 0.491116 0.016401
+vt 0.491139 0.019694
+vt 0.474935 0.016494
+vt 0.474952 0.019796
+vt 0.458717 0.016555
+vt 0.458726 0.019863
+vt 0.442462 0.016580
+vt 0.442465 0.019896
+vt 0.426175 0.016569
+vt 0.426169 0.019891
+vt 0.409859 0.016518
+vt 0.409845 0.019846
+vt 0.393516 0.016426
+vt 0.393493 0.019759
+vt 0.377149 0.016288
+vt 0.377117 0.019626
+vt 0.360762 0.016103
+vt 0.360719 0.019445
+vt 0.344356 0.015870
+vt 0.344304 0.019215
+vt 0.327936 0.015588
+vt 0.327873 0.018935
+vt 0.311507 0.015254
+vt 0.311434 0.018603
+vt 0.295074 0.014870
+vt 0.294990 0.018219
+vt 0.278641 0.014434
+vt 0.278546 0.017782
+vt 0.262211 0.013944
+vt 0.262105 0.017292
+vt 0.245787 0.013401
+vt 0.245670 0.016747
+vt 0.229373 0.012804
+vt 0.229245 0.016148
+vt 0.212971 0.012153
+vt 0.212833 0.015495
+vt 0.196578 0.011449
+vt 0.196429 0.014789
+vt 0.180193 0.010695
+vt 0.180034 0.014033
+vt 0.163819 0.009891
+vt 0.163651 0.013227
+vt 0.147458 0.009041
+vt 0.147280 0.012375
+vt 0.131104 0.008148
+vt 0.130918 0.011481
+vt 0.114755 0.007216
+vt 0.114561 0.010547
+vt 0.098407 0.006248
+vt 0.098207 0.009579
+vt 0.082058 0.005250
+vt 0.081852 0.008581
+vt 0.065706 0.004228
+vt 0.065497 0.007560
+vt 0.049350 0.003188
+vt 0.049137 0.006521
+vt 0.032984 0.002136
+vt 0.032769 0.005471
+vt 0.016610 0.001077
+vt 0.016394 0.004413
+vt 0.000231 0.000014
+vt 0.000014 0.003351
+vt 0.999853 0.000691
+vn -0.024542 0.000000 0.999699
+vn -0.073565 0.000000 0.997290
+vn -0.122409 0.000000 0.992480
+vn -0.170962 0.000000 0.985278
+vn -0.219100 0.000000 0.975702
+vn -0.266712 0.000000 0.963776
+vn -0.313685 0.000000 0.949527
+vn -0.359896 0.000000 0.932992
+vn -0.405242 0.000000 0.914210
+vn -0.449609 0.000000 0.893226
+vn -0.492897 0.000000 0.870088
+vn -0.534998 0.000000 0.844853
+vn -0.575809 0.000000 0.817585
+vn -0.615230 0.000000 0.788347
+vn -0.653174 0.000000 0.757208
+vn -0.689540 0.000000 0.724247
+vn -0.724247 0.000000 0.689541
+vn -0.757208 0.000000 0.653174
+vn -0.788347 0.000000 0.615231
+vn -0.817585 0.000000 0.575808
+vn -0.844854 0.000000 0.534998
+vn -0.870087 0.000000 0.492898
+vn -0.893225 0.000000 0.449611
+vn -0.914210 0.000000 0.405242
+vn -0.932993 0.000000 0.359896
+vn -0.949528 0.000000 0.313681
+vn -0.963776 0.000000 0.266712
+vn -0.975702 0.000000 0.219102
+vn -0.985278 0.000000 0.170961
+vn -0.992480 0.000000 0.122410
+vn -0.997291 0.000000 0.073563
+vn -0.999699 0.000000 0.024541
+vn -0.999699 0.000000 -0.024541
+vn -0.997290 0.000000 -0.073566
+vn -0.992480 0.000000 -0.122410
+vn -0.985278 0.000000 -0.170962
+vn -0.975702 0.000000 -0.219102
+vn -0.963776 0.000000 -0.266714
+vn -0.949528 0.000000 -0.313682
+vn -0.932993 0.000000 -0.359895
+vn -0.914209 0.000000 -0.405242
+vn -0.893224 0.000000 -0.449611
+vn -0.870087 0.000000 -0.492898
+vn -0.844854 0.000000 -0.534998
+vn -0.817585 0.000000 -0.575808
+vn -0.788347 0.000000 -0.615231
+vn -0.757209 0.000000 -0.653172
+vn -0.724247 0.000000 -0.689541
+vn -0.689542 0.000000 -0.724246
+vn -0.653173 0.000000 -0.757208
+vn -0.615232 0.000000 -0.788346
+vn -0.575810 0.000000 -0.817584
+vn -0.534998 0.000000 -0.844853
+vn -0.492898 0.000000 -0.870087
+vn -0.449613 0.000000 -0.893224
+vn -0.405246 0.000000 -0.914208
+vn -0.359897 0.000000 -0.932992
+vn -0.313682 0.000000 -0.949528
+vn -0.266712 0.000000 -0.963776
+vn -0.219104 0.000000 -0.975701
+vn -0.170962 0.000000 -0.985278
+vn -0.122410 0.000000 -0.992480
+vn -0.073569 0.000000 -0.997290
+vn -0.024542 0.000000 -0.999699
+vn -0.170965 0.000000 0.985277
+vn -0.313681 0.000000 0.949528
+vn -0.359893 0.000000 0.932994
+vn -0.449612 0.000000 0.893224
+vn -0.492900 0.000000 0.870086
+vn -0.615233 0.000000 0.788346
+vn -0.653173 0.000000 0.757209
+vn -0.724248 0.000000 0.689539
+vn -0.817585 0.000000 0.575809
+vn -0.870088 0.000000 0.492897
+vn -0.893224 0.000000 0.449611
+vn -0.914210 0.000000 0.405241
+vn -0.932993 0.000000 0.359895
+vn -0.914209 0.000000 -0.405243
+vn -0.844853 0.000000 -0.534999
+vn -0.757208 0.000000 -0.653174
+vn -0.689541 0.000000 -0.724247
+vn -0.615233 0.000000 -0.788346
+vn -0.575807 0.000000 -0.817586
+vn -0.405239 0.000000 -0.914211
+vn -0.359893 0.000000 -0.932993
+vn -0.313686 0.000000 -0.949527
+vn -0.122413 0.000000 -0.992479
+s off
+f 3/1/1 4/2/1 2/3/1
+f 5/4/2 6/5/2 4/2/2
+f 7/6/3 8/7/3 6/5/3
+f 9/8/4 10/9/4 8/7/4
+f 11/10/5 12/11/5 10/9/5
+f 13/12/6 14/13/6 12/11/6
+f 15/14/7 16/15/7 14/13/7
+f 17/16/8 18/17/8 16/15/8
+f 19/18/9 20/19/9 18/17/9
+f 21/20/10 22/21/10 20/19/10
+f 23/22/11 24/23/11 22/21/11
+f 25/24/12 26/25/12 24/23/12
+f 27/26/13 28/27/13 26/25/13
+f 29/28/14 30/29/14 28/27/14
+f 31/30/15 32/31/15 30/29/15
+f 33/32/16 34/33/16 32/31/16
+f 35/34/17 36/35/17 34/33/17
+f 37/36/18 38/37/18 36/35/18
+f 39/38/19 40/39/19 38/37/19
+f 41/40/20 42/41/20 40/39/20
+f 43/42/21 44/43/21 42/41/21
+f 45/44/22 46/45/22 44/43/22
+f 47/46/23 48/47/23 46/45/23
+f 49/48/24 50/49/24 48/47/24
+f 51/50/25 52/51/25 50/49/25
+f 53/52/26 54/53/26 52/51/26
+f 55/54/27 56/55/27 54/53/27
+f 57/56/28 58/57/28 56/55/28
+f 59/58/29 60/59/29 58/57/29
+f 61/60/30 62/61/30 60/59/30
+f 63/62/31 64/63/31 62/61/31
+f 65/64/32 66/65/32 64/63/32
+f 67/66/33 68/67/33 66/65/33
+f 69/68/34 70/69/34 68/67/34
+f 71/70/35 72/71/35 70/69/35
+f 73/72/36 74/73/36 72/71/36
+f 75/74/37 76/75/37 74/73/37
+f 77/76/38 78/77/38 76/75/38
+f 79/78/39 80/79/39 78/77/39
+f 81/80/40 82/81/40 80/79/40
+f 83/82/41 84/83/41 82/81/41
+f 85/84/42 86/85/42 84/83/42
+f 87/86/43 88/87/43 86/85/43
+f 89/88/44 90/89/44 88/87/44
+f 91/90/45 92/91/45 90/89/45
+f 93/92/46 94/93/46 92/91/46
+f 95/94/47 96/95/47 94/93/47
+f 97/96/48 98/97/48 96/95/48
+f 99/98/49 100/99/49 98/97/49
+f 101/100/50 102/101/50 100/99/50
+f 103/102/51 104/103/51 102/101/51
+f 105/104/52 106/105/52 104/103/52
+f 107/106/53 108/107/53 106/105/53
+f 109/108/54 110/109/54 108/107/54
+f 111/110/55 112/111/55 110/109/55
+f 113/112/56 114/113/56 112/111/56
+f 115/114/57 116/115/57 114/113/57
+f 117/116/58 118/117/58 116/115/58
+f 119/118/59 120/119/59 118/117/59
+f 121/120/60 122/121/60 120/119/60
+f 123/122/61 124/123/61 122/121/61
+f 125/124/62 126/125/62 124/123/62
+f 127/126/63 128/127/63 126/125/63
+f 129/128/64 130/129/64 128/127/64
+f 1/130/1 3/1/1 2/3/1
+f 3/1/2 5/4/2 4/2/2
+f 5/4/3 7/6/3 6/5/3
+f 7/6/65 9/8/65 8/7/65
+f 9/8/5 11/10/5 10/9/5
+f 11/10/6 13/12/6 12/11/6
+f 13/12/66 15/14/66 14/13/66
+f 15/14/67 17/16/67 16/15/67
+f 17/16/9 19/18/9 18/17/9
+f 19/18/68 21/20/68 20/19/68
+f 21/20/69 23/22/69 22/21/69
+f 23/22/12 25/24/12 24/23/12
+f 25/24/13 27/26/13 26/25/13
+f 27/26/70 29/28/70 28/27/70
+f 29/28/71 31/30/71 30/29/71
+f 31/30/16 33/32/16 32/31/16
+f 33/32/72 35/34/72 34/33/72
+f 35/34/18 37/36/18 36/35/18
+f 37/36/19 39/38/19 38/37/19
+f 39/38/73 41/40/73 40/39/73
+f 41/40/21 43/42/21 42/41/21
+f 43/42/74 45/44/74 44/43/74
+f 45/44/75 47/46/75 46/45/75
+f 47/46/76 49/48/76 48/47/76
+f 49/48/77 51/50/77 50/49/77
+f 51/50/26 53/52/26 52/51/26
+f 53/52/27 55/54/27 54/53/27
+f 55/54/28 57/56/28 56/55/28
+f 57/56/29 59/58/29 58/57/29
+f 59/58/30 61/60/30 60/59/30
+f 61/60/31 63/62/31 62/61/31
+f 63/62/32 65/64/32 64/63/32
+f 65/64/33 67/66/33 66/65/33
+f 67/66/34 69/68/34 68/67/34
+f 69/68/35 71/70/35 70/69/35
+f 71/70/36 73/72/36 72/71/36
+f 73/72/37 75/74/37 74/73/37
+f 75/74/38 77/76/38 76/75/38
+f 77/76/39 79/78/39 78/77/39
+f 79/78/40 81/80/40 80/79/40
+f 81/80/78 83/82/78 82/81/78
+f 83/82/42 85/84/42 84/83/42
+f 85/84/43 87/86/43 86/85/43
+f 87/86/79 89/88/79 88/87/79
+f 89/88/45 91/90/45 90/89/45
+f 91/90/46 93/92/46 92/91/46
+f 93/92/80 95/94/80 94/93/80
+f 95/94/48 97/96/48 96/95/48
+f 97/96/81 99/98/81 98/97/81
+f 99/98/50 101/100/50 100/99/50
+f 101/100/82 103/102/82 102/101/82
+f 103/102/83 105/104/83 104/103/83
+f 105/104/53 107/106/53 106/105/53
+f 107/106/54 109/108/54 108/107/54
+f 109/108/55 111/110/55 110/109/55
+f 111/110/84 113/112/84 112/111/84
+f 113/112/85 115/114/85 114/113/85
+f 115/114/86 117/116/86 116/115/86
+f 117/116/59 119/118/59 118/117/59
+f 119/118/60 121/120/60 120/119/60
+f 121/120/61 123/122/61 122/121/61
+f 123/122/87 125/124/87 124/123/87
+f 125/124/63 127/126/63 126/125/63
+f 127/126/64 129/128/64 128/127/64
diff --git a/examples/qt3d/audio-visualizer-qml/music/tiltshifted_lost_neon_sun.mp3 b/examples/qt3d/audio-visualizer-qml/music/tiltshifted_lost_neon_sun.mp3
new file mode 100644
index 000000000..a9a3850f3
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/music/tiltshifted_lost_neon_sun.mp3
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/music/visualization.raw b/examples/qt3d/audio-visualizer-qml/music/visualization.raw
new file mode 100644
index 000000000..0b2d7c444
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/music/visualization.raw
Binary files differ
diff --git a/examples/qt3d/audio-visualizer-qml/touchsettings.cpp b/examples/qt3d/audio-visualizer-qml/touchsettings.cpp
new file mode 100644
index 000000000..f55705395
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/touchsettings.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "touchsettings.h"
+#include <QtGui/QTouchDevice>
+#include <QDebug>
+
+TouchSettings::TouchSettings(QObject *parent)
+ : QObject(parent)
+{
+}
+
+bool TouchSettings::isHoverEnabled() const
+{
+#if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX)
+ || defined(Q_OS_WINRT)
+ return false;
+#else
+ bool isTouch = false;
+ foreach (const QTouchDevice *dev, QTouchDevice::devices())
+ if (dev->type() == QTouchDevice::TouchScreen) {
+ isTouch = true;
+ break;
+ }
+ bool isMobile = false;
+ if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_MOBILE")) {
+ isMobile = true;
+ }
+ return !isTouch && !isMobile;
+#endif
+}
diff --git a/examples/qt3d/audio-visualizer-qml/touchsettings.h b/examples/qt3d/audio-visualizer-qml/touchsettings.h
new file mode 100644
index 000000000..61a760508
--- /dev/null
+++ b/examples/qt3d/audio-visualizer-qml/touchsettings.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCHSETTINGS_H
+#define TOUCHSETTINGS_H
+
+#include <QtCore/QObject>
+
+class TouchSettings : public QObject
+{
+ Q_OBJECT
+public:
+ explicit TouchSettings(QObject *parent = 0);
+
+ Q_INVOKABLE bool isHoverEnabled() const;
+
+};
+
+#endif // TOUCHSETTINGS_H
diff --git a/examples/qt3d/qt3d.pro b/examples/qt3d/qt3d.pro
index 829eb2789..c7d26b6be 100644
--- a/examples/qt3d/qt3d.pro
+++ b/examples/qt3d/qt3d.pro
@@ -46,6 +46,8 @@ SUBDIRS += \
transforms-qml \
lights
+qtHaveModule(multimedia): SUBDIRS += audio-visualizer-qml
+
# qmake seems to break in some CI configurations, disable this for now
#SUBDIRS += qgltf
diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf
index 49f612619..cecdf7705 100644
--- a/src/doc/qt3d.qdocconf
+++ b/src/doc/qt3d.qdocconf
@@ -71,7 +71,8 @@ imagedirs += images \
../../examples/qt3d/shadow-map-qml/doc/images \
../../examples/qt3d/basicshapes-cpp/doc/images \
../../examples/qt3d/planets-qml/doc/images \
- ../../examples/qt3d/wireframe/doc/images
+ ../../examples/qt3d/wireframe/doc/images \
+ ../../examples/qt3d/audio-visualizer-qml/doc/images
Cpp.ignoretokens += QT3DCORE_PRIVATE_EXPORT \
QT3DINPUTSHARED_EXPORT \