summaryrefslogtreecommitdiffstats
path: root/examples/multimedia/audiorecorder/audiorecorder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/audiorecorder/audiorecorder.cpp')
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.cpp218
1 files changed, 110 insertions, 108 deletions
diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp
index 992e0a486..4131d5d51 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.cpp
+++ b/examples/multimedia/audiorecorder/audiorecorder.cpp
@@ -1,125 +1,103 @@
-/****************************************************************************
-**
-** 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 <QMediaRecorder>
+#include <QAudioBuffer>
+#include <QAudioDevice>
+#include <QAudioInput>
#include <QDir>
#include <QFileDialog>
+#include <QImageCapture>
+#include <QMediaDevices>
+#include <QMediaFormat>
#include <QMediaRecorder>
-#include <QStandardPaths>
-#include <qmediadevices.h>
-#include <qmediaformat.h>
-#include <qaudiodevice.h>
-#include <qaudiobuffer.h>
-#include <qaudioinput.h>
-#include <qimagecapture.h>
#include <QMimeType>
+#include <QStandardPaths>
+
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
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 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
- ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
- for (auto device: QMediaDevices::audioInputs()) {
- auto name = device.description();
- ui->audioDeviceBox->addItem(name, QVariant::fromValue(device));
- }
-
- //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()));
-
- //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
+ // quality
ui->qualitySlider->setRange(0, int(QImageCapture::VeryHighQuality));
ui->qualitySlider->setValue(int(QImageCapture::NormalQuality));
- //bit rates:
+ // 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, &QMediaRecorder::durationChanged, this, &AudioRecorder::updateProgress);
- connect(m_audioRecorder, &QMediaRecorder::recorderStateChanged, this, &AudioRecorder::onStateChanged);
- connect(m_audioRecorder, &QMediaRecorder::errorChanged, this, &AudioRecorder::displayErrorMessage);
+ // 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);
}
void AudioRecorder::updateProgress(qint64 duration)
@@ -171,20 +149,20 @@ static QVariant boxValue(const QComboBox *box)
void AudioRecorder::toggleRecord()
{
if (m_audioRecorder->recorderState() == QMediaRecorder::StoppedState) {
- m_captureSession.audioInput()->setDevice(boxValue(ui->audioDeviceBox).value<QAudioDevice>());
+ 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->setEncodingMode(ui->constantQualityRadioButton->isChecked()
+ ? QMediaRecorder::ConstantQualityEncoding
+ : QMediaRecorder::ConstantBitRateEncoding);
m_audioRecorder->record();
- }
- else {
+ } else {
m_audioRecorder->stop();
}
}
@@ -200,9 +178,9 @@ void AudioRecorder::togglePause()
void AudioRecorder::setOutputLocation()
{
#ifdef Q_OS_ANDROID
- QString fileName = QFileDialog::getSaveFileName(this, tr("Save Recording"),
- "output."
- + selectedMediaFormat().mimeType().preferredSuffix());
+ QString fileName = QFileDialog::getSaveFileName(
+ this, tr("Save Recording"),
+ "output." + selectedMediaFormat().mimeType().preferredSuffix());
#else
QString fileName = QFileDialog::getSaveFileName();
#endif
@@ -215,6 +193,25 @@ void AudioRecorder::displayErrorMessage()
ui->statusbar->showMessage(m_audioRecorder->errorString());
}
+void AudioRecorder::updateDevices()
+{
+ 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);
+}
+
void AudioRecorder::updateFormats()
{
if (m_updatingFormats)
@@ -229,23 +226,27 @@ void AudioRecorder::updateFormats()
int currentIndex = 0;
ui->audioCodecBox->clear();
- ui->audioCodecBox->addItem(tr("Default audio codec"), QVariant::fromValue(QMediaFormat::AudioCodec::Unspecified));
+ 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->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));
+ 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->addItem(QMediaFormat::fileFormatDescription(container),
+ QVariant::fromValue(container));
}
ui->containerBox->setCurrentIndex(currentIndex);
@@ -254,7 +255,7 @@ void AudioRecorder::updateFormats()
void AudioRecorder::clearAudioLevels()
{
- for (auto m_audioLevel : qAsConst(m_audioLevels))
+ for (auto m_audioLevel : std::as_const(m_audioLevels))
m_audioLevel->setLevel(0);
}
@@ -295,7 +296,7 @@ QList<qreal> getBufferLevels(const QAudioBuffer &buffer)
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);
@@ -311,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));
}
+