Changed the audio library to SFML. Now working in qt5.3.2.

This commit is contained in:
santi 2014-07-25 20:38:18 +02:00
parent 37835e7571
commit 1dd20c9b05
11 changed files with 143 additions and 319 deletions

View file

@ -1,5 +1,7 @@
#include "audiolayerwidget.h"
#include<iostream>
#include <QDebug>
#include <QVBoxLayout>
#include <QFile>
@ -10,36 +12,16 @@
AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
QGroupBox(parent)
, m_suspendResumeButton(0)
, m_deviceBox(0)
, m_watchDMX(new QTimer(this))
, m_pullTimer(new QTimer(this))
, m_device(QAudioDeviceInfo::defaultOutputDevice())
, m_audioOutput(0)
, m_output(0)
, m_buffer(BufferSize, 0)
, m_decoder(0)
, m_progressCounter(new QTime(0,0,0,1))
, m_progressMs(0)
, m_currentMedia(" ")
, m_running(false)
, m_emptyBuffer()
{
this->setTitle(name);
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));
}
m_deviceBox->setMaximumWidth(250);
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);
@ -118,35 +100,9 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
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);
// Init the silent buffer
QAudioBuffer *abuf = new QAudioBuffer(44100, m_format, -1);
QByteArray ba((const char*)abuf->data(), abuf->byteCount());
m_emptyBuffer.append(ba);
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);
m_decoder->start();
connect(m_decoder, SIGNAL(totalTimeChanged(qint64)),
this, SLOT(durationChanged(qint64)));
connect(m_pullTimer, SIGNAL(timeout()),
this, SLOT(pullTimerExpired()));
connect(m_watchDMX, SIGNAL(timeout()),
this, SLOT(watchDMXExpired()));
m_watchDMX->start(1000);
createAudioOutput();
m_watchDMX->start(200);
}
AudioLayerWidget::~AudioLayerWidget()
@ -154,54 +110,46 @@ AudioLayerWidget::~AudioLayerWidget()
}
void AudioLayerWidget::createAudioOutput()
{
m_audioOutput = new QAudioOutput(m_device, m_format, this);
Q_CHECK_PTR(m_audioOutput);
m_audioOutput->setNotifyInterval(NOTIFY_INTERVAL);
m_audioOutput->setCategory("LibreMediaServer");
connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
m_output = m_audioOutput->start();
Q_CHECK_PTR(m_output);
m_statusValue->setText(PAUSE_LABEL);
connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(handleStateChanged(QAudio::State)));
m_pullTimer->start(PULL_TIMER_INTERVAL);
}
void AudioLayerWidget::deviceChanged(int index)
{
m_pullTimer->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));
m_music.setVolume(value);
}
// volume range 0 -100
void AudioLayerWidget::setVol(qreal vol)
{
m_audioOutput->setVolume(vol);
m_music.setVolume(vol);
m_volumeSlider->blockSignals(true);
int volume = vol * 100;
m_volumeSlider->setValue(volume);
m_volumeSlider->setValue(vol);
m_volumeSlider->blockSignals(false);
}
void AudioLayerWidget::loadMedia(QString file)
{
if (m_currentMedia == file)
return;
if (QFile::exists(file)){
m_decoder->loadMedia(file);
setInitPosition();
m_currentMedia = file;
if (m_currentMedia == file ) {
fileLoaded(file);
return;
}
if (!QFile::exists(file)) {
qWarning("Can not access to file %s", file.toLatin1().constData());
return;
}
// Load an ogg music file
if (!m_music.openFromFile(file.toStdString())) {
qWarning("Can not open file %s", file.toLatin1().constData());
return;
}
m_music.setAttenuation(0);
m_progressCounter->restart();
durationChanged(m_music.getDuration().asMilliseconds());
fileLoaded(file);
// Display music informations
std::cout << file.toLatin1().constData() << " : " << std::endl;
std::cout << " " << m_music.getDuration().asSeconds() << " seconds" << std::endl;
std::cout << " " << m_music.getSampleRate() << " samples / sec" << std::endl;
std::cout << " " << m_music.getChannelCount() << " channels" << std::endl;
}
void AudioLayerWidget::fileLoaded(QString file)
@ -212,133 +160,37 @@ void AudioLayerWidget::fileLoaded(QString file)
m_folderValue->setText(list.at(size - 2));
m_fileValue->setText(list.at(size - 1));
}
m_progressMs = 0;
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(m_progressMs));
}
void AudioLayerWidget::notified()
{
m_progressMs += m_progressCounter->restart();
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(m_progressMs));
m_progressSlider->setValue(m_progressMs);
/* 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) {
if (m_running) {
const qint64 len = m_decoder->read(m_buffer.data(), m_audioOutput->periodSize());
if ( len == -1) {
stop();
qDebug("End of file %s", this->title().toLatin1().constData());
break;
}
if (len) {
m_output->write(m_buffer.data(), len);
}
if (len != m_audioOutput->periodSize())
break;
} else {
m_output->write(m_emptyBuffer.data(), m_audioOutput->periodSize());
}
--chunks;
}
}
}
void AudioLayerWidget::toggleSuspendResume()
{
if (m_audioOutput->state() == QAudio::SuspendedState) {
resume();
} else if (m_audioOutput->state() == QAudio::ActiveState) {
pause();
} else if (m_audioOutput->state() == QAudio::StoppedState) {
play();
} else if (m_audioOutput->state() == QAudio::IdleState) {
qWarning("%s: IdleState", this->title().toLatin1().constData());
reset();
resume();
}
}
void AudioLayerWidget::handleStateChanged(QAudio::State state)
{
if (state == QAudio::SuspendedState) {
m_statusValue->setText(PAUSE_LABEL);
qDebug("Pause");
} else if (state == QAudio::ActiveState) {
m_statusValue->setText(PLAY_LABEL);
qDebug("Play");
} else if (m_audioOutput->state() == QAudio::StoppedState) {
m_statusValue->setText(STOP_LABEL);
qDebug("Stop");
} else if (state == QAudio::IdleState) {
m_statusValue->setText(IDDLE_LABEL);
qDebug("Iddle");
}
}
// duration in miliseconds
void AudioLayerWidget::durationChanged(qint64 dur)
{
if (dur == -1)
return;
m_totalTimeValue->setTime(QTime::fromMSecsSinceStartOfDay(dur));
m_progressSlider->setMaximum(dur);
m_totalTimeValue->setTime(QTime::fromMSecsSinceStartOfDay(dur));
}
void AudioLayerWidget::play()
{
setInitPosition();
// m_pullTimer->start(PULL_TIMER_INTERVAL);
// m_audioOutput->resume();
m_running = true;
pullTimerExpired();
m_progressCounter->start();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
m_music.play();
m_progressCounter->restart();
}
void AudioLayerWidget::pause()
{
// m_pullTimer->stop();
// m_audioOutput->suspend();
m_running = false;
m_suspendResumeButton->setText(tr(RESUME_LABEL));
}
void AudioLayerWidget::resume()
{
// m_pullTimer->start(PULL_TIMER_INTERVAL);
// m_audioOutput->resume();
m_running = true;
pullTimerExpired();
m_progressCounter->start();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
m_music.pause();
m_progressCounter->restart();
}
void AudioLayerWidget::stop()
{
m_running = false;
setInitPosition();
}
void AudioLayerWidget::reset()
{
m_pullTimer->stop();
m_audioOutput->reset();
m_output = m_audioOutput->start();
Q_CHECK_PTR(m_output);
}
void AudioLayerWidget::setInitPosition()
{
// reset();
m_decoder->setPos(0);
m_progressMs = 0;
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(m_progressMs));
m_progressSlider->setValue(m_progressMs);
m_music.stop();
}
void AudioLayerWidget::watchDMXExpired() {
@ -348,9 +200,26 @@ void AudioLayerWidget::watchDMXExpired() {
void AudioLayerWidget::updateWatchDMX(bool b)
{
m_receiveDMX->setChecked(b);
switch (m_music.getStatus()) {
case sf::SoundSource::Playing:
m_progressMs += m_progressCounter->restart();
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(m_progressMs));
m_statusValue->setText(PLAY_LABEL);
break;
case sf::SoundSource::Paused:
m_statusValue->setText(PAUSE_LABEL);
break;
case sf::SoundSource::Stopped:
m_progressCounter->restart();
m_progressMs = 0;
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(m_progressMs));
m_statusValue->setText(STOP_LABEL);
break;
}
}
void AudioLayerWidget::flushBuffer()
void AudioLayerWidget::toggleSuspendResume()
{
// Esto es una chapuza para arreglar que reset() no limpia el buffer realmente
}