libreMediaServer no refresca directamente la ui, solo actualiza
valores en audiowidget. la ui se actualiza con un timer en audiowidget. Quitadas señales en todo, mejora rendimiento. fade en volumen basado en la trama dmx (25 ms) para evitar clicks. refresca los valores de la capa cuando carga un media. Ui Ok. nuevo formato de archivo de configuración xml.
This commit is contained in:
parent
5915d4898e
commit
7a9c0cd0ac
20 changed files with 271 additions and 160 deletions
|
@ -27,6 +27,8 @@ v 0.2.0 Antígona (24/04/2024)
|
||||||
+ Compilation without GUI (-DNOGUI).
|
+ Compilation without GUI (-DNOGUI).
|
||||||
+ New Status "Iddle" in playbacks if is not loaded.
|
+ 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);
|
+ 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)
|
v 0.1.3 Leúcade (19/04/2024)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<dmxSettings fileVersion="1" layersNumber="4" path="/home/snt/Documentos/lab/lms/media/sound">
|
<lmsAudio ui="1" layersNumber="4" path="../media/sound" >
|
||||||
<audioDevice id="3" />
|
<audioDevice devicesNumber="2" id0="3" id1="4" />
|
||||||
<layer0 dmx="1" universe="1" />
|
<layer id="0" dmx="1" universe="1" />
|
||||||
<layer1 dmx="17" universe="1" />
|
<layer id="1" dmx="17" universe="1" />
|
||||||
<layer2 dmx="33" universe="1" />
|
<layer id="2" dmx="33" universe="1" />
|
||||||
<layer3 dmx="49" universe="1" />
|
<layer id="3" dmx="49" universe="1" />
|
||||||
</dmxSettings>
|
</lmsAudio>
|
||||||
|
|
|
@ -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.
|
- 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.
|
- Logs, verbosity, timestamp.
|
||||||
- New play 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.
|
- 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.
|
- SettingsDialog.
|
||||||
- Load/save conf file.
|
- Load/save conf file.
|
||||||
- ¿Exit Point? is it needed?
|
- ¿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.
|
- 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).
|
||||||
|
|
|
@ -52,6 +52,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer):
|
||||||
m_progressTime->setReadOnly(true);
|
m_progressTime->setReadOnly(true);
|
||||||
m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||||
m_progressTime->setMinimumWidth(80);
|
m_progressTime->setMinimumWidth(80);
|
||||||
|
m_progressTime->setMaximumWidth(80);
|
||||||
m_progressTime->setFocusPolicy(Qt::NoFocus);
|
m_progressTime->setFocusPolicy(Qt::NoFocus);
|
||||||
m_progressTime->setAlignment(Qt::AlignHCenter);
|
m_progressTime->setAlignment(Qt::AlignHCenter);
|
||||||
m_progressTime->setContentsMargins(0,0,0,0);
|
m_progressTime->setContentsMargins(0,0,0,0);
|
||||||
|
@ -138,7 +139,7 @@ void AudioLayerWidget::openMediaDialog()
|
||||||
QStringList fileNames;
|
QStringList fileNames;
|
||||||
fileNames = dialog.selectedFiles();
|
fileNames = dialog.selectedFiles();
|
||||||
emit uiLoadMedia(m_layer, fileNames.at(0));
|
emit uiLoadMedia(m_layer, fileNames.at(0));
|
||||||
this->fileLoaded(fileNames.at(0));
|
this->setMediaFile(fileNames.at(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// from DMX signals
|
// from DMX signals
|
||||||
|
@ -163,7 +164,7 @@ void AudioLayerWidget::setPitch(int pitch)
|
||||||
m_pitch->blockSignals(false);
|
m_pitch->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::fileLoaded(QString file)
|
void AudioLayerWidget::setMediaFile(QString file)
|
||||||
{
|
{
|
||||||
QStringList list = file.split("/");
|
QStringList list = file.split("/");
|
||||||
int size = list.size();
|
int size = list.size();
|
||||||
|
@ -174,19 +175,18 @@ void AudioLayerWidget::fileLoaded(QString file)
|
||||||
this->setPlaybackStatus(Status::Stopped);
|
this->setPlaybackStatus(Status::Stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::setPlaybackStatus(Status status)
|
void AudioLayerWidget::setPlaybackStatus(Status s)
|
||||||
{
|
{
|
||||||
if (!strcmp(StatusStr[status], m_suspendResumeButton->text().toLatin1().constData()))
|
Status status = static_cast<Status>(s);
|
||||||
return;
|
|
||||||
m_suspendResumeButton->blockSignals(true);
|
m_suspendResumeButton->blockSignals(true);
|
||||||
m_status = status;
|
m_status = status;
|
||||||
if (status == Status::Stopped)
|
//if (status == Status::Stopped)
|
||||||
refreshCurrentTime(0);
|
// refreshCurrentTime(0);
|
||||||
m_suspendResumeButton->setText(StatusStr[status]);
|
m_suspendResumeButton->setText(StatusStr[status]);
|
||||||
m_suspendResumeButton->blockSignals(false);
|
m_suspendResumeButton->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::durationChanged(float dur)
|
void AudioLayerWidget::setDuration(float dur)
|
||||||
{
|
{
|
||||||
m_progress->blockSignals(true);
|
m_progress->blockSignals(true);
|
||||||
m_progressTime->blockSignals(true);
|
m_progressTime->blockSignals(true);
|
||||||
|
@ -200,7 +200,7 @@ void AudioLayerWidget::durationChanged(float dur)
|
||||||
m_totalTimeValue->blockSignals(false);
|
m_totalTimeValue->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::refreshCurrentTime(float progress)
|
void AudioLayerWidget::setCurrentTime(float progress)
|
||||||
{
|
{
|
||||||
progress *= 1000;
|
progress *= 1000;
|
||||||
m_progress->blockSignals(true);
|
m_progress->blockSignals(true);
|
||||||
|
|
|
@ -18,13 +18,6 @@ class AudioLayerWidget : public QWidget
|
||||||
public:
|
public:
|
||||||
explicit AudioLayerWidget(QWidget *parent = 0, int layer = 0);
|
explicit AudioLayerWidget(QWidget *parent = 0, int layer = 0);
|
||||||
~AudioLayerWidget();
|
~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:
|
private:
|
||||||
Status m_status;
|
Status m_status;
|
||||||
|
@ -39,17 +32,23 @@ private:
|
||||||
QTimeEdit *m_totalTimeValue;
|
QTimeEdit *m_totalTimeValue;
|
||||||
QProgressBar *m_progress;
|
QProgressBar *m_progress;
|
||||||
|
|
||||||
|
// From DMX
|
||||||
public slots:
|
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 toggleSuspendResume();
|
||||||
void volumeChanged(int vol);
|
void volumeChanged(int vol);
|
||||||
void panChanged(int pan);
|
void panChanged(int pan);
|
||||||
void pitchChanged(int pitch);
|
void pitchChanged(int pitch);
|
||||||
void fileLoaded(QString file);
|
|
||||||
void durationChanged(float dur);
|
|
||||||
void refreshCurrentTime(float progress);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void openMediaDialog();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void uiPlaybackChanged(int layer, Status s);
|
void uiPlaybackChanged(int layer, Status s);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "audiowidget.h"
|
#include "audiowidget.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
AudioWidget::AudioWidget(QWidget *parent) :
|
AudioWidget::AudioWidget(QWidget *parent) :
|
||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
|
@ -15,39 +15,79 @@ AudioWidget::AudioWidget(QWidget *parent) :
|
||||||
m_layout->setSpacing(0);
|
m_layout->setSpacing(0);
|
||||||
m_layout->setContentsMargins(1, 1, 1, 1);
|
m_layout->setContentsMargins(1, 1, 1, 1);
|
||||||
setLayout(m_layout);
|
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)
|
void AudioWidget::mediaLoaded(int layer, QString file, float duration)
|
||||||
{
|
{
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
m_layerUpdate[layer].media = file;
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->fileLoaded(file);
|
m_layerUpdate[layer].duration = duration;
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->durationChanged(duration);
|
m_layerUpdate[layer].updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::volChanged(int layer, float vol) {
|
void AudioWidget::volChanged(int layer, float vol) {
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
m_layerUpdate[layer].vol = vol;
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setVol(vol);
|
m_layerUpdate[layer].updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::panChanged(int layer, int pan) {
|
void AudioWidget::panChanged(int layer, int pan) {
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
m_layerUpdate[layer].pan = pan;
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setPan(pan);
|
m_layerUpdate[layer].updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::pitchChanged(int layer, int pitch) {
|
void AudioWidget::pitchChanged(int layer, int pitch) {
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setPitch(pitch);
|
m_layerUpdate[layer].pitch = pitch;
|
||||||
|
m_layerUpdate[layer].updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::playbackChanged(int layer, Status status)
|
void AudioWidget::playbackChanged(int layer, Status status)
|
||||||
{
|
{
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
m_layerUpdate[layer].status = status;
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setPlaybackStatus(status);
|
m_layerUpdate[layer].updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::cursorChanged(int layer, float cursor)
|
void AudioWidget::cursorChanged(int layer, float cursor)
|
||||||
{
|
{
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
m_layerUpdate[layer].cursor = floor(cursor * 1000) / 1000;
|
||||||
AudioLayerWidget *alw = dynamic_cast<AudioLayerWidget *>(item->widget());
|
m_layerUpdate[layer].updated = true;
|
||||||
alw->refreshCurrentTime(cursor);
|
}
|
||||||
|
|
||||||
|
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<AudioLayerWidget *>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "audiolayerwidget.h"
|
#include "audiolayerwidget.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "miniaudioengine.h"
|
|
||||||
#include "defines.h" // MAX_LAYERS
|
#include "defines.h" // MAX_LAYERS
|
||||||
|
|
||||||
class AudioWidget : public QWidget
|
class AudioWidget : public QWidget
|
||||||
|
@ -14,14 +13,22 @@ class AudioWidget : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioWidget(QWidget *parent = nullptr);
|
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 volChanged(int layer, float vol);
|
||||||
void panChanged(int layer, int pan);
|
void panChanged(int layer, int pan);
|
||||||
void pitchChanged(int layer, int pitch);
|
void pitchChanged(int layer, int pitch);
|
||||||
void playbackChanged(int layer, Status status);
|
|
||||||
void cursorChanged(int layer, float cursor);
|
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:
|
signals:
|
||||||
void uiPlaybackChanged(int layer, Status s);
|
void uiPlaybackChanged(int layer, Status s);
|
||||||
void uiSliderChanged(int layer, Slider s, int vol);
|
void uiSliderChanged(int layer, Slider s, int vol);
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
#define LICENSE "GPL 3 Licensed. See LICENSE.txt."
|
#define LICENSE "GPL 3 Licensed. See LICENSE.txt."
|
||||||
#define DEFAULT_FILE "lms-audio.xlm"
|
#define DEFAULT_FILE "lms-audio.xlm"
|
||||||
#define MAX_LAYERS 4
|
#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 {
|
struct dmxSetting {
|
||||||
int address;
|
int address;
|
||||||
unsigned int universe;
|
unsigned int universe;
|
||||||
|
@ -41,5 +42,15 @@ enum Slider
|
||||||
Pitch,
|
Pitch,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
struct layerData {
|
||||||
|
QString media;
|
||||||
|
Status status;
|
||||||
|
bool updated;
|
||||||
|
float vol;
|
||||||
|
float cursor;
|
||||||
|
int pan;
|
||||||
|
int pitch;
|
||||||
|
float duration;
|
||||||
|
};
|
||||||
#endif // DEFINES_H
|
#endif // DEFINES_H
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#define ENTRY_POINT_COARSE 5
|
#define ENTRY_POINT_COARSE 5
|
||||||
#define ENTRY_POINT_FINE 4
|
#define ENTRY_POINT_FINE 4
|
||||||
#define PITCH 7
|
#define PITCH 7
|
||||||
|
|
||||||
#define LAYER_CHANNELS 9
|
#define LAYER_CHANNELS 9
|
||||||
|
|
||||||
#endif // DMXPERSONALITY_H
|
#endif // DMXPERSONALITY_H
|
||||||
|
|
|
@ -38,7 +38,7 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent)
|
||||||
this->setContentsMargins(5, 5, 5, 5);
|
this->setContentsMargins(5, 5, 5, 5);
|
||||||
this->setStyleSheet(
|
this->setStyleSheet(
|
||||||
"color: white;"
|
"color: white;"
|
||||||
"background-color: gray;"
|
"background-color: #4f4048;"
|
||||||
"selection-color: blue;"
|
"selection-color: blue;"
|
||||||
"selection-background-color: green"
|
"selection-background-color: green"
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
#include "libremediaserver-audio.h"
|
#include "libremediaserver-audio.h"
|
||||||
|
|
||||||
|
|
||||||
libreMediaServerAudio::libreMediaServerAudio(bool gui)
|
libreMediaServerAudio::libreMediaServerAudio()
|
||||||
{
|
{
|
||||||
m_ui = gui;
|
m_settings = Settings::getInstance();
|
||||||
Settings *set = Settings::getInstance();
|
m_settings->readFile();
|
||||||
set->readFile();
|
m_ui = m_settings->getShowUi();
|
||||||
m_mediaLibrary = new MediaLibrary;
|
m_mediaLibrary = new MediaLibrary;
|
||||||
m_mediaLibrary->initMediaLibrary();
|
m_mediaLibrary->initMediaLibrary();
|
||||||
for (int i = 0; i < MAX_LAYERS; i++) {
|
for (int i = 0; i < MAX_LAYERS; i++) {
|
||||||
|
@ -38,12 +38,11 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui)
|
||||||
m_updateUi[i][3] = -1;
|
m_updateUi[i][3] = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_ola = new olaThread(this, set->getLayersNumber());
|
m_ola = new olaThread(this, m_settings->getLayersNumber());
|
||||||
Q_CHECK_PTR(m_ola);
|
Q_CHECK_PTR(m_ola);
|
||||||
m_ola->blockSignals(true);
|
m_ola->blockSignals(true);
|
||||||
connect(m_ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int)));
|
|
||||||
m_ola->registerUniverse();
|
m_ola->registerUniverse();
|
||||||
m_mae.startEngine(set->getAudioDeviceId());
|
m_mae.startEngine(m_settings->getAudioDeviceId());
|
||||||
qDebug("Core init Complete. Start reading DMX.");
|
qDebug("Core init Complete. Start reading DMX.");
|
||||||
m_ola->blockSignals(false);
|
m_ola->blockSignals(false);
|
||||||
#ifdef NOGUI
|
#ifdef NOGUI
|
||||||
|
@ -57,16 +56,9 @@ libreMediaServerAudio::~libreMediaServerAudio()
|
||||||
m_mae.stopEngine();
|
m_mae.stopEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
void libreMediaServerAudio::loadMedia(int layer, int folder, int file)
|
||||||
{
|
{
|
||||||
if (layer >= MAX_LAYERS || channel >= LAYER_CHANNELS)
|
QString mediaFile = m_mediaLibrary->requestNewFile(folder, file);
|
||||||
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)
|
if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
|
||||||
return;
|
return;
|
||||||
if (QFile::exists(mediaFile)){
|
if (QFile::exists(mediaFile)){
|
||||||
|
@ -76,8 +68,17 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
if (m_ui)
|
if (m_ui)
|
||||||
m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));
|
m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));
|
||||||
#endif
|
#endif
|
||||||
|
m_mae.printFormatInfo(layer);
|
||||||
}
|
}
|
||||||
} else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) {
|
}
|
||||||
|
|
||||||
|
void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
|
{
|
||||||
|
if (layer >= MAX_LAYERS || channel >= LAYER_CHANNELS)
|
||||||
|
return;
|
||||||
|
QString mediaFile = NULL;
|
||||||
|
int aux;
|
||||||
|
if (channel == VOLUME_COARSE || channel == VOLUME_FINE) {
|
||||||
float tmp = value / 65025.0f;
|
float tmp = value / 65025.0f;
|
||||||
m_mae.volChanged(layer, tmp);
|
m_mae.volChanged(layer, tmp);
|
||||||
m_updateUi[layer][0] = tmp * 100.0f;
|
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_mae.playbackChanged(layer, s);
|
||||||
m_currentStatus[layer] = s;
|
m_currentStatus[layer] = s;
|
||||||
#ifndef NOGUI
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOGUI
|
#ifndef NOGUI
|
||||||
void libreMediaServerAudio::refreshUi() {
|
void libreMediaServerAudio::refreshUi() {
|
||||||
if (!m_ui) return;
|
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) {
|
if (m_updateUi[i][0] >= 0) {
|
||||||
m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]);
|
m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]);
|
||||||
m_updateUi[i][0] = -1;
|
m_updateUi[i][0] = -1;
|
||||||
|
@ -125,7 +128,9 @@ void libreMediaServerAudio::refreshUi() {
|
||||||
m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]);
|
m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]);
|
||||||
m_updateUi[i][2] = -1;
|
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_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i));
|
||||||
m_updateUi[i][3] = -1;
|
m_updateUi[i][3] = -1;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +140,7 @@ void libreMediaServerAudio::refreshUi() {
|
||||||
void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi)
|
void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi)
|
||||||
{
|
{
|
||||||
m_lmsUi = lmsUi;
|
m_lmsUi = lmsUi;
|
||||||
|
m_ui = true;
|
||||||
connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int)));
|
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(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(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status)));
|
||||||
|
@ -145,6 +151,7 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi)
|
||||||
m_ola->start(QThread::TimeCriticalPriority );
|
m_ola->start(QThread::TimeCriticalPriority );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// From Ui widgets
|
||||||
void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value)
|
void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value)
|
||||||
{
|
{
|
||||||
switch (s){
|
switch (s){
|
||||||
|
@ -166,8 +173,12 @@ void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s)
|
||||||
m_currentStatus[layer] = 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
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define LIBREMEDIASERVERAUDIO_H
|
#define LIBREMEDIASERVERAUDIO_H
|
||||||
|
|
||||||
#include "medialibrary.h"
|
#include "medialibrary.h"
|
||||||
|
#include "miniaudioengine.h"
|
||||||
#include "olathread.h"
|
#include "olathread.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
@ -33,33 +34,35 @@ class libreMediaServerAudio : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
libreMediaServerAudio(bool gui = false);
|
libreMediaServerAudio();
|
||||||
virtual ~libreMediaServerAudio();
|
virtual ~libreMediaServerAudio();
|
||||||
void dmxInput(int layer, int channel, int value);
|
void dmxInput(int layer, int channel, int value);
|
||||||
|
void loadMedia(int layer, int folder, int file);
|
||||||
#ifndef NOGUI
|
#ifndef NOGUI
|
||||||
void setUi(libreMediaServerAudioUi *lmsUi);
|
void setUi(libreMediaServerAudioUi *lmsUi);
|
||||||
|
bool inline getShowUi() { return m_settings->getShowUi(); }
|
||||||
#endif
|
#endif
|
||||||
//static void NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer);
|
|
||||||
private:
|
private:
|
||||||
olaThread *m_ola;
|
olaThread *m_ola;
|
||||||
MediaLibrary *m_mediaLibrary;
|
MediaLibrary *m_mediaLibrary;
|
||||||
MiniAudioEngine m_mae;
|
MiniAudioEngine m_mae;
|
||||||
|
Settings *m_settings;
|
||||||
QString m_currentMedia[MAX_LAYERS];
|
QString m_currentMedia[MAX_LAYERS];
|
||||||
Status m_currentStatus[MAX_LAYERS];
|
Status m_currentStatus[MAX_LAYERS];
|
||||||
static QList<dmxSetting> m_dmxSettings;
|
QList<dmxSetting> m_dmxSettings;
|
||||||
#ifndef NOGUI
|
|
||||||
bool m_ui;
|
bool m_ui;
|
||||||
|
#ifndef NOGUI
|
||||||
QTimer *m_refreshUi;
|
QTimer *m_refreshUi;
|
||||||
libreMediaServerAudioUi *m_lmsUi;
|
libreMediaServerAudioUi *m_lmsUi;
|
||||||
float m_updateUi[MAX_LAYERS][4];
|
float m_updateUi[MAX_LAYERS][4];
|
||||||
#endif
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#ifndef NOGUI
|
|
||||||
void refreshUi();
|
void refreshUi();
|
||||||
void uiSliderChanged(int layer, Slider s, int value);
|
void uiSliderChanged(int layer, Slider s, int value);
|
||||||
void uiPlaybackChanged(int layer, Status s);
|
void uiPlaybackChanged(int layer, Status s);
|
||||||
void uiLoadMedia(int layer, QString s);
|
void uiLoadMedia(int layer, QString s);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,9 @@ bool hasUi(int &argc, char *argv[])
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
libreMediaServerAudio lms(hasUi(argc, argv));
|
libreMediaServerAudio lms;
|
||||||
#ifndef NOGUI
|
#ifndef NOGUI
|
||||||
if (hasUi(argc, argv))
|
if (hasUi(argc, argv) || lms.getShowUi())
|
||||||
{
|
{
|
||||||
libreMediaServerAudioUi *lmsUi = new libreMediaServerAudioUi();
|
libreMediaServerAudioUi *lmsUi = new libreMediaServerAudioUi();
|
||||||
lms.setUi(lmsUi);
|
lms.setUi(lmsUi);
|
||||||
|
|
|
@ -4,6 +4,11 @@ MiniAudioEngine::MiniAudioEngine()
|
||||||
{
|
{
|
||||||
for (int i =0; i < MAX_LAYERS; i++) {
|
for (int i =0; i < MAX_LAYERS; i++) {
|
||||||
m_mediaLoaded[i] = false;
|
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 = 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.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.decodedChannels = 0;
|
||||||
resourceManagerConfig.decodedSampleRate = 0;
|
resourceManagerConfig.decodedSampleRate = ma_standard_sample_rate_48000;
|
||||||
resourceManagerConfig.jobThreadCount = 0;
|
resourceManagerConfig.jobThreadCount = 1;
|
||||||
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
|
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
qCritical("Failed to initialize audio resource manager.");
|
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 MiniAudioEngine::loadMedia(int layer, char *file)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
float vol = -1;
|
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == true)
|
if (m_mediaLoaded[layer] == true)
|
||||||
{
|
{
|
||||||
vol = ma_sound_get_volume(&m_currentSound[layer]);
|
|
||||||
ma_sound_uninit(&m_currentSound[layer]);
|
ma_sound_uninit(&m_currentSound[layer]);
|
||||||
m_mediaLoaded[layer] = false;
|
m_mediaLoaded[layer] = false;
|
||||||
}
|
}
|
||||||
|
@ -133,10 +136,8 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file)
|
||||||
qWarning("Failed to load file %s", file);
|
qWarning("Failed to load file %s", file);
|
||||||
else {
|
else {
|
||||||
m_mediaLoaded[layer] = true;
|
m_mediaLoaded[layer] = true;
|
||||||
if (vol == -1)
|
this->refreshValues(layer);
|
||||||
this->volChanged(layer, 0);
|
m_currentLayerValues[layer].media = file;
|
||||||
else
|
|
||||||
this->volChanged(layer, vol);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +192,7 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
|
||||||
qWarning("Failed to get data format %i\n", layer);
|
qWarning("Failed to get data format %i\n", layer);
|
||||||
return MA_INVALID_DATA;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,9 +201,10 @@ void MiniAudioEngine::volChanged(int layer, float vol)
|
||||||
{
|
{
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
if (vol > 1)
|
if (vol >= 1)
|
||||||
vol = 1;
|
vol = 0.99f;
|
||||||
ma_sound_group_set_volume(&m_currentSound[layer], vol);
|
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)
|
void MiniAudioEngine::panChanged(int layer, float value)
|
||||||
|
@ -213,6 +215,7 @@ void MiniAudioEngine::panChanged(int layer, float value)
|
||||||
return;
|
return;
|
||||||
result = (value / 128.0) - 1.0;
|
result = (value / 128.0) - 1.0;
|
||||||
ma_sound_group_set_pan(&m_currentSound[layer], result);
|
ma_sound_group_set_pan(&m_currentSound[layer], result);
|
||||||
|
m_currentLayerValues[layer].pan = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::pitchChanged(int layer, float value)
|
void MiniAudioEngine::pitchChanged(int layer, float value)
|
||||||
|
@ -223,6 +226,7 @@ void MiniAudioEngine::pitchChanged(int layer, float value)
|
||||||
return;
|
return;
|
||||||
result = value / 128.0;
|
result = value / 128.0;
|
||||||
ma_sound_group_set_pitch(&m_currentSound[layer], result);
|
ma_sound_group_set_pitch(&m_currentSound[layer], result);
|
||||||
|
m_currentLayerValues[layer].pitch = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::playbackChanged(int layer, Status status)
|
void MiniAudioEngine::playbackChanged(int layer, Status status)
|
||||||
|
@ -235,7 +239,7 @@ void MiniAudioEngine::playbackChanged(int layer, Status status)
|
||||||
break;
|
break;
|
||||||
case Status::Stopped:
|
case Status::Stopped:
|
||||||
ma_sound_stop(&m_currentSound[layer]);
|
ma_sound_stop(&m_currentSound[layer]);
|
||||||
ma_sound_seek_to_pcm_frame(&m_currentSound[layer], 0);
|
this->setCursor(layer, m_currentLayerValues[layer].cursor);
|
||||||
break;
|
break;
|
||||||
case Status::PlayingLoop:
|
case Status::PlayingLoop:
|
||||||
ma_sound_set_looping(&m_currentSound[layer], true);
|
ma_sound_set_looping(&m_currentSound[layer], true);
|
||||||
|
@ -248,30 +252,35 @@ void MiniAudioEngine::playbackChanged(int layer, Status status)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
m_currentLayerValues[layer].status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::setCursor(int layer, int cursor)
|
void MiniAudioEngine::setCursor(int layer, int cursor)
|
||||||
{
|
{
|
||||||
ma_uint64 f;
|
ma_uint64 end;
|
||||||
|
|
||||||
|
m_currentLayerValues[layer].cursor = cursor;
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &f);
|
ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end);
|
||||||
f = (cursor * f) / 65025;
|
ma_uint64 start = (cursor * end) / 65025;
|
||||||
ma_sound_seek_to_pcm_frame(&m_currentSound[layer], f);
|
ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start);
|
||||||
// ToDo: change the loop entry point too
|
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)
|
Status MiniAudioEngine::getStatus(int layer)
|
||||||
{
|
{
|
||||||
if (m_mediaLoaded[layer] == false)
|
return m_currentLayerValues[layer].status;
|
||||||
return Status::Iddle;
|
}
|
||||||
if (ma_sound_is_playing(&m_currentSound[layer])) {
|
|
||||||
if (ma_sound_is_looping(&m_currentSound[layer]))
|
void MiniAudioEngine::refreshValues(int layer)
|
||||||
return Status::PlayingLoop;
|
{
|
||||||
return Status::PlayingOnce;
|
this->panChanged(layer, m_currentLayerValues[layer].pan);
|
||||||
}
|
this->volChanged(layer, m_currentLayerValues[layer].vol);
|
||||||
if (this->getDuration(layer) > 0)
|
this->pitchChanged(layer, m_currentLayerValues[layer].pitch);
|
||||||
return Status::Paused;
|
this->playbackChanged(layer, m_currentLayerValues[layer].status);
|
||||||
return Status::Stopped;
|
this->setCursor(layer, m_currentLayerValues[layer].cursor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,12 @@ private:
|
||||||
ma_context context;
|
ma_context context;
|
||||||
ma_sound m_currentSound[MAX_LAYERS];
|
ma_sound m_currentSound[MAX_LAYERS];
|
||||||
ma_bool8 m_mediaLoaded[MAX_LAYERS];
|
ma_bool8 m_mediaLoaded[MAX_LAYERS];
|
||||||
|
layerData m_currentLayerValues[MAX_LAYERS];
|
||||||
|
|
||||||
ma_result getAllAudioDevices();
|
ma_result getAllAudioDevices();
|
||||||
ma_result startDevice(int id);
|
ma_result startDevice(int id);
|
||||||
ma_result startContext();
|
ma_result startContext();
|
||||||
|
void refreshValues(int layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MINIAUDIOENGINE_H
|
#endif // MINIAUDIOENGINE_H
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "libremediaserver-audio.h"
|
#include "libremediaserver-audio.h"
|
||||||
//#include "olathread.h"
|
|
||||||
|
|
||||||
olaThread::olaThread(QObject *parent, int layers) :
|
olaThread::olaThread(QObject *parent, int layers) :
|
||||||
m_counter(0)
|
m_counter(0)
|
||||||
|
@ -36,7 +35,6 @@ void olaThread::init()
|
||||||
}
|
}
|
||||||
m_client = m_clientWrapper->GetClient();
|
m_client = m_clientWrapper->GetClient();
|
||||||
m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx));
|
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_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss));
|
||||||
m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed));
|
m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed));
|
||||||
m_dmxSettings = Settings::getInstance()->getDmxSettings();
|
m_dmxSettings = Settings::getInstance()->getDmxSettings();
|
||||||
|
@ -69,30 +67,31 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data,
|
||||||
bool volSent = false;
|
bool volSent = false;
|
||||||
bool entrySent = false;
|
bool entrySent = false;
|
||||||
bool fileSent = false;
|
bool fileSent = false;
|
||||||
|
int aux;
|
||||||
for (int j = 0; j < LAYER_CHANNELS; j++){
|
for (int j = 0; j < LAYER_CHANNELS; j++){
|
||||||
int value = buffer.Get((i.address) + j);
|
int value = buffer.Get((i.address) + j);
|
||||||
if (m_dmx[i.layer][j] != value) {
|
if (m_dmx[i.layer][j] != value) {
|
||||||
m_dmx[i.layer][j] = value;
|
m_dmx[i.layer][j] = value;
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case DMX_FOLDER:
|
case DMX_FOLDER:
|
||||||
value *= 0x100;
|
aux = buffer.Get(i.address + DMX_FILE);
|
||||||
value += buffer.Get(i.address + DMX_FILE);
|
qobject_cast<libreMediaServerAudio *>(parent())->loadMedia(i.layer, value, aux);
|
||||||
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
m_dmx[i.layer][DMX_FILE] = aux;
|
||||||
m_dmx[i.layer][DMX_FILE] = buffer.Get(i.address + DMX_FILE);
|
|
||||||
fileSent = true;
|
fileSent = true;
|
||||||
break;
|
break;
|
||||||
case DMX_FILE:
|
case DMX_FILE:
|
||||||
if (fileSent)
|
if (fileSent)
|
||||||
break;
|
break;
|
||||||
value += buffer.Get(i.address + DMX_FOLDER) * 0x100;
|
aux = buffer.Get(i.address + DMX_FOLDER);
|
||||||
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
qobject_cast<libreMediaServerAudio *>(parent())->loadMedia(i.layer, aux, value);
|
||||||
m_dmx[i.layer][DMX_FOLDER] = buffer.Get(i.address + DMX_FOLDER);
|
m_dmx[i.layer][DMX_FOLDER] = aux;
|
||||||
fileSent = true;
|
fileSent = true;
|
||||||
break;
|
break;
|
||||||
case VOLUME_FINE:
|
case VOLUME_FINE:
|
||||||
value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value;
|
aux = buffer.Get(i.address + VOLUME_COARSE);
|
||||||
|
value += (aux * 0x100);
|
||||||
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
qobject_cast<libreMediaServerAudio *>(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;
|
volSent = true;
|
||||||
break;
|
break;
|
||||||
case VOLUME_COARSE:
|
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);
|
m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE);
|
||||||
volSent = true;
|
volSent = true;
|
||||||
break;
|
break;
|
||||||
|
case PLAYBACK:
|
||||||
|
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
||||||
|
break;
|
||||||
case ENTRY_POINT_FINE:
|
case ENTRY_POINT_FINE:
|
||||||
value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value;
|
value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value;
|
||||||
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
qobject_cast<libreMediaServerAudio *>(parent())->dmxInput(i.layer, j, value);
|
||||||
|
|
|
@ -15,6 +15,7 @@ Settings::Settings(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
m_layersNumber = 0;
|
m_layersNumber = 0;
|
||||||
|
m_ui = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the dmx settings for dmx.xml At the moment we need:
|
// 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 first DMX channel of each source/layer
|
||||||
// - The universe to bind in OLA
|
// - The universe to bind in OLA
|
||||||
// - Audio device id
|
// - Audio device id
|
||||||
|
// - Show the Ui or not
|
||||||
void Settings::readFromFile(QString file) {
|
void Settings::readFromFile(QString file) {
|
||||||
QFile* xmlFile = new QFile(file);
|
QFile* xmlFile = new QFile(file);
|
||||||
if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
@ -34,53 +36,56 @@ void Settings::readFromFile(QString file) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
QXmlStreamReader* xmlReader = new QXmlStreamReader(xmlFile);
|
QXmlStreamReader* xmlReader = new QXmlStreamReader(xmlFile);
|
||||||
int counter = 0;
|
while(!xmlReader->atEnd() && !xmlReader->hasError()) {
|
||||||
//Parse the XML until we reach end of it
|
|
||||||
while(!xmlReader->atEnd() && !xmlReader->hasError() && counter < MAX_LAYERS) {
|
|
||||||
// Read next element
|
|
||||||
QXmlStreamReader::TokenType token = xmlReader->readNext();
|
QXmlStreamReader::TokenType token = xmlReader->readNext();
|
||||||
//If token is just StartDocument - go to next
|
|
||||||
if(token == QXmlStreamReader::StartDocument) {
|
if(token == QXmlStreamReader::StartDocument) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//If token is StartElement - read it
|
|
||||||
if(token == QXmlStreamReader::StartElement) {
|
if(token == QXmlStreamReader::StartElement) {
|
||||||
if(xmlReader->name() == "dmxSettings") {
|
if(xmlReader->name() == "lmsAudio") {
|
||||||
int version = xmlReader->attributes().value("fileVersion").toLocal8Bit().toInt();
|
m_ui = xmlReader->attributes().value("ui").toLocal8Bit().toInt();
|
||||||
if(version == 1) {
|
|
||||||
m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt();
|
m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt();
|
||||||
m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit();
|
m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(xmlReader->name() == "audioDevice") {
|
if(xmlReader->name() == "audioDevice") {
|
||||||
m_audioDeviceId = xmlReader->attributes().value("id").toLocal8Bit().toInt();
|
m_audioDeviceQty = xmlReader->attributes().value("devicesNumber").toLocal8Bit().toInt();
|
||||||
continue;
|
for (uint i = 0; i < m_audioDeviceQty; i++)
|
||||||
|
{
|
||||||
|
m_audioDeviceId[i] = xmlReader->attributes().value(QString("id%1").arg(i)).toLocal8Bit().toInt();
|
||||||
}
|
}
|
||||||
QString add = "layer";
|
|
||||||
add.append(QString("%1").arg(counter));
|
}
|
||||||
if((xmlReader->name() == add)) {
|
if(xmlReader->name() == "layer") {
|
||||||
dmxSetting temp;
|
dmxSetting temp;
|
||||||
temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1;
|
temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1;
|
||||||
temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt();
|
temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt();
|
||||||
temp.layer = counter;
|
temp.layer = xmlReader->attributes().value("id").toLocal8Bit().toInt();
|
||||||
m_settings.append(temp);
|
m_settings.append(temp);
|
||||||
if (!m_universe.contains(temp.universe)) {
|
if (!m_universe.contains(temp.universe)) {
|
||||||
m_universe.insert(temp.universe);
|
m_universe.insert(temp.universe);
|
||||||
}
|
}
|
||||||
counter++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(xmlReader->hasError()) {
|
if(xmlReader->hasError()) {
|
||||||
QMessageBox::critical(NULL,"File xml Parse Error ", xmlReader->errorString(), QMessageBox::Ok);
|
QMessageBox::critical(NULL,"File xml Parse Error ", xmlReader->errorString(), QMessageBox::Ok);
|
||||||
qWarning("File xml Parse Error %s", xmlReader->errorString().toLatin1().constData());
|
qWarning("File xml Parse Error %s", xmlReader->errorString().toLatin1().constData());
|
||||||
return;
|
// ToDo: manage this, open a dialog to load a new file.
|
||||||
}
|
}
|
||||||
xmlReader->clear();
|
xmlReader->clear();
|
||||||
xmlFile->close();
|
xmlFile->close();
|
||||||
delete xmlReader;
|
delete xmlReader;
|
||||||
delete xmlFile;
|
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() {
|
void Settings::readFile() {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "medialibrary.h"
|
#include "medialibrary.h"
|
||||||
#include "audiowidget.h"
|
#include "audiowidget.h"
|
||||||
|
@ -15,25 +16,27 @@ class Settings : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Settings(QObject *parent = 0);
|
||||||
static Settings *getInstance();
|
static Settings *getInstance();
|
||||||
inline QSet<int> getUniverses() { return m_universe; }
|
inline QSet<int> getUniverses() { return m_universe; }
|
||||||
inline QString getPathMedia() { return m_pathmedia; }
|
inline QString getPathMedia() { return m_pathmedia; }
|
||||||
inline QList<dmxSetting> getDmxSettings() { return m_settings; }
|
inline QList<dmxSetting> getDmxSettings() { return m_settings; }
|
||||||
inline int getLayersNumber() { return m_layersNumber; }
|
inline int getLayersNumber() { return m_layersNumber; }
|
||||||
|
inline int getAudioDeviceId() { return m_audioDeviceId[0]; }
|
||||||
|
inline bool getShowUi() { return m_ui; }
|
||||||
void readFile();
|
void readFile();
|
||||||
inline int getAudioDeviceId() { return m_audioDeviceId; }
|
void readFromFile(QString file);
|
||||||
|
void printSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Settings *_instance;
|
static Settings *_instance;
|
||||||
QList<dmxSetting> m_settings;
|
QList<dmxSetting> m_settings;
|
||||||
QString m_pathmedia;
|
QString m_pathmedia;
|
||||||
uint m_audioDeviceId;
|
uint m_audioDeviceId[MAX_AUDIODEVICES];
|
||||||
|
uint m_audioDeviceQty;
|
||||||
QSet<int> m_universe;
|
QSet<int> m_universe;
|
||||||
int m_layersNumber;
|
int m_layersNumber;
|
||||||
|
bool m_ui;
|
||||||
explicit Settings(QObject *parent = 0);
|
|
||||||
void readFromFile(QString file);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
|
@ -18,10 +18,11 @@ SliderGroup::SliderGroup(QString name,
|
||||||
slider->setMinimumHeight(0);
|
slider->setMinimumHeight(0);
|
||||||
slider->setSingleStep(1);
|
slider->setSingleStep(1);
|
||||||
slider->setRange(min, max);
|
slider->setRange(min, max);
|
||||||
|
slider->setValue(0);
|
||||||
slider->setMinimumWidth(50);
|
slider->setMinimumWidth(50);
|
||||||
slider->setToolTip(name);
|
slider->setToolTip(name);
|
||||||
slider->setStyleSheet("QSlider {"
|
slider->setStyleSheet("QSlider {"
|
||||||
"border: 2px solid #685060;"
|
"border: 1px solid #5a4855;"
|
||||||
"margin: 0px;"
|
"margin: 0px;"
|
||||||
"height: 200px;"
|
"height: 200px;"
|
||||||
"width: 50px;}"
|
"width: 50px;}"
|
||||||
|
@ -32,17 +33,20 @@ SliderGroup::SliderGroup(QString name,
|
||||||
valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||||
valueBox->setMinimumWidth(50);
|
valueBox->setMinimumWidth(50);
|
||||||
valueBox->setRange(min, max);
|
valueBox->setRange(min, max);
|
||||||
|
valueBox->setValue(0);
|
||||||
valueBox->setDecimals(decimals);
|
valueBox->setDecimals(decimals);
|
||||||
valueBox->setObjectName(name);
|
valueBox->setObjectName(name);
|
||||||
valueBox->setToolTip(name);
|
valueBox->setToolTip(name);
|
||||||
valueBox->setAlignment(Qt::AlignHCenter);
|
valueBox->setAlignment(Qt::AlignHCenter);
|
||||||
valueBox->setContentsMargins(0, 0, 0, 0);
|
valueBox->setContentsMargins(0, 0, 0, 0);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
|
||||||
|
//connect(slider, SIGNAL(mousePressEvent(QMouseEvent)), this, SLOT(mousePressEvent(QMouseEvent *)));
|
||||||
layout->addWidget(slider);
|
layout->addWidget(slider);
|
||||||
layout->addWidget(valueBox);
|
layout->addWidget(valueBox);
|
||||||
this->setStyleSheet("border: 2px solid #685060;"
|
this->setStyleSheet("border: 1px solid #5a4855;"
|
||||||
"width: 50px;"
|
"width: 50px;"
|
||||||
"margin: 0px;"
|
"margin: 0px;"
|
||||||
|
"background-color: #383034;"
|
||||||
);
|
);
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
@ -67,3 +71,11 @@ void SliderGroup::setValue(float value)
|
||||||
slider->blockSignals(false);
|
slider->blockSignals(false);
|
||||||
valueBox->blockSignals(false);
|
valueBox->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SliderGroup::mousePressEvent(QMouseEvent* event) {
|
||||||
|
Q_UNUSED(event);
|
||||||
|
if (slider->isEnabled())
|
||||||
|
slider->setDisabled(true);
|
||||||
|
else
|
||||||
|
slider->setDisabled(false);
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ public slots:
|
||||||
private:
|
private:
|
||||||
QSlider *slider;
|
QSlider *slider;
|
||||||
QDoubleSpinBox *valueBox;
|
QDoubleSpinBox *valueBox;
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent* event);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue