refactorizada la GUI, ola y audioengine se ejecutan fuera de widgets.
Opción para ejecutar sin mostrar la GUI. Los controles de la interfaz no son reactivos, no están conectados a las órdenes de audio. cambio en la personalidad dmx para procesar los canales en mejor orden. evita mandar dos veces los canales dobles por cada dmx frame, incluyendo file/folder.
This commit is contained in:
parent
4ee82c5e5f
commit
1fccbf64fd
20 changed files with 416 additions and 323 deletions
|
@ -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
|
||||
|
|
|
@ -1,64 +1,67 @@
|
|||
#include "audiolayerwidget.h"
|
||||
#include <QComboBox>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
#include <QPushButton>
|
||||
#include <QTimeEdit>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
|
||||
#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();
|
||||
|
|
|
@ -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<AudioLayerWidget *>(item->widget())->fileLoaded(file);
|
||||
dynamic_cast<AudioLayerWidget *>(item->widget())->durationChanged(pLength);
|
||||
dynamic_cast<AudioLayerWidget *>(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<AudioLayerWidget *>(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<AudioLayerWidget *>(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<AudioLayerWidget *>(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<AudioLayerWidget *>(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<AudioLayerWidget *>(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<AudioLayerWidget *>(item->widget());
|
||||
Status s = aw->getPlaybackStatus();
|
||||
if (s == Status::PlayingOnce || s == Status::PlayingLoop) {
|
||||
aw->refreshUi(m_mae.getCursor(i));
|
||||
}
|
||||
}
|
||||
AudioLayerWidget *alw = dynamic_cast<AudioLayerWidget *>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <lms@criptomart.net>"
|
||||
#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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
48
src/libremediaserver-audio-gui.cpp
Normal file
48
src/libremediaserver-audio-gui.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
|
||||
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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();
|
||||
}
|
48
src/libremediaserver-audio-gui.h
Normal file
48
src/libremediaserver-audio-gui.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Libre Media Server Audio - An Open source Media Server for arts and performing.
|
||||
(c) Criptomart - Santiago Noreña 2012-2024 <lms@criptomart.net>
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBREMEDIASERVERAUDIOUI_H
|
||||
#define LIBREMEDIASERVERAUDIOUI_H
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QWebView>
|
||||
|
||||
#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
|
|
@ -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
|
||||
|
|
|
@ -20,35 +20,41 @@
|
|||
#ifndef LIBREMEDIASERVERAUDIO_H
|
||||
#define LIBREMEDIASERVERAUDIO_H
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QWebView>
|
||||
|
||||
#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
|
||||
|
|
39
src/main.cpp
39
src/main.cpp
|
@ -18,34 +18,29 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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();
|
||||
}
|
||||
|
|
20
src/main.h
Normal file
20
src/main.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QApplication>
|
||||
|
||||
#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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -6,16 +6,15 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QSlider>
|
||||
|
||||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue