diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-06-28 15:55:23 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-06-28 21:45:14 +0000 |
commit | 0571dc3e96fb6ad525aef186a9cfc816652cffa5 (patch) | |
tree | 8090e00b72d8d849d97554dfd99ba17b97916888 | |
parent | bd2ef7692b82135fc2ba381cec69c4185bd4d18f (diff) |
Polish the audiopanning example
- Move the members out of the class
- Use QFormLayout for convenience
- Improve the QFileDialog handling
- Add QCommandLineParser
Change-Id: I017e2111105907c870a85ffcc0ab70a6cc222f5d
Reviewed-by: Lars Knoll <lars.knoll@gmail.com>
(cherry picked from commit 4bcf25dde4dabe068aa2741bef03e14ee12370a4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | examples/spatialaudio/audiopanning/main.cpp | 351 |
1 files changed, 202 insertions, 149 deletions
diff --git a/examples/spatialaudio/audiopanning/main.cpp b/examples/spatialaudio/audiopanning/main.cpp index ea56274e5..9eb298700 100644 --- a/examples/spatialaudio/audiopanning/main.cpp +++ b/examples/spatialaudio/audiopanning/main.cpp @@ -1,155 +1,36 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QtWidgets/QtWidgets> + #include <QtSpatialAudio/QtSpatialAudio> + +#include <QtWidgets/QApplication> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QComboBox> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QFormLayout> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QSlider> + #include <QtCore/QPropertyAnimation> 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(tr("Azimuth (-180 - 180 degree):")), 1, 0); - grid->addWidget(azimuth, 1, 1); - elevation = new QSlider(Qt::Horizontal); - elevation->setRange(-90, 90); - grid->addWidget(new QLabel(tr("Elevation (-90 - 90 degree)")), 2, 0); - grid->addWidget(elevation, 2, 1); - distance = new QSlider(Qt::Horizontal); - distance->setRange(0, 1000); - distance->setValue(100); - grid->addWidget(new QLabel(tr("Distance (0 - 10 meter):")), 3, 0); - grid->addWidget(distance, 3, 1); - occlusion = new QSlider(Qt::Horizontal); - occlusion->setRange(0, 400); - grid->addWidget(new QLabel(tr("Occlusion (0 - 4):")), 4, 0); - grid->addWidget(occlusion, 4, 1); - - roomDimension = new QSlider(Qt::Horizontal); - roomDimension->setRange(0, 10000); - roomDimension->setValue(1000); - grid->addWidget(new QLabel(tr("Room dimension (0 - 100 meter):")), 5, 0); - grid->addWidget(roomDimension, 5, 1); - - reverbGain = new QSlider(Qt::Horizontal); - reverbGain->setRange(0, 500); - reverbGain->setValue(0); - grid->addWidget(new QLabel(tr("Reverb gain (0-5):")), 6, 0); - grid->addWidget(reverbGain, 6, 1); - - reflectionGain = new QSlider(Qt::Horizontal); - reflectionGain->setRange(0, 500); - reflectionGain->setValue(0); - grid->addWidget(new QLabel(tr("Reflection gain (0-5):")), 7, 0); - grid->addWidget(reflectionGain, 7, 1); - - mode = new QComboBox; - mode->addItem(tr("Surround"), QVariant::fromValue(QAudioEngine::Surround)); - mode->addItem(tr("Stereo"), QVariant::fromValue(QAudioEngine::Stereo)); - mode->addItem(tr("Headphone"), QVariant::fromValue(QAudioEngine::Headphone)); - grid->addWidget(new QLabel(tr("Output mode:")), 8, 0); - grid->addWidget(mode, 8, 1); - - animateButton = new QCheckBox(tr("Animate sound position")); - grid->addWidget(animateButton, 9, 0); - - connect(fileEdit, &QLineEdit::textChanged, this, &AudioWidget::fileChanged); - connect(fileDialogButton, &QPushButton::clicked, this, &AudioWidget::openFileDialog); - - connect(azimuth, &QSlider::valueChanged, this, &AudioWidget::updatePosition); - connect(elevation, &QSlider::valueChanged, this, &AudioWidget::updatePosition); - connect(distance, &QSlider::valueChanged, this, &AudioWidget::updatePosition); - connect(occlusion, &QSlider::valueChanged, this, &AudioWidget::newOcclusion); - - connect(roomDimension, &QSlider::valueChanged, this, &AudioWidget::updateRoom); - connect(reverbGain, &QSlider::valueChanged, this, &AudioWidget::updateRoom); - connect(reflectionGain, &QSlider::valueChanged, this, &AudioWidget::updateRoom); - - connect(mode, &QComboBox::currentIndexChanged, this, &AudioWidget::modeChanged); - - room = new QAudioRoom(&engine); - room->setWallMaterial(QAudioRoom::BackWall, QAudioRoom::BrickBare); - room->setWallMaterial(QAudioRoom::FrontWall, QAudioRoom::BrickBare); - room->setWallMaterial(QAudioRoom::LeftWall, QAudioRoom::BrickBare); - room->setWallMaterial(QAudioRoom::RightWall, QAudioRoom::BrickBare); - room->setWallMaterial(QAudioRoom::Floor, QAudioRoom::Marble); - room->setWallMaterial(QAudioRoom::Ceiling, QAudioRoom::WoodCeiling); - updateRoom(); - - listener = new QAudioListener(&engine); - listener->setPosition({}); - listener->setRotation({}); - engine.start(); - - sound = new QSpatialSound(&engine); - updatePosition(); - - animation = new QPropertyAnimation(azimuth, "value"); - animation->setDuration(10000); - animation->setStartValue(-180); - animation->setEndValue(180); - animation->setLoopCount(-1); - connect(animateButton, &QCheckBox::toggled, this, &AudioWidget::animateChanged); - } - void setFile(const QString &file) { fileEdit->setText(file); } -private slots: - void updatePosition() - { - float az = azimuth->value()/180.*M_PI; - float el = elevation->value()/180.*M_PI; - float d = distance->value(); - - float x = d*sin(az)*cos(el); - float y = d*sin(el); - float z = -d*cos(az)*cos(el); - sound->setPosition({x, y, z}); - } - void newOcclusion() - { - sound->setOcclusionIntensity(occlusion->value()/100.); - } - void modeChanged() - { - engine.setOutputMode(mode->currentData().value<QAudioEngine::OutputMode>()); - } - void fileChanged(const QString &file) - { - sound->setSource(QUrl::fromLocalFile(file)); - sound->setSize(5); - sound->setLoops(QSpatialSound::Infinite); - } - void openFileDialog() - { - auto file = QFileDialog::getOpenFileName(this); - fileEdit->setText(file); - } - void updateRoom() - { - float d = roomDimension->value(); - room->setDimensions(QVector3D(d, d, 400)); - room->setReflectionGain(float(reflectionGain->value())/100); - room->setReverbGain(float(reverbGain->value())/100); - } - void animateChanged() - { - if (animateButton->isChecked()) - animation->start(); - else - animation->stop(); - } + AudioWidget(); + void setFile(const QString &file); +private slots: + void updatePosition(); + void newOcclusion(); + void modeChanged(); + void fileChanged(const QString &file); + void openFileDialog(); + void updateRoom(); + void animateChanged(); + +private: QLineEdit *fileEdit = nullptr; QPushButton *fileDialogButton = nullptr; QSlider *azimuth = nullptr; @@ -167,18 +48,190 @@ private slots: QAudioListener *listener = nullptr; QSpatialSound *sound = nullptr; QAudioRoom *room = nullptr; + QFileDialog *fileDialog = nullptr; }; +AudioWidget::AudioWidget() + : QWidget() +{ + setMinimumSize(400, 300); + auto *form = new QFormLayout(this); + + auto *fileLayout = new QHBoxLayout; + fileEdit = new QLineEdit; + fileEdit->setPlaceholderText(tr("Audio File")); + fileLayout->addWidget(fileEdit); + fileDialogButton = new QPushButton(tr("Choose...")); + fileLayout->addWidget(fileDialogButton); + form->addRow(fileLayout); + + azimuth = new QSlider(Qt::Horizontal); + azimuth->setRange(-180, 180); + form->addRow(tr("Azimuth (-180 - 180 degree):"), azimuth); + + elevation = new QSlider(Qt::Horizontal); + elevation->setRange(-90, 90); + form->addRow(tr("Elevation (-90 - 90 degree)"), elevation); + + distance = new QSlider(Qt::Horizontal); + distance->setRange(0, 1000); + distance->setValue(100); + form->addRow(tr("Distance (0 - 10 meter):"), distance); + + occlusion = new QSlider(Qt::Horizontal); + occlusion->setRange(0, 400); + form->addRow(tr("Occlusion (0 - 4):"), occlusion); + + roomDimension = new QSlider(Qt::Horizontal); + roomDimension->setRange(0, 10000); + roomDimension->setValue(1000); + form->addRow(tr("Room dimension (0 - 100 meter):"), roomDimension); + + reverbGain = new QSlider(Qt::Horizontal); + reverbGain->setRange(0, 500); + reverbGain->setValue(0); + form->addRow(tr("Reverb gain (0-5):"), reverbGain); + + reflectionGain = new QSlider(Qt::Horizontal); + reflectionGain->setRange(0, 500); + reflectionGain->setValue(0); + form->addRow(tr("Reflection gain (0-5):"), reflectionGain); + + mode = new QComboBox; + mode->addItem(tr("Surround"), QVariant::fromValue(QAudioEngine::Surround)); + mode->addItem(tr("Stereo"), QVariant::fromValue(QAudioEngine::Stereo)); + mode->addItem(tr("Headphone"), QVariant::fromValue(QAudioEngine::Headphone)); + + form->addRow(tr("Output mode:"), mode); + + animateButton = new QCheckBox(tr("Animate sound position")); + form->addRow(animateButton); + + connect(fileEdit, &QLineEdit::textChanged, this, &AudioWidget::fileChanged); + connect(fileDialogButton, &QPushButton::clicked, this, &AudioWidget::openFileDialog); + + connect(azimuth, &QSlider::valueChanged, this, &AudioWidget::updatePosition); + connect(elevation, &QSlider::valueChanged, this, &AudioWidget::updatePosition); + connect(distance, &QSlider::valueChanged, this, &AudioWidget::updatePosition); + connect(occlusion, &QSlider::valueChanged, this, &AudioWidget::newOcclusion); + + connect(roomDimension, &QSlider::valueChanged, this, &AudioWidget::updateRoom); + connect(reverbGain, &QSlider::valueChanged, this, &AudioWidget::updateRoom); + connect(reflectionGain, &QSlider::valueChanged, this, &AudioWidget::updateRoom); + + connect(mode, &QComboBox::currentIndexChanged, this, &AudioWidget::modeChanged); + + room = new QAudioRoom(&engine); + room->setWallMaterial(QAudioRoom::BackWall, QAudioRoom::BrickBare); + room->setWallMaterial(QAudioRoom::FrontWall, QAudioRoom::BrickBare); + room->setWallMaterial(QAudioRoom::LeftWall, QAudioRoom::BrickBare); + room->setWallMaterial(QAudioRoom::RightWall, QAudioRoom::BrickBare); + room->setWallMaterial(QAudioRoom::Floor, QAudioRoom::Marble); + room->setWallMaterial(QAudioRoom::Ceiling, QAudioRoom::WoodCeiling); + updateRoom(); + + listener = new QAudioListener(&engine); + listener->setPosition({}); + listener->setRotation({}); + engine.start(); + + sound = new QSpatialSound(&engine); + updatePosition(); + + animation = new QPropertyAnimation(azimuth, "value"); + animation->setDuration(10000); + animation->setStartValue(-180); + animation->setEndValue(180); + animation->setLoopCount(-1); + connect(animateButton, &QCheckBox::toggled, this, &AudioWidget::animateChanged); +} + +void AudioWidget::setFile(const QString &file) +{ + fileEdit->setText(file); +} + +void AudioWidget::updatePosition() +{ + const float az = azimuth->value() / 180. * M_PI; + const float el = elevation->value() / 180. * M_PI; + const float d = distance->value(); + + const float x = d * sin(az) * cos(el); + const float y = d * sin(el); + const float z = -d * cos(az) * cos(el); + sound->setPosition({x, y, z}); +} + +void AudioWidget::newOcclusion() +{ + sound->setOcclusionIntensity(occlusion->value() / 100.); +} + +void AudioWidget::modeChanged() +{ + engine.setOutputMode(mode->currentData().value<QAudioEngine::OutputMode>()); +} + +void AudioWidget::fileChanged(const QString &file) +{ + sound->setSource(QUrl::fromLocalFile(file)); + sound->setSize(5); + sound->setLoops(QSpatialSound::Infinite); +} + +void AudioWidget::openFileDialog() +{ + if (fileDialog == nullptr) { + const QString dir = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); + fileDialog = new QFileDialog(this, tr("Open Audio File"), dir); + fileDialog->setAcceptMode(QFileDialog::AcceptOpen); + const QStringList mimeTypes{"audio/mpeg", "audio/aac", "audio/x-ms-wma", + "audio/x-flac+ogg", "audio/x-wav"}; + fileDialog->setMimeTypeFilters(mimeTypes); + fileDialog->selectMimeTypeFilter(mimeTypes.constFirst()); + } + + if (fileDialog->exec() == QDialog::Accepted) + fileEdit->setText(fileDialog->selectedFiles().constFirst()); +} + +void AudioWidget::updateRoom() +{ + const float d = roomDimension->value(); + room->setDimensions(QVector3D(d, d, 400)); + room->setReflectionGain(float(reflectionGain->value()) / 100); + room->setReverbGain(float(reverbGain->value()) / 100); +} + +void AudioWidget::animateChanged() +{ + if (animateButton->isChecked()) + animation->start(); + else + animation->stop(); +} + 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); - } + QCoreApplication::setApplicationVersion(qVersion()); + QGuiApplication::setApplicationDisplayName(AudioWidget::tr("Spatial Audio test application")); + + QCommandLineParser commandLineParser; + commandLineParser.addVersionOption(); + commandLineParser.addHelpOption(); + commandLineParser.addPositionalArgument("Audio File", + "Audio File to play"); + + commandLineParser.process(app); + + AudioWidget w; + w.show(); + + if (!commandLineParser.positionalArguments().isEmpty()) + w.setFile(commandLineParser.positionalArguments().constFirst()); return app.exec(); } |