Qt 3D:音频可视化器范例

演示组合 Qt 3D 渲染和 Qt Quick 2 元素。

音频 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.

运行范例

要运行范例从 Qt Creator ,打开 欢迎 模式,然后选择范例从 范例 。更多信息,拜访 构建和运行范例 .

Qt Quick 2D 实现

The Qt Quick Implementation main.qml of the example uses MediaPlayer 去播放音频内容。

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 mainview 改变。

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 实现

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

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.

文件:

图像: