From 1fccbf64fdd0ea55b3f7c66661223ec4a2160fc4 Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 01:43:44 +0200 Subject: [PATCH 01/13] =?UTF-8?q?refactorizada=20la=20GUI,=20ola=20y=20aud?= =?UTF-8?q?ioengine=20se=20ejecutan=20fuera=20de=20widgets.=20Opci=C3=B3n?= =?UTF-8?q?=20para=20ejecutar=20sin=20mostrar=20la=20GUI.=20Los=20controle?= =?UTF-8?q?s=20de=20la=20interfaz=20no=20son=20reactivos,=20no=20est=C3=A1?= =?UTF-8?q?n=20conectados=20a=20las=20=C3=B3rdenes=20de=20audio.=20cambio?= =?UTF-8?q?=20en=20la=20personalidad=20dmx=20para=20procesar=20los=20canal?= =?UTF-8?q?es=20en=20mejor=20orden.=20evita=20mandar=20dos=20veces=20los?= =?UTF-8?q?=20canales=20dobles=20por=20cada=20dmx=20frame,=20incluyendo=20?= =?UTF-8?q?file/folder.?= 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); From 88704cd7269cb6bfe5e377dff44e63fdc0e9b6ec Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 15:05:45 +0200 Subject: [PATCH 02/13] better ui, change colors and font --- docs/changelog.txt | 52 ++++++++++++++----------- docs/roadmap.txt | 18 ++++----- src/audiolayerwidget.cpp | 50 ++++++++++++++++-------- src/audiowidget.cpp | 2 + src/dmxwidget.cpp | 2 + src/libremediaserver-audio-gui.cpp | 8 ++++ src/libremediaserver-audio-gui.ui | 62 +++++++++--------------------- src/slidergroup.cpp | 29 ++++++++++++-- src/slidergroup.h | 3 +- 9 files changed, 129 insertions(+), 97 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 48b0ddf..22a7e1f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -4,39 +4,47 @@ Libre Media Server Audio - An Open source Media Server for arts and performing. https://git.criptomart.net/libremediaserver ******************************************************************************* -Lbre Media Server ChangeLog +Libre Media Server ChangeLog -v 0.2.0 Antigona (24/04/2024) -+ change engine to miniaudio because is imposible pan in SFML and it has not access to low API and audio processing. -+ Refactor all audio methods to MiniAudioEngine. + + + + + +v 0.2.0 Antígona (24/04/2024) ++ Change audio engine to miniaudio because is imposible pan in SFML and it has not access to low API and audio processing. ++ Refactor all audio methods to MiniAudioEngine class. + Select sound device output. -+ pan. -+ Show faders values. -+ play offset. ++ Pan. ++ Show faders values. New SliderGroup class. ++ Entry Point 16 bits. + Refactor AudioMasterWidget to AudioDMXReceptionWidget. -+ mp3, flac, wav (mp3 has given some errors seeking cursor...). -+ settings dialog not working, only read the conf file at startup. -+ variable number of layers. -+ olathread, send double channels only once for each dmx frame buffer. ++ Read mp3, flac, wav (mp3 has given some errors seeking cursor...). ++ Removed settings dialog, only read xml conf file at startup. ++ Real dynamic variable number of layers based on conf file setting. ++ OlaThread send double channels (volume, entry point, load media) only once for each dmx frame buffer. ++ Terminal mode without graphical interface. All audio methods has been refactorized out of QWidget world. ++ Compilation without GUI (-DNOGUI). ++ New Status "Iddle" in playbacks if is not loaded. ++ New DMX personality version, better sort for audio needs (first load media, set vol, pan, etc, last playback order); -v 0.1.3 Unreleased (19/04/2024) +v 0.1.3 Leúcade (19/04/2024) + Ubuntu 22.04 jammy. -+ Use SFML as audio engine. + Qt 5.15.3. -+ pitch. -+ loop. ++ Pitch. ++ Loop. v 0.1.2 Mayordomo (12/08/2015) -- GUI config -- Several bugs tested in real world -- variable layers -- SFML as audio engine +- GUI config. +- Several bugs tested in real world. +- Variable layers. +- SFML as audio engine. v 0.1.1 Pascual (24/09/2014) -+ First Version: 4 layers playing .ogg -+ Needs Open Lighting Arquitecture => 0.9.0 -+ Pure Data as audio engine ++ First Version: 4 layers playing .ogg. ++ Needs Open Lighting Arquitecture => 0.9.0. ++ Pure Data as audio engine. diff --git a/docs/roadmap.txt b/docs/roadmap.txt index 8ff57d7..6b12098 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -20,8 +20,8 @@ v 0.2.2 + hay que empaquetar OLA, incluirlo en el binario, o implementar sACN y linkarlo estáticamente. + https://github.com/ETCLabs/sACN - Qt6. -- audio processing (eq, rev, compresor, ...) por master y capa. -- CIPT/MSex, send icons play-pause-stop. +- Audio processing (eq, rev, compresor, ...) by master and layer. +- CIPT/MSex, send icons play/pause/stop. - Rasp build. - Octopus Sound Card support (6 outputs - 8 inputs). @@ -41,15 +41,13 @@ v 0.2.1 - audio device linked, outputs will be redirected there. - dmx address + universe settings. - Rose noise and sine generator in menu to test system. -- Keyboards strokes, load media files from ui. -- Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante. +- Ui/Ux; Keyboards strokes, load media files from ui. +- Ui/Ux: Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante. - Logs, verbosity, timestamp. -- Bufgix: depurar errores cuando no carga la librería de medias, cambia el númmero de capas, cambia el universo, etc. -- New control mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH +- New play mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH - Vumeter or indicator about audio output in layer and master. - SettingsDialog. - Load/save conf file. -- ¿stop offset? is it needed? -- decouple MiniAudioEngine from AudioWidget, starts whith no gui or with audio in a dedicated thread. -- New Status "Iddle" in playbacks if is not loaded. -- check return errors, we are too happy.... +- ¿Exit Point? is it needed? +- Hardening: check return errors, i'm too happy.... +- Tests: errors on wrong conf file. diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index ffb8341..23dcb9a 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -8,9 +8,31 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): { QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout *playback = new QVBoxLayout; + m_folderValue = new QLabel; + //m_folderValue->setMaximumWidth(160); + m_folderValue->setAlignment(Qt::AlignHCenter); + m_folderValue->setStyleSheet( + "color: white;" + "background-color: black;" + ); + playback->addWidget(m_folderValue); + m_fileValue = new QLabel; + //m_fileValue->setMaximumWidth(160); + m_fileValue->setAlignment(Qt::AlignHCenter); + m_fileValue->setStyleSheet( + "color: white;" + "background-color: black;" + ); + + playback->addWidget(m_fileValue); + playback->setSpacing(0); + playback->setContentsMargins(0, 0, 0, 0); + layout->addLayout(playback); + m_suspendResumeButton = new QPushButton(this); m_suspendResumeButton->setText(StatusStr[Status::Iddle]); - m_suspendResumeButton->setMaximumWidth(200); + //m_suspendResumeButton->setMaximumWidth(180); //connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); layout->addWidget(m_suspendResumeButton); @@ -19,7 +41,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progress->setRange(0, 0); m_progress->setValue(0); m_progress->setFormat("%v / %m"); - m_progress->setMaximumWidth(200); + //m_progress->setMaximumWidth(180); layout->addWidget(m_progress); m_progressTime = new QTimeEdit; @@ -28,7 +50,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime->setDisplayFormat("h:mm:ss:zzz"); m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_progressTime->setMaximumWidth(88); + //m_progressTime->setMaximumWidth(80); m_progressTime->setFocusPolicy(Qt::NoFocus); m_totalTimeValue = new QTimeEdit; m_totalTimeValue->setObjectName("Track Length"); @@ -36,32 +58,28 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_totalTimeValue->setDisplayFormat("h:mm:ss:zzz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_totalTimeValue->setMaximumWidth(88); + //m_totalTimeValue->setMaximumWidth(80); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); 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); - playback->addWidget(m_folderValue); - m_fileValue = new QLabel; - m_fileValue->setMaximumWidth(200); - playback->addWidget(m_fileValue); - layout->addLayout(playback); - QHBoxLayout *volumeBox = new QHBoxLayout; - m_volume = new SliderGroup(0 , 100, 2, NULL); + m_volume = new SliderGroup("Vol", 0 , 100, 2, NULL); volumeBox->addWidget(m_volume); connect(m_volume, SIGNAL(valueChanged(float)), this, SLOT(volumeChanged(float))); - m_pan = new SliderGroup(0 , 255, 0, NULL); + m_pan = new SliderGroup("Pan", 0 , 255, 0, NULL); volumeBox->addWidget(m_pan); connect(m_pan, SIGNAL(valueChanged(float)), this, SLOT(panChanged(float))); - m_pitch = new SliderGroup(0 , 255, 0, NULL); + m_pitch = new SliderGroup("Pitch", 0 , 255, 0, NULL); volumeBox->addWidget(m_pitch); + volumeBox->setSpacing(0); + volumeBox->setContentsMargins(0, 0, 0, 0); connect(m_pitch, SIGNAL(valueChanged(float)), this, SLOT(pitchChanged(float))); layout->addLayout(volumeBox); + layout->setAlignment(Qt::AlignHCenter); + layout->setSpacing(0); + layout->setContentsMargins(2, 2, 2, 2); this->setLayout(layout); } diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 69dc60d..316e43a 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -10,6 +10,8 @@ AudioWidget::AudioWidget() : connect(alw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderAction(int, Slider, int))); connect(alw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiChangePlaybackStatus(int, Status))); } + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); setLayout(m_layout); } diff --git a/src/dmxwidget.cpp b/src/dmxwidget.cpp index 60d4206..c5b4150 100644 --- a/src/dmxwidget.cpp +++ b/src/dmxwidget.cpp @@ -9,6 +9,8 @@ dmxWidget::dmxWidget(QWidget *parent) : QVBoxLayout *vbox = new QVBoxLayout; m_receiveDMX->setText("DMX Signal"); vbox->addWidget(m_receiveDMX); + vbox->setSpacing(1); + vbox->setContentsMargins(1, 1, 1, 1); this->setLayout(vbox); connect(m_watchDMX, SIGNAL(timeout()), this, SLOT(watchDMXExpired())); diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp index a300229..5c366ac 100644 --- a/src/libremediaserver-audio-gui.cpp +++ b/src/libremediaserver-audio-gui.cpp @@ -32,8 +32,16 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent) QDockWidget *topWidget = new QDockWidget(tr("Master"), this); topWidget->setAllowedAreas(Qt::TopDockWidgetArea); topWidget->setWidget(m_dmxWidget); + topWidget->setContentsMargins(0, 0, 0, 0); addDockWidget(Qt::TopDockWidgetArea, topWidget); connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup())); + this->setContentsMargins(5, 5, 5, 5); + this->setStyleSheet( + "color: white;" + "background-color: gray;" + "selection-color: blue;" + "selection-background-color: green" + ); } libreMediaServerAudioUi::~libreMediaServerAudioUi() diff --git a/src/libremediaserver-audio-gui.ui b/src/libremediaserver-audio-gui.ui index 6ade744..65c83c2 100644 --- a/src/libremediaserver-audio-gui.ui +++ b/src/libremediaserver-audio-gui.ui @@ -1,19 +1,31 @@ - Santi Noreña belfegor@gmail.com + Santi Noreña lms@criptomart.net LibreMediaServerAudio - + 0 0 - 114 - 218 + 800 + 800 + + + Unifont + 12 + 75 + true + + LibreMediaServer + + + ../../../../criptomart/artwork/logo_v2_criptomart.net.png../../../../criptomart/artwork/logo_v2_criptomart.net.png + @@ -21,7 +33,7 @@ 0 0 114 - 22 + 21 @@ -32,47 +44,9 @@ - - - Exit - - - - - Open Configuration... - - - - - Save Configuration... - - - - - Settings... - - - - - false - - - Init - - - - - IP Address - - - - - Make Thumbs - - - OLA Setup... + OLA Setup diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index 2941bc4..4bef674 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -1,6 +1,7 @@ #include "slidergroup.h" -SliderGroup::SliderGroup(int min, +SliderGroup::SliderGroup(QString name, + int min, int max, int decimals, QWidget *parent) @@ -8,23 +9,43 @@ SliderGroup::SliderGroup(int min, { QVBoxLayout *layout = new QVBoxLayout; layout->setAlignment(Qt::AlignHCenter); - this->setMaximumWidth(65); + layout->setContentsMargins(0, 0, 0, 0); + //this->setMaximumWidth(40); slider = new QSlider(Qt::Orientation::Vertical); slider->setFocusPolicy(Qt::StrongFocus); slider->setTickPosition(QSlider::TicksBothSides); slider->setTickInterval((max - min) / 11); + slider->setMinimumHeight(100); slider->setSingleStep(1); slider->setRange(min, max); - slider->setMaximumWidth(65); + //slider->setMaximumWidth(40); + slider->setToolTip(name); + slider->setStyleSheet("QSlider {" + "border: 1px solid #999999;" + "margin: 0px;" + "height: 200px;" + "width: 40px;}" + ); + slider->setContentsMargins(0, 0, 0, 0); valueBox = new QDoubleSpinBox(); valueBox->setFocusPolicy(Qt::NoFocus); valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - valueBox->setMaximumWidth(65); + //valueBox->setMaximumWidth(40); valueBox->setRange(min, max); valueBox->setDecimals(decimals); + valueBox->setObjectName(name); + valueBox->setToolTip(name); + valueBox->setAlignment(Qt::AlignHCenter); + valueBox->setContentsMargins(0, 0, 0, 0); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int))); layout->addWidget(slider); layout->addWidget(valueBox); + this->setStyleSheet("border: 1px solid #999999;" + "width: 40px;" + "margin: 0px;" + ); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); this->setLayout(layout); } diff --git a/src/slidergroup.h b/src/slidergroup.h index 8972d56..1d8cc8c 100644 --- a/src/slidergroup.h +++ b/src/slidergroup.h @@ -11,7 +11,8 @@ class SliderGroup : public QWidget Q_OBJECT public: - SliderGroup(int min, + SliderGroup(QString name, + int min, int max, int decimals, QWidget *parent = nullptr); From 5a7a82736febc489a258d9c53c342f9452781714 Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 16:45:05 +0200 Subject: [PATCH 03/13] working UI controls --- src/audiolayerwidget.cpp | 25 +++++++++++++------------ src/audiolayerwidget.h | 6 +++--- src/audiowidget.cpp | 29 ++++++++++------------------- src/audiowidget.h | 16 ++++++---------- src/libremediaserver-audio-gui.cpp | 2 +- src/libremediaserver-audio.cpp | 22 ++++++++++++++++++++++ src/libremediaserver-audio.h | 2 ++ src/medialibrary.h | 6 ------ src/slidergroup.cpp | 2 -- src/slidergroup.h | 2 +- 10 files changed, 58 insertions(+), 54 deletions(-) diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 23dcb9a..2dd1d94 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -24,7 +24,6 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): "color: white;" "background-color: black;" ); - playback->addWidget(m_fileValue); playback->setSpacing(0); playback->setContentsMargins(0, 0, 0, 0); @@ -33,7 +32,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_suspendResumeButton = new QPushButton(this); m_suspendResumeButton->setText(StatusStr[Status::Iddle]); //m_suspendResumeButton->setMaximumWidth(180); - //connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); + connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); layout->addWidget(m_suspendResumeButton); m_progress = new QProgressBar(this); @@ -47,19 +46,21 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime = new QTimeEdit; m_progressTime->setToolTip("Current Time"); m_progressTime->setObjectName("Current Time"); - m_progressTime->setDisplayFormat("h:mm:ss:zzz"); + m_progressTime->setDisplayFormat("mm:ss:zz"); m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); - //m_progressTime->setMaximumWidth(80); + m_progressTime->setMaximumWidth(75); m_progressTime->setFocusPolicy(Qt::NoFocus); + m_progressTime->setAlignment(Qt::AlignHCenter); m_totalTimeValue = new QTimeEdit; m_totalTimeValue->setObjectName("Track Length"); m_totalTimeValue->setToolTip("Track Length"); - m_totalTimeValue->setDisplayFormat("h:mm:ss:zzz"); + m_totalTimeValue->setDisplayFormat("mm:ss:zz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); - //m_totalTimeValue->setMaximumWidth(80); + m_totalTimeValue->setMaximumWidth(75); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); + m_totalTimeValue->setAlignment(Qt::AlignHCenter); QHBoxLayout *status = new QHBoxLayout; status->addWidget(m_progressTime); status->addWidget(m_totalTimeValue); @@ -67,15 +68,15 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): QHBoxLayout *volumeBox = new QHBoxLayout; m_volume = new SliderGroup("Vol", 0 , 100, 2, NULL); volumeBox->addWidget(m_volume); - connect(m_volume, SIGNAL(valueChanged(float)), this, SLOT(volumeChanged(float))); + connect(m_volume, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int))); m_pan = new SliderGroup("Pan", 0 , 255, 0, NULL); volumeBox->addWidget(m_pan); - connect(m_pan, SIGNAL(valueChanged(float)), this, SLOT(panChanged(float))); + connect(m_pan, SIGNAL(valueChanged(int)), this, SLOT(panChanged(int))); m_pitch = new SliderGroup("Pitch", 0 , 255, 0, NULL); volumeBox->addWidget(m_pitch); volumeBox->setSpacing(0); volumeBox->setContentsMargins(0, 0, 0, 0); - connect(m_pitch, SIGNAL(valueChanged(float)), this, SLOT(pitchChanged(float))); + connect(m_pitch, SIGNAL(valueChanged(int)), this, SLOT(pitchChanged(int))); layout->addLayout(volumeBox); layout->setAlignment(Qt::AlignHCenter); layout->setSpacing(0); @@ -89,17 +90,17 @@ AudioLayerWidget::~AudioLayerWidget() } // From UI. -void AudioLayerWidget::volumeChanged(float value) +void AudioLayerWidget::volumeChanged(int value) { emit(uiSliderChanged(m_layer, Slider::Volume, value)); } -void AudioLayerWidget::panChanged(float value) +void AudioLayerWidget::panChanged(int value) { emit(uiSliderChanged(m_layer, Slider::Pan, value)); } -void AudioLayerWidget::pitchChanged(float value) +void AudioLayerWidget::pitchChanged(int value) { emit(uiSliderChanged(m_layer, Slider::Pitch, value)); } diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h index df5853a..4f89d17 100644 --- a/src/audiolayerwidget.h +++ b/src/audiolayerwidget.h @@ -39,9 +39,9 @@ private: public slots: void toggleSuspendResume(); - void volumeChanged(float vol); - void panChanged(float pan); - void pitchChanged(float pitch); + void volumeChanged(int vol); + void panChanged(int pan); + void pitchChanged(int pitch); void fileLoaded(QString file); void durationChanged(float dur); void refreshUi(float progress); diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 316e43a..58ca7fd 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -1,17 +1,18 @@ #include "audiowidget.h" -AudioWidget::AudioWidget() : - m_layout(new QHBoxLayout()) +AudioWidget::AudioWidget(QWidget *parent) : + QWidget(parent) + , m_layout(new QHBoxLayout()) { for (int i= 0; i < Settings::getInstance()->getLayersNumber(); 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))); + connect(alw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SIGNAL(uiSliderChanged(int, Slider, int))); + connect(alw, SIGNAL(uiPlaybackChanged(int, Status)), this, SIGNAL(uiPlaybackChanged(int, Status))); } m_layout->setSpacing(0); - m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setContentsMargins(1, 1, 1, 1); setLayout(m_layout); } @@ -49,22 +50,12 @@ void AudioWidget::cursorChanged(int layer, float cursor) AudioLayerWidget *alw = dynamic_cast(item->widget()); alw->refreshUi(cursor); } - -void AudioWidget::uiSliderAction(int layer, Slider s, int value) +/* +void AudioWidget::uiSliderAction(int layer, Slider s, float value) { - switch (s){ - case Slider::Volume: - emit uiVolChanged(layer, value); - break; - case Slider::Pan: - emit uiPanChanged(layer, value); - break; - case Slider::Pitch: - emit uiPitchChanged(layer, value); - break; - } + emit uiSliderChanged(layer, s, value); } void AudioWidget::uiChangePlaybackStatus(int layer, Status s) { emit uiPlaybackChanged(layer, s); -} +}*/ diff --git a/src/audiowidget.h b/src/audiowidget.h index 3314127..ff3adea 100644 --- a/src/audiowidget.h +++ b/src/audiowidget.h @@ -13,7 +13,7 @@ class AudioWidget : public QWidget Q_OBJECT public: - AudioWidget(); + AudioWidget(QWidget *parent = nullptr); void mediaLoaded(int layer, QString media, float duration); void volChanged(int layer, float vol); void panChanged(int layer, int pan); @@ -21,18 +21,14 @@ public: void playbackChanged(int layer, Status status); void cursorChanged(int layer, float cursor); QHBoxLayout *m_layout; - +/* public slots: - void uiSliderAction(int layer, Slider s, int value); + void uiSliderAction(int layer, Slider s, float value); void uiChangePlaybackStatus(int layer, Status s); - +*/ 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); + void uiPlaybackChanged(int layer, Status s); + void uiSliderChanged(int layer, Slider s, int vol); }; #endif // AUDIOWIDGET_H diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp index 5c366ac..2d92918 100644 --- a/src/libremediaserver-audio-gui.cpp +++ b/src/libremediaserver-audio-gui.cpp @@ -26,7 +26,7 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent) { ui.setupUi(this); this->setWindowTitle(VERSION); - m_aw = new AudioWidget; + m_aw = new AudioWidget(this); setCentralWidget(m_aw); m_dmxWidget = new dmxWidget(this); QDockWidget *topWidget = new QDockWidget(tr("Master"), this); diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index d049c44..deb1a7d 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -134,6 +134,28 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) { m_lmsUi = lmsUi; connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int))); + connect(m_lmsUi->m_aw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderChanged(int, Slider, int))); + connect(m_lmsUi->m_aw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status))); }; +void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) +{ + switch (s){ + case Slider::Volume: + m_mae.volChanged(layer, float((value / 100.0f))); + break; + case Slider::Pan: + m_mae.panChanged(layer, value); + break; + case Slider::Pitch: + m_mae.pitchChanged(layer, value); + break; + } +} + +void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s) +{ + m_mae.playbackChanged(layer, s); +} + #endif diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 923a42b..9c8f152 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -54,6 +54,8 @@ private slots: void dmxInput(int layer, int channel, int value); #ifndef NOGUI void refreshUi(); + void uiSliderChanged(int layer, Slider s, int value); + void uiPlaybackChanged(int layer, Status s); #endif }; diff --git a/src/medialibrary.h b/src/medialibrary.h index 5a0b55b..8c2eb07 100644 --- a/src/medialibrary.h +++ b/src/medialibrary.h @@ -27,12 +27,6 @@ class MediaLibrary : public QObject public: MediaLibrary(QObject *parent = 0); - /** - * @brief request a new file from the media library - * @param int folder - the folder required - * @param int layer - file required - * @return QString the file required with full path - */ QString requestNewFile(int folder, int layer); void initMediaLibrary(); diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index 4bef674..e58588e 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -52,8 +52,6 @@ SliderGroup::SliderGroup(QString name, void SliderGroup::sliderValueChanged(int value) { valueBox->setValue(value); - if (valueBox->decimals() > 1) - value /= 100.0f; emit valueChanged(value); }; diff --git a/src/slidergroup.h b/src/slidergroup.h index 1d8cc8c..f597a5b 100644 --- a/src/slidergroup.h +++ b/src/slidergroup.h @@ -18,7 +18,7 @@ public: QWidget *parent = nullptr); signals: - void valueChanged(float value); + void valueChanged(int value); public slots: void setValue(float value); From 389966782d739776fe570fdf48a5da1dcb69e6ca Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 19:35:12 +0200 Subject: [PATCH 04/13] =?UTF-8?q?open=20file=20dialog=20clicking=20on=20fi?= =?UTF-8?q?le/folder=20labels.=20se=20atasca=20y=20se=20pone=20a=20100%,?= =?UTF-8?q?=20los=20faders=20no=20refrescan=20como=20debieran,=20parece=20?= =?UTF-8?q?que=20se=20saturan=20las=20se=C3=B1ales.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libremediaserver-audio.pro | 2 ++ src/audiolayerwidget.cpp | 29 +++++++++++++++++++++++++---- src/audiolayerwidget.h | 13 +++++++++---- src/audiowidget.cpp | 10 +--------- src/audiowidget.h | 7 ++----- src/clickablelabel.cpp | 13 +++++++++++++ src/clickablelabel.h | 22 ++++++++++++++++++++++ src/defines.h | 6 +++--- src/libremediaserver-audio.cpp | 6 ++++++ src/libremediaserver-audio.h | 1 + src/miniaudioengine.cpp | 2 ++ 11 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 src/clickablelabel.cpp create mode 100644 src/clickablelabel.h diff --git a/libremediaserver-audio.pro b/libremediaserver-audio.pro index 154d1fe..42ef0d1 100644 --- a/libremediaserver-audio.pro +++ b/libremediaserver-audio.pro @@ -2,6 +2,7 @@ TEMPLATE = app TARGET = libremediaserver-audio QT += webkitwidgets widgets HEADERS += src/libremediaserver-audio.h \ + src/clickablelabel.h \ src/dmxwidget.h \ src/libremediaserver-audio-gui.h \ src/main.h \ @@ -16,6 +17,7 @@ HEADERS += src/libremediaserver-audio.h \ src/settings.h \ src/slidergroup.h SOURCES += src/main.cpp \ + src/clickablelabel.cpp \ src/dmxwidget.cpp \ src/libremediaserver-audio-gui.cpp \ src/miniaudio.c \ diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 2dd1d94..ee112dd 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -9,7 +9,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *playback = new QVBoxLayout; - m_folderValue = new QLabel; + m_folderValue = new ClickableLabel; //m_folderValue->setMaximumWidth(160); m_folderValue->setAlignment(Qt::AlignHCenter); m_folderValue->setStyleSheet( @@ -17,7 +17,9 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): "background-color: black;" ); playback->addWidget(m_folderValue); - m_fileValue = new QLabel; + m_fileValue = new ClickableLabel; + connect(m_fileValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); + connect(m_folderValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); //m_fileValue->setMaximumWidth(160); m_fileValue->setAlignment(Qt::AlignHCenter); m_fileValue->setStyleSheet( @@ -52,6 +54,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime->setMaximumWidth(75); m_progressTime->setFocusPolicy(Qt::NoFocus); m_progressTime->setAlignment(Qt::AlignHCenter); + m_progressTime->setContentsMargins(0,0,0,0); m_totalTimeValue = new QTimeEdit; m_totalTimeValue->setObjectName("Track Length"); m_totalTimeValue->setToolTip("Track Length"); @@ -61,6 +64,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_totalTimeValue->setMaximumWidth(75); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); m_totalTimeValue->setAlignment(Qt::AlignHCenter); + m_totalTimeValue->setContentsMargins(0,0,0,0); QHBoxLayout *status = new QHBoxLayout; status->addWidget(m_progressTime); status->addWidget(m_totalTimeValue); @@ -115,13 +119,28 @@ void AudioLayerWidget::toggleSuspendResume() break; case Status::Paused: case Status::Stopped: - this->setPlaybackStatus(Status::PlayingOnce); + //this->setPlaybackStatus(Status::PlayingOnce); emit uiPlaybackChanged(m_layer, Status::PlayingOnce); case Status::Iddle: break; } } +void AudioLayerWidget::openMediaDialog() +{ + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter(tr("Sound Tracks (*.mp3 *.mp3 *.flac *.wav")); + dialog.setViewMode(QFileDialog::Detail); + dialog.setDirectory(Settings::getInstance()->getPathMedia()); + if (!dialog.exec()) + return; + QStringList fileNames; + fileNames = dialog.selectedFiles(); + emit uiLoadMedia(m_layer, fileNames.at(0)); + this->fileLoaded(fileNames.at(0)); +} + // from DMX signals void AudioLayerWidget::setVol(float vol) { @@ -157,10 +176,12 @@ void AudioLayerWidget::fileLoaded(QString file) void AudioLayerWidget::setPlaybackStatus(Status status) { + if (StatusStr[status] == m_suspendResumeButton->text()) + return; + m_suspendResumeButton->blockSignals(true); m_status = status; if (status == Status::Stopped) m_progress->setValue(0); - m_suspendResumeButton->blockSignals(true); m_suspendResumeButton->setText(StatusStr[status]); m_suspendResumeButton->blockSignals(false); } diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h index 4f89d17..c0c6b3b 100644 --- a/src/audiolayerwidget.h +++ b/src/audiolayerwidget.h @@ -3,11 +3,13 @@ #include #include -#include +#include #include #include "defines.h" #include "slidergroup.h" +#include "clickablelabel.h" +#include "settings.h" class AudioLayerWidget : public QWidget { @@ -28,8 +30,8 @@ private: Status m_status; int m_layer; QPushButton *m_suspendResumeButton; - QLabel *m_fileValue; - QLabel * m_folderValue; + ClickableLabel *m_fileValue; + ClickableLabel * m_folderValue; SliderGroup *m_volume; SliderGroup *m_pan; SliderGroup *m_pitch; @@ -46,10 +48,13 @@ public slots: void durationChanged(float dur); void refreshUi(float progress); +private slots: + void openMediaDialog(); + signals: void uiPlaybackChanged(int layer, Status s); void uiSliderChanged(int layer, Slider s, int value); - + void uiLoadMedia(int layer, QString s); }; #endif // AUDIOLAYERWIDGET_H diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 58ca7fd..47d7ce5 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -10,6 +10,7 @@ AudioWidget::AudioWidget(QWidget *parent) : m_layout->insertWidget(i, alw); connect(alw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SIGNAL(uiSliderChanged(int, Slider, int))); connect(alw, SIGNAL(uiPlaybackChanged(int, Status)), this, SIGNAL(uiPlaybackChanged(int, Status))); + connect(alw, SIGNAL(uiLoadMedia(int, QString)), this, SIGNAL(uiLoadMedia(int, QString))); } m_layout->setSpacing(0); m_layout->setContentsMargins(1, 1, 1, 1); @@ -50,12 +51,3 @@ void AudioWidget::cursorChanged(int layer, float cursor) AudioLayerWidget *alw = dynamic_cast(item->widget()); alw->refreshUi(cursor); } -/* -void AudioWidget::uiSliderAction(int layer, Slider s, float value) -{ - emit uiSliderChanged(layer, s, value); -} - -void AudioWidget::uiChangePlaybackStatus(int layer, Status s) { - emit uiPlaybackChanged(layer, s); -}*/ diff --git a/src/audiowidget.h b/src/audiowidget.h index ff3adea..a293a0a 100644 --- a/src/audiowidget.h +++ b/src/audiowidget.h @@ -21,14 +21,11 @@ public: void playbackChanged(int layer, Status status); void cursorChanged(int layer, float cursor); QHBoxLayout *m_layout; -/* -public slots: - void uiSliderAction(int layer, Slider s, float value); - void uiChangePlaybackStatus(int layer, Status s); -*/ + signals: void uiPlaybackChanged(int layer, Status s); void uiSliderChanged(int layer, Slider s, int vol); + void uiLoadMedia(int layer, QString s); }; #endif // AUDIOWIDGET_H diff --git a/src/clickablelabel.cpp b/src/clickablelabel.cpp new file mode 100644 index 0000000..333219b --- /dev/null +++ b/src/clickablelabel.cpp @@ -0,0 +1,13 @@ +#include "clickablelabel.h" + +ClickableLabel::ClickableLabel(QWidget *parent, Qt::WindowFlags f) + : QLabel{parent} +{ + +} + +ClickableLabel::~ClickableLabel() {} + +void ClickableLabel::mousePressEvent(QMouseEvent* event) { + emit clicked(); +} diff --git a/src/clickablelabel.h b/src/clickablelabel.h new file mode 100644 index 0000000..e75aae7 --- /dev/null +++ b/src/clickablelabel.h @@ -0,0 +1,22 @@ +#ifndef CLICKABLELABEL_H +#define CLICKABLELABEL_H + +#include +#include +#include + +class ClickableLabel : public QLabel +{ + Q_OBJECT +public: + explicit ClickableLabel(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); + ~ClickableLabel(); + +signals: + void clicked(); + +protected: + void mousePressEvent(QMouseEvent* event); +}; + +#endif // CLICKABLELABEL_H diff --git a/src/defines.h b/src/defines.h index dee7850..633b06c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -3,10 +3,10 @@ #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 LICENSE "GPL 3 Licensed. See LICENSE.txt." #define DEFAULT_FILE "lms-audio.xlm" -#define MAX_LAYERS 16 -#define UI_REFRESH_TIME 200 +#define MAX_LAYERS 4 +#define UI_REFRESH_TIME 1000 // struct where save the DMX settings for each layer struct dmxSetting { diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index deb1a7d..b59a8f1 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -126,6 +126,7 @@ void libreMediaServerAudio::refreshUi() { Status s = m_mae.getStatus(i); if (s == Status::PlayingOnce || s == Status::PlayingLoop) { m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); + //m_lmsUi->m_aw->playbackChanged(i, s); } } } @@ -136,6 +137,7 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int))); connect(m_lmsUi->m_aw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderChanged(int, Slider, int))); connect(m_lmsUi->m_aw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status))); + connect(m_lmsUi->m_aw, SIGNAL(uiLoadMedia(int, QString)), this, SLOT(uiLoadMedia(int, QString))); }; void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) @@ -158,4 +160,8 @@ void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s) m_mae.playbackChanged(layer, s); } +void libreMediaServerAudio::uiLoadMedia(int layer, QString s) +{ + m_mae.loadMedia(layer, s.toLatin1().data()); +} #endif diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 9c8f152..6b80f97 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -56,6 +56,7 @@ private slots: void refreshUi(); void uiSliderChanged(int layer, Slider s, int value); void uiPlaybackChanged(int layer, Status s); + void uiLoadMedia(int layer, QString s); #endif }; diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index 7ec94ba..1f2c0b4 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -122,6 +122,7 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) MA_SOUND_FLAG_NO_SPATIALIZATION \ /*| MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE \ | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC \ + | MA_SOUND_FLAG_NO_PITCH \ | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM \*/ , NULL, NULL, &m_currentSound[layer]); if (result != MA_SUCCESS) @@ -249,6 +250,7 @@ void MiniAudioEngine::setCursor(int layer, int cursor) ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &f); f = (cursor * f) / 65025; ma_sound_seek_to_pcm_frame(&m_currentSound[layer], f); + // ToDo: change the loop entry point too } Status MiniAudioEngine::getStatus(int layer) From ef653553d9801b495f0d4ab73c05188517718518 Mon Sep 17 00:00:00 2001 From: snt Date: Sat, 4 May 2024 19:38:43 +0200 Subject: [PATCH 05/13] update magicq head qith new personality --- docs/LibreMediaServer_Audio.hed | 146 ++++++++++++++++---------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/docs/LibreMediaServer_Audio.hed b/docs/LibreMediaServer_Audio.hed index 5da3a28..58d0fd5 100644 --- a/docs/LibreMediaServer_Audio.hed +++ b/docs/LibreMediaServer_Audio.hed @@ -1,76 +1,76 @@ ް׆ˌĠ򝤫鿰맫͓Ԕ ҊÅЁ䍡 ӽ -䉭ėĈ -ϛ -Ӧ -ڑ -ė - -ݍ -Ȫ -웣傪Ⓨ֚ -ކՂ -߸“ -Ŷ -ѝ -ωƀ - - - - -ŕ -ʷí -̙ -򴹤 -ԥѼ܅ -𗹣َ -̚ -Რ - -Ņ -⽬ -̫ -喤쏎ʁǏ - -߬ػс -썎ޛ - -쏎 - - - -Ճ - -尨 -ގ - -ލ -ƕ - -ŗ - - - - - -ˤ - - - - - -쏐 - - - -쏎 -󩼿 - - - -ÛƘ - - - - +Ꭸʆ +ɑ +ɬ +򉇁 +Ԑɉ + +ٿդϨ҃ +񀠧ڔ +ڑŌ +򻴧 + + + + + + + + +쏎ބ +힇ݳ + +Ԓlj + +έ +倬쏎 + +޽ڊ + +؛ +ŕ +ðݑ +ȕ +˛ +̽ɧ + +𓎍 + + +ً + +ʐ +ï +뷪 + + +܋ +Ò +뻡 +ǒ + +𓎍 +ʟ + +㍛ + + + + + + +𓎑 + + + +ҟ + + + +ف + + + + From 246a8a2f98a201883d51177c5fb89998282b5976 Mon Sep 17 00:00:00 2001 From: snt Date: Sun, 5 May 2024 14:39:21 +0200 Subject: [PATCH 06/13] =?UTF-8?q?restringe=20las=20se=C3=B1ales=20de=20los?= =?UTF-8?q?=20sliders,=20en=20vez=20de=20actualizar=20en=20directo,=20s?= =?UTF-8?q?=C3=B3lo=20actualiza=20con=20el=20timer=20refreshGui.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/roadmap.txt | 2 +- libremediaserver-audio.pro | 4 +-- src/clickablelabel.cpp | 3 +- src/defines.h | 2 +- src/libremediaserver-audio.cpp | 60 +++++++++++++++++++--------------- src/libremediaserver-audio.h | 2 ++ src/miniaudioengine.cpp | 7 ++-- src/slidergroup.cpp | 7 +++- 8 files changed, 53 insertions(+), 34 deletions(-) diff --git a/docs/roadmap.txt b/docs/roadmap.txt index 6b12098..894c32c 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -49,5 +49,5 @@ v 0.2.1 - SettingsDialog. - Load/save conf file. - ¿Exit Point? is it needed? -- Hardening: check return errors, i'm too happy.... +- Hardening: check return errors, catch execptions, i'm too happy.... - Tests: errors on wrong conf file. diff --git a/libremediaserver-audio.pro b/libremediaserver-audio.pro index 42ef0d1..41d6ecd 100644 --- a/libremediaserver-audio.pro +++ b/libremediaserver-audio.pro @@ -30,9 +30,9 @@ SOURCES += src/main.cpp \ src/settings.cpp \ src/slidergroup.cpp FORMS += src/libremediaserver-audio-gui.ui -CCFLAG += -msse2 -mavx2 #-fsanitize=address -g -O0 +CCFLAG += -msse2 -mavx2 #-fsanitize=address -g3 -O0 QMAKE_CXXFLAGS += $$(CXXFLAG) -#QMAKE_CXXFLAGS += -fsanitize=address -g -O0 +#QMAKE_CXXFLAGS += -fsanitize=address -g3 -O0 QMAKE_CFLAGS += $$(CCFLAG) QMAKE_LFLAGS += $$(LDFLAG) LIBS += -lola -lolacommon -ldl -lpthread -lm diff --git a/src/clickablelabel.cpp b/src/clickablelabel.cpp index 333219b..623493d 100644 --- a/src/clickablelabel.cpp +++ b/src/clickablelabel.cpp @@ -3,11 +3,12 @@ ClickableLabel::ClickableLabel(QWidget *parent, Qt::WindowFlags f) : QLabel{parent} { - + Q_UNUSED(f); } ClickableLabel::~ClickableLabel() {} void ClickableLabel::mousePressEvent(QMouseEvent* event) { + Q_UNUSED(event); emit clicked(); } diff --git a/src/defines.h b/src/defines.h index 633b06c..a4eeea5 100644 --- a/src/defines.h +++ b/src/defines.h @@ -6,7 +6,7 @@ #define LICENSE "GPL 3 Licensed. See LICENSE.txt." #define DEFAULT_FILE "lms-audio.xlm" #define MAX_LAYERS 4 -#define UI_REFRESH_TIME 1000 +#define UI_REFRESH_TIME 200 // struct where save the DMX settings for each layer struct dmxSetting { diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index b59a8f1..d146e10 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -28,6 +28,12 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui) set->readFile(); m_mediaLibrary = new MediaLibrary; m_mediaLibrary->initMediaLibrary(); + for (int i = 0; i < MAX_LAYERS; i++) { + m_currentMedia[i] = Status::Iddle; + m_updateUi[i][0] = -1; + m_updateUi[i][1] = -1; + m_updateUi[i][2] = -1; + } m_ola = new olaThread(this, set->getLayersNumber()); Q_CHECK_PTR(m_ola); m_ola->blockSignals(true); @@ -54,7 +60,7 @@ libreMediaServerAudio::~libreMediaServerAudio() void libreMediaServerAudio::dmxInput(int layer, int channel, int value) { - if (layer > LAYER_CHANNELS) + if (layer >= MAX_LAYERS || channel >= LAYER_CHANNELS) return; QString mediaFile = NULL; int aux; @@ -66,40 +72,32 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) return; if (QFile::exists(mediaFile)){ m_mae.loadMedia(layer, mediaFile.toLatin1().data()); -#ifndef NOGUI + m_currentMedia[layer] = mediaFile; +#ifndef NOGIO if (m_ui) m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); #endif - m_currentMedia[layer] = mediaFile; } + return; } 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 + float tmp = value / 65025.0f; + m_mae.volChanged(layer, tmp); + m_updateUi[layer][0] = tmp * 100; } else if (channel == PAN) { m_mae.panChanged(layer, value); -#ifndef NOGUI - if (m_ui) - m_lmsUi->m_aw->panChanged(layer, value); -#endif + m_updateUi[layer][1] = value; } else if (channel == PITCH) { m_mae.pitchChanged(layer, value); -#ifndef NOGUI - if (m_ui) - m_lmsUi->m_aw->pitchChanged(layer, value); -#endif + m_updateUi[layer][2] = value; } 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)); + m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); #endif - + return; } else if (channel == PLAYBACK && value > 0) { - Status s = m_mae.getStatus(layer); aux = value / 25; + Status s = m_currentStatus[layer]; if (s != aux) { if (aux == 0) s = Status::PlayingOnce; @@ -110,9 +108,9 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) else if (aux == 3) s = Status::PlayingLoop; m_mae.playbackChanged(layer, s); + m_currentStatus[layer] = s; #ifndef NOGUI - if (m_ui) - m_lmsUi->m_aw->playbackChanged(layer, s); + if (m_ui) m_lmsUi->m_aw->playbackChanged(layer, s); #endif } } @@ -120,13 +118,23 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) #ifndef NOGUI void libreMediaServerAudio::refreshUi() { - if (!m_ui) - return; + if (!m_ui) return; for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { - Status s = m_mae.getStatus(i); + Status s = m_currentStatus[i]; if (s == Status::PlayingOnce || s == Status::PlayingLoop) { m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); - //m_lmsUi->m_aw->playbackChanged(i, s); + } + if (m_updateUi[i][0] >= 0) { + m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]); + m_updateUi[i][0] = -1; + } + if (m_updateUi[i][1] >= 0) { + m_lmsUi->m_aw->panChanged(i, m_updateUi[i][1]); + m_updateUi[i][1] = -1; + } + if (m_updateUi[i][2] >= 0) { + m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]); + m_updateUi[i][2] = -1; } } } diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 6b80f97..9782d88 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -44,10 +44,12 @@ private: MediaLibrary *m_mediaLibrary; MiniAudioEngine m_mae; QString m_currentMedia[MAX_LAYERS]; + Status m_currentStatus[MAX_LAYERS]; #ifndef NOGUI bool m_ui; QTimer *m_refreshUi; libreMediaServerAudioUi *m_lmsUi; + int m_updateUi[MAX_LAYERS][3]; #endif private slots: diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index 1f2c0b4..8dc38da 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -2,7 +2,9 @@ MiniAudioEngine::MiniAudioEngine() { - + for (int i =0; i < MAX_LAYERS; i++) { + m_mediaLoaded[i] = false; + } } void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) @@ -194,6 +196,7 @@ void MiniAudioEngine::volChanged(int layer, float vol) if (m_mediaLoaded[layer] == false) return; ma_sound_group_set_volume(&m_currentSound[layer], vol); + qDebug() << "vol: " << vol; } void MiniAudioEngine::panChanged(int layer, float value) @@ -255,7 +258,7 @@ void MiniAudioEngine::setCursor(int layer, int cursor) Status MiniAudioEngine::getStatus(int layer) { - if (m_mediaLoaded[layer] == ma_bool8(false)) + if (m_mediaLoaded[layer] == false) return Status::Iddle; if (ma_sound_is_playing(&m_currentSound[layer])) { if (ma_sound_is_looping(&m_currentSound[layer])) diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index e58588e..6120093 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -57,6 +57,11 @@ void SliderGroup::sliderValueChanged(int value) void SliderGroup::setValue(float value) { - slider->setValue(value); + slider->blockSignals(true); + valueBox->blockSignals(true); + if (int(value) != slider->value()) + slider->setValue(value); valueBox->setValue(value); + slider->blockSignals(false); + valueBox->blockSignals(false); } From d34b972a549a315b40977766e8f000af375caa4c Mon Sep 17 00:00:00 2001 From: snt Date: Sun, 5 May 2024 17:36:20 +0200 Subject: [PATCH 07/13] mejor rendimiento --- src/audiolayerwidget.cpp | 14 +++++------ src/audiolayerwidget.h | 2 +- src/audiowidget.cpp | 2 +- src/defines.h | 2 +- src/libremediaserver-audio-gui.ui | 8 +++--- src/libremediaserver-audio.cpp | 42 ++++++++++++++----------------- src/libremediaserver-audio.h | 2 +- src/main.cpp | 1 - src/miniaudioengine.cpp | 3 ++- src/miniaudioengine.h | 1 + src/slidergroup.cpp | 18 +++++++------ 11 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index ee112dd..563eeb9 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -51,7 +51,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime->setDisplayFormat("mm:ss:zz"); m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_progressTime->setMaximumWidth(75); + m_progressTime->setMinimumWidth(80); m_progressTime->setFocusPolicy(Qt::NoFocus); m_progressTime->setAlignment(Qt::AlignHCenter); m_progressTime->setContentsMargins(0,0,0,0); @@ -61,7 +61,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_totalTimeValue->setDisplayFormat("mm:ss:zz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_totalTimeValue->setMaximumWidth(75); + m_totalTimeValue->setMinimumWidth(80); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); m_totalTimeValue->setAlignment(Qt::AlignHCenter); m_totalTimeValue->setContentsMargins(0,0,0,0); @@ -119,8 +119,8 @@ void AudioLayerWidget::toggleSuspendResume() break; case Status::Paused: case Status::Stopped: - //this->setPlaybackStatus(Status::PlayingOnce); - emit uiPlaybackChanged(m_layer, Status::PlayingOnce); + this->setPlaybackStatus(Status::PlayingLoop); + emit uiPlaybackChanged(m_layer, Status::PlayingLoop); case Status::Iddle: break; } @@ -176,12 +176,12 @@ void AudioLayerWidget::fileLoaded(QString file) void AudioLayerWidget::setPlaybackStatus(Status status) { - if (StatusStr[status] == m_suspendResumeButton->text()) + if (!strcmp(StatusStr[status], m_suspendResumeButton->text().toLatin1().constData())) return; m_suspendResumeButton->blockSignals(true); m_status = status; if (status == Status::Stopped) - m_progress->setValue(0); + refreshCurrentTime(0); m_suspendResumeButton->setText(StatusStr[status]); m_suspendResumeButton->blockSignals(false); } @@ -200,7 +200,7 @@ void AudioLayerWidget::durationChanged(float dur) m_totalTimeValue->blockSignals(false); } -void AudioLayerWidget::refreshUi(float progress) +void AudioLayerWidget::refreshCurrentTime(float progress) { progress *= 1000; m_progress->blockSignals(true); diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h index c0c6b3b..1c0ee83 100644 --- a/src/audiolayerwidget.h +++ b/src/audiolayerwidget.h @@ -46,7 +46,7 @@ public slots: void pitchChanged(int pitch); void fileLoaded(QString file); void durationChanged(float dur); - void refreshUi(float progress); + void refreshCurrentTime(float progress); private slots: void openMediaDialog(); diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 47d7ce5..3d17c2d 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -49,5 +49,5 @@ void AudioWidget::cursorChanged(int layer, float cursor) { QLayoutItem * const item = m_layout->itemAt(layer); AudioLayerWidget *alw = dynamic_cast(item->widget()); - alw->refreshUi(cursor); + alw->refreshCurrentTime(cursor); } diff --git a/src/defines.h b/src/defines.h index a4eeea5..f8a2312 100644 --- a/src/defines.h +++ b/src/defines.h @@ -6,7 +6,7 @@ #define LICENSE "GPL 3 Licensed. See LICENSE.txt." #define DEFAULT_FILE "lms-audio.xlm" #define MAX_LAYERS 4 -#define UI_REFRESH_TIME 200 +#define UI_REFRESH_TIME 93 // struct where save the DMX settings for each layer struct dmxSetting { diff --git a/src/libremediaserver-audio-gui.ui b/src/libremediaserver-audio-gui.ui index 65c83c2..c0f11ad 100644 --- a/src/libremediaserver-audio-gui.ui +++ b/src/libremediaserver-audio-gui.ui @@ -2,13 +2,13 @@ Santi Noreña lms@criptomart.net LibreMediaServerAudio - + 0 0 - 800 - 800 + 500 + 400 @@ -32,7 +32,7 @@ 0 0 - 114 + 500 21 diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index d146e10..5eb65aa 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -40,16 +40,9 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui) connect(m_ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int))); m_ola->registerUniverse(); m_mae.startEngine(set->getAudioDeviceId()); - qDebug("Init Complete."); + qDebug("Core init Complete. Start reading DMX."); 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() @@ -73,7 +66,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) if (QFile::exists(mediaFile)){ m_mae.loadMedia(layer, mediaFile.toLatin1().data()); m_currentMedia[layer] = mediaFile; -#ifndef NOGIO +#ifndef NOGUI if (m_ui) m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); #endif @@ -82,7 +75,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) } else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) { float tmp = value / 65025.0f; m_mae.volChanged(layer, tmp); - m_updateUi[layer][0] = tmp * 100; + m_updateUi[layer][0] = tmp * 100.0f; } else if (channel == PAN) { m_mae.panChanged(layer, value); m_updateUi[layer][1] = value; @@ -98,21 +91,19 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) } else if (channel == PLAYBACK && value > 0) { aux = value / 25; Status s = m_currentStatus[layer]; - 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); - m_currentStatus[layer] = s; + 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); + m_currentStatus[layer] = s; #ifndef NOGUI - if (m_ui) m_lmsUi->m_aw->playbackChanged(layer, s); + if (m_ui) m_lmsUi->m_aw->playbackChanged(layer, s); #endif - } } } @@ -136,6 +127,7 @@ void libreMediaServerAudio::refreshUi() { m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]); m_updateUi[i][2] = -1; } + //m_lmsUi->m_aw->playbackChanged(i, m_currentStatus[i]); } } @@ -146,6 +138,9 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) connect(m_lmsUi->m_aw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderChanged(int, Slider, int))); connect(m_lmsUi->m_aw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status))); connect(m_lmsUi->m_aw, SIGNAL(uiLoadMedia(int, QString)), this, SLOT(uiLoadMedia(int, QString))); + m_refreshUi = new QTimer(this); + connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); + m_refreshUi->start(UI_REFRESH_TIME); }; void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) @@ -166,6 +161,7 @@ void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s) { m_mae.playbackChanged(layer, s); + m_currentStatus[layer] = s; } void libreMediaServerAudio::uiLoadMedia(int layer, QString s) diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 9782d88..5e956ac 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -49,7 +49,7 @@ private: bool m_ui; QTimer *m_refreshUi; libreMediaServerAudioUi *m_lmsUi; - int m_updateUi[MAX_LAYERS][3]; + float m_updateUi[MAX_LAYERS][3]; #endif private slots: diff --git a/src/main.cpp b/src/main.cpp index 99643b0..eea3c29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,7 +32,6 @@ bool hasUi(int &argc, char *argv[]) int main(int argc, char *argv[]) { QApplication app(argc, argv); - libreMediaServerAudio lms(hasUi(argc, argv)); #ifndef NOGUI if (hasUi(argc, argv)) diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index 8dc38da..59345e9 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -195,8 +195,9 @@ void MiniAudioEngine::volChanged(int layer, float vol) { if (m_mediaLoaded[layer] == false) return; + if (vol > 1) + vol = 1; ma_sound_group_set_volume(&m_currentSound[layer], vol); - qDebug() << "vol: " << vol; } void MiniAudioEngine::panChanged(int layer, float value) diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 2bf224b..169d33b 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -27,6 +27,7 @@ protected: void setCursor(int layer, int cursor); ma_result printFormatInfo(int layer); Status getStatus(int layer); + inline float getVol(int layer) { return ma_sound_get_volume(&m_currentSound[layer]); } private: ma_resource_manager_config resourceManagerConfig; diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index 6120093..a488560 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -1,5 +1,5 @@ #include "slidergroup.h" - +#include SliderGroup::SliderGroup(QString name, int min, int max, @@ -15,22 +15,22 @@ SliderGroup::SliderGroup(QString name, slider->setFocusPolicy(Qt::StrongFocus); slider->setTickPosition(QSlider::TicksBothSides); slider->setTickInterval((max - min) / 11); - slider->setMinimumHeight(100); + slider->setMinimumHeight(0); slider->setSingleStep(1); slider->setRange(min, max); - //slider->setMaximumWidth(40); + slider->setMinimumWidth(50); slider->setToolTip(name); slider->setStyleSheet("QSlider {" - "border: 1px solid #999999;" + "border: 2px solid #685060;" "margin: 0px;" "height: 200px;" - "width: 40px;}" + "width: 50px;}" ); slider->setContentsMargins(0, 0, 0, 0); valueBox = new QDoubleSpinBox(); valueBox->setFocusPolicy(Qt::NoFocus); valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - //valueBox->setMaximumWidth(40); + valueBox->setMinimumWidth(50); valueBox->setRange(min, max); valueBox->setDecimals(decimals); valueBox->setObjectName(name); @@ -40,8 +40,8 @@ SliderGroup::SliderGroup(QString name, connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int))); layout->addWidget(slider); layout->addWidget(valueBox); - this->setStyleSheet("border: 1px solid #999999;" - "width: 40px;" + this->setStyleSheet("border: 2px solid #685060;" + "width: 50px;" "margin: 0px;" ); layout->setSpacing(0); @@ -51,7 +51,9 @@ SliderGroup::SliderGroup(QString name, void SliderGroup::sliderValueChanged(int value) { + valueBox->blockSignals(true); valueBox->setValue(value); + valueBox->blockSignals(false); emit valueChanged(value); }; From 5915d4898e9f85eef11a1a4cf183b44f0251d790 Mon Sep 17 00:00:00 2001 From: snt Date: Sun, 5 May 2024 21:44:21 +0200 Subject: [PATCH 08/13] =?UTF-8?q?cambida=20se=C3=B1al=20dmx=20por=20llamad?= =?UTF-8?q?a=20directa=20al=20m=C3=A9todo,=20reduce=20un=2020%=20de=20cpu?= =?UTF-8?q?=20en=20mi=20ordenador.=20Restringida=20actualizaci=C3=B3n=20de?= =?UTF-8?q?=20entry=20point=20como=20volumen,=20sigue=20cascando=20la=20b?= =?UTF-8?q?=C3=BAsqueda=20en=20mp3,=20wav=20va=20fino.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/audiolayerwidget.cpp | 2 +- src/libremediaserver-audio.cpp | 24 +++++++++++++----------- src/libremediaserver-audio.h | 9 +++++---- src/miniaudioengine.cpp | 7 ++++++- src/olathread.cpp | 21 +++++++++++---------- src/olathread.h | 19 +++++++++---------- 6 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 563eeb9..02da882 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -58,7 +58,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_totalTimeValue = new QTimeEdit; m_totalTimeValue->setObjectName("Track Length"); m_totalTimeValue->setToolTip("Track Length"); - m_totalTimeValue->setDisplayFormat("mm:ss:zz"); + m_totalTimeValue->setDisplayFormat("mm:ss:zzz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); m_totalTimeValue->setMinimumWidth(80); diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index 5eb65aa..589c190 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -29,10 +29,14 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui) m_mediaLibrary = new MediaLibrary; m_mediaLibrary->initMediaLibrary(); for (int i = 0; i < MAX_LAYERS; i++) { - m_currentMedia[i] = Status::Iddle; + m_currentMedia[i] = ""; + m_currentStatus[i] = Status::Iddle; +#ifdef NOGUI m_updateUi[i][0] = -1; m_updateUi[i][1] = -1; m_updateUi[i][2] = -1; + m_updateUi[i][3] = -1; +#endif } m_ola = new olaThread(this, set->getLayersNumber()); Q_CHECK_PTR(m_ola); @@ -42,7 +46,9 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui) m_mae.startEngine(set->getAudioDeviceId()); qDebug("Core init Complete. Start reading DMX."); m_ola->blockSignals(false); +#ifdef NOGUI m_ola->start(QThread::TimeCriticalPriority ); +#endif } libreMediaServerAudio::~libreMediaServerAudio() @@ -71,7 +77,6 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); #endif } - return; } else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) { float tmp = value / 65025.0f; m_mae.volChanged(layer, tmp); @@ -84,10 +89,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) m_updateUi[layer][2] = value; } else if (channel == ENTRY_POINT_COARSE || channel == ENTRY_POINT_FINE) { m_mae.setCursor(layer, value); -#ifndef NOGUI - m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); -#endif - return; + m_updateUi[layer][3] = value; } else if (channel == PLAYBACK && value > 0) { aux = value / 25; Status s = m_currentStatus[layer]; @@ -111,10 +113,6 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) void libreMediaServerAudio::refreshUi() { if (!m_ui) return; for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { - Status s = m_currentStatus[i]; - if (s == Status::PlayingOnce || s == Status::PlayingLoop) { - m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); - } if (m_updateUi[i][0] >= 0) { m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]); m_updateUi[i][0] = -1; @@ -127,7 +125,10 @@ void libreMediaServerAudio::refreshUi() { m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]); m_updateUi[i][2] = -1; } - //m_lmsUi->m_aw->playbackChanged(i, m_currentStatus[i]); + if (m_updateUi[i][3] >= 0) { + m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); + m_updateUi[i][3] = -1; + } } } @@ -141,6 +142,7 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) m_refreshUi = new QTimer(this); connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); m_refreshUi->start(UI_REFRESH_TIME); + m_ola->start(QThread::TimeCriticalPriority ); }; void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 5e956ac..665f3e2 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -35,25 +35,26 @@ class libreMediaServerAudio : public QObject public: libreMediaServerAudio(bool gui = false); virtual ~libreMediaServerAudio(); - olaThread *m_ola; + void dmxInput(int layer, int channel, int value); #ifndef NOGUI void setUi(libreMediaServerAudioUi *lmsUi); #endif - + //static void NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer); private: + olaThread *m_ola; MediaLibrary *m_mediaLibrary; MiniAudioEngine m_mae; QString m_currentMedia[MAX_LAYERS]; Status m_currentStatus[MAX_LAYERS]; + static QList m_dmxSettings; #ifndef NOGUI bool m_ui; QTimer *m_refreshUi; libreMediaServerAudioUi *m_lmsUi; - float m_updateUi[MAX_LAYERS][3]; + float m_updateUi[MAX_LAYERS][4]; #endif private slots: - void dmxInput(int layer, int channel, int value); #ifndef NOGUI void refreshUi(); void uiSliderChanged(int layer, Slider s, int value); diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index 59345e9..f65744d 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -114,9 +114,11 @@ ma_result MiniAudioEngine::getAllAudioDevices() ma_result MiniAudioEngine::loadMedia(int layer, char *file) { ma_result result; + float vol = -1; if (m_mediaLoaded[layer] == true) { + vol = ma_sound_get_volume(&m_currentSound[layer]); ma_sound_uninit(&m_currentSound[layer]); m_mediaLoaded[layer] = false; } @@ -131,7 +133,10 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) qWarning("Failed to load file %s", file); else { m_mediaLoaded[layer] = true; - this->volChanged(layer, 0); + if (vol == -1) + this->volChanged(layer, 0); + else + this->volChanged(layer, vol); } return result; } diff --git a/src/olathread.cpp b/src/olathread.cpp index 471775c..409cf79 100644 --- a/src/olathread.cpp +++ b/src/olathread.cpp @@ -1,11 +1,11 @@ -#include "olathread.h" - +#include "libremediaserver-audio.h" +//#include "olathread.h" olaThread::olaThread(QObject *parent, int layers) : m_counter(0) , m_layers(layers) { - Q_UNUSED(parent); + this->setParent(parent); gettimeofday(&m_last_data, NULL); for (int i=0; i < MAX_LAYERS; i++) { @@ -36,6 +36,7 @@ void olaThread::init() } m_client = m_clientWrapper->GetClient(); m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx)); + //m_client->SetDMXCallback(ola::NewCallback((libreMediaServerAudio *)this->parent(), libreMediaServerAudio::NewDmx)); m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss)); m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed)); m_dmxSettings = Settings::getInstance()->getDmxSettings(); @@ -76,7 +77,7 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, case DMX_FOLDER: value *= 0x100; value += buffer.Get(i.address + DMX_FILE); - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][DMX_FILE] = buffer.Get(i.address + DMX_FILE); fileSent = true; break; @@ -84,13 +85,13 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, if (fileSent) break; value += buffer.Get(i.address + DMX_FOLDER) * 0x100; - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][DMX_FOLDER] = buffer.Get(i.address + DMX_FOLDER); fileSent = true; break; case VOLUME_FINE: value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value; - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][VOLUME_COARSE] = buffer.Get(i.address + VOLUME_COARSE); volSent = true; break; @@ -98,13 +99,13 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, if (volSent) break; value = (value * 0x100) + buffer.Get(i.address + VOLUME_FINE); - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE); volSent = true; break; case ENTRY_POINT_FINE: value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value; - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][ENTRY_POINT_COARSE] = buffer.Get(i.address + ENTRY_POINT_COARSE); entrySent = true; break; @@ -112,12 +113,12 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, if (entrySent) break; value = (value * 0x100) + buffer.Get(i.address + ENTRY_POINT_FINE); - emit dmxOutput(i.layer,j,value); + qobject_cast(parent())->dmxInput(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); + qobject_cast(parent())->dmxInput(i.layer, j, value); break; } } diff --git a/src/olathread.h b/src/olathread.h index dcae35b..ed2735a 100644 --- a/src/olathread.h +++ b/src/olathread.h @@ -20,10 +20,17 @@ class olaThread : public QThread Q_OBJECT public: + QList m_dmxSettings; + int m_dmx[MAX_LAYERS][LAYER_CHANNELS]; + ola::client::OlaClientWrapper *m_clientWrapper; + ola::client::OlaClient *m_client; + unsigned int m_counter; + struct timeval m_last_data; // Last DMX frame received + int m_layers; olaThread(QObject *parent = 0, int layers = 0); virtual ~olaThread(); - + void run (); /** Retorna el valor de un canal *@param int layer the layer for we want the channel *@param int channel the channel for the value wanted @@ -35,14 +42,6 @@ public: void resendDmx(); private: - void run (); - ola::client::OlaClientWrapper *m_clientWrapper; - ola::client::OlaClient *m_client; - unsigned int m_counter; - struct timeval m_last_data; // Last DMX frame received - int m_layers; - int m_dmx[MAX_LAYERS][LAYER_CHANNELS]; - QList m_dmxSettings; /** * @brief Callback from ola. Control de errores en el registro de Universos en OLA * typedef SingleUseCallback1 ola::client::SetCallback @@ -67,7 +66,7 @@ private: * This is called one for second if there is not updated in the DMX frame. * emit only the channels that has been changed. */ - void NewDmx(const ola::client::DMXMetadata &dmx_meta, const ola::DmxBuffer &buffer); // + void NewDmx(const ola::client::DMXMetadata &dmx_meta, const ola::DmxBuffer &buffer); /** * @brief Sometimes the ola server closes the connection. This is a callback to handle this event an reconect to ola */ From 7a9c0cd0ac3d1fd32a47e1779ce053f810b01baf Mon Sep 17 00:00:00 2001 From: snt Date: Tue, 7 May 2024 20:23:09 +0200 Subject: [PATCH 09/13] =?UTF-8?q?libreMediaServer=20no=20refresca=20direct?= =?UTF-8?q?amente=20la=20ui,=20solo=20actualiza=20valores=20en=20=20audiow?= =?UTF-8?q?idget.=20la=20ui=20se=20actualiza=20con=20un=20timer=20en=20aud?= =?UTF-8?q?iowidget.=20Quitadas=20se=C3=B1ales=20en=20todo,=20mejora=20ren?= =?UTF-8?q?dimiento.=20fade=20en=20volumen=20basado=20en=20la=20trama=20dm?= =?UTF-8?q?x=20(25=20ms)=20para=20evitar=20clicks.=20refresca=20los=20valo?= =?UTF-8?q?res=20de=20la=20capa=20cuando=20carga=20un=20media.=20Ui=20Ok.?= =?UTF-8?q?=20nuevo=20formato=20de=20archivo=20de=20configuraci=C3=B3n=20x?= =?UTF-8?q?ml.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog.txt | 2 + docs/lms-audio.xlm | 14 +++--- docs/roadmap.txt | 8 +++- src/audiolayerwidget.cpp | 18 ++++---- src/audiolayerwidget.h | 25 +++++------ src/audiowidget.cpp | 70 +++++++++++++++++++++++------- src/audiowidget.h | 15 +++++-- src/defines.h | 17 ++++++-- src/dmxPersonality.h | 1 - src/libremediaserver-audio-gui.cpp | 2 +- src/libremediaserver-audio.cpp | 67 ++++++++++++++++------------ src/libremediaserver-audio.h | 15 ++++--- src/main.cpp | 4 +- src/miniaudioengine.cpp | 65 +++++++++++++++------------ src/miniaudioengine.h | 2 + src/olathread.cpp | 24 +++++----- src/settings.cpp | 49 +++++++++++---------- src/settings.h | 15 ++++--- src/slidergroup.cpp | 16 ++++++- src/slidergroup.h | 2 + 20 files changed, 271 insertions(+), 160 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 22a7e1f..a69017b 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -27,6 +27,8 @@ v 0.2.0 Antígona (24/04/2024) + Compilation without GUI (-DNOGUI). + New Status "Iddle" in playbacks if is not loaded. + New DMX personality version, better sort for audio needs (first load media, set vol, pan, etc, last playback order); ++ Refresh layer values when it loads a new sound file. ++ No QtSignals for sending data, better performance about 20% in my machine. Now, libremediaserver only updates values in AudioWidget, ui refresh is doing with a timer in audiowidget, so there is not problems between graphical and ola thread (the callback). v 0.1.3 Leúcade (19/04/2024) diff --git a/docs/lms-audio.xlm b/docs/lms-audio.xlm index cc498ca..4274267 100644 --- a/docs/lms-audio.xlm +++ b/docs/lms-audio.xlm @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + diff --git a/docs/roadmap.txt b/docs/roadmap.txt index 894c32c..bd98089 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -45,9 +45,13 @@ v 0.2.1 - Ui/Ux: Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante. - Logs, verbosity, timestamp. - New play mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH -- Vumeter or indicator about audio output in layer and master. +- Vumeter or indicator about audio output in layer and master, add to sliderGroup. +- QSlider can not accept floats and it can no manage high frequency updates. - SettingsDialog. - Load/save conf file. - ¿Exit Point? is it needed? -- Hardening: check return errors, catch execptions, i'm too happy.... +- Hardening: check return errors, try/catch exceptions, i'm too happy.... - Tests: errors on wrong conf file. +- BUGFIX: there are some small clicks when changing volume and play/stop/pause. vol 24 bits? microfades in engine? setVol 0 before changing playback state? +- refactorize dmxInput: loadMedia, changePlayBack, +- BUGFIX: in nogui mode we need more info print at terminal (load media, change playback status). diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 02da882..a22b2cc 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -52,6 +52,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); m_progressTime->setMinimumWidth(80); + m_progressTime->setMaximumWidth(80); m_progressTime->setFocusPolicy(Qt::NoFocus); m_progressTime->setAlignment(Qt::AlignHCenter); m_progressTime->setContentsMargins(0,0,0,0); @@ -138,7 +139,7 @@ void AudioLayerWidget::openMediaDialog() QStringList fileNames; fileNames = dialog.selectedFiles(); emit uiLoadMedia(m_layer, fileNames.at(0)); - this->fileLoaded(fileNames.at(0)); + this->setMediaFile(fileNames.at(0)); } // from DMX signals @@ -163,7 +164,7 @@ void AudioLayerWidget::setPitch(int pitch) m_pitch->blockSignals(false); } -void AudioLayerWidget::fileLoaded(QString file) +void AudioLayerWidget::setMediaFile(QString file) { QStringList list = file.split("/"); int size = list.size(); @@ -174,19 +175,18 @@ void AudioLayerWidget::fileLoaded(QString file) this->setPlaybackStatus(Status::Stopped); } -void AudioLayerWidget::setPlaybackStatus(Status status) +void AudioLayerWidget::setPlaybackStatus(Status s) { - if (!strcmp(StatusStr[status], m_suspendResumeButton->text().toLatin1().constData())) - return; + Status status = static_cast(s); m_suspendResumeButton->blockSignals(true); m_status = status; - if (status == Status::Stopped) - refreshCurrentTime(0); + //if (status == Status::Stopped) + // refreshCurrentTime(0); m_suspendResumeButton->setText(StatusStr[status]); m_suspendResumeButton->blockSignals(false); } -void AudioLayerWidget::durationChanged(float dur) +void AudioLayerWidget::setDuration(float dur) { m_progress->blockSignals(true); m_progressTime->blockSignals(true); @@ -200,7 +200,7 @@ void AudioLayerWidget::durationChanged(float dur) m_totalTimeValue->blockSignals(false); } -void AudioLayerWidget::refreshCurrentTime(float progress) +void AudioLayerWidget::setCurrentTime(float progress) { progress *= 1000; m_progress->blockSignals(true); diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h index 1c0ee83..9380b81 100644 --- a/src/audiolayerwidget.h +++ b/src/audiolayerwidget.h @@ -18,13 +18,6 @@ class AudioLayerWidget : public QWidget public: explicit AudioLayerWidget(QWidget *parent = 0, int layer = 0); ~AudioLayerWidget(); - void setVol(float vol); - void resume(); - void setPan(int pan); - void setPitch(int pitch); - void setLoop(bool on); - void setPlaybackStatus(Status status); - inline Status getPlaybackStatus() { return m_status; } private: Status m_status; @@ -39,17 +32,23 @@ private: QTimeEdit *m_totalTimeValue; QProgressBar *m_progress; +// From DMX public slots: + void setMediaFile(QString file); + void setDuration(float dur); + void setCurrentTime(float progress); + void setPlaybackStatus(Status status); + void setVol(float vol); + void setPan(int pan); + void setPitch(int pitch); + +// From Ui +private slots: + void openMediaDialog(); void toggleSuspendResume(); void volumeChanged(int vol); void panChanged(int pan); void pitchChanged(int pitch); - void fileLoaded(QString file); - void durationChanged(float dur); - void refreshCurrentTime(float progress); - -private slots: - void openMediaDialog(); signals: void uiPlaybackChanged(int layer, Status s); diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 3d17c2d..ca2633a 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -1,5 +1,5 @@ #include "audiowidget.h" - +#include AudioWidget::AudioWidget(QWidget *parent) : QWidget(parent) @@ -15,39 +15,79 @@ AudioWidget::AudioWidget(QWidget *parent) : m_layout->setSpacing(0); m_layout->setContentsMargins(1, 1, 1, 1); setLayout(m_layout); + m_refreshUi = new QTimer(this); + connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); + m_refreshUi->start(UI_REFRESH_TIME * 2); } void AudioWidget::mediaLoaded(int layer, QString file, float duration) { - QLayoutItem * const item = m_layout->itemAt(layer); - dynamic_cast(item->widget())->fileLoaded(file); - dynamic_cast(item->widget())->durationChanged(duration); + m_layerUpdate[layer].media = file; + m_layerUpdate[layer].duration = duration; + m_layerUpdate[layer].updated = true; } void AudioWidget::volChanged(int layer, float vol) { - QLayoutItem * const item = m_layout->itemAt(layer); - dynamic_cast(item->widget())->setVol(vol); + m_layerUpdate[layer].vol = vol; + m_layerUpdate[layer].updated = true; } void AudioWidget::panChanged(int layer, int pan) { - QLayoutItem * const item = m_layout->itemAt(layer); - dynamic_cast(item->widget())->setPan(pan); + m_layerUpdate[layer].pan = pan; + m_layerUpdate[layer].updated = true; } void AudioWidget::pitchChanged(int layer, int pitch) { - QLayoutItem * const item = m_layout->itemAt(layer); - dynamic_cast(item->widget())->setPitch(pitch); + + m_layerUpdate[layer].pitch = pitch; + m_layerUpdate[layer].updated = true; } void AudioWidget::playbackChanged(int layer, Status status) { - QLayoutItem * const item = m_layout->itemAt(layer); - dynamic_cast(item->widget())->setPlaybackStatus(status); + m_layerUpdate[layer].status = status; + m_layerUpdate[layer].updated = true; } void AudioWidget::cursorChanged(int layer, float cursor) { - QLayoutItem * const item = m_layout->itemAt(layer); - AudioLayerWidget *alw = dynamic_cast(item->widget()); - alw->refreshCurrentTime(cursor); + m_layerUpdate[layer].cursor = floor(cursor * 1000) / 1000; + m_layerUpdate[layer].updated = true; +} + +void AudioWidget::refreshUi() +{ + for (int i = 0; i < MAX_LAYERS; i++) + { + if (m_layerUpdate[i].updated) { + QLayoutItem * const item = m_layout->itemAt(i); + AudioLayerWidget *alw = dynamic_cast(item->widget()); + if (m_layerUpdate[i].vol > -1) { + alw->setVol(m_layerUpdate[i].vol); + m_layerUpdate[i].vol = -1; + } + if (m_layerUpdate[i].cursor > -1) { + alw->setCurrentTime(m_layerUpdate[i].cursor); + m_layerUpdate[i].cursor = -1; + } + if (m_layerUpdate[i].pan > -1) { + alw->setPan(m_layerUpdate[i].pan); + m_layerUpdate[i].pan = -1; + } + if (m_layerUpdate[i].pitch > -1) { + alw->setPitch(m_layerUpdate[i].pitch); + m_layerUpdate[i].pitch = -1; + } + if (m_layerUpdate[i].status != Status::Iddle) { + alw->setPlaybackStatus(m_layerUpdate[i].status); + m_layerUpdate[i].status = Status::Iddle; + } + if (m_layerUpdate[i].duration > -1) { + alw->setMediaFile(m_layerUpdate[i].media); + alw->setDuration(m_layerUpdate[i].duration); + m_layerUpdate[i].duration = -1; + } + m_layerUpdate[i].updated = false; + } + } } diff --git a/src/audiowidget.h b/src/audiowidget.h index a293a0a..dd9b1f1 100644 --- a/src/audiowidget.h +++ b/src/audiowidget.h @@ -5,7 +5,6 @@ #include "audiolayerwidget.h" #include "settings.h" -#include "miniaudioengine.h" #include "defines.h" // MAX_LAYERS class AudioWidget : public QWidget @@ -14,14 +13,22 @@ class AudioWidget : public QWidget public: AudioWidget(QWidget *parent = nullptr); - void mediaLoaded(int layer, QString media, float duration); + +private: + QHBoxLayout *m_layout; + layerData m_layerUpdate[MAX_LAYERS]; + QTimer *m_refreshUi; + +public slots: 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 cursorChanged(int layer, float cursor); - QHBoxLayout *m_layout; + void mediaLoaded(int layer, QString media, float duration); + void playbackChanged(int layer, Status status); +private slots: + void refreshUi(); signals: void uiPlaybackChanged(int layer, Status s); void uiSliderChanged(int layer, Slider s, int vol); diff --git a/src/defines.h b/src/defines.h index f8a2312..6552d19 100644 --- a/src/defines.h +++ b/src/defines.h @@ -6,9 +6,10 @@ #define LICENSE "GPL 3 Licensed. See LICENSE.txt." #define DEFAULT_FILE "lms-audio.xlm" #define MAX_LAYERS 4 -#define UI_REFRESH_TIME 93 +#define MAX_AUDIODEVICES 8 +#define UI_REFRESH_TIME 77 +#define FADE_TIME 25 // DMX Frame time, 40 fps, avoid clicks -// struct where save the DMX settings for each layer struct dmxSetting { int address; unsigned int universe; @@ -41,5 +42,15 @@ enum Slider Pitch, }; +#include +struct layerData { + QString media; + Status status; + bool updated; + float vol; + float cursor; + int pan; + int pitch; + float duration; +}; #endif // DEFINES_H - diff --git a/src/dmxPersonality.h b/src/dmxPersonality.h index c56829e..82f9468 100644 --- a/src/dmxPersonality.h +++ b/src/dmxPersonality.h @@ -10,7 +10,6 @@ #define ENTRY_POINT_COARSE 5 #define ENTRY_POINT_FINE 4 #define PITCH 7 - #define LAYER_CHANNELS 9 #endif // DMXPERSONALITY_H diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp index 2d92918..b769679 100644 --- a/src/libremediaserver-audio-gui.cpp +++ b/src/libremediaserver-audio-gui.cpp @@ -38,7 +38,7 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent) this->setContentsMargins(5, 5, 5, 5); this->setStyleSheet( "color: white;" - "background-color: gray;" + "background-color: #4f4048;" "selection-color: blue;" "selection-background-color: green" ); diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index 589c190..cb18dc2 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -21,11 +21,11 @@ #include "libremediaserver-audio.h" -libreMediaServerAudio::libreMediaServerAudio(bool gui) +libreMediaServerAudio::libreMediaServerAudio() { - m_ui = gui; - Settings *set = Settings::getInstance(); - set->readFile(); + m_settings = Settings::getInstance(); + m_settings->readFile(); + m_ui = m_settings->getShowUi(); m_mediaLibrary = new MediaLibrary; m_mediaLibrary->initMediaLibrary(); for (int i = 0; i < MAX_LAYERS; i++) { @@ -38,12 +38,11 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui) m_updateUi[i][3] = -1; #endif } - m_ola = new olaThread(this, set->getLayersNumber()); + m_ola = new olaThread(this, m_settings->getLayersNumber()); Q_CHECK_PTR(m_ola); m_ola->blockSignals(true); - connect(m_ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int))); m_ola->registerUniverse(); - m_mae.startEngine(set->getAudioDeviceId()); + m_mae.startEngine(m_settings->getAudioDeviceId()); qDebug("Core init Complete. Start reading DMX."); m_ola->blockSignals(false); #ifdef NOGUI @@ -57,27 +56,29 @@ libreMediaServerAudio::~libreMediaServerAudio() m_mae.stopEngine(); } +void libreMediaServerAudio::loadMedia(int layer, int folder, int file) +{ + QString 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()); + m_currentMedia[layer] = mediaFile; +#ifndef NOGUI + if (m_ui) + m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); +#endif + m_mae.printFormatInfo(layer); + } +} + void libreMediaServerAudio::dmxInput(int layer, int channel, int value) { if (layer >= MAX_LAYERS || channel >= LAYER_CHANNELS) return; QString mediaFile = NULL; int aux; - 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()); - m_currentMedia[layer] = mediaFile; -#ifndef NOGUI - if (m_ui) - m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); -#endif - } - } else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) { + if (channel == VOLUME_COARSE || channel == VOLUME_FINE) { float tmp = value / 65025.0f; m_mae.volChanged(layer, tmp); m_updateUi[layer][0] = tmp * 100.0f; @@ -104,15 +105,17 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) m_mae.playbackChanged(layer, s); m_currentStatus[layer] = s; #ifndef NOGUI - if (m_ui) m_lmsUi->m_aw->playbackChanged(layer, s); + if (m_ui) { + m_lmsUi->m_aw->playbackChanged(layer, s); + m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); + } #endif } } - #ifndef NOGUI void libreMediaServerAudio::refreshUi() { if (!m_ui) return; - for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) { + for (int i= 0; i < m_settings->getLayersNumber(); i++ ) { if (m_updateUi[i][0] >= 0) { m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]); m_updateUi[i][0] = -1; @@ -125,7 +128,9 @@ void libreMediaServerAudio::refreshUi() { m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]); m_updateUi[i][2] = -1; } - if (m_updateUi[i][3] >= 0) { + if (m_updateUi[i][3] >= 0 \ + || m_currentStatus[i] == Status::PlayingOnce\ + || m_currentStatus[i] == Status::PlayingLoop) { m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); m_updateUi[i][3] = -1; } @@ -135,6 +140,7 @@ void libreMediaServerAudio::refreshUi() { void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) { m_lmsUi = lmsUi; + m_ui = true; connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int))); connect(m_lmsUi->m_aw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderChanged(int, Slider, int))); connect(m_lmsUi->m_aw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status))); @@ -145,6 +151,7 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi) m_ola->start(QThread::TimeCriticalPriority ); }; +// From Ui widgets void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) { switch (s){ @@ -166,8 +173,12 @@ void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s) m_currentStatus[layer] = s; } -void libreMediaServerAudio::uiLoadMedia(int layer, QString s) +void libreMediaServerAudio::uiLoadMedia(int layer, QString mediaFile) { - m_mae.loadMedia(layer, s.toLatin1().data()); + if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0) + return; + m_mae.loadMedia(layer, mediaFile.toLatin1().data()); + m_currentMedia[layer] = mediaFile; + m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); } #endif diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 665f3e2..1af37df 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -21,6 +21,7 @@ #define LIBREMEDIASERVERAUDIO_H #include "medialibrary.h" +#include "miniaudioengine.h" #include "olathread.h" #include "settings.h" #include "defines.h" @@ -33,33 +34,35 @@ class libreMediaServerAudio : public QObject Q_OBJECT public: - libreMediaServerAudio(bool gui = false); + libreMediaServerAudio(); virtual ~libreMediaServerAudio(); void dmxInput(int layer, int channel, int value); + void loadMedia(int layer, int folder, int file); #ifndef NOGUI void setUi(libreMediaServerAudioUi *lmsUi); + bool inline getShowUi() { return m_settings->getShowUi(); } #endif - //static void NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer); + private: olaThread *m_ola; MediaLibrary *m_mediaLibrary; MiniAudioEngine m_mae; + Settings *m_settings; QString m_currentMedia[MAX_LAYERS]; Status m_currentStatus[MAX_LAYERS]; - static QList m_dmxSettings; -#ifndef NOGUI + QList m_dmxSettings; bool m_ui; +#ifndef NOGUI QTimer *m_refreshUi; libreMediaServerAudioUi *m_lmsUi; float m_updateUi[MAX_LAYERS][4]; -#endif private slots: -#ifndef NOGUI void refreshUi(); void uiSliderChanged(int layer, Slider s, int value); void uiPlaybackChanged(int layer, Status s); void uiLoadMedia(int layer, QString s); + #endif }; diff --git a/src/main.cpp b/src/main.cpp index eea3c29..79b7a91 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,9 +32,9 @@ bool hasUi(int &argc, char *argv[]) int main(int argc, char *argv[]) { QApplication app(argc, argv); - libreMediaServerAudio lms(hasUi(argc, argv)); + libreMediaServerAudio lms; #ifndef NOGUI - if (hasUi(argc, argv)) + if (hasUi(argc, argv) || lms.getShowUi()) { libreMediaServerAudioUi *lmsUi = new libreMediaServerAudioUi(); lms.setUi(lmsUi); diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index f65744d..c2d9a6d 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -4,6 +4,11 @@ MiniAudioEngine::MiniAudioEngine() { for (int i =0; i < MAX_LAYERS; i++) { m_mediaLoaded[i] = false; + m_currentLayerValues[i].status = Status::Iddle; + m_currentLayerValues[i].pan = 128; + m_currentLayerValues[i].pitch = 128; + m_currentLayerValues[i].vol = 0; + m_currentLayerValues[i].cursor = 0; } } @@ -79,8 +84,8 @@ ma_result MiniAudioEngine::startContext() resourceManagerConfig = ma_resource_manager_config_init(); resourceManagerConfig.decodedFormat = ma_format_f32; /* ma_format_f32 should almost always be used as that's what the engine (and most everything else) uses for mixing. */ resourceManagerConfig.decodedChannels = 0; - resourceManagerConfig.decodedSampleRate = 0; - resourceManagerConfig.jobThreadCount = 0; + resourceManagerConfig.decodedSampleRate = ma_standard_sample_rate_48000; + resourceManagerConfig.jobThreadCount = 1; result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager); if (result != MA_SUCCESS) { qCritical("Failed to initialize audio resource manager."); @@ -114,11 +119,9 @@ ma_result MiniAudioEngine::getAllAudioDevices() ma_result MiniAudioEngine::loadMedia(int layer, char *file) { ma_result result; - float vol = -1; if (m_mediaLoaded[layer] == true) { - vol = ma_sound_get_volume(&m_currentSound[layer]); ma_sound_uninit(&m_currentSound[layer]); m_mediaLoaded[layer] = false; } @@ -133,10 +136,8 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) qWarning("Failed to load file %s", file); else { m_mediaLoaded[layer] = true; - if (vol == -1) - this->volChanged(layer, 0); - else - this->volChanged(layer, vol); + this->refreshValues(layer); + m_currentLayerValues[layer].media = file; } return result; } @@ -191,7 +192,7 @@ ma_result MiniAudioEngine::printFormatInfo(int layer) qWarning("Failed to get data format %i\n", layer); return MA_INVALID_DATA; } - qInfo("samples/sec: %u format: %u channels: %u", sampleRate, format, channels); + qInfo() << "name:" << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; return result; } @@ -200,9 +201,10 @@ void MiniAudioEngine::volChanged(int layer, float vol) { if (m_mediaLoaded[layer] == false) return; - if (vol > 1) - vol = 1; - ma_sound_group_set_volume(&m_currentSound[layer], vol); + if (vol >= 1) + vol = 0.99f; + ma_sound_group_set_fade_in_milliseconds(&m_currentSound[layer], -1, vol, FADE_TIME); + m_currentLayerValues[layer].vol = vol; } void MiniAudioEngine::panChanged(int layer, float value) @@ -213,6 +215,7 @@ void MiniAudioEngine::panChanged(int layer, float value) return; result = (value / 128.0) - 1.0; ma_sound_group_set_pan(&m_currentSound[layer], result); + m_currentLayerValues[layer].pan = value; } void MiniAudioEngine::pitchChanged(int layer, float value) @@ -223,6 +226,7 @@ void MiniAudioEngine::pitchChanged(int layer, float value) return; result = value / 128.0; ma_sound_group_set_pitch(&m_currentSound[layer], result); + m_currentLayerValues[layer].pitch = value; } void MiniAudioEngine::playbackChanged(int layer, Status status) @@ -235,7 +239,7 @@ void MiniAudioEngine::playbackChanged(int layer, Status status) break; case Status::Stopped: ma_sound_stop(&m_currentSound[layer]); - ma_sound_seek_to_pcm_frame(&m_currentSound[layer], 0); + this->setCursor(layer, m_currentLayerValues[layer].cursor); break; case Status::PlayingLoop: ma_sound_set_looping(&m_currentSound[layer], true); @@ -248,30 +252,35 @@ void MiniAudioEngine::playbackChanged(int layer, Status status) default: break; } + m_currentLayerValues[layer].status = status; } void MiniAudioEngine::setCursor(int layer, int cursor) { - ma_uint64 f; + ma_uint64 end; + m_currentLayerValues[layer].cursor = cursor; if (m_mediaLoaded[layer] == false) return; - ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &f); - f = (cursor * f) / 65025; - ma_sound_seek_to_pcm_frame(&m_currentSound[layer], f); - // ToDo: change the loop entry point too + ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end); + ma_uint64 start = (cursor * end) / 65025; + ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start); + ma_result result = ma_data_source_set_loop_point_in_pcm_frames(&m_currentSound[layer], start, end); + if (result != MA_SUCCESS) { + return; // Failed to set the loop point. + } } Status MiniAudioEngine::getStatus(int layer) { - if (m_mediaLoaded[layer] == 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; + return m_currentLayerValues[layer].status; +} + +void MiniAudioEngine::refreshValues(int layer) +{ + this->panChanged(layer, m_currentLayerValues[layer].pan); + this->volChanged(layer, m_currentLayerValues[layer].vol); + this->pitchChanged(layer, m_currentLayerValues[layer].pitch); + this->playbackChanged(layer, m_currentLayerValues[layer].status); + this->setCursor(layer, m_currentLayerValues[layer].cursor); } diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 169d33b..2c3ec5a 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -40,10 +40,12 @@ private: ma_context context; ma_sound m_currentSound[MAX_LAYERS]; ma_bool8 m_mediaLoaded[MAX_LAYERS]; + layerData m_currentLayerValues[MAX_LAYERS]; ma_result getAllAudioDevices(); ma_result startDevice(int id); ma_result startContext(); + void refreshValues(int layer); }; #endif // MINIAUDIOENGINE_H diff --git a/src/olathread.cpp b/src/olathread.cpp index 409cf79..6ca9325 100644 --- a/src/olathread.cpp +++ b/src/olathread.cpp @@ -1,5 +1,4 @@ #include "libremediaserver-audio.h" -//#include "olathread.h" olaThread::olaThread(QObject *parent, int layers) : m_counter(0) @@ -36,7 +35,6 @@ void olaThread::init() } m_client = m_clientWrapper->GetClient(); m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx)); - //m_client->SetDMXCallback(ola::NewCallback((libreMediaServerAudio *)this->parent(), libreMediaServerAudio::NewDmx)); m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss)); m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed)); m_dmxSettings = Settings::getInstance()->getDmxSettings(); @@ -69,30 +67,31 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, bool volSent = false; bool entrySent = false; bool fileSent = false; + int aux; 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 DMX_FOLDER: - value *= 0x100; - value += buffer.Get(i.address + DMX_FILE); - qobject_cast(parent())->dmxInput(i.layer, j, value); - m_dmx[i.layer][DMX_FILE] = buffer.Get(i.address + DMX_FILE); + aux = buffer.Get(i.address + DMX_FILE); + qobject_cast(parent())->loadMedia(i.layer, value, aux); + m_dmx[i.layer][DMX_FILE] = aux; fileSent = true; break; case DMX_FILE: if (fileSent) break; - value += buffer.Get(i.address + DMX_FOLDER) * 0x100; - qobject_cast(parent())->dmxInput(i.layer, j, value); - m_dmx[i.layer][DMX_FOLDER] = buffer.Get(i.address + DMX_FOLDER); + aux = buffer.Get(i.address + DMX_FOLDER); + qobject_cast(parent())->loadMedia(i.layer, aux, value); + m_dmx[i.layer][DMX_FOLDER] = aux; fileSent = true; break; case VOLUME_FINE: - value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value; + aux = buffer.Get(i.address + VOLUME_COARSE); + value += (aux * 0x100); qobject_cast(parent())->dmxInput(i.layer, j, value); - m_dmx[i.layer][VOLUME_COARSE] = buffer.Get(i.address + VOLUME_COARSE); + m_dmx[i.layer][VOLUME_COARSE] = aux; volSent = true; break; case VOLUME_COARSE: @@ -103,6 +102,9 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data, m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE); volSent = true; break; + case PLAYBACK: + qobject_cast(parent())->dmxInput(i.layer, j, value); + break; case ENTRY_POINT_FINE: value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value; qobject_cast(parent())->dmxInput(i.layer, j, value); diff --git a/src/settings.cpp b/src/settings.cpp index f664bb0..9e00914 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -15,6 +15,7 @@ Settings::Settings(QObject *parent) : QObject(parent) { m_layersNumber = 0; + m_ui = false; } // Read the dmx settings for dmx.xml At the moment we need: @@ -23,6 +24,7 @@ Settings::Settings(QObject *parent) : // - The first DMX channel of each source/layer // - The universe to bind in OLA // - Audio device id +// - Show the Ui or not void Settings::readFromFile(QString file) { QFile* xmlFile = new QFile(file); if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -34,53 +36,56 @@ void Settings::readFromFile(QString file) { exit(1); } QXmlStreamReader* xmlReader = new QXmlStreamReader(xmlFile); - int counter = 0; - //Parse the XML until we reach end of it - while(!xmlReader->atEnd() && !xmlReader->hasError() && counter < MAX_LAYERS) { - // Read next element + while(!xmlReader->atEnd() && !xmlReader->hasError()) { QXmlStreamReader::TokenType token = xmlReader->readNext(); - //If token is just StartDocument - go to next if(token == QXmlStreamReader::StartDocument) { continue; } - //If token is StartElement - read it if(token == QXmlStreamReader::StartElement) { - if(xmlReader->name() == "dmxSettings") { - int version = xmlReader->attributes().value("fileVersion").toLocal8Bit().toInt(); - if(version == 1) { - m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt(); - m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit(); - continue; - } - } - if(xmlReader->name() == "audioDevice") { - m_audioDeviceId = xmlReader->attributes().value("id").toLocal8Bit().toInt(); + if(xmlReader->name() == "lmsAudio") { + m_ui = xmlReader->attributes().value("ui").toLocal8Bit().toInt(); + m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt(); + m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit(); continue; } - QString add = "layer"; - add.append(QString("%1").arg(counter)); - if((xmlReader->name() == add)) { + if(xmlReader->name() == "audioDevice") { + m_audioDeviceQty = xmlReader->attributes().value("devicesNumber").toLocal8Bit().toInt(); + for (uint i = 0; i < m_audioDeviceQty; i++) + { + m_audioDeviceId[i] = xmlReader->attributes().value(QString("id%1").arg(i)).toLocal8Bit().toInt(); + } + + } + if(xmlReader->name() == "layer") { dmxSetting temp; temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1; temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt(); - temp.layer = counter; + temp.layer = xmlReader->attributes().value("id").toLocal8Bit().toInt(); m_settings.append(temp); if (!m_universe.contains(temp.universe)) { m_universe.insert(temp.universe); } - counter++; } } } if(xmlReader->hasError()) { QMessageBox::critical(NULL,"File xml Parse Error ", xmlReader->errorString(), QMessageBox::Ok); qWarning("File xml Parse Error %s", xmlReader->errorString().toLatin1().constData()); - return; + // ToDo: manage this, open a dialog to load a new file. } xmlReader->clear(); xmlFile->close(); delete xmlReader; delete xmlFile; + this->printSettings(); +} + +void Settings::printSettings() { + qInfo() << "Settings read;\nShow Ui:" << m_ui << "Layers:" << m_layersNumber << "Path:" << m_pathmedia <<"Audio Device qty:" << m_audioDeviceQty; + for (uint i = 0; i < m_audioDeviceQty; i++) + qInfo() << "Audio device id:" << m_audioDeviceId[i]; + for (int i = 0; i < m_layersNumber; i++) + qInfo() << "Layer:" << m_settings[i].layer << "Address:" << m_settings[i].address << "Universe:" << m_settings[i].universe; } void Settings::readFile() { diff --git a/src/settings.h b/src/settings.h index 8cd55bb..f27da6a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "medialibrary.h" #include "audiowidget.h" @@ -15,25 +16,27 @@ class Settings : public QObject Q_OBJECT public: + Settings(QObject *parent = 0); static Settings *getInstance(); inline QSet getUniverses() { return m_universe; } inline QString getPathMedia() { return m_pathmedia; } inline QList getDmxSettings() { return m_settings; } inline int getLayersNumber() { return m_layersNumber; } + inline int getAudioDeviceId() { return m_audioDeviceId[0]; } + inline bool getShowUi() { return m_ui; } void readFile(); - inline int getAudioDeviceId() { return m_audioDeviceId; } + void readFromFile(QString file); + void printSettings(); private: static Settings *_instance; QList m_settings; QString m_pathmedia; - uint m_audioDeviceId; + uint m_audioDeviceId[MAX_AUDIODEVICES]; + uint m_audioDeviceQty; QSet m_universe; int m_layersNumber; - - explicit Settings(QObject *parent = 0); - void readFromFile(QString file); - + bool m_ui; }; #endif // SETTINGS_H diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp index a488560..9ef9680 100644 --- a/src/slidergroup.cpp +++ b/src/slidergroup.cpp @@ -18,10 +18,11 @@ SliderGroup::SliderGroup(QString name, slider->setMinimumHeight(0); slider->setSingleStep(1); slider->setRange(min, max); + slider->setValue(0); slider->setMinimumWidth(50); slider->setToolTip(name); slider->setStyleSheet("QSlider {" - "border: 2px solid #685060;" + "border: 1px solid #5a4855;" "margin: 0px;" "height: 200px;" "width: 50px;}" @@ -32,17 +33,20 @@ SliderGroup::SliderGroup(QString name, valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons); valueBox->setMinimumWidth(50); valueBox->setRange(min, max); + valueBox->setValue(0); valueBox->setDecimals(decimals); valueBox->setObjectName(name); valueBox->setToolTip(name); valueBox->setAlignment(Qt::AlignHCenter); valueBox->setContentsMargins(0, 0, 0, 0); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int))); + //connect(slider, SIGNAL(mousePressEvent(QMouseEvent)), this, SLOT(mousePressEvent(QMouseEvent *))); layout->addWidget(slider); layout->addWidget(valueBox); - this->setStyleSheet("border: 2px solid #685060;" + this->setStyleSheet("border: 1px solid #5a4855;" "width: 50px;" "margin: 0px;" + "background-color: #383034;" ); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); @@ -67,3 +71,11 @@ void SliderGroup::setValue(float value) slider->blockSignals(false); valueBox->blockSignals(false); } + +void SliderGroup::mousePressEvent(QMouseEvent* event) { + Q_UNUSED(event); + if (slider->isEnabled()) + slider->setDisabled(true); + else + slider->setDisabled(false); +} diff --git a/src/slidergroup.h b/src/slidergroup.h index f597a5b..5bfeeb8 100644 --- a/src/slidergroup.h +++ b/src/slidergroup.h @@ -27,6 +27,8 @@ public slots: private: QSlider *slider; QDoubleSpinBox *valueBox; + + void mousePressEvent(QMouseEvent* event); }; #endif From 0979c3608e3f1d961453fb4f128f2c1c9573d450 Mon Sep 17 00:00:00 2001 From: snt Date: Tue, 7 May 2024 20:57:13 +0200 Subject: [PATCH 10/13] puliendo --- docs/changelog.txt | 8 ++------ docs/roadmap.txt | 6 +----- src/audiolayerwidget.cpp | 3 --- src/libremediaserver-audio.cpp | 1 + src/miniaudioengine.cpp | 2 +- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index a69017b..5c7e0b6 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -6,12 +6,7 @@ https://git.criptomart.net/libremediaserver Libre Media Server ChangeLog - - - - - -v 0.2.0 Antígona (24/04/2024) +v 0.2.0 Antígona (26/05/2024) + Change audio engine to miniaudio because is imposible pan in SFML and it has not access to low API and audio processing. + Refactor all audio methods to MiniAudioEngine class. + Select sound device output. @@ -29,6 +24,7 @@ v 0.2.0 Antígona (24/04/2024) + New DMX personality version, better sort for audio needs (first load media, set vol, pan, etc, last playback order); + Refresh layer values when it loads a new sound file. + No QtSignals for sending data, better performance about 20% in my machine. Now, libremediaserver only updates values in AudioWidget, ui refresh is doing with a timer in audiowidget, so there is not problems between graphical and ola thread (the callback). ++ Load media files from ui clicking in the media labels. v 0.1.3 Leúcade (19/04/2024) diff --git a/docs/roadmap.txt b/docs/roadmap.txt index bd98089..153c596 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -41,17 +41,13 @@ v 0.2.1 - audio device linked, outputs will be redirected there. - dmx address + universe settings. - Rose noise and sine generator in menu to test system. -- Ui/Ux; Keyboards strokes, load media files from ui. +- Ui/Ux; Keyboards strokes. - Ui/Ux: Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante. - Logs, verbosity, timestamp. - New play mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH - Vumeter or indicator about audio output in layer and master, add to sliderGroup. -- QSlider can not accept floats and it can no manage high frequency updates. - SettingsDialog. - Load/save conf file. - ¿Exit Point? is it needed? - Hardening: check return errors, try/catch exceptions, i'm too happy.... - Tests: errors on wrong conf file. -- BUGFIX: there are some small clicks when changing volume and play/stop/pause. vol 24 bits? microfades in engine? setVol 0 before changing playback state? -- refactorize dmxInput: loadMedia, changePlayBack, -- BUGFIX: in nogui mode we need more info print at terminal (load media, change playback status). diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index a22b2cc..4a07451 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -172,7 +172,6 @@ void AudioLayerWidget::setMediaFile(QString file) m_folderValue->setText(list.at(size - 2)); m_fileValue->setText(list.at(size - 1)); } - this->setPlaybackStatus(Status::Stopped); } void AudioLayerWidget::setPlaybackStatus(Status s) @@ -180,8 +179,6 @@ void AudioLayerWidget::setPlaybackStatus(Status s) Status status = static_cast(s); m_suspendResumeButton->blockSignals(true); m_status = status; - //if (status == Status::Stopped) - // refreshCurrentTime(0); m_suspendResumeButton->setText(StatusStr[status]); m_suspendResumeButton->blockSignals(false); } diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index cb18dc2..ab12820 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -104,6 +104,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) s = Status::PlayingLoop; m_mae.playbackChanged(layer, s); m_currentStatus[layer] = s; + qInfo() << "Layer" << layer << StatusStr[s]; #ifndef NOGUI if (m_ui) { m_lmsUi->m_aw->playbackChanged(layer, s); diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index c2d9a6d..fa58464 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -192,7 +192,7 @@ ma_result MiniAudioEngine::printFormatInfo(int layer) qWarning("Failed to get data format %i\n", layer); return MA_INVALID_DATA; } - qInfo() << "name:" << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; + qInfo() << "Layer:" << layer << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; return result; } From cd0105c9f9d66173dd8f6d61e5eec3327990b1fb Mon Sep 17 00:00:00 2001 From: snt Date: Wed, 8 May 2024 18:56:16 +0200 Subject: [PATCH 11/13] =?UTF-8?q?quitado=20peque=C3=B1o=20glitch=20cuando?= =?UTF-8?q?=20entry=20point=20no=20es=20cero.=20stop=20con=20fade=20out=20?= =?UTF-8?q?para=20evitar=20click.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/roadmap.txt | 6 +- src/audiolayerwidget.cpp | 10 ++-- src/audiowidget.cpp | 11 +++- src/defines.h | 2 +- src/libremediaserver-audio.cpp | 24 ++++++-- src/miniaudioengine.cpp | 105 ++++++++++++++++++--------------- src/miniaudioengine.h | 14 +++-- src/settings.cpp | 4 +- 8 files changed, 105 insertions(+), 71 deletions(-) diff --git a/docs/roadmap.txt b/docs/roadmap.txt index 153c596..94081f4 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -5,7 +5,6 @@ https://git.criptomart.net/libremediaserver ******************************************************************************* Libre Media Server Roadmap -(en continuo crecimiento...) v 0.2.x - skin, UI/UX @@ -45,9 +44,12 @@ v 0.2.1 - Ui/Ux: Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante. - Logs, verbosity, timestamp. - New play mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH -- Vumeter or indicator about audio output in layer and master, add to sliderGroup. - SettingsDialog. - Load/save conf file. - ¿Exit Point? is it needed? - Hardening: check return errors, try/catch exceptions, i'm too happy.... - Tests: errors on wrong conf file. + +v0.2.0: +- BUGFIX: crash at startup and no dmx signal. +- Vumeter or indicator about audio output in layer and master, add to sliderGroup. diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 4a07451..e8d22bd 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -10,8 +10,8 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): QVBoxLayout *playback = new QVBoxLayout; m_folderValue = new ClickableLabel; - //m_folderValue->setMaximumWidth(160); - m_folderValue->setAlignment(Qt::AlignHCenter); + m_folderValue->setMaximumWidth(160); + m_folderValue->setAlignment(Qt::AlignLeft); m_folderValue->setStyleSheet( "color: white;" "background-color: black;" @@ -20,8 +20,8 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_fileValue = new ClickableLabel; connect(m_fileValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); connect(m_folderValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); - //m_fileValue->setMaximumWidth(160); - m_fileValue->setAlignment(Qt::AlignHCenter); + m_fileValue->setMaximumWidth(160); + m_fileValue->setAlignment(Qt::AlignLeft); m_fileValue->setStyleSheet( "color: white;" "background-color: black;" @@ -33,7 +33,6 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_suspendResumeButton = new QPushButton(this); m_suspendResumeButton->setText(StatusStr[Status::Iddle]); - //m_suspendResumeButton->setMaximumWidth(180); connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); layout->addWidget(m_suspendResumeButton); @@ -42,7 +41,6 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progress->setRange(0, 0); m_progress->setValue(0); m_progress->setFormat("%v / %m"); - //m_progress->setMaximumWidth(180); layout->addWidget(m_progress); m_progressTime = new QTimeEdit; diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index ca2633a..8bd077c 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -11,13 +11,20 @@ AudioWidget::AudioWidget(QWidget *parent) : connect(alw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SIGNAL(uiSliderChanged(int, Slider, int))); connect(alw, SIGNAL(uiPlaybackChanged(int, Status)), this, SIGNAL(uiPlaybackChanged(int, Status))); connect(alw, SIGNAL(uiLoadMedia(int, QString)), this, SIGNAL(uiLoadMedia(int, QString))); + m_layerUpdate[i].status = Status::Iddle; + m_layerUpdate[i].duration = 0; + m_layerUpdate[i].media = ""; + m_layerUpdate[i].vol = 0; + m_layerUpdate[i].pan = 128; + m_layerUpdate[i].pitch = 128; + m_layerUpdate[i].cursor = 0; } m_layout->setSpacing(0); m_layout->setContentsMargins(1, 1, 1, 1); setLayout(m_layout); m_refreshUi = new QTimer(this); connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); - m_refreshUi->start(UI_REFRESH_TIME * 2); + m_refreshUi->start(UI_REFRESH_TIME * 1.5); } void AudioWidget::mediaLoaded(int layer, QString file, float duration) @@ -51,7 +58,7 @@ void AudioWidget::playbackChanged(int layer, Status status) void AudioWidget::cursorChanged(int layer, float cursor) { - m_layerUpdate[layer].cursor = floor(cursor * 1000) / 1000; + m_layerUpdate[layer].cursor = cursor; m_layerUpdate[layer].updated = true; } diff --git a/src/defines.h b/src/defines.h index 6552d19..a9c92b8 100644 --- a/src/defines.h +++ b/src/defines.h @@ -7,7 +7,7 @@ #define DEFAULT_FILE "lms-audio.xlm" #define MAX_LAYERS 4 #define MAX_AUDIODEVICES 8 -#define UI_REFRESH_TIME 77 +#define UI_REFRESH_TIME 66 #define FADE_TIME 25 // DMX Frame time, 40 fps, avoid clicks struct dmxSetting { diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index ab12820..2ea3266 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -108,7 +108,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) #ifndef NOGUI if (m_ui) { m_lmsUi->m_aw->playbackChanged(layer, s); - m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); + //m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer)); } #endif } @@ -170,16 +170,28 @@ void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value) void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s) { - m_mae.playbackChanged(layer, s); - m_currentStatus[layer] = s; + ma_result result; + + result = m_mae.playbackChanged(layer, s); + if (result == MA_SUCCESS) { + m_currentStatus[layer] = s; + } else { + qWarning() << "ui playback change error" << result << "status" << s << "layer" << layer; + } } void libreMediaServerAudio::uiLoadMedia(int layer, QString mediaFile) { + ma_result result; + if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0) return; - m_mae.loadMedia(layer, mediaFile.toLatin1().data()); - m_currentMedia[layer] = mediaFile; - m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); + result = m_mae.loadMedia(layer, mediaFile.toLatin1().data()); + if (result == MA_SUCCESS) { + m_currentMedia[layer] = mediaFile; + m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); + } else { + qWarning() << "ui load media error" << result << "file" << mediaFile << "layer" << layer; + } } #endif diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index fa58464..d1040b9 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -1,5 +1,5 @@ #include "miniaudioengine.h" - +#include //enum macro MiniAudioEngine::MiniAudioEngine() { for (int i =0; i < MAX_LAYERS; i++) { @@ -27,25 +27,26 @@ void MiniAudioEngine::stopEngine() ma_resource_manager_uninit(&resourceManager); } -bool MiniAudioEngine::startEngine(int n) +bool MiniAudioEngine::startEngine(uint n) { ma_result result; result = this->startContext(); - if (result != MA_SUCCESS) { - return result; - } - this->getAllAudioDevices(); + if (result != MA_SUCCESS) return result; + result = this->getAllAudioDevices(); + if (result != MA_SUCCESS) return result; result = this->startDevice(n); return result; } -ma_result MiniAudioEngine::startDevice(int id) +ma_result MiniAudioEngine::startDevice(uint id) { ma_result result; ma_device_config deviceConfig; ma_engine_config engineConfig; + if (id >= playbackDeviceCount) + id = playbackDeviceCount - 1; deviceConfig = ma_device_config_init(ma_device_type_playback); deviceConfig.playback.pDeviceID = &pPlaybackDeviceInfos[id].id; deviceConfig.playback.format = resourceManager.config.decodedFormat; @@ -73,7 +74,7 @@ ma_result MiniAudioEngine::startDevice(int id) return result; } iChosenDevice = id; - qInfo("Initialized audio device %d: %s", id, pPlaybackDeviceInfos[id].name); + qInfo("Initialized audio device %d : %s", id, pPlaybackDeviceInfos[id].name); return result; } @@ -85,7 +86,7 @@ ma_result MiniAudioEngine::startContext() resourceManagerConfig.decodedFormat = ma_format_f32; /* ma_format_f32 should almost always be used as that's what the engine (and most everything else) uses for mixing. */ resourceManagerConfig.decodedChannels = 0; resourceManagerConfig.decodedSampleRate = ma_standard_sample_rate_48000; - resourceManagerConfig.jobThreadCount = 1; + resourceManagerConfig.jobThreadCount = 4; result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager); if (result != MA_SUCCESS) { qCritical("Failed to initialize audio resource manager."); @@ -109,7 +110,7 @@ ma_result MiniAudioEngine::getAllAudioDevices() ma_context_uninit(&context); return result; } - printf("Audio devices detected in system:\n"); + printf("Audio devices available:\n"); for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < playbackDeviceCount; iAvailableDevice += 1) { qInfo("%d: : %s", iAvailableDevice, pPlaybackDeviceInfos[iAvailableDevice].name); } @@ -127,10 +128,8 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) } result = ma_sound_init_from_file(&engine, file, \ MA_SOUND_FLAG_NO_SPATIALIZATION \ - /*| MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE \ - | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC \ - | MA_SOUND_FLAG_NO_PITCH \ - | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM \*/ + | MA_SOUND_FLAG_DECODE \ + /*| MA_SOUND_FLAG_NO_PITCH \*/ , NULL, NULL, &m_currentSound[layer]); if (result != MA_SUCCESS) qWarning("Failed to load file %s", file); @@ -157,7 +156,7 @@ float MiniAudioEngine::getDuration(int layer) } result = ma_sound_get_data_format(&m_currentSound[layer], NULL, NULL, &sampleRate, NULL, 0); if (result != MA_SUCCESS) { - return result; + return MA_ERROR; } ret = 1000.0f * (lengthInPCMFrames / float(sampleRate)); return ret; @@ -173,8 +172,8 @@ float MiniAudioEngine::getCursor(int layer) result = ma_sound_get_cursor_in_seconds(&m_currentSound[layer], &ret); if (result != MA_SUCCESS) { - qWarning("Can not get cursor %i", layer); - ret = -1; + qWarning("%i can not get cursor error %i", layer, result); + ret = MA_ERROR; } return ret; } @@ -188,11 +187,10 @@ ma_result MiniAudioEngine::printFormatInfo(int layer) if (m_mediaLoaded[layer] == false) return MA_DOES_NOT_EXIST; ma_result result = ma_sound_get_data_format(&m_currentSound[layer], &format, &channels, &sampleRate, NULL, 0); - if (result != MA_SUCCESS) { - qWarning("Failed to get data format %i\n", layer); - return MA_INVALID_DATA; - } - qInfo() << "Layer:" << layer << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; + if (result != MA_SUCCESS) + qWarning("%i failed to get data format %i\n", layer, result); + else + qInfo() << "Layer:" << layer << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; return result; } @@ -220,55 +218,70 @@ void MiniAudioEngine::panChanged(int layer, float value) void MiniAudioEngine::pitchChanged(int layer, float value) { - float result; + float pitch; if (m_mediaLoaded[layer] == false) return; - result = value / 128.0; - ma_sound_group_set_pitch(&m_currentSound[layer], result); + pitch = value / 128.0; + ma_sound_group_set_pitch(&m_currentSound[layer], pitch); m_currentLayerValues[layer].pitch = value; } -void MiniAudioEngine::playbackChanged(int layer, Status status) +ma_result MiniAudioEngine::playbackChanged(int layer, Status status) { + ma_result result = MA_SUCCESS; + if (m_mediaLoaded[layer] == false) - return; + return MA_DOES_NOT_EXIST; switch (status) { case Status::Paused: - ma_sound_stop(&m_currentSound[layer]); + result = ma_sound_stop_with_fade_in_milliseconds(&m_currentSound[layer], FADE_TIME); break; case Status::Stopped: - ma_sound_stop(&m_currentSound[layer]); - this->setCursor(layer, m_currentLayerValues[layer].cursor); + result = ma_sound_stop_with_fade_in_milliseconds(&m_currentSound[layer], FADE_TIME); + result = this->seekToCursor(layer, m_currentLayerValues[layer].cursor); break; case Status::PlayingLoop: + ma_sound_set_stop_time_in_milliseconds(&m_currentSound[layer], ~(ma_uint64)0); ma_sound_set_looping(&m_currentSound[layer], true); - ma_sound_start(&m_currentSound[layer]); - break; + result = ma_sound_start(&m_currentSound[layer]); + break; case Status::PlayingOnce: + ma_sound_set_stop_time_in_milliseconds(&m_currentSound[layer], ~(ma_uint64)0); ma_sound_set_looping(&m_currentSound[layer], false); - ma_sound_start(&m_currentSound[layer]); + result = ma_sound_start(&m_currentSound[layer]); break; default: break; } - m_currentLayerValues[layer].status = status; + if (result == MA_SUCCESS) + m_currentLayerValues[layer].status = status; + return result; } -void MiniAudioEngine::setCursor(int layer, int cursor) +ma_result MiniAudioEngine::seekToCursor(int layer, int cursor) { - ma_uint64 end; + ma_result result = MA_SUCCESS; + ma_uint64 end, start; + + if (m_mediaLoaded[layer] == false) + return MA_DOES_NOT_EXIST; + result = ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end); + if (result != MA_SUCCESS) { return result; } + start = (cursor * end) / 65025; + result = ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start); + //if (result != MA_SUCCESS) { return result; } + //result = ma_data_source_set_loop_point_in_pcm_frames(&m_currentSound[layer], start, end); + return (result); +} + +ma_result MiniAudioEngine::setCursor(int layer, int cursor) +{ + ma_result result = MA_SUCCESS; m_currentLayerValues[layer].cursor = cursor; - if (m_mediaLoaded[layer] == false) - return; - ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end); - ma_uint64 start = (cursor * end) / 65025; - ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start); - ma_result result = ma_data_source_set_loop_point_in_pcm_frames(&m_currentSound[layer], start, end); - if (result != MA_SUCCESS) { - return; // Failed to set the loop point. - } + result = this->seekToCursor(layer, cursor); + return (result); } Status MiniAudioEngine::getStatus(int layer) @@ -278,9 +291,9 @@ Status MiniAudioEngine::getStatus(int layer) void MiniAudioEngine::refreshValues(int layer) { + this->seekToCursor(layer, m_currentLayerValues[layer].cursor); this->panChanged(layer, m_currentLayerValues[layer].pan); this->volChanged(layer, m_currentLayerValues[layer].vol); this->pitchChanged(layer, m_currentLayerValues[layer].pitch); this->playbackChanged(layer, m_currentLayerValues[layer].status); - this->setCursor(layer, m_currentLayerValues[layer].cursor); } diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 2c3ec5a..6d0ea19 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -13,7 +13,7 @@ class MiniAudioEngine public: MiniAudioEngine(); void stopEngine(); - bool startEngine(int id); + bool startEngine(uint id); static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); protected: @@ -21,13 +21,14 @@ protected: void volChanged(int layer, float vol); void panChanged(int layer, float pan); void pitchChanged(int layer, float pitch); - void playbackChanged(int layer, Status status); + ma_result playbackChanged(int layer, Status status); + ma_result setCursor(int layer, int cursor); + ma_result printFormatInfo(int layer); float getDuration(int layer); float getCursor(int layer); - void setCursor(int layer, int cursor); - ma_result printFormatInfo(int layer); Status getStatus(int layer); - inline float getVol(int layer) { return ma_sound_get_volume(&m_currentSound[layer]); } + inline float getVol(int layer) { + return ma_sound_get_volume(&m_currentSound[layer]); } private: ma_resource_manager_config resourceManagerConfig; @@ -43,9 +44,10 @@ private: layerData m_currentLayerValues[MAX_LAYERS]; ma_result getAllAudioDevices(); - ma_result startDevice(int id); + ma_result startDevice(uint id); ma_result startContext(); void refreshValues(int layer); + ma_result seekToCursor(int layer, int cursor); }; #endif // MINIAUDIOENGINE_H diff --git a/src/settings.cpp b/src/settings.cpp index 9e00914..9d06394 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -81,9 +81,9 @@ void Settings::readFromFile(QString file) { } void Settings::printSettings() { - qInfo() << "Settings read;\nShow Ui:" << m_ui << "Layers:" << m_layersNumber << "Path:" << m_pathmedia <<"Audio Device qty:" << m_audioDeviceQty; + qInfo() << "Settings readed:\nShow Ui:" << m_ui << "Layers:" << m_layersNumber << "Path:" << m_pathmedia <<"Audio Device qty:" << m_audioDeviceQty; for (uint i = 0; i < m_audioDeviceQty; i++) - qInfo() << "Audio device id:" << m_audioDeviceId[i]; + qInfo() << "Audio device internal id:" << i << "system id:" << m_audioDeviceId[i]; for (int i = 0; i < m_layersNumber; i++) qInfo() << "Layer:" << m_settings[i].layer << "Address:" << m_settings[i].address << "Universe:" << m_settings[i].universe; } From f67ad9b1e1c2b2a98b2f7c6abf5d925a1f35a48b Mon Sep 17 00:00:00 2001 From: snt Date: Thu, 9 May 2024 14:07:24 +0200 Subject: [PATCH 12/13] =?UTF-8?q?nuevos=20modos=20de=20reproducci=C3=B3n:?= =?UTF-8?q?=20Play=20Folder,=20Play=20Folder=20Loop,=20Play=20Folder=20Ran?= =?UTF-8?q?dom.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/roadmap.txt | 1 - src/defines.h | 13 +++++-- src/libremediaserver-audio.cpp | 64 +++++++++++++++++++++++++++++++++- src/libremediaserver-audio.h | 1 + src/medialibrary.h | 3 ++ src/miniaudioengine.cpp | 3 ++ src/miniaudioengine.h | 2 ++ 7 files changed, 83 insertions(+), 4 deletions(-) diff --git a/docs/roadmap.txt b/docs/roadmap.txt index 94081f4..0771257 100644 --- a/docs/roadmap.txt +++ b/docs/roadmap.txt @@ -51,5 +51,4 @@ v 0.2.1 - Tests: errors on wrong conf file. v0.2.0: -- BUGFIX: crash at startup and no dmx signal. - Vumeter or indicator about audio output in layer and master, add to sliderGroup. diff --git a/src/defines.h b/src/defines.h index a9c92b8..ff299c1 100644 --- a/src/defines.h +++ b/src/defines.h @@ -22,7 +22,10 @@ enum Status Paused, PlayingOnce, PlayingLoop, - Iddle + Iddle, + PlayingFolder, + PlayingFolderLoop, + PlayingFolderRandom }; static const char* StatusStr[] = @@ -30,8 +33,11 @@ static const char* StatusStr[] = "Stop", "Pause", "Playing One", - "Playing Loop", + "Playing One Loop", "Iddle", + "Playing Folder", + "Playing Folder Loop", + "Playing Folder Random", 0x0 }; @@ -52,5 +58,8 @@ struct layerData { int pan; int pitch; float duration; + int address; + unsigned int universe; + int device; }; #endif // DEFINES_H diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp index 2ea3266..a9868fd 100644 --- a/src/libremediaserver-audio.cpp +++ b/src/libremediaserver-audio.cpp @@ -70,6 +70,14 @@ void libreMediaServerAudio::loadMedia(int layer, int folder, int file) #endif m_mae.printFormatInfo(layer); } + if (m_currentStatus[layer] == Status::PlayingFolder \ + || (m_currentStatus[layer] == Status::PlayingFolderLoop)\ + || (m_currentStatus[layer] == Status::PlayingFolderRandom)) { + m_played.append(file); + } else if (m_currentStatus[layer] == Status::PlayingOnce \ + || m_currentStatus[layer] == Status::PlayingLoop) { + m_played.clear(); + } } void libreMediaServerAudio::dmxInput(int layer, int channel, int value) @@ -102,6 +110,12 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value) s = Status::Paused; else if (aux == 3) s = Status::PlayingLoop; + else if (aux == 4) + s = Status::PlayingFolder; + else if (aux == 5) + s = Status::PlayingFolderLoop; + else if (aux == 6) + s = Status::PlayingFolderRandom; m_mae.playbackChanged(layer, s); m_currentStatus[layer] = s; qInfo() << "Layer" << layer << StatusStr[s]; @@ -131,10 +145,58 @@ void libreMediaServerAudio::refreshUi() { } if (m_updateUi[i][3] >= 0 \ || m_currentStatus[i] == Status::PlayingOnce\ - || m_currentStatus[i] == Status::PlayingLoop) { + || m_currentStatus[i] == Status::PlayingLoop\ + || m_currentStatus[i] == Status::PlayingFolder\ + || m_currentStatus[i] == Status::PlayingFolderLoop + || m_currentStatus[i] == Status::PlayingFolderRandom) { m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i)); m_updateUi[i][3] = -1; } + if (m_mae.getAtEnd(i)) { + if (m_played.isEmpty()) + m_played.append(m_ola->getValue(i, DMX_FILE)); + if (m_currentStatus[i] == Status::PlayingOnce) { + m_currentStatus[i] = Status::Stopped; + } + if (m_currentStatus[i] == Status::PlayingFolder) { + uint last = m_played.last(); + int folder = m_ola->getValue(i, DMX_FOLDER); + last++; + if (last < m_mediaLibrary->getMediaFolderCount(folder)) { + this->loadMedia(i, folder, last); + m_mae.playbackChanged(i, Status::PlayingFolder); + } + else { + m_currentStatus[i] = Status::Stopped; + m_lmsUi->m_aw->playbackChanged(i, Status::Stopped); + } + } + if (m_currentStatus[i] == Status::PlayingFolderLoop) { + uint last = m_played.last(); + int folder = m_ola->getValue(i, DMX_FOLDER); + last++; + if (last >= m_mediaLibrary->getMediaFolderCount(folder)) { + this->loadMedia(i, folder, 0); + m_mae.playbackChanged(i, Status::PlayingFolderLoop); + } else { + this->loadMedia(i, folder, last); + m_mae.playbackChanged(i, Status::PlayingFolder); + } + } + if (m_currentStatus[i] == Status::PlayingFolderRandom) { + int last = -1; + int folder = m_ola->getValue(i, DMX_FOLDER); + if (uint(abs(m_played.size())) >= m_mediaLibrary->getMediaFolderCount(folder)) + m_played.clear(); + while (last == -1) { + last = rand() % m_mediaLibrary->getMediaFolderCount(folder); + if (m_played.contains(last)) + last = -1; + } + this->loadMedia(i, folder, last); + m_mae.playbackChanged(i, Status::PlayingFolderRandom); + } + } } } diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h index 1af37df..d83446a 100644 --- a/src/libremediaserver-audio.h +++ b/src/libremediaserver-audio.h @@ -52,6 +52,7 @@ private: Status m_currentStatus[MAX_LAYERS]; QList m_dmxSettings; bool m_ui; + QList m_played; #ifndef NOGUI QTimer *m_refreshUi; libreMediaServerAudioUi *m_lmsUi; diff --git a/src/medialibrary.h b/src/medialibrary.h index 8c2eb07..ea92bca 100644 --- a/src/medialibrary.h +++ b/src/medialibrary.h @@ -29,6 +29,9 @@ public: MediaLibrary(QObject *parent = 0); QString requestNewFile(int folder, int layer); void initMediaLibrary(); + inline uint getMediaFolderCount(int folder) { + return m_media->at(folder).m_ElementCount; + } private: QList *m_media; diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index d1040b9..9204636 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -247,6 +247,9 @@ ma_result MiniAudioEngine::playbackChanged(int layer, Status status) result = ma_sound_start(&m_currentSound[layer]); break; case Status::PlayingOnce: + case Status::PlayingFolder: + case Status::PlayingFolderLoop: + case Status::PlayingFolderRandom: ma_sound_set_stop_time_in_milliseconds(&m_currentSound[layer], ~(ma_uint64)0); ma_sound_set_looping(&m_currentSound[layer], false); result = ma_sound_start(&m_currentSound[layer]); diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 6d0ea19..6e1393c 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -5,6 +5,7 @@ #include "miniaudio.h" #include "defines.h" // MAX_LAYERS #include // prints messages +#define MA_DEBUG_OUTPUT class MiniAudioEngine { @@ -29,6 +30,7 @@ protected: Status getStatus(int layer); inline float getVol(int layer) { return ma_sound_get_volume(&m_currentSound[layer]); } + inline bool getAtEnd(int layer) { return m_currentSound[layer].atEnd; } private: ma_resource_manager_config resourceManagerConfig; From 7631e54d51aa2dc2bcb8c6640047cec8272219bc Mon Sep 17 00:00:00 2001 From: snt Date: Thu, 9 May 2024 14:10:46 +0200 Subject: [PATCH 13/13] =?UTF-8?q?nuevos=20modos=20reproducci=C3=B3n=20en?= =?UTF-8?q?=20personalidad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/LibreMediaServer_Audio.hed | 105 ++++++++++++++++---------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/docs/LibreMediaServer_Audio.hed b/docs/LibreMediaServer_Audio.hed index 58d0fd5..fda3e2d 100644 --- a/docs/LibreMediaServer_Audio.hed +++ b/docs/LibreMediaServer_Audio.hed @@ -2,7 +2,7 @@ ҊÅЁ䍡 ӽ Ꭸʆ -ɑ +ɑ ɬ 򉇁 Ԑɉ @@ -24,53 +24,56 @@ Ԓlj -έ -倬쏎 - -޽ڊ - -؛ -ŕ -ðݑ -ȕ -˛ -̽ɧ - -𓎍 - - -ً - -ʐ -ï -뷪 - - -܋ -Ò -뻡 -ǒ - -𓎍 -ʟ - -㍛ - - - - - - -𓎑 - - - -ҟ - - - -ف - - - - +Ŷ§ +ÐŽÊ +𡭟Ē + +܊ +񢰽 +зм +񓎍 +ҭ +ܻۏ +ڑן +ޏ + +Ƴ + + + +Ǖ + +𓎍Ԏ + + +Ξ +ֆ + +ց + +ᱯ +݈ + +؈ + +馹 +۴ +𓎍 + + + + + +𓎑 + + + +Ɨ + + + +Ӌ +쏎 + + +