Qt 5.9 | Qt 3D | Qt 3D: Audio Visualizer Example

Qt 5.9.3 Reference Documentation

# Qt 3D: Audio Visualizer Example

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.

## Running the Example

To run the example from Qt Creator, open the Welcome mode and select the example from Examples. For more information, visit Building and Running an Example.

## Qt Quick 2D Implementation

The Qt Quick Implementation main.qml of the example uses `MediaPlayer` to play audio content.

      MediaPlayer {
          id: mediaPlayer
          autoPlay: true
          volume: 0.5
          source: "qrc:/music/tiltshifted_lost_neon_sun.mp3"

The player is controlled with the `playButton` and c{stopButton}. Based on the clicked buttons the `state` of the `mainview` changes.

The 3D content is rendered using the `Scene3D` type. The state of the Audio Visualizer is maintained in the `mainview`. It's passed on to the `visualizer` as it's needed for the bar animations.

      Scene3D {
          anchors.fill: parent

          Visualizer {
              id: visualizer
              animationState: mainview.state
              numberOfBars: 120
              barRotationTimeMs: 8160 // 68 ms per bar
          }
      }

## Qt 3D Implementation

The 3D elements of the example are created in the Visualizer.qml. The camera is set to a fixed position to show the visualized bars from a correct angle.

      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)
      }

A `NodeInstantiator` is used to create the bars that visualize the magnitude of the music.

      // 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
          }
      }

The `visualizer` also contains an `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.

      // 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]
      }

In 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.

      QQ2.NumberAnimation {
          id: angleAnimation
          target: angleTransform
          property: "barAngle"
          duration: rotationTimeMs
          loops: QQ2.Animation.Infinite
          running: true
          from: startAngle
          to: 360 + startAngle
      }
      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
          }
      }

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.

Files:

- audio-visualizer-qml/BarEntity.qml
- audio-visualizer-qml/Visualizer.qml
- audio-visualizer-qml/main.qml
- audio-visualizer-qml/touchsettings.cpp
- audio-visualizer-qml/touchsettings.h
- audio-visualizer-qml/main.cpp
- audio-visualizer-qml/audio-visualizer-qml.pro
- audio-visualizer-qml/audio-visualizer-qml.qrc

Images:

- audio-visualizer-qml/images/albumcover.png
- audio-visualizer-qml/images/demotitle.png
- audio-visualizer-qml/images/normalmap.png
- audio-visualizer-qml/images/pausehoverpressed.png
- audio-visualizer-qml/images/pausenormal.png
- audio-visualizer-qml/images/playhoverpressed.png
- audio-visualizer-qml/images/playnormal.png
- audio-visualizer-qml/images/songtitle.png
- audio-visualizer-qml/images/stopdisabled.png
- audio-visualizer-qml/images/stophoverpressed.png
- audio-visualizer-qml/images/stopnormal.png