summaryrefslogtreecommitdiffstats
path: root/examples/multimedia/audiorecorder
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/audiorecorder')
-rw-r--r--examples/multimedia/audiorecorder/CMakeLists.txt51
-rw-r--r--examples/multimedia/audiorecorder/Info.plist.in44
-rw-r--r--examples/multimedia/audiorecorder/audiolevel.cpp56
-rw-r--r--examples/multimedia/audiorecorder/audiolevel.h53
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.cpp411
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.h79
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.pro1
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.ui8
-rw-r--r--examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc92
-rw-r--r--examples/multimedia/audiorecorder/main.cpp53
10 files changed, 344 insertions, 504 deletions
diff --git a/examples/multimedia/audiorecorder/CMakeLists.txt b/examples/multimedia/audiorecorder/CMakeLists.txt
new file mode 100644
index 000000000..6ff9306fe
--- /dev/null
+++ b/examples/multimedia/audiorecorder/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(audiorecorder LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimedia/audiorecorder")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Multimedia Widgets)
+
+qt_add_executable(audiorecorder
+ audiolevel.cpp audiolevel.h
+ audiorecorder.cpp audiorecorder.h audiorecorder.ui
+ main.cpp
+)
+
+set_target_properties(audiorecorder PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
+)
+
+target_include_directories(audiorecorder PUBLIC
+ ../shared
+)
+
+target_link_libraries(audiorecorder PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::Multimedia
+ Qt::Widgets
+)
+
+if(WIN32)
+ target_include_directories(audiorecorder PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+endif()
+
+install(TARGETS audiorecorder
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/multimedia/audiorecorder/Info.plist.in b/examples/multimedia/audiorecorder/Info.plist.in
new file mode 100644
index 000000000..43b966509
--- /dev/null
+++ b/examples/multimedia/audiorecorder/Info.plist.in
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
+
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+
+ <key>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Qt Multimedia Example</string>
+
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+</dict>
+</plist>
diff --git a/examples/multimedia/audiorecorder/audiolevel.cpp b/examples/multimedia/audiorecorder/audiolevel.cpp
index b13e7fbc8..444dca9a4 100644
--- a/examples/multimedia/audiorecorder/audiolevel.cpp
+++ b/examples/multimedia/audiorecorder/audiolevel.cpp
@@ -1,58 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "audiolevel.h"
+
#include <QPainter>
-AudioLevel::AudioLevel(QWidget *parent)
- : QWidget(parent)
+AudioLevel::AudioLevel(QWidget *parent) : QWidget(parent)
{
setMinimumHeight(15);
setMaximumHeight(50);
@@ -77,3 +30,4 @@ void AudioLevel::paintEvent(QPaintEvent *event)
// clear the rest of the control
painter.fillRect(widthLevel, 0, width(), height(), Qt::black);
}
+
diff --git a/examples/multimedia/audiorecorder/audiolevel.h b/examples/multimedia/audiorecorder/audiolevel.h
index 3c71264c5..7a42a8d01 100644
--- a/examples/multimedia/audiorecorder/audiolevel.h
+++ b/examples/multimedia/audiorecorder/audiolevel.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef AUDIOLEVEL_H
#define AUDIOLEVEL_H
@@ -57,7 +10,7 @@ class AudioLevel : public QWidget
{
Q_OBJECT
public:
- explicit AudioLevel(QWidget *parent = 0);
+ explicit AudioLevel(QWidget *parent = nullptr);
// Using [0; 1.0] range
void setLevel(qreal level);
diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp
index 4eecae835..4131d5d51 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.cpp
+++ b/examples/multimedia/audiorecorder/audiorecorder.cpp
@@ -1,128 +1,102 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "audiorecorder.h"
#include "audiolevel.h"
-
#include "ui_audiorecorder.h"
-#include <QAudioProbe>
-#include <QAudioRecorder>
+#include <QAudioBuffer>
+#include <QAudioDevice>
+#include <QAudioInput>
#include <QDir>
#include <QFileDialog>
+#include <QImageCapture>
+#include <QMediaDevices>
+#include <QMediaFormat>
#include <QMediaRecorder>
+#include <QMimeType>
#include <QStandardPaths>
-static qreal getPeakValue(const QAudioFormat &format);
-static QList<qreal> getBufferLevels(const QAudioBuffer &buffer);
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
-template<class T>
-static QList<qreal> getBufferLevels(const T *buffer, int frames, int channels);
+static QList<qreal> getBufferLevels(const QAudioBuffer &buffer);
-AudioRecorder::AudioRecorder()
- : ui(new Ui::AudioRecorder)
+AudioRecorder::AudioRecorder() : ui(new Ui::AudioRecorder)
{
ui->setupUi(this);
- m_audioRecorder = new QAudioRecorder(this);
- m_probe = new QAudioProbe(this);
- connect(m_probe, &QAudioProbe::audioBufferProbed,
- this, &AudioRecorder::processBuffer);
- m_probe->setSource(m_audioRecorder);
-
- //audio devices
- ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
- for (auto &device: m_audioRecorder->audioInputs()) {
- ui->audioDeviceBox->addItem(device, QVariant(device));
- }
-
- //audio codecs
- ui->audioCodecBox->addItem(tr("Default"), QVariant(QString()));
- for (auto &codecName: m_audioRecorder->supportedAudioCodecs()) {
- ui->audioCodecBox->addItem(codecName, QVariant(codecName));
- }
-
- //containers
- ui->containerBox->addItem(tr("Default"), QVariant(QString()));
- for (auto &containerName: m_audioRecorder->supportedContainers()) {
- ui->containerBox->addItem(containerName, QVariant(containerName));
- }
-
- //sample rate
- ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
- for (int sampleRate: m_audioRecorder->supportedAudioSampleRates()) {
- ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
- sampleRate));
- }
-
- //channels
+ // channels
ui->channelsBox->addItem(tr("Default"), QVariant(-1));
ui->channelsBox->addItem(QStringLiteral("1"), QVariant(1));
ui->channelsBox->addItem(QStringLiteral("2"), QVariant(2));
ui->channelsBox->addItem(QStringLiteral("4"), QVariant(4));
- //quality
- ui->qualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
- ui->qualitySlider->setValue(int(QMultimedia::NormalQuality));
+ // quality
+ ui->qualitySlider->setRange(0, int(QImageCapture::VeryHighQuality));
+ ui->qualitySlider->setValue(int(QImageCapture::NormalQuality));
- //bitrates:
+ // bit rates:
ui->bitrateBox->addItem(tr("Default"), QVariant(0));
ui->bitrateBox->addItem(QStringLiteral("32000"), QVariant(32000));
ui->bitrateBox->addItem(QStringLiteral("64000"), QVariant(64000));
ui->bitrateBox->addItem(QStringLiteral("96000"), QVariant(96000));
ui->bitrateBox->addItem(QStringLiteral("128000"), QVariant(128000));
- connect(m_audioRecorder, &QAudioRecorder::durationChanged, this, &AudioRecorder::updateProgress);
- connect(m_audioRecorder, &QAudioRecorder::statusChanged, this, &AudioRecorder::updateStatus);
- connect(m_audioRecorder, &QAudioRecorder::stateChanged, this, &AudioRecorder::onStateChanged);
- connect(m_audioRecorder, QOverload<QMediaRecorder::Error>::of(&QAudioRecorder::error), this,
+ // audio input initialization
+ init();
+}
+
+void AudioRecorder::init()
+{
+#if QT_CONFIG(permissions)
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &AudioRecorder::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
+
+ m_audioRecorder = new QMediaRecorder(this);
+ m_captureSession.setRecorder(m_audioRecorder);
+ m_captureSession.setAudioInput(new QAudioInput(this));
+ // ### replace with a monitoring output once we have it.
+ // m_probe = new QAudioProbe(this);
+ // connect(m_probe, &QAudioProbe::audioBufferProbed,
+ // this, &AudioRecorder::processBuffer);
+ // m_probe->setSource(m_audioRecorder);
+
+ // audio devices
+ m_mediaDevices = new QMediaDevices(this);
+ connect(m_mediaDevices, &QMediaDevices::audioInputsChanged, this,
+ &AudioRecorder::updateDevices);
+ updateDevices();
+
+ // audio codecs and container formats
+ updateFormats();
+ connect(ui->audioCodecBox, &QComboBox::currentIndexChanged, this,
+ &AudioRecorder::updateFormats);
+ connect(ui->containerBox, &QComboBox::currentIndexChanged, this, &AudioRecorder::updateFormats);
+
+ // sample rate
+ ui->sampleRateBox->setRange(m_captureSession.audioInput()->device().minimumSampleRate(),
+ m_captureSession.audioInput()->device().maximumSampleRate());
+ ui->sampleRateBox->setValue(
+ qBound(m_captureSession.audioInput()->device().minimumSampleRate(), 44100,
+ m_captureSession.audioInput()->device().maximumSampleRate()));
+
+ connect(m_audioRecorder, &QMediaRecorder::durationChanged, this,
+ &AudioRecorder::updateProgress);
+ connect(m_audioRecorder, &QMediaRecorder::recorderStateChanged, this,
+ &AudioRecorder::onStateChanged);
+ connect(m_audioRecorder, &QMediaRecorder::errorChanged, this,
&AudioRecorder::displayErrorMessage);
}
@@ -134,48 +108,33 @@ void AudioRecorder::updateProgress(qint64 duration)
ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
}
-void AudioRecorder::updateStatus(QMediaRecorder::Status status)
+void AudioRecorder::onStateChanged(QMediaRecorder::RecorderState state)
{
QString statusMessage;
- switch (status) {
- case QMediaRecorder::RecordingStatus:
- statusMessage = tr("Recording to %1").arg(m_audioRecorder->actualLocation().toString());
- break;
- case QMediaRecorder::PausedStatus:
- clearAudioLevels();
- statusMessage = tr("Paused");
- break;
- case QMediaRecorder::UnloadedStatus:
- case QMediaRecorder::LoadedStatus:
- clearAudioLevels();
- statusMessage = tr("Stopped");
- default:
- break;
- }
-
- if (m_audioRecorder->error() == QMediaRecorder::NoError)
- ui->statusbar->showMessage(statusMessage);
-}
-
-void AudioRecorder::onStateChanged(QMediaRecorder::State state)
-{
switch (state) {
case QMediaRecorder::RecordingState:
+ statusMessage = tr("Recording to %1").arg(m_audioRecorder->actualLocation().toString());
ui->recordButton->setText(tr("Stop"));
ui->pauseButton->setText(tr("Pause"));
break;
case QMediaRecorder::PausedState:
+ clearAudioLevels();
+ statusMessage = tr("Paused");
ui->recordButton->setText(tr("Stop"));
ui->pauseButton->setText(tr("Resume"));
break;
case QMediaRecorder::StoppedState:
+ clearAudioLevels();
+ statusMessage = tr("Stopped");
ui->recordButton->setText(tr("Record"));
ui->pauseButton->setText(tr("Pause"));
break;
}
- ui->pauseButton->setEnabled(m_audioRecorder->state() != QMediaRecorder::StoppedState);
+ ui->pauseButton->setEnabled(m_audioRecorder->recorderState() != QMediaRecorder::StoppedState);
+ if (m_audioRecorder->error() == QMediaRecorder::NoError)
+ ui->statusbar->showMessage(statusMessage);
}
static QVariant boxValue(const QComboBox *box)
@@ -189,32 +148,28 @@ static QVariant boxValue(const QComboBox *box)
void AudioRecorder::toggleRecord()
{
- if (m_audioRecorder->state() == QMediaRecorder::StoppedState) {
- m_audioRecorder->setAudioInput(boxValue(ui->audioDeviceBox).toString());
-
- QAudioEncoderSettings settings;
- settings.setCodec(boxValue(ui->audioCodecBox).toString());
- settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
- settings.setBitRate(boxValue(ui->bitrateBox).toInt());
- settings.setChannelCount(boxValue(ui->channelsBox).toInt());
- settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
- settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
- QMultimedia::ConstantQualityEncoding :
- QMultimedia::ConstantBitRateEncoding);
-
- QString container = boxValue(ui->containerBox).toString();
-
- m_audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
+ if (m_audioRecorder->recorderState() == QMediaRecorder::StoppedState) {
+ m_captureSession.audioInput()->setDevice(
+ boxValue(ui->audioDeviceBox).value<QAudioDevice>());
+
+ m_audioRecorder->setMediaFormat(selectedMediaFormat());
+ m_audioRecorder->setAudioSampleRate(ui->sampleRateBox->value());
+ m_audioRecorder->setAudioBitRate(boxValue(ui->bitrateBox).toInt());
+ m_audioRecorder->setAudioChannelCount(boxValue(ui->channelsBox).toInt());
+ m_audioRecorder->setQuality(QMediaRecorder::Quality(ui->qualitySlider->value()));
+ m_audioRecorder->setEncodingMode(ui->constantQualityRadioButton->isChecked()
+ ? QMediaRecorder::ConstantQualityEncoding
+ : QMediaRecorder::ConstantBitRateEncoding);
+
m_audioRecorder->record();
- }
- else {
+ } else {
m_audioRecorder->stop();
}
}
void AudioRecorder::togglePause()
{
- if (m_audioRecorder->state() != QMediaRecorder::PausedState)
+ if (m_audioRecorder->recorderState() != QMediaRecorder::PausedState)
m_audioRecorder->pause();
else
m_audioRecorder->record();
@@ -222,14 +177,10 @@ void AudioRecorder::togglePause()
void AudioRecorder::setOutputLocation()
{
-#ifdef Q_OS_WINRT
- // UWP does not allow to store outside the sandbox
- const QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
- if (!QDir().mkpath(cacheDir)) {
- qWarning() << "Failed to create cache directory";
- return;
- }
- QString fileName = cacheDir + QLatin1String("/output.wav");
+#ifdef Q_OS_ANDROID
+ QString fileName = QFileDialog::getSaveFileName(
+ this, tr("Save Recording"),
+ "output." + selectedMediaFormat().mimeType().preferredSuffix());
#else
QString fileName = QFileDialog::getSaveFileName();
#endif
@@ -242,48 +193,78 @@ void AudioRecorder::displayErrorMessage()
ui->statusbar->showMessage(m_audioRecorder->errorString());
}
-void AudioRecorder::clearAudioLevels()
+void AudioRecorder::updateDevices()
{
- for (int i = 0; i < m_audioLevels.size(); ++i)
- m_audioLevels.at(i)->setLevel(0);
+ const auto currentDevice = boxValue(ui->audioDeviceBox).value<QAudioDevice>();
+ int currentDeviceIndex = 0;
+
+ ui->audioDeviceBox->clear();
+
+ ui->audioDeviceBox->addItem(tr("Default"), {});
+ for (const auto &device : m_mediaDevices->audioInputs()) {
+ const auto name = device.description();
+ ui->audioDeviceBox->addItem(name, QVariant::fromValue(device));
+
+ if (device.id() == currentDevice.id())
+ currentDeviceIndex = ui->audioDeviceBox->count() - 1;
+ }
+
+ ui->audioDeviceBox->setCurrentIndex(currentDeviceIndex);
}
-// This function returns the maximum possible sample value for a given audio format
-qreal getPeakValue(const QAudioFormat& format)
+void AudioRecorder::updateFormats()
{
- // Note: Only the most common sample formats are supported
- if (!format.isValid())
- return qreal(0);
+ if (m_updatingFormats)
+ return;
+ m_updatingFormats = true;
+
+ QMediaFormat format;
+ if (ui->containerBox->count())
+ format.setFileFormat(boxValue(ui->containerBox).value<QMediaFormat::FileFormat>());
+ if (ui->audioCodecBox->count())
+ format.setAudioCodec(boxValue(ui->audioCodecBox).value<QMediaFormat::AudioCodec>());
+
+ int currentIndex = 0;
+ ui->audioCodecBox->clear();
+ ui->audioCodecBox->addItem(tr("Default audio codec"),
+ QVariant::fromValue(QMediaFormat::AudioCodec::Unspecified));
+ for (auto codec : format.supportedAudioCodecs(QMediaFormat::Encode)) {
+ if (codec == format.audioCodec())
+ currentIndex = ui->audioCodecBox->count();
+ ui->audioCodecBox->addItem(QMediaFormat::audioCodecDescription(codec),
+ QVariant::fromValue(codec));
+ }
+ ui->audioCodecBox->setCurrentIndex(currentIndex);
+
+ currentIndex = 0;
+ ui->containerBox->clear();
+ ui->containerBox->addItem(tr("Default file format"),
+ QVariant::fromValue(QMediaFormat::UnspecifiedFormat));
+ for (auto container : format.supportedFileFormats(QMediaFormat::Encode)) {
+ if (container < QMediaFormat::Mpeg4Audio) // Skip video formats
+ continue;
+ if (container == format.fileFormat())
+ currentIndex = ui->containerBox->count();
+ ui->containerBox->addItem(QMediaFormat::fileFormatDescription(container),
+ QVariant::fromValue(container));
+ }
+ ui->containerBox->setCurrentIndex(currentIndex);
- if (format.codec() != "audio/pcm")
- return qreal(0);
+ m_updatingFormats = false;
+}
- switch (format.sampleType()) {
- case QAudioFormat::Unknown:
- break;
- case QAudioFormat::Float:
- if (format.sampleSize() != 32) // other sample formats are not supported
- return qreal(0);
- return qreal(1.00003);
- case QAudioFormat::SignedInt:
- if (format.sampleSize() == 32)
- return qreal(INT_MAX);
- if (format.sampleSize() == 16)
- return qreal(SHRT_MAX);
- if (format.sampleSize() == 8)
- return qreal(CHAR_MAX);
- break;
- case QAudioFormat::UnSignedInt:
- if (format.sampleSize() == 32)
- return qreal(UINT_MAX);
- if (format.sampleSize() == 16)
- return qreal(USHRT_MAX);
- if (format.sampleSize() == 8)
- return qreal(UCHAR_MAX);
- break;
- }
+void AudioRecorder::clearAudioLevels()
+{
+ for (auto m_audioLevel : std::as_const(m_audioLevels))
+ m_audioLevel->setLevel(0);
+}
- return qreal(0);
+QMediaFormat AudioRecorder::selectedMediaFormat() const
+{
+ QMediaFormat format;
+ format.setFileFormat(boxValue(ui->containerBox).value<QMediaFormat::FileFormat>());
+ format.setAudioCodec(boxValue(ui->audioCodecBox).value<QMediaFormat::AudioCodec>());
+ return format;
}
// returns the audio level for each channel
@@ -291,70 +272,31 @@ QList<qreal> getBufferLevels(const QAudioBuffer &buffer)
{
QList<qreal> values;
- if (!buffer.format().isValid() || buffer.format().byteOrder() != QAudioFormat::LittleEndian)
- return values;
-
- if (buffer.format().codec() != "audio/pcm")
- return values;
-
- int channelCount = buffer.format().channelCount();
- values.fill(0, channelCount);
- qreal peak_value = getPeakValue(buffer.format());
- if (qFuzzyCompare(peak_value, qreal(0)))
+ auto format = buffer.format();
+ if (!format.isValid())
return values;
- switch (buffer.format().sampleType()) {
- case QAudioFormat::Unknown:
- case QAudioFormat::UnSignedInt:
- if (buffer.format().sampleSize() == 32)
- values = getBufferLevels(buffer.constData<quint32>(), buffer.frameCount(), channelCount);
- if (buffer.format().sampleSize() == 16)
- values = getBufferLevels(buffer.constData<quint16>(), buffer.frameCount(), channelCount);
- if (buffer.format().sampleSize() == 8)
- values = getBufferLevels(buffer.constData<quint8>(), buffer.frameCount(), channelCount);
- for (int i = 0; i < values.size(); ++i)
- values[i] = qAbs(values.at(i) - peak_value / 2) / (peak_value / 2);
- break;
- case QAudioFormat::Float:
- if (buffer.format().sampleSize() == 32) {
- values = getBufferLevels(buffer.constData<float>(), buffer.frameCount(), channelCount);
- for (int i = 0; i < values.size(); ++i)
- values[i] /= peak_value;
- }
- break;
- case QAudioFormat::SignedInt:
- if (buffer.format().sampleSize() == 32)
- values = getBufferLevels(buffer.constData<qint32>(), buffer.frameCount(), channelCount);
- if (buffer.format().sampleSize() == 16)
- values = getBufferLevels(buffer.constData<qint16>(), buffer.frameCount(), channelCount);
- if (buffer.format().sampleSize() == 8)
- values = getBufferLevels(buffer.constData<qint8>(), buffer.frameCount(), channelCount);
- for (int i = 0; i < values.size(); ++i)
- values[i] /= peak_value;
- break;
- }
-
- return values;
-}
+ int channels = buffer.format().channelCount();
+ values.fill(0, channels);
-template<class T>
-QList<qreal> getBufferLevels(const T *buffer, int frames, int channels)
-{
+ int bytesPerSample = format.bytesPerSample();
QList<qreal> max_values;
max_values.fill(0, channels);
- for (int i = 0; i < frames; ++i) {
+ const char *data = buffer.constData<char>();
+ for (int i = 0; i < buffer.frameCount(); ++i) {
for (int j = 0; j < channels; ++j) {
- qreal value = qAbs(qreal(buffer[i * channels + j]));
+ qreal value = qAbs(format.normalizedSampleValue(data));
if (value > max_values.at(j))
- max_values.replace(j, value);
+ max_values[j] = value;
+ data += bytesPerSample;
}
}
return max_values;
}
-void AudioRecorder::processBuffer(const QAudioBuffer& buffer)
+void AudioRecorder::processBuffer(const QAudioBuffer &buffer)
{
if (m_audioLevels.count() != buffer.format().channelCount()) {
qDeleteAll(m_audioLevels);
@@ -370,3 +312,4 @@ void AudioRecorder::processBuffer(const QAudioBuffer& buffer)
for (int i = 0; i < levels.count(); ++i)
m_audioLevels.at(i)->setLevel(levels.at(i));
}
+
diff --git a/examples/multimedia/audiorecorder/audiorecorder.h b/examples/multimedia/audiorecorder/audiorecorder.h
index 6818dba90..2ce71c162 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.h
+++ b/examples/multimedia/audiorecorder/audiorecorder.h
@@ -1,65 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef AUDIORECORDER_H
#define AUDIORECORDER_H
#include <QMainWindow>
+#include <QMediaCaptureSession>
#include <QMediaRecorder>
#include <QUrl>
QT_BEGIN_NAMESPACE
-namespace Ui { class AudioRecorder; }
-class QAudioRecorder;
-class QAudioProbe;
+namespace Ui {
+class AudioRecorder;
+}
class QAudioBuffer;
+class QMediaDevices;
QT_END_NAMESPACE
class AudioLevel;
@@ -72,28 +27,34 @@ public:
AudioRecorder();
public slots:
- void processBuffer(const QAudioBuffer&);
+ void processBuffer(const QAudioBuffer &);
private slots:
+ void init();
void setOutputLocation();
void togglePause();
void toggleRecord();
- void updateStatus(QMediaRecorder::Status);
- void onStateChanged(QMediaRecorder::State);
+ void onStateChanged(QMediaRecorder::RecorderState);
void updateProgress(qint64 pos);
void displayErrorMessage();
+ void updateDevices();
+ void updateFormats();
+
private:
void clearAudioLevels();
+ QMediaFormat selectedMediaFormat() const;
Ui::AudioRecorder *ui = nullptr;
- QAudioRecorder *m_audioRecorder = nullptr;
- QAudioProbe *m_probe = nullptr;
- QList<AudioLevel*> m_audioLevels;
- bool m_outputLocationSet = false;
+ QMediaCaptureSession m_captureSession;
+ QMediaRecorder *m_audioRecorder = nullptr;
+ QMediaDevices *m_mediaDevices = nullptr;
+ QList<AudioLevel *> m_audioLevels;
+ bool m_outputLocationSet = false;
+ bool m_updatingFormats = false;
};
#endif // AUDIORECORDER_H
diff --git a/examples/multimedia/audiorecorder/audiorecorder.pro b/examples/multimedia/audiorecorder/audiorecorder.pro
index dfd0364a4..a0e05cc03 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.pro
+++ b/examples/multimedia/audiorecorder/audiorecorder.pro
@@ -21,3 +21,4 @@ INSTALLS += target
QT+=widgets
include(../shared/shared.pri)
+
diff --git a/examples/multimedia/audiorecorder/audiorecorder.ui b/examples/multimedia/audiorecorder/audiorecorder.ui
index 6ea510524..bd2560622 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.ui
+++ b/examples/multimedia/audiorecorder/audiorecorder.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>297</width>
- <height>374</height>
+ <height>476</height>
</rect>
</property>
<property name="windowTitle">
@@ -51,9 +51,6 @@
<item row="2" column="1">
<widget class="QComboBox" name="containerBox"/>
</item>
- <item row="3" column="1">
- <widget class="QComboBox" name="sampleRateBox"/>
- </item>
<item row="1" column="1">
<widget class="QComboBox" name="audioCodecBox"/>
</item>
@@ -67,6 +64,9 @@
<item row="4" column="1">
<widget class="QComboBox" name="channelsBox"/>
</item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="sampleRateBox"/>
+ </item>
</layout>
</item>
<item row="1" column="0" colspan="3">
diff --git a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
index 4e4032bff..71481f24d 100644
--- a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
+++ b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
@@ -1,35 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** 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.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2015 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \example multimedia/audiorecorder
+ \example audiorecorder
\title Audio Recorder Example
\ingroup multimedia_examples
+ \ingroup audio_examples
+ \examplecategory {Multimedia}
\brief Discovering the available devices and supported codecs.
+ \meta {tag} {widgets}
\e{Audio Recorder} demonstrates how to identify the available devices and
supported codecs, and the use of QAudioRecorder class.
@@ -41,30 +20,33 @@
\section1 Displaying the Window and Audio Settings
We display a window for the user to select the appropriate audio input,
- codec, container, and sample rate. Allow a setting of either quality or
- bitrate. Finally, the output file can be selected and recording can be
- started.
-
- The lists are setup using the \l{QAudioRecorder::audioInputs()}{audioInputs()},
- \l{QAudioRecorder::supportedAudioCodecs()}{supportedAudioCodecs()},
- \l{QAudioRecorder::supportedContainers()}{supportedContainers()},
- \l{QAudioRecorder::supportedContainers()}{supportedContainers()}, and
- \l{QAudioRecorder::supportedAudioSampleRates()}{supportedAudioSampleRates()}
- methods. The quality slider is setup from 0 (zero) to
- \l{QMultimedia::VeryHighQuality} with a default value of
- \l{QMultimedia::NormalQuality}, while the bitrates are hardcoded
+ codec, container, sample rate, and channels. It allows setting of either
+ quality or bit rate. Finally, the output file can be selected and recording
+ can be started.
+
+ The lists are populated using the following methods:
+ \list
+ \li \l{QMediaDevices::audioInputs()}
+ \li \l{QMediaFormat::supportedAudioCodecs}
+ \li \l{QMediaFormat::supportedFileFormats}
+ \li \l{QAudioDevice::maximumSampleRate()}
+ \li \l{QAudioDevice::minimumSampleRate()}
+ \endlist
+ The quality slider is setup from 0 (zero) to
+ \l{QMediaRecorder::VeryHighQuality} with a default value of
+ \l{QMediaRecorder::NormalQuality}, while the bit rate box are hard-coded
into the list.
\section1 Recording Audio
- To record audio we simply create a QAudioRecorder object.
+ To record audio we simply create a QAudioRecorder object,
\code
audioRecorder = new QAudioRecorder(this);
\endcode
- And setup the lists as described above. The text on the record and pause
- buttons are toggled depending on the \l{QMediaRecorder::State}{state} of
+ and setup the lists as described above. The text on the record and pause
+ buttons are toggled depending on the \l{QMediaRecorder::RecorderState}{state} of
the \c audioRecorder object. This means that if the state is
\l{QMediaRecorder::StoppedState} then the button text will be "Record" and
"Pause". In \l{QMediaRecorder::RecordingState} the record button will have
@@ -72,25 +54,23 @@
will have the text "Resume".
Pressing the buttons will also result in a toggle based on the state. If
- recording is stopped, then pressing the record button will setup the
- \l{QAudioEncoderSettings} based on the values of the selection lists,
- will set the encoding settings and container on the \c audioRecorder
- object, and start recording using the
- \l{QMediaRecorder::record()}{record()} method.
+ recording is stopped, then pressing the record button will set the encoding
+ settings and container on the \c audioRecorder object, and start recording
+ using the \l{QMediaRecorder::record()}{record()} method.
\code
- QAudioEncoderSettings settings;
- settings.setCodec(boxValue(ui->audioCodecBox).toString());
- settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
- settings.setBitRate(boxValue(ui->bitrateBox).toInt());
- settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
- settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
- QMultimedia::ConstantQualityEncoding :
- QMultimedia::ConstantBitRateEncoding);
+ QMediaFormat format;
+ format.setCodec(boxValue(ui->audioCodecBox).toString());
+ audioRecorder->setMediaFormat(format);
+ audioRecorder->setSampleRate(boxValue(ui->sampleRateBox).toInt());
+ audioRecorder->setBitRate(boxValue(ui->bitrateBox).toInt());
+ audioRecorder->setQuality(QMediaRecorder::EncodingQuality(ui->qualitySlider->value()));
+ audioRecorder->setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
+ QMediaRecorder::ConstantQualityEncoding :
+ QMediaRecorder::ConstantBitRateEncoding);
QString container = boxValue(ui->containerBox).toString();
- audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
audioRecorder->record();
\endcode
diff --git a/examples/multimedia/audiorecorder/main.cpp b/examples/multimedia/audiorecorder/main.cpp
index f13940b23..407729616 100644
--- a/examples/multimedia/audiorecorder/main.cpp
+++ b/examples/multimedia/audiorecorder/main.cpp
@@ -1,56 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "audiorecorder.h"
-#include <QtWidgets>
+#include <QApplication>
int main(int argc, char *argv[])
{