summaryrefslogtreecommitdiffstats
path: root/examples/multimedia
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2022-04-25 19:56:56 +0200
committerLars Knoll <lars.knoll@qt.io>2022-05-11 08:23:57 +0200
commitc6749ee963b68ed2b9f6afc70bcd07695734c3f2 (patch)
tree7302d07ef4b855bfef0cd241627bf73cda190e07 /examples/multimedia
parente610585d68b3ec6d655335fbf29eaafc94a6fbf8 (diff)
Add example for spatial audio
A simple widget based example that lets you pan one sound source around in space. Change-Id: I09e66fd217a136ef5bacaf7c3bb46af462993736 Reviewed-by: Rafael Roquetto <rafael.roquetto@qt.io>
Diffstat (limited to 'examples/multimedia')
-rw-r--r--examples/multimedia/CMakeLists.txt1
-rw-r--r--examples/multimedia/spatialaudio/CMakeLists.txt33
-rw-r--r--examples/multimedia/spatialaudio/main.cpp161
3 files changed, 195 insertions, 0 deletions
diff --git a/examples/multimedia/CMakeLists.txt b/examples/multimedia/CMakeLists.txt
index 6123c7994..44b701120 100644
--- a/examples/multimedia/CMakeLists.txt
+++ b/examples/multimedia/CMakeLists.txt
@@ -10,6 +10,7 @@ if(TARGET Qt::Widgets)
endif()
qt_internal_add_example(audiosource)
qt_internal_add_example(audiooutput)
+ qt_internal_add_example(spatialaudio)
endif()
if(TARGET Qt::Quick)
qt_internal_add_example(declarative-camera)
diff --git a/examples/multimedia/spatialaudio/CMakeLists.txt b/examples/multimedia/spatialaudio/CMakeLists.txt
new file mode 100644
index 000000000..9e6649fc8
--- /dev/null
+++ b/examples/multimedia/spatialaudio/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.16)
+project(audiodecoder LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimedia/spatialaudio")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Multimedia Widgets)
+
+qt_add_executable(spatialaudio
+ main.cpp
+)
+
+set_target_properties(spatialaudio PROPERTIES
+ WIN32_EXECUTABLE FALSE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(spatialaudio PUBLIC
+ Qt::Core
+ Qt::Multimedia
+ Qt::Widgets
+)
+
+install(TARGETS spatialaudio
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/multimedia/spatialaudio/main.cpp b/examples/multimedia/spatialaudio/main.cpp
new file mode 100644
index 000000000..a0f1e52b5
--- /dev/null
+++ b/examples/multimedia/spatialaudio/main.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+#include <QtWidgets/QtWidgets>
+#include <QtMultimedia/QtMultimedia>
+
+class AudioWidget : public QWidget
+{
+public:
+ AudioWidget()
+ : QWidget()
+ {
+ setWindowTitle(tr("Spatial Audio test application"));
+
+ setMinimumSize(400, 300);
+ auto *grid = new QGridLayout(this);
+ fileEdit = new QLineEdit;
+ fileDialogButton = new QPushButton(tr("Open Filedialog"));
+ grid->addWidget(fileEdit, 0, 0);
+ grid->addWidget(fileDialogButton, 0, 1);
+
+ azimuth = new QSlider(Qt::Horizontal);
+ azimuth->setRange(-180, 180);
+ grid->addWidget(new QLabel("Azimuth:"), 1, 0);
+ grid->addWidget(azimuth, 1, 1);
+ elevation = new QSlider(Qt::Horizontal);
+ elevation->setRange(-90, 90);
+ grid->addWidget(new QLabel("Elevation:"), 2, 0);
+ grid->addWidget(elevation, 2, 1);
+ distance = new QSlider(Qt::Horizontal);
+ distance->setRange(0, 100);
+ grid->addWidget(new QLabel("Distance:"), 3, 0);
+ grid->addWidget(distance, 3, 1);
+ occlusion = new QSlider(Qt::Horizontal);
+ occlusion->setRange(0, 1000);
+ grid->addWidget(new QLabel("Occlusion:"), 4, 0);
+ grid->addWidget(occlusion, 4, 1);
+
+ useHeadphone = new QCheckBox(tr("Use headphone spatialization"));
+ grid->addWidget(useHeadphone, 5, 1, 1, 2);
+
+ connect(azimuth, &QSlider::valueChanged, this, &AudioWidget::newPosition);
+ connect(elevation, &QSlider::valueChanged, this, &AudioWidget::newPosition);
+ connect(distance, &QSlider::valueChanged, this, &AudioWidget::newPosition);
+ connect(occlusion, &QSlider::valueChanged, this, &AudioWidget::newOcclusion);
+ connect(useHeadphone, &QCheckBox::stateChanged, this, &AudioWidget::useHeadphoneChanged);
+ connect(fileEdit, &QLineEdit::textChanged, this, &AudioWidget::fileChanged);
+ connect(fileDialogButton, &QPushButton::clicked, this, &AudioWidget::openFileDialog);
+
+ listener = new QSpatialAudioListener(&engine);
+ listener->setPosition({});
+ listener->setRotation({});
+ engine.start();
+
+ sound = new QSpatialAudioSoundSource(&engine);
+
+ distance->setValue(1);
+ }
+ void setFile(const QString &file) { fileEdit->setText(file); }
+private slots:
+ void newPosition()
+ {
+ float az = azimuth->value()/180.*M_PI;
+ float el = elevation->value()/180.*M_PI;
+ float d = distance->value()/10.;
+
+ float x = d*sin(az)*cos(el);
+ float y = d*cos(az)*cos(el);
+ float z = d*sin(el);
+ sound->setPosition({x, y, z});
+ }
+ void newOcclusion()
+ {
+ sound->setOcclusionIntensity(occlusion->value()/100.);
+ }
+ void useHeadphoneChanged(int state)
+ {
+ engine.setOutputMode(state ? QSpatialAudioEngine::Headphone : QSpatialAudioEngine::Stereo);
+ }
+ void fileChanged(const QString &file)
+ {
+ sound->setSource(QUrl::fromLocalFile(file));
+ }
+ void openFileDialog()
+ {
+ auto file = QFileDialog::getOpenFileName(this);
+ fileEdit->setText(file);
+ }
+
+ QLineEdit *fileEdit = nullptr;
+ QPushButton *fileDialogButton = nullptr;
+ QSlider *azimuth = nullptr;
+ QSlider *elevation = nullptr;
+ QSlider *distance = nullptr;
+ QSlider *occlusion = nullptr;
+ QCheckBox *useHeadphone = nullptr;
+
+ QSpatialAudioEngine engine;
+ QSpatialAudioListener *listener = nullptr;
+ QSpatialAudioSoundSource *sound = nullptr;
+};
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ AudioWidget *w = new AudioWidget;
+ w->show();
+ if (argc > 1) {
+ auto file = QString::fromUtf8(argv[1]);
+ w->setFile(file);
+ }
+
+ return app.exec();
+}