From 1fccbf64fdd0ea55b3f7c66661223ec4a2160fc4 Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 01:43:44 +0200 Subject: [PATCH] =?UTF-8?q?refactorizada=20la=20GUI,=20ola=20y=20audioengi?= =?UTF-8?q?ne=20se=20ejecutan=20fuera=20de=20widgets.=20Opci=C3=B3n=20para?= =?UTF-8?q?=20ejecutar=20sin=20mostrar=20la=20GUI.=20Los=20controles=20de?= =?UTF-8?q?=20la=20interfaz=20no=20son=20reactivos,=20no=20est=C3=A1n=20co?= =?UTF-8?q?nectados=20a=20las=20=C3=B3rdenes=20de=20audio.=20cambio=20en?= =?UTF-8?q?=20la=20personalidad=20dmx=20para=20procesar=20los=20canales=20?= =?UTF-8?q?en=20mejor=20orden.=20evita=20mandar=20dos=20veces=20los=20cana?= =?UTF-8?q?les=20dobles=20por=20cada=20dmx=20frame,=20incluyendo=20file/fo?= =?UTF-8?q?lder.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libremediaserver-audio.pro | 5 +- src/audiolayerwidget.cpp | 101 +++++------ src/audiolayerwidget.h | 8 +- src/audiowidget.cpp | 73 ++------ src/audiowidget.h | 21 +-- src/defines.h | 5 +- src/dmxPersonality.h | 43 ++--- src/libremediaserver-audio-gui.cpp | 48 ++++++ src/libremediaserver-audio-gui.h | 48 ++++++ ...audio.ui => libremediaserver-audio-gui.ui} | 0 src/libremediaserver-audio.cpp | 161 ++++++++++-------- src/libremediaserver-audio.h | 32 ++-- src/main.cpp | 39 ++--- src/main.h | 20 +++ src/miniaudioengine.cpp | 36 +++- src/miniaudioengine.h | 3 +- src/olathread.cpp | 59 ++++--- src/olathread.h | 2 +- src/slidergroup.cpp | 24 ++- src/slidergroup.h | 11 +- 20 files changed, 416 insertions(+), 323 deletions(-) create mode 100644 src/libremediaserver-audio-gui.cpp create mode 100644 src/libremediaserver-audio-gui.h rename src/{libremediaserver-audio.ui => libremediaserver-audio-gui.ui} (100%) create mode 100644 src/main.h diff --git a/libremediaserver-audio.pro b/libremediaserver-audio.pro index a33e231..154d1fe 100644 --- a/libremediaserver-audio.pro +++ b/libremediaserver-audio.pro @@ -3,6 +3,8 @@ TARGET = libremediaserver-audio QT += webkitwidgets widgets HEADERS += src/libremediaserver-audio.h \ src/dmxwidget.h \ + src/libremediaserver-audio-gui.h \ + src/main.h \ src/miniaudio.h \ src/medialibrary.h \ src/miniaudioengine.h \ @@ -15,6 +17,7 @@ HEADERS += src/libremediaserver-audio.h \ src/slidergroup.h SOURCES += src/main.cpp \ src/dmxwidget.cpp \ + src/libremediaserver-audio-gui.cpp \ src/miniaudio.c \ src/libremediaserver-audio.cpp \ src/medialibrary.cpp \ @@ -24,7 +27,7 @@ SOURCES += src/main.cpp \ src/audiowidget.cpp \ src/settings.cpp \ src/slidergroup.cpp -FORMS += src/libremediaserver-audio.ui +FORMS += src/libremediaserver-audio-gui.ui CCFLAG += -msse2 -mavx2 #-fsanitize=address -g -O0 QMAKE_CXXFLAGS += $$(CXXFLAG) #QMAKE_CXXFLAGS += -fsanitize=address -g -O0 diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 99e1996..ffb8341 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -1,64 +1,67 @@ #include "audiolayerwidget.h" +#include - -AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name, int layer): - QGroupBox(parent) +AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): + QWidget(parent) , m_layer(layer) , m_suspendResumeButton(0) { - this->setTitle(name); QVBoxLayout *layout = new QVBoxLayout; - QHBoxLayout *progressTime = new QHBoxLayout; + m_suspendResumeButton = new QPushButton(this); + m_suspendResumeButton->setText(StatusStr[Status::Iddle]); + m_suspendResumeButton->setMaximumWidth(200); + //connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); + layout->addWidget(m_suspendResumeButton); + + m_progress = new QProgressBar(this); + m_progress->setOrientation(Qt::Horizontal); + m_progress->setRange(0, 0); + m_progress->setValue(0); + m_progress->setFormat("%v / %m"); + m_progress->setMaximumWidth(200); + layout->addWidget(m_progress); + m_progressTime = new QTimeEdit; - m_progressTime->text(); + m_progressTime->setToolTip("Current Time"); + m_progressTime->setObjectName("Current Time"); m_progressTime->setDisplayFormat("h:mm:ss:zzz"); m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_progressTime->setMaximumWidth(90); + m_progressTime->setMaximumWidth(88); m_progressTime->setFocusPolicy(Qt::NoFocus); - progressTime->addWidget(m_progressTime); m_totalTimeValue = new QTimeEdit; + m_totalTimeValue->setObjectName("Track Length"); + m_totalTimeValue->setToolTip("Track Length"); m_totalTimeValue->setDisplayFormat("h:mm:ss:zzz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_totalTimeValue->setMaximumWidth(90); + m_totalTimeValue->setMaximumWidth(88); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); - progressTime->addWidget(m_totalTimeValue); - layout->addLayout(progressTime); - - m_progressSlider = new QSlider(Qt::Horizontal); - m_progressSlider->setFocusPolicy(Qt::NoFocus); - layout->addWidget(m_progressSlider); - - QGridLayout *status = new QGridLayout; - m_statusValue = new QLabel; - status->addWidget(m_statusValue, 0, 0); + QHBoxLayout *status = new QHBoxLayout; + status->addWidget(m_progressTime); + status->addWidget(m_totalTimeValue); + layout->addLayout(status); + QVBoxLayout *playback = new QVBoxLayout; m_folderValue = new QLabel; m_folderValue->setMaximumWidth(200); - status->addWidget(m_folderValue, 1, 0); + playback->addWidget(m_folderValue); m_fileValue = new QLabel; m_fileValue->setMaximumWidth(200); - status->addWidget(m_fileValue, 2, 0); - layout->addLayout(status); + playback->addWidget(m_fileValue); + layout->addLayout(playback); QHBoxLayout *volumeBox = new QHBoxLayout; - m_volume = new SliderGroup("Vol", 0 , 100, 2, NULL); + m_volume = new SliderGroup(0 , 100, 2, NULL); volumeBox->addWidget(m_volume); connect(m_volume, SIGNAL(valueChanged(float)), this, SLOT(volumeChanged(float))); - m_pan = new SliderGroup("Pan", 0 , 255, 0, NULL); + m_pan = new SliderGroup(0 , 255, 0, NULL); volumeBox->addWidget(m_pan); connect(m_pan, SIGNAL(valueChanged(float)), this, SLOT(panChanged(float))); - m_pitch = new SliderGroup("Pitch", 0 , 255, 0, NULL); + m_pitch = new SliderGroup(0 , 255, 0, NULL); volumeBox->addWidget(m_pitch); connect(m_pitch, SIGNAL(valueChanged(float)), this, SLOT(pitchChanged(float))); layout->addLayout(volumeBox); - - m_suspendResumeButton = new QPushButton(this); - m_suspendResumeButton->setText(StatusStr[Status::Stopped]); - connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); - layout->addWidget(m_suspendResumeButton); - this->setLayout(layout); } @@ -95,6 +98,7 @@ void AudioLayerWidget::toggleSuspendResume() case Status::Stopped: this->setPlaybackStatus(Status::PlayingOnce); emit uiPlaybackChanged(m_layer, Status::PlayingOnce); + case Status::Iddle: break; } } @@ -129,43 +133,40 @@ void AudioLayerWidget::fileLoaded(QString file) m_folderValue->setText(list.at(size - 2)); m_fileValue->setText(list.at(size - 1)); } + this->setPlaybackStatus(Status::Stopped); } void AudioLayerWidget::setPlaybackStatus(Status status) { m_status = status; if (status == Status::Stopped) - m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0)); - m_statusValue->blockSignals(true); + m_progress->setValue(0); m_suspendResumeButton->blockSignals(true); - m_statusValue->setText(StatusStr[status]); m_suspendResumeButton->setText(StatusStr[status]); - switch (m_status) { - case Status::Paused: - m_statusValue->setStyleSheet("QLabel { color : red; }"); - break; - case Status::PlayingLoop: - case Status::PlayingOnce: - m_statusValue->setStyleSheet("QLabel { color : green; }"); - break; - case Status::Stopped: - m_statusValue->setStyleSheet("QLabel { color : red; }"); - break; - } - m_statusValue->blockSignals(false); m_suspendResumeButton->blockSignals(false); } void AudioLayerWidget::durationChanged(float dur) { - dur *= 1000; - m_progressSlider->setMaximum(dur); + m_progress->blockSignals(true); + m_progressTime->blockSignals(true); + m_totalTimeValue->blockSignals(true); + m_progress->setRange(0, dur); + m_progress->setValue(0); + m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0)); m_totalTimeValue->setTime(QTime::fromMSecsSinceStartOfDay(dur)); + m_progress->blockSignals(false); + m_progressTime->blockSignals(false); + m_totalTimeValue->blockSignals(false); } void AudioLayerWidget::refreshUi(float progress) { progress *= 1000; - m_progressSlider->setValue(progress); + m_progress->blockSignals(true); + m_progressTime->blockSignals(true); + m_progress->setValue(progress); m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(progress)); + m_progress->blockSignals(false); + m_progressTime->blockSignals(false); } diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h index 53401fb..df5853a 100644 --- a/src/audiolayerwidget.h +++ b/src/audiolayerwidget.h @@ -4,16 +4,17 @@ #include #include #include +#include #include "defines.h" #include "slidergroup.h" -class AudioLayerWidget : public QGroupBox +class AudioLayerWidget : public QWidget { Q_OBJECT public: - explicit AudioLayerWidget(QWidget *parent = 0, QString name = "Layer", int layer = 0); + explicit AudioLayerWidget(QWidget *parent = 0, int layer = 0); ~AudioLayerWidget(); void setVol(float vol); void resume(); @@ -27,15 +28,14 @@ private: Status m_status; int m_layer; QPushButton *m_suspendResumeButton; - QLabel * m_statusValue; QLabel *m_fileValue; QLabel * m_folderValue; SliderGroup *m_volume; SliderGroup *m_pan; SliderGroup *m_pitch; - QSlider *m_progressSlider; QTimeEdit *m_progressTime; QTimeEdit *m_totalTimeValue; + QProgressBar *m_progress; public slots: void toggleSuspendResume(); diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 4b35a5c..69dc60d 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -3,119 +3,66 @@ AudioWidget::AudioWidget() : m_layout(new QHBoxLayout()) - , m_refreshUi(new QTimer(this)) { for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { - AudioLayerWidget *alw = new AudioLayerWidget(this, tr("Layer %1").arg(i + 1), i); + AudioLayerWidget *alw = new AudioLayerWidget(this, i); m_layout->insertWidget(i, alw); connect(alw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderAction(int, Slider, int))); connect(alw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiChangePlaybackStatus(int, Status))); } setLayout(m_layout); - connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); - m_refreshUi->start(UI_REFRESH_TIME); } -bool AudioWidget::startEngine(int id) +void AudioWidget::mediaLoaded(int layer, QString file, float duration) { - return (m_mae.startEngine(id)); -} - -bool AudioWidget::startEngine() -{ - return (m_mae.startEngine(Settings::getInstance()->getAudioDeviceId())); -} - -void AudioWidget::stopEngine() -{ - m_mae.stopEngine(); -} - -void AudioWidget::mediaLoaded(int layer, QString file) -{ - ma_result result; - - if (m_currentMedia[layer].compare(file) == 0 ) { - return; - } - if (!QFile::exists(file)) { - qWarning("Can not access to file %s", file.toLatin1().constData()); - return; - } - result = m_mae.loadMedia(layer, file.toLatin1().data()); - if (result != MA_SUCCESS) { - qWarning("can not open file %s", file.toLatin1().constData()); - return; - } - m_currentMedia[layer] = file; - float pLength = m_mae.getDuration(layer); - qInfo("File loaded: %s - Duration: %f secs", file.toLatin1().constData(), pLength); - m_mae.printFormatInfo(layer); QLayoutItem * const item = m_layout->itemAt(layer); dynamic_cast(item->widget())->fileLoaded(file); - dynamic_cast(item->widget())->durationChanged(pLength); + dynamic_cast(item->widget())->durationChanged(duration); } void AudioWidget::volChanged(int layer, float vol) { - m_mae.volChanged(layer, vol); QLayoutItem * const item = m_layout->itemAt(layer); dynamic_cast(item->widget())->setVol(vol); } void AudioWidget::panChanged(int layer, int pan) { - m_mae.panChanged(layer, pan); QLayoutItem * const item = m_layout->itemAt(layer); dynamic_cast(item->widget())->setPan(pan); } void AudioWidget::pitchChanged(int layer, int pitch) { - m_mae.pitchChanged(layer, pitch); QLayoutItem * const item = m_layout->itemAt(layer); dynamic_cast(item->widget())->setPitch(pitch); } void AudioWidget::playbackChanged(int layer, Status status) { - m_mae.playbackChanged(layer, status); QLayoutItem * const item = m_layout->itemAt(layer); dynamic_cast(item->widget())->setPlaybackStatus(status); } -void AudioWidget::entryPointChanged(int layer, int cursor) +void AudioWidget::cursorChanged(int layer, float cursor) { - m_mae.setCursor(layer, cursor); QLayoutItem * const item = m_layout->itemAt(layer); - AudioLayerWidget *aw = dynamic_cast(item->widget()); - aw->refreshUi(m_mae.getCursor(layer)); -} - -void AudioWidget::refreshUi() { - for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { - QLayoutItem * const item = m_layout->itemAt(i); - AudioLayerWidget *aw = dynamic_cast(item->widget()); - Status s = aw->getPlaybackStatus(); - if (s == Status::PlayingOnce || s == Status::PlayingLoop) { - aw->refreshUi(m_mae.getCursor(i)); - } - } + AudioLayerWidget *alw = dynamic_cast(item->widget()); + alw->refreshUi(cursor); } void AudioWidget::uiSliderAction(int layer, Slider s, int value) { switch (s){ case Slider::Volume: - m_mae.volChanged(layer, value); + emit uiVolChanged(layer, value); break; case Slider::Pan: - m_mae.panChanged(layer, value); + emit uiPanChanged(layer, value); break; case Slider::Pitch: - m_mae.pitchChanged(layer, value); + emit uiPitchChanged(layer, value); break; } } void AudioWidget::uiChangePlaybackStatus(int layer, Status s) { - m_mae.playbackChanged(layer, s); + emit uiPlaybackChanged(layer, s); } - diff --git a/src/audiowidget.h b/src/audiowidget.h index 254e59e..3314127 100644 --- a/src/audiowidget.h +++ b/src/audiowidget.h @@ -14,28 +14,25 @@ class AudioWidget : public QWidget public: AudioWidget(); - bool startEngine(); - bool startEngine(int id); - void stopEngine(); - void mediaLoaded(int layer, QString media ); + void mediaLoaded(int layer, QString media, float duration); void volChanged(int layer, float vol); void panChanged(int layer, int pan); void pitchChanged(int layer, int pitch); void playbackChanged(int layer, Status status); - void entryPointChanged(int layer, int cursor); - -private: - MiniAudioEngine m_mae; - QString m_currentMedia[MAX_LAYERS]; + void cursorChanged(int layer, float cursor); QHBoxLayout *m_layout; - QTimer *m_refreshUi; public slots: void uiSliderAction(int layer, Slider s, int value); void uiChangePlaybackStatus(int layer, Status s); -private slots: - void refreshUi(); +signals: + void uiMediaLoaded(int layer, QString media ); + void uiVolChanged(int layer, float vol); + void uiPanChanged(int layer, int pan); + void uiPitchChanged(int layer, int pitch); + void uiPlaybackChanged(int layer, Status status); + void uiEntryPointChanged(int layer, int cursor); }; #endif // AUDIOWIDGET_H diff --git a/src/defines.h b/src/defines.h index 68675c2..dee7850 100644 --- a/src/defines.h +++ b/src/defines.h @@ -1,8 +1,7 @@ #ifndef DEFINES_H #define DEFINES_H -//#define VERSION "LibreMediaServerAudio 0.2.0 Antigona Release" -#define VERSION "Kike Substitutor - No AI required - v0.2.0" +#define VERSION "LibreMediaServerAudio 0.2.0 Antigona Release" #define COPYRIGHT "(C) 2014-2024 Santi Noreña " #define LICENSE "GPL 3 Licensed. See LICENSE.txt.\nSound guys are not allowed to use this software." #define DEFAULT_FILE "lms-audio.xlm" @@ -22,6 +21,7 @@ enum Status Paused, PlayingOnce, PlayingLoop, + Iddle }; static const char* StatusStr[] = @@ -30,6 +30,7 @@ static const char* StatusStr[] = "Pause", "Playing One", "Playing Loop", + "Iddle", 0x0 }; diff --git a/src/dmxPersonality.h b/src/dmxPersonality.h index 1e42df7..c56829e 100644 --- a/src/dmxPersonality.h +++ b/src/dmxPersonality.h @@ -1,39 +1,16 @@ #ifndef DMXPERSONALITY_H #define DMXPERSONALITY_H -/** Define the DMX personality to avoid dealing with - * numbers and change it easyly in case - * -1 - Volumen Coarse -2 - Pan -3 - Folder -4 - File -5 - Playback - 0-24 : Play once. - 25-49: Stop. Returns to start of file. - 50-74: Pause. It keeps the time of reproductions. - 75-99: Play loop. -6 - Control - Reservado, sin uso en este momento. -7 - Volume Fine -8 - Entry Point Coarse - Punto de entrada de reproducción. -9 - Entry Point Fine - El valor de estos dos canales en centésimas de segundo. -10 - Pan -11 - Pitch -*/ +#define VOLUME_COARSE 3 +#define PAN 6 +#define DMX_FOLDER 0 +#define DMX_FILE 1 +#define PLAYBACK 8 +#define VOLUME_FINE 2 +#define ENTRY_POINT_COARSE 5 +#define ENTRY_POINT_FINE 4 +#define PITCH 7 -// ToDo: Mejor inicializacion, primero folder, file, después params, ultimo playback.7 -// quitar CONTROL no usado -#define VOLUME_COARSE 0 -#define PAN 1 -#define DMX_FOLDER 2 -#define DMX_FILE 3 -#define PLAYBACK 4 -#define CONTROL 5 -#define VOLUME_FINE 6 -#define ENTRY_POINT_COARSE 7 -#define ENTRY_POINT_FINE 8 -#define PITCH 9 - -#define LAYER_CHANNELS 10 +#define LAYER_CHANNELS 9 #endif // DMXPERSONALITY_H diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp new file mode 100644 index 0000000..a300229 --- /dev/null +++ b/src/libremediaserver-audio-gui.cpp @@ -0,0 +1,48 @@ +/* + + Libre Media Server Audio - An Open source Media Server for arts and performing. + (c) Criptomart - Santiago Noreña 2012-2024 + https://git.criptomart.net/libremediaserver + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "libremediaserver-audio-gui.h" + + +libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent) + : QMainWindow(parent) +{ + ui.setupUi(this); + this->setWindowTitle(VERSION); + m_aw = new AudioWidget; + setCentralWidget(m_aw); + m_dmxWidget = new dmxWidget(this); + QDockWidget *topWidget = new QDockWidget(tr("Master"), this); + topWidget->setAllowedAreas(Qt::TopDockWidgetArea); + topWidget->setWidget(m_dmxWidget); + addDockWidget(Qt::TopDockWidgetArea, topWidget); + connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup())); +} + +libreMediaServerAudioUi::~libreMediaServerAudioUi() +{ +} + +void libreMediaServerAudioUi::olasetup() +{ + QWebView *view = new QWebView(); + view->load(QUrl("http://localhost:9090/ola.html")); + view->show(); +} diff --git a/src/libremediaserver-audio-gui.h b/src/libremediaserver-audio-gui.h new file mode 100644 index 0000000..50b4d8b --- /dev/null +++ b/src/libremediaserver-audio-gui.h @@ -0,0 +1,48 @@ +/* + Libre Media Server Audio - An Open source Media Server for arts and performing. + (c) Criptomart - Santiago Noreña 2012-2024 + https://git.criptomart.net/libremediaserver + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef LIBREMEDIASERVERAUDIOUI_H +#define LIBREMEDIASERVERAUDIOUI_H + +#include +#include + +#include "audiowidget.h" +#include "dmxwidget.h" +#include "defines.h" +#include "ui_libremediaserver-audio-gui.h" + +class libreMediaServerAudioUi : public QMainWindow +{ + Q_OBJECT + +public: + libreMediaServerAudioUi(QWidget *parent = 0); + virtual ~libreMediaServerAudioUi(); + AudioWidget *m_aw; + dmxWidget *m_dmxWidget; + +private: + Ui::LibreMediaServerAudio ui; + +private slots: + void olasetup(); +}; + +#endif // LIBREMEDIASERVERAUDIOUI_H diff --git a/src/libremediaserver-audio.ui b/src/libremediaserver-audio-gui.ui similarity index 100% rename from src/libremediaserver-audio.ui rename to src/libremediaserver-audio-gui.ui diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index 0d595ec..d049c44 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -21,50 +21,35 @@ #include "libremediaserver-audio.h" -libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent) - : QMainWindow(parent) +libreMediaServerAudio::libreMediaServerAudio(bool gui) { - Q_UNUSED(args); - qDebug() << VERSION; - qDebug() << COPYRIGHT; - qDebug() << LICENSE; - ui.setupUi(this); - this->setWindowTitle(VERSION); + m_ui = gui; Settings *set = Settings::getInstance(); set->readFile(); m_mediaLibrary = new MediaLibrary; m_mediaLibrary->initMediaLibrary(); - m_aw = new AudioWidget; - setCentralWidget(m_aw); - m_dmxWidget = new dmxWidget(this); - QDockWidget *topWidget = new QDockWidget(tr("Master"), this); - topWidget->setAllowedAreas(Qt::TopDockWidgetArea); - topWidget->setWidget(m_dmxWidget); - addDockWidget(Qt::TopDockWidgetArea, topWidget); m_ola = new olaThread(this, set->getLayersNumber()); Q_CHECK_PTR(m_ola); m_ola->blockSignals(true); - connect(m_ola, SIGNAL (universeReceived(int)), m_dmxWidget, SLOT(updateWatchDMX(int))); connect(m_ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int))); m_ola->registerUniverse(); - connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup())); - m_aw->startEngine(); + m_mae.startEngine(set->getAudioDeviceId()); qDebug("Init Complete."); m_ola->blockSignals(false); m_ola->start(QThread::TimeCriticalPriority ); +#ifndef NOGUI + if (m_ui) { + m_refreshUi = new QTimer(this); + connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); + m_refreshUi->start(UI_REFRESH_TIME); + } +#endif } libreMediaServerAudio::~libreMediaServerAudio() { m_ola->stop(); - m_aw->stopEngine(); -} - -void libreMediaServerAudio::olasetup() -{ - QWebView *view = new QWebView(); - view->load(QUrl("http://localhost:9090/ola.html")); - view->show(); + m_mae.stopEngine(); } void libreMediaServerAudio::dmxInput(int layer, int channel, int value) @@ -73,54 +58,82 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) return; QString mediaFile = NULL; int aux; - switch(channel){ - case DMX_FOLDER: - aux = m_ola->getValue(layer, DMX_FILE); - mediaFile = m_mediaLibrary->requestNewFile(value, aux); - if (QFile::exists(mediaFile)) - m_aw->mediaLoaded(layer, mediaFile); - break; - case DMX_FILE: - aux = m_ola->getValue(layer, DMX_FOLDER); - mediaFile = m_mediaLibrary->requestNewFile(aux, value); - if (QFile::exists(mediaFile)) - m_aw->mediaLoaded(layer, mediaFile); - break; - case VOLUME_COARSE: - case VOLUME_FINE: - m_aw->volChanged(layer, (value / 65025.0f)); - break; - case PAN: - m_aw->panChanged(layer, value); - break; - case PITCH: - m_aw->pitchChanged(layer, value); - break; - case ENTRY_POINT_COARSE: - case ENTRY_POINT_FINE: - m_aw->entryPointChanged(layer, value); - break; - case PLAYBACK: - if (value == 0) - break; - aux = value / 25; - switch (aux) { - case 0 : - m_aw->playbackChanged(layer, PlayingOnce); - break; - case 1 : - m_aw->playbackChanged(layer, Stopped); - break; - case 2 : - m_aw->playbackChanged(layer, Paused); - break; - case 3 : - m_aw->playbackChanged(layer, PlayingLoop); - break; - default : - break; + if (channel == DMX_FOLDER || channel == DMX_FILE){ + int folder = (value >> 8) & 0x000000FF; + int file = value & 0x000000FF; + mediaFile = m_mediaLibrary->requestNewFile(folder, file); + if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0) + return; + if (QFile::exists(mediaFile)){ + m_mae.loadMedia(layer, mediaFile.toLatin1().data()); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); +#endif + m_currentMedia[layer] = mediaFile; + } + } else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) { + m_mae.volChanged(layer, (value / 65025.0f)); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->volChanged(layer, (value / 650.25f)); +#endif + } else if (channel == PAN) { + m_mae.panChanged(layer, value); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->panChanged(layer, value); +#endif + } else if (channel == PITCH) { + m_mae.pitchChanged(layer, value); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->pitchChanged(layer, value); +#endif + } else if (channel == ENTRY_POINT_COARSE || channel == ENTRY_POINT_FINE) { + m_mae.setCursor(layer, value); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); +#endif + + } else if (channel == PLAYBACK && value > 0) { + Status s = m_mae.getStatus(layer); + aux = value / 25; + if (s != aux) { + if (aux == 0) + s = Status::PlayingOnce; + else if (aux == 1) + s = Status::Stopped; + else if (aux == 2) + s = Status::Paused; + else if (aux == 3) + s = Status::PlayingLoop; + m_mae.playbackChanged(layer, s); +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->playbackChanged(layer, s); +#endif } - default: - break; } } + +#ifndef NOGUI +void libreMediaServerAudio::refreshUi() { + if (!m_ui) + return; + for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { + Status s = m_mae.getStatus(i); + if (s == Status::PlayingOnce || s == Status::PlayingLoop) { + m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); + } + } +} + +void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) +{ + m_lmsUi = lmsUi; + connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int))); +}; + +#endif diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 9cd154b..923a42b 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -20,35 +20,41 @@ #ifndef LIBREMEDIASERVERAUDIO_H #define LIBREMEDIASERVERAUDIO_H -#include -#include - -#include "audiowidget.h" #include "medialibrary.h" #include "olathread.h" #include "settings.h" -#include "dmxwidget.h" #include "defines.h" -#include "ui_libremediaserver-audio.h" +#ifndef NOGUI +#include "libremediaserver-audio-gui.h" +#endif -class libreMediaServerAudio : public QMainWindow +class libreMediaServerAudio : public QObject { Q_OBJECT public: - libreMediaServerAudio (QStringList args, QWidget *parent = 0); + libreMediaServerAudio(bool gui = false); virtual ~libreMediaServerAudio(); - Ui::LibreMediaServerAudio ui; + olaThread *m_ola; +#ifndef NOGUI + void setUi(libreMediaServerAudioUi *lmsUi); +#endif private: - AudioWidget *m_aw; - dmxWidget *m_dmxWidget; - olaThread *m_ola; MediaLibrary *m_mediaLibrary; + MiniAudioEngine m_mae; + QString m_currentMedia[MAX_LAYERS]; +#ifndef NOGUI + bool m_ui; + QTimer *m_refreshUi; + libreMediaServerAudioUi *m_lmsUi; +#endif private slots: - void olasetup(); void dmxInput(int layer, int channel, int value); +#ifndef NOGUI + void refreshUi(); +#endif }; #endif // LIBREMEDIASERVERAUDIO_H diff --git a/src/main.cpp b/src/main.cpp index bfadafe..99643b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,34 +18,29 @@ along with this program. If not, see . */ -#include "libremediaserver-audio.h" +#include "main.h" +bool hasUi(int &argc, char *argv[]) +{ + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--gui")) + return true; + } + return false; +} int main(int argc, char *argv[]) { QApplication app(argc, argv); - QStringList args = app.arguments(); - if (args.size() > 1) + + libreMediaServerAudio lms(hasUi(argc, argv)); +#ifndef NOGUI + if (hasUi(argc, argv)) { - if (args.contains("-v")) - { - qDebug() << VERSION; - qDebug() << COPYRIGHT; - qDebug() << LICENSE; - return 0; - } - if (args.contains("-h")) - { - qDebug() << VERSION; - qDebug() << COPYRIGHT; - qDebug() << LICENSE; - qDebug() << "Help for command line options:"; - qDebug() << "-v show the version and exits"; - qDebug() << "-h this help"; - return 0; - } + libreMediaServerAudioUi *lmsUi = new libreMediaServerAudioUi(); + lms.setUi(lmsUi); + lmsUi->show(); } - libreMediaServerAudio libreMediaServerAudio(args); - libreMediaServerAudio.show(); +#endif return app.exec(); } diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..1a96ff6 --- /dev/null +++ b/src/main.h @@ -0,0 +1,20 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include + +#include "medialibrary.h" +#include "olathread.h" +#include "settings.h" +#include "libremediaserver-audio.h" +#include "libremediaserver-audio-gui.h" +#include "defines.h" + + olaThread *m_ola; + MediaLibrary *m_mediaLibrary; + + // slots + void dmxInput(int layer, int channel, int value); + +#endif // MAIN_H diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index 6d5490c..7ec94ba 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -115,7 +115,6 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) if (m_mediaLoaded[layer] == true) { - qInfo("removing sound %i", layer); ma_sound_uninit(&m_currentSound[layer]); m_mediaLoaded[layer] = false; } @@ -137,16 +136,21 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) float MiniAudioEngine::getDuration(int layer) { ma_result result; - float ret = 0; + ma_uint64 lengthInPCMFrames; + ma_uint32 sampleRate; + float ret; if (m_mediaLoaded[layer] == false) return MA_DOES_NOT_EXIST; - result = ma_sound_get_length_in_seconds(&m_currentSound[layer], &ret); - if (result != MA_SUCCESS) - { - qWarning("Can not get duration %i", layer); - ret = 0; + result = ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &lengthInPCMFrames); + if (result != MA_SUCCESS) { + return result; } + result = ma_sound_get_data_format(&m_currentSound[layer], NULL, NULL, &sampleRate, NULL, 0); + if (result != MA_SUCCESS) { + return result; + } + ret = 1000.0f * (lengthInPCMFrames / float(sampleRate)); return ret; } @@ -161,7 +165,7 @@ float MiniAudioEngine::getCursor(int layer) if (result != MA_SUCCESS) { qWarning("Can not get cursor %i", layer); - ret = 0; + ret = -1; } return ret; } @@ -231,6 +235,8 @@ void MiniAudioEngine::playbackChanged(int layer, Status status) ma_sound_set_looping(&m_currentSound[layer], false); ma_sound_start(&m_currentSound[layer]); break; + default: + break; } } @@ -244,3 +250,17 @@ void MiniAudioEngine::setCursor(int layer, int cursor) f = (cursor * f) / 65025; ma_sound_seek_to_pcm_frame(&m_currentSound[layer], f); } + +Status MiniAudioEngine::getStatus(int layer) +{ + if (m_mediaLoaded[layer] == ma_bool8(false)) + return Status::Iddle; + if (ma_sound_is_playing(&m_currentSound[layer])) { + if (ma_sound_is_looping(&m_currentSound[layer])) + return Status::PlayingLoop; + return Status::PlayingOnce; + } + if (this->getDuration(layer) > 0) + return Status::Paused; + return Status::Stopped; +} diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 9549602..2bf224b 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -8,7 +8,7 @@ class MiniAudioEngine { - friend class AudioWidget; + friend class libreMediaServerAudio; public: MiniAudioEngine(); @@ -26,6 +26,7 @@ protected: float getCursor(int layer); void setCursor(int layer, int cursor); ma_result printFormatInfo(int layer); + Status getStatus(int layer); private: ma_resource_manager_config resourceManagerConfig; diff --git a/src/olathread.cpp b/src/olathread.cpp index ed0998b..471775c 100644 --- a/src/olathread.cpp +++ b/src/olathread.cpp @@ -63,39 +63,58 @@ void olaThread::stop() void olaThread::NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer) { - bool volSent = false; - bool entrySent = false; - foreach (const dmxSetting &i, m_dmxSettings) { if(i.universe == data.universe && i.address > -1) { + bool volSent = false; + bool entrySent = false; + bool fileSent = false; for (int j = 0; j < LAYER_CHANNELS; j++){ int value = buffer.Get((i.address) + j); if (m_dmx[i.layer][j] != value) { m_dmx[i.layer][j] = value; switch (j) { - case VOLUME_COARSE: - value = (value * 0x100) + buffer.Get(i.address + VOLUME_FINE); + case DMX_FOLDER: + value *= 0x100; + value += buffer.Get(i.address + DMX_FILE); emit dmxOutput(i.layer,j,value); - volSent = true; + m_dmx[i.layer][DMX_FILE] = buffer.Get(i.address + DMX_FILE); + fileSent = true; break; - case ENTRY_POINT_COARSE: - value = (value * 0x100) + buffer.Get(i.address + ENTRY_POINT_FINE); + case DMX_FILE: + if (fileSent) + break; + value += buffer.Get(i.address + DMX_FOLDER) * 0x100; emit dmxOutput(i.layer,j,value); - entrySent = true; + m_dmx[i.layer][DMX_FOLDER] = buffer.Get(i.address + DMX_FOLDER); + fileSent = true; break; case VOLUME_FINE: - if (volSent == false) - { - value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value; - emit dmxOutput(i.layer,j,value); - } + value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value; + emit dmxOutput(i.layer,j,value); + m_dmx[i.layer][VOLUME_COARSE] = buffer.Get(i.address + VOLUME_COARSE); + volSent = true; + break; + case VOLUME_COARSE: + if (volSent) + break; + value = (value * 0x100) + buffer.Get(i.address + VOLUME_FINE); + emit dmxOutput(i.layer,j,value); + m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE); + volSent = true; break; case ENTRY_POINT_FINE: - if (entrySent == false) - { - value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value; - emit dmxOutput(i.layer,j,value); - } + value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value; + emit dmxOutput(i.layer,j,value); + m_dmx[i.layer][ENTRY_POINT_COARSE] = buffer.Get(i.address + ENTRY_POINT_COARSE); + entrySent = true; + break; + case ENTRY_POINT_COARSE: + if (entrySent) + break; + value = (value * 0x100) + buffer.Get(i.address + ENTRY_POINT_FINE); + emit dmxOutput(i.layer,j,value); + m_dmx[i.layer][ENTRY_POINT_FINE] = buffer.Get(i.address + ENTRY_POINT_FINE); + entrySent = true; break; default: emit dmxOutput(i.layer,j,value); @@ -127,7 +146,7 @@ bool olaThread::CheckDataLoss() { void olaThread::socketClosed() { - qWarning("ola closed connection. Try reopening it... "); + qWarning("ola daemon closed connection, reopening it... "); m_clientWrapper->GetSelectServer()->Terminate(); m_client = NULL; m_clientWrapper = NULL; diff --git a/src/olathread.h b/src/olathread.h index 91d78b6..dcae35b 100644 --- a/src/olathread.h +++ b/src/olathread.h @@ -53,7 +53,7 @@ private: if (error.Success()) { qDebug("Register Universe success"); } else { - qWarning("Register command failed: %s", error.Error().c_str()); + qCritical("Register command failed: %s", error.Error().c_str()); } } /** diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index e80a03f..2941bc4 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -1,45 +1,43 @@ #include "slidergroup.h" -SliderGroup::SliderGroup(const QString &title, \ - int min, +SliderGroup::SliderGroup(int min, int max, int decimals, QWidget *parent) - : QGroupBox(title, parent) + : QWidget(parent) { - this->setFlat(true); - this->setTitle(title); + QVBoxLayout *layout = new QVBoxLayout; + layout->setAlignment(Qt::AlignHCenter); + this->setMaximumWidth(65); slider = new QSlider(Qt::Orientation::Vertical); slider->setFocusPolicy(Qt::StrongFocus); slider->setTickPosition(QSlider::TicksBothSides); slider->setTickInterval((max - min) / 11); slider->setSingleStep(1); slider->setRange(min, max); + slider->setMaximumWidth(65); valueBox = new QDoubleSpinBox(); valueBox->setFocusPolicy(Qt::NoFocus); valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - valueBox->setMaximumWidth(45); + valueBox->setMaximumWidth(65); valueBox->setRange(min, max); valueBox->setDecimals(decimals); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int))); - QVBoxLayout *slidersLayout = new QVBoxLayout(); - slidersLayout->addWidget(valueBox); - slidersLayout->addWidget(slider); - setLayout(slidersLayout); + layout->addWidget(slider); + layout->addWidget(valueBox); + this->setLayout(layout); } void SliderGroup::sliderValueChanged(int value) { + valueBox->setValue(value); if (valueBox->decimals() > 1) value /= 100.0f; emit valueChanged(value); - valueBox->setValue(value); }; void SliderGroup::setValue(float value) { - if (valueBox->decimals() > 1) - value *= 100.0f; slider->setValue(value); valueBox->setValue(value); } diff --git a/src/slidergroup.h b/src/slidergroup.h index f5bae60..8972d56 100644 --- a/src/slidergroup.h +++ b/src/slidergroup.h @@ -6,16 +6,15 @@ #include #include -class SliderGroup : public QGroupBox +class SliderGroup : public QWidget { Q_OBJECT public: - SliderGroup(const QString &title, - int min, - int max, - int decimals, - QWidget *parent = nullptr); + SliderGroup(int min, + int max, + int decimals, + QWidget *parent = nullptr); signals: void valueChanged(float value);