Qt5 upgrade and new audio engine based in QtMultimedia.

New GUI.
This commit is contained in:
santi 2014-07-10 01:51:29 +02:00
parent 6e268323d2
commit cccd987bdd
23 changed files with 724 additions and 983 deletions

View file

@ -1,22 +1,120 @@
#include "audiolayerwidget.h"
#include <QDebug>
#include <QVBoxLayout>
#include <QFile>
#include <QTime>
AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
QGroupBox(parent)
, m_pullTimer(new QTimer(this))
, m_suspendResumeButton(0)
, m_deviceBox(0)
, m_output(0)
, m_device(QAudioDeviceInfo::defaultOutputDevice())
, m_audioOutput(0)
, m_buffer(BufferSize, 0)
{
folder = new QLabel(this);
file = new QLabel(this);
status = new QLabel(this);
vol = new QSlider(this);
vol->setMaximum(99);
mute = new QCheckBox(this);
this->setTitle(name);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(folder);
vbox->addWidget(file);
vbox->addWidget(status);
vbox->addWidget(vol);
vbox->addWidget(mute);
this->setLayout(vbox);
QVBoxLayout *layout = new QVBoxLayout;
m_deviceBox = new QComboBox(this);
const QAudioDeviceInfo &defaultDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
m_deviceBox->addItem(defaultDeviceInfo.deviceName(), qVariantFromValue(defaultDeviceInfo));
foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) {
if (deviceInfo != defaultDeviceInfo)
m_deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
}
connect(m_deviceBox,SIGNAL(activated(int)),
this, SLOT(deviceChanged(int)));
layout->addWidget(m_deviceBox);
QHBoxLayout *status = new QHBoxLayout;
m_statusLabel = new QLabel;
m_statusLabel->setText(STATUS_LABEL);
m_statusValue = new QLabel;
status->addWidget(m_statusLabel);
status->addWidget(m_statusValue);
layout->addLayout(status);
QHBoxLayout *folderLoaded = new QHBoxLayout;
m_folderLabel = new QLabel;
m_folderLabel->setText(FOLDER_LABEL);
m_folderValue = new QLabel;
folderLoaded->addWidget(m_folderLabel);
folderLoaded->addWidget(m_folderValue);
layout->addLayout(folderLoaded);
QHBoxLayout *fileLoaded = new QHBoxLayout;
m_fileLabel = new QLabel;
m_fileLabel->setText(FILE_LABEL);
m_fileValue = new QLabel;
fileLoaded->addWidget(m_fileLabel);
fileLoaded->addWidget(m_fileValue);
layout->addLayout(fileLoaded);
m_suspendResumeButton = new QPushButton(this);
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
layout->addWidget(m_suspendResumeButton);
QHBoxLayout *volumeBox = new QHBoxLayout;
m_volumeLabel = new QLabel;
m_volumeLabel->setText(tr(VOLUME_LABEL));
m_volumeSlider = new QSlider(Qt::Horizontal);
m_volumeSlider->setMinimum(0);
m_volumeSlider->setMaximum(100);
m_volumeSlider->setSingleStep(1);
connect(m_volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));
volumeBox->addWidget(m_volumeLabel);
volumeBox->addWidget(m_volumeSlider);
layout->addLayout(volumeBox);
QHBoxLayout *progressSlider = new QHBoxLayout;
m_progressLabel = new QLabel;
m_progressLabel->setText(PROGRESS_LABEL);
m_progressSlider = new QSlider(Qt::Horizontal);
progressSlider->addWidget(m_progressLabel);
progressSlider->addWidget(m_progressSlider);
layout->addLayout(progressSlider);
QHBoxLayout *progressTime = new QHBoxLayout;
m_progressTimeLabel = new QLabel;
m_progressTimeLabel->setText(PROGRESS_TIME_LABEL);
m_progressTimeValue = new QLabel;
m_progressTimeValue->setText("0:00:00:000");
progressTime->addWidget(m_progressTimeLabel);
progressTime->addWidget(m_progressTimeValue);
layout->addLayout(progressTime);
QHBoxLayout *totalTime = new QHBoxLayout;
m_totalTimeLabel = new QLabel;
m_totalTimeLabel->setText(TOTAL_TIME_LABEL);
m_totalTimeValue = new QLabel;
totalTime->addWidget(m_totalTimeLabel);
totalTime->addWidget(m_totalTimeValue);
layout->addLayout(totalTime);
this->setLayout(layout);
m_format.setSampleRate(DataSampleRateHz);
m_format.setChannelCount(2);
m_format.setSampleSize(16);
m_format.setCodec("audio/pcm");
m_format.setByteOrder(QAudioFormat::LittleEndian);
m_format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(m_format)) {
qWarning() << "Default format not supported - trying to use nearest";
m_format = info.nearestFormat(m_format);
}
m_decoder = new AudioDecoder(m_format, this);
connect(m_decoder, SIGNAL(totalTimeChanged(qint64)),
this, SLOT(durationChanged(qint64)));
connect(m_pullTimer, SIGNAL(timeout()),
this, SLOT(pullTimerExpired()));
createAudioOutput();
}
AudioLayerWidget::~AudioLayerWidget()
@ -24,3 +122,152 @@ AudioLayerWidget::~AudioLayerWidget()
}
void AudioLayerWidget::createAudioOutput()
{
m_audioOutput = new QAudioOutput(m_device, m_format, this);
m_audioOutput->setNotifyInterval(100);
connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(handleStateChanged(QAudio::State)));
m_decoder->start();
}
void AudioLayerWidget::deviceChanged(int index)
{
m_pullTimer->stop();
m_decoder->stop();
m_audioOutput->stop();
m_audioOutput->disconnect(this);
m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
createAudioOutput();
}
void AudioLayerWidget::volumeChanged(int value)
{
if (m_audioOutput)
m_audioOutput->setVolume(qreal(value/100.0f));
}
void AudioLayerWidget::setVol(qreal vol)
{
m_audioOutput->setVolume(vol);
m_volumeSlider->blockSignals(true);
int volume = vol * 100;
m_volumeSlider->setValue(volume);
m_volumeSlider->blockSignals(false);
}
void AudioLayerWidget::loadMedia(QString file)
{
stop();
if (QFile::exists(file)){
m_decoder->loadMedia(file);
fileLoaded(file);
}
}
void AudioLayerWidget::notified()
{
QTime real(0,0,0,0);
qint64 ms = m_audioOutput->processedUSecs() / 1000 ;
real = real.addMSecs(ms);
m_progressTimeValue->setText(real.toString("h:mm:ss:zzz"));
m_progressSlider->setValue(ms);
/* qDebug() << "bytesFree = " << m_audioOutput->bytesFree()
<< ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs()
<< ", " << "processedUSecs = " << m_audioOutput->processedUSecs();
*/
}
void AudioLayerWidget::pullTimerExpired()
{
if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize();
while (chunks) {
const qint64 len = m_decoder->read(m_buffer.data(), m_audioOutput->periodSize());
if ( len == -1) {
qDebug() << "End of file";
stop();
break;
}
if (len) {
m_output->write(m_buffer.data(), len);
}
if (len != m_audioOutput->periodSize())
break;
--chunks;
}
}
}
void AudioLayerWidget::toggleSuspendResume()
{
if (m_audioOutput->state() == QAudio::SuspendedState) {
// qDebug() << "status: Suspended, resume()";
m_audioOutput->resume();
m_pullTimer->start(20);
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
m_statusValue->setText(PLAY_LABEL);
} else if (m_audioOutput->state() == QAudio::ActiveState) {
// qDebug() << "status: Active, suspend()";
m_audioOutput->suspend();
m_pullTimer->stop();
m_suspendResumeButton->setText(tr(RESUME_LABEL));
m_statusValue->setText(PAUSE_LABEL);
} else if (m_audioOutput->state() == QAudio::StoppedState) {
// qDebug() << "status: Stopped, resume()";
play();
} else if (m_audioOutput->state() == QAudio::IdleState) {
// qDebug() << "status: IdleState";
m_statusValue->setText(IDDLE_LABEL);
}
}
void AudioLayerWidget::handleStateChanged(QAudio::State state)
{
qDebug() << this->title() << " state = " << state;
}
void AudioLayerWidget::durationChanged(qint64 dur)
{
if (dur == -1)
return;
QTime temp(0,0,0,0);
QTime real = temp.addMSecs(dur);
m_totalTimeValue->setText(real.toString("h:mm:ss:zzz"));
m_progressSlider->setMaximum(dur);
qDebug() << this->title() << " Duration Changed: " << dur;
}
void AudioLayerWidget::fileLoaded(QString file)
{
QStringList list = file.split("/");
int size = list.size();
if (size >= 2) {
m_folderValue->setText(list.at(size - 2));
m_fileValue->setText(list.at(size - 1));
}
}
void AudioLayerWidget::play()
{
m_decoder->setPos(0);
m_output = m_audioOutput->start();
m_pullTimer->start(20);
m_statusValue->setText(PLAY_LABEL);
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
}
void AudioLayerWidget::pause()
{
toggleSuspendResume();
}
void AudioLayerWidget::stop()
{
m_pullTimer->stop();
m_audioOutput->suspend();
m_audioOutput->reset();
m_decoder->setPos(0);
m_statusValue->setText(STOP_LABEL);
m_suspendResumeButton->setText(tr(RESUME_LABEL));
}