qt6-bb10/qtmultimedia/tests/manual/audiodecoder/audiodecoder.cpp

162 lines
4.2 KiB
C++

// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "audiodecoder.h"
#include <QtCore/qfile.h>
#include <QtCore/qdebug.h>
AudioDecoder::AudioDecoder(bool isPlayback, bool isDelete, const QString &targetFileName)
: m_cout(stdout, QIODevice::WriteOnly), m_targetFilename(targetFileName)
{
m_isPlayback = isPlayback;
m_isDelete = isDelete;
connect(&m_decoder, &QAudioDecoder::bufferReady, this, &AudioDecoder::bufferReady);
connect(&m_decoder, QOverload<QAudioDecoder::Error>::of(&QAudioDecoder::error), this,
QOverload<QAudioDecoder::Error>::of(&AudioDecoder::error));
connect(&m_decoder, &QAudioDecoder::isDecodingChanged, this, &AudioDecoder::isDecodingChanged);
connect(&m_decoder, &QAudioDecoder::finished, this, &AudioDecoder::finished);
connect(&m_decoder, &QAudioDecoder::positionChanged, this, &AudioDecoder::updateProgress);
connect(&m_decoder, &QAudioDecoder::durationChanged, this, &AudioDecoder::updateProgress);
connect(&m_soundEffect, &QSoundEffect::statusChanged, this,
&AudioDecoder::playbackStatusChanged);
connect(&m_soundEffect, &QSoundEffect::playingChanged, this, &AudioDecoder::playingChanged);
m_progress = -1.0;
}
AudioDecoder::~AudioDecoder()
{
delete m_waveDecoder;
}
void AudioDecoder::setSource(const QString &fileName)
{
m_decoder.setSource(QUrl::fromLocalFile(fileName));
}
void AudioDecoder::start()
{
m_decoder.start();
}
void AudioDecoder::stop()
{
m_decoder.stop();
}
QAudioDecoder::Error AudioDecoder::getError()
{
return m_decoder.error();
}
void AudioDecoder::setTargetFilename(const QString &fileName)
{
m_targetFilename = fileName;
}
void AudioDecoder::bufferReady()
{
// read a buffer from audio decoder
QAudioBuffer buffer = m_decoder.read();
if (!buffer.isValid())
return;
if (!m_waveDecoder) {
QIODevice *target = new QFile(m_targetFilename, this);
if (!target->open(QIODevice::WriteOnly)) {
qWarning() << "target file is not writable";
m_decoder.stop();
return;
}
m_waveDecoder = new QWaveDecoder(target, buffer.format());
}
if (!m_waveDecoder
|| (!m_waveDecoder->isOpen() && !m_waveDecoder->open(QIODevice::WriteOnly))) {
m_decoder.stop();
return;
}
m_waveDecoder->write(buffer.constData<char>(), buffer.byteCount());
}
void AudioDecoder::error(QAudioDecoder::Error error)
{
switch (error) {
case QAudioDecoder::NoError:
return;
case QAudioDecoder::ResourceError:
m_cout << "Resource error\n";
break;
case QAudioDecoder::FormatError:
m_cout << "Format error\n";
break;
case QAudioDecoder::AccessDeniedError:
m_cout << "Access denied error\n";
break;
case QAudioDecoder::NotSupportedError:
m_cout << "Service missing error\n";
break;
}
emit done();
}
void AudioDecoder::isDecodingChanged(bool isDecoding)
{
if (isDecoding)
m_cout << "Decoding...\n";
else
m_cout << "Decoding stopped\n";
}
void AudioDecoder::finished()
{
m_waveDecoder->close();
m_cout << "Decoding finished\n";
if (m_isPlayback) {
m_cout << "Starting playback\n";
m_soundEffect.setSource(QUrl::fromLocalFile(m_targetFilename));
m_soundEffect.play();
} else {
emit done();
}
}
void AudioDecoder::playbackStatusChanged()
{
if (m_soundEffect.status() == QSoundEffect::Error) {
m_cout << "Playback error\n";
emit done();
}
}
void AudioDecoder::playingChanged()
{
if (!m_soundEffect.isPlaying()) {
m_cout << "Playback finished\n";
if (m_isDelete)
QFile::remove(m_targetFilename);
emit done();
}
}
void AudioDecoder::updateProgress()
{
qint64 position = m_decoder.position();
qint64 duration = m_decoder.duration();
qreal progress = m_progress;
if (position >= 0 && duration > 0)
progress = position / (qreal)duration;
if (progress > m_progress + 0.1) {
m_cout << "Decoding progress: " << (int)(progress * 100.0) << "%\n";
m_progress = progress;
}
}