pan, pitch, loop

This commit is contained in:
snt 2024-04-18 02:17:09 +02:00
parent 5d57eb705a
commit ba9fcfadeb
12 changed files with 196 additions and 51 deletions

View file

@ -13,6 +13,11 @@ v 0.1.3 (1/05/2024)
- Ubuntu 22.04 jammy - Ubuntu 22.04 jammy
- Use SFML as audio engine - Use SFML as audio engine
- Qt 5.15.3 - Qt 5.15.3
- pan
- pitch
- loop
- loop points
- play offset
v 0.1.2 (12/08/2015) v 0.1.2 (12/08/2015)

View file

@ -1,7 +1,7 @@
******************************************************************************* *******************************************************************************
Libre Media Server Audio - An Open source Media Server. Libre Media Server Audio - An Open source Media Server.
(c) Santiago Noreña 2014-2024 <libremediaserver@criptomart.net> (c) Santiago Noreña 2014-2024 <libremediaserver@criptomart.net>
http://git.criptomart.net/libremediaserver 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 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. 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.
@ -11,7 +11,9 @@ You should have received a copy of the GNU General Public License along with thi
0. Requisites 0. Requisites
- sudo apt-get install build-essential qmake-qt5 gcc g++ libtool libsfml-dev qtbase5-dev libqt5webkit5-dev qtwebengine5-dev - sudo apt-get install build-essential qmake-qt5 gcc g++ libtool libsfml-dev qtbase5-dev libqt5webkit5-dev qtwebengine5-dev
- OLA https://www.openlighting.org/ola/linuxinstall/#Git - OLA https://www.openlighting.org/ola/linuxinstall/#Git
-- ToDo: la instalación de OLA es un infierno, hay que empaquetarlo -- ToDo: la instalación de OLA es un infierno, hay que empaquetarlo o mirar si hay alguna lib de sACN
https://github.com/ETCLabs/sACN
1. Compiles 1. Compiles
$ qmake -spec linux-g++ -o Makefile libremediaserver-audio.pro $ qmake -spec linux-g++ -o Makefile libremediaserver-audio.pro

View file

@ -28,13 +28,19 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
// status->addWidget(m_receiveDMX); // status->addWidget(m_receiveDMX);
status->addWidget(m_statusLabel); status->addWidget(m_statusLabel);
status->addWidget(m_statusValue); status->addWidget(m_statusValue);
m_loopCheckLabel = new QLabel;
m_loopCheckLabel->setText("Loop");
m_loopCheck = new QCheckBox();
connect(m_loopCheck, SIGNAL(stateChanged(int)), this, SLOT(loopChanged(int)));
status->addWidget(m_loopCheckLabel);
status->addWidget(m_loopCheck);
layout->addLayout(status); layout->addLayout(status);
QHBoxLayout *folderLoaded = new QHBoxLayout; QHBoxLayout *folderLoaded = new QHBoxLayout;
m_folderLabel = new QLabel; m_folderLabel = new QLabel;
m_folderLabel->setText(FOLDER_LABEL); m_folderLabel->setText(FOLDER_LABEL);
m_folderValue = new QLabel; m_folderValue = new QLabel;
m_folderValue->setMaximumWidth(150); m_folderValue->setMaximumWidth(200);
folderLoaded->addWidget(m_folderLabel); folderLoaded->addWidget(m_folderLabel);
folderLoaded->addWidget(m_folderValue); folderLoaded->addWidget(m_folderValue);
layout->addLayout(folderLoaded); layout->addLayout(folderLoaded);
@ -43,24 +49,42 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
m_fileLabel = new QLabel; m_fileLabel = new QLabel;
m_fileLabel->setText(FILE_LABEL); m_fileLabel->setText(FILE_LABEL);
m_fileValue = new QLabel; m_fileValue = new QLabel;
m_fileValue->setMaximumWidth(150); m_fileValue->setMaximumWidth(200);
fileLoaded->addWidget(m_fileLabel); fileLoaded->addWidget(m_fileLabel);
fileLoaded->addWidget(m_fileValue); fileLoaded->addWidget(m_fileValue);
layout->addLayout(fileLoaded); layout->addLayout(fileLoaded);
QHBoxLayout *volumeBox = new QHBoxLayout; QGridLayout *volumeBox = new QGridLayout;
m_volumeLabel = new QLabel; m_volumeLabel = new QLabel;
m_volumeLabel->setText(tr(VOLUME_LABEL)); m_volumeLabel->setText(tr(VOLUME_LABEL));
m_volumeSlider = new QSlider(Qt::Horizontal); m_volumeSlider = new QSlider(Qt::Horizontal);
m_volumeSlider->setMinimum(0); m_volumeSlider->setMinimum(0);
m_volumeSlider->setMaximum(80); m_volumeSlider->setMaximum(90);
m_volumeSlider->setSingleStep(1); m_volumeSlider->setSingleStep(1);
connect(m_volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int))); connect(m_volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));
volumeBox->addWidget(m_volumeLabel); volumeBox->addWidget(m_volumeLabel, 0, 0);
volumeBox->addWidget(m_volumeSlider); volumeBox->addWidget(m_volumeSlider, 0, 1);
m_panLabel = new QLabel;
m_panLabel->setText("Pan");
m_panSlider = new QSlider(Qt::Horizontal);
m_panSlider->setMinimum(0);
m_panSlider->setMaximum(255);
m_panSlider->setSingleStep(1);
connect(m_panSlider, SIGNAL(valueChanged(int)), this, SLOT(panChanged(int)));
volumeBox->addWidget(m_panLabel, 1, 0);
volumeBox->addWidget(m_panSlider, 1, 1);
m_pitchLabel = new QLabel;
m_pitchLabel->setText("Pitch");
m_pitchSlider = new QSlider(Qt::Horizontal);
m_pitchSlider->setMinimum(0);
m_pitchSlider->setMaximum(255);
m_pitchSlider->setSingleStep(1);
connect(m_pitchSlider, SIGNAL(valueChanged(int)), this, SLOT(pitchChanged(int)));
volumeBox->addWidget(m_pitchLabel, 2, 0);
volumeBox->addWidget(m_pitchSlider, 2, 1);
layout->addLayout(volumeBox); layout->addLayout(volumeBox);
QGridLayout *progressTime = new QGridLayout; QHBoxLayout *progressTime = new QHBoxLayout;
m_progressTimeLabel = new QLabel; m_progressTimeLabel = new QLabel;
m_progressTimeLabel->setText(PROGRESS_TIME_LABEL); m_progressTimeLabel->setText(PROGRESS_TIME_LABEL);
m_progressTime = new QTimeEdit; m_progressTime = new QTimeEdit;
@ -68,19 +92,18 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
m_progressTime->setDisplayFormat("h:mm:ss:zzz"); m_progressTime->setDisplayFormat("h:mm:ss:zzz");
m_progressTime->setReadOnly(true); m_progressTime->setReadOnly(true);
m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons);
m_progressTime->setMaximumWidth(80); m_progressTime->setMaximumWidth(120);
progressTime->addWidget(m_progressTimeLabel, 0 ,0); progressTime->addWidget(m_progressTimeLabel);
progressTime->addWidget(m_progressTime,0 ,1); progressTime->addWidget(m_progressTime);
m_totalTimeLabel = new QLabel; m_totalTimeLabel = new QLabel;
m_totalTimeLabel->setText(TOTAL_TIME_LABEL); m_totalTimeLabel->setText(TOTAL_TIME_LABEL);
m_totalTimeValue = new QTimeEdit; m_totalTimeValue = new QTimeEdit;
m_totalTimeValue->setDisplayFormat("h:mm:ss:zzz"); m_totalTimeValue->setDisplayFormat("h:mm:ss:zzz");
m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setReadOnly(true);
m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons);
m_totalTimeValue->setMaximumWidth(80); m_totalTimeValue->setMaximumWidth(120);
progressTime->addWidget(m_totalTimeLabel,1 , 0); progressTime->addWidget(m_totalTimeLabel);
progressTime->addWidget(m_totalTimeValue, 1 ,1); progressTime->addWidget(m_totalTimeValue);
layout->addLayout(progressTime); layout->addLayout(progressTime);
QHBoxLayout *progressSlider = new QHBoxLayout; QHBoxLayout *progressSlider = new QHBoxLayout;
@ -100,7 +123,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name):
connect(m_watchDMX, SIGNAL(timeout()), connect(m_watchDMX, SIGNAL(timeout()),
this, SLOT(watchDMXExpired())); this, SLOT(watchDMXExpired()));
m_watchDMX->start(243); m_watchDMX->start(100);
m_music.setAttenuation(0); m_music.setAttenuation(0);
} }
@ -115,6 +138,21 @@ void AudioLayerWidget::volumeChanged(int value)
m_music.setVolume(value); m_music.setVolume(value);
} }
void AudioLayerWidget::panChanged(int value)
{
m_music.setPosition((value - 128) / 32.0, 0, 0);
}
void AudioLayerWidget::pitchChanged(int value)
{
m_music.setPitch(qreal(value / 128.0 ));
}
void AudioLayerWidget::loopChanged(int value)
{
m_music.setLoop(value);
}
void AudioLayerWidget::setVol(qreal vol) void AudioLayerWidget::setVol(qreal vol)
{ {
m_music.setVolume(vol); m_music.setVolume(vol);
@ -123,6 +161,22 @@ void AudioLayerWidget::setVol(qreal vol)
m_volumeSlider->blockSignals(false); m_volumeSlider->blockSignals(false);
} }
void AudioLayerWidget::setPan(qreal pan)
{
m_music.setPosition(float((pan - 128) / 32.0), 0, 0);
m_panSlider->blockSignals(true);
m_panSlider->setValue(pan);
m_panSlider->blockSignals(false);
}
void AudioLayerWidget::setPitch(qreal pitch)
{
m_music.setPitch(float(pitch / 128 ));
m_pitchSlider->blockSignals(true);
m_pitchSlider->setValue(pitch);
m_pitchSlider->blockSignals(false);
}
void AudioLayerWidget::loadMedia(QString file) void AudioLayerWidget::loadMedia(QString file)
{ {
if (m_currentMedia.compare(file) == 0 ) { if (m_currentMedia.compare(file) == 0 ) {
@ -165,9 +219,13 @@ void AudioLayerWidget::durationChanged(qint64 dur)
m_totalTimeValue->setTime(QTime::fromMSecsSinceStartOfDay(dur)); m_totalTimeValue->setTime(QTime::fromMSecsSinceStartOfDay(dur));
} }
void AudioLayerWidget::play() void AudioLayerWidget::play(bool loop)
{ {
m_music.play(); m_music.play();
m_music.setLoop(loop);
m_loopCheck->blockSignals(true);
m_loopCheck->setChecked(m_music.getLoop());
m_loopCheck->blockSignals(false);
} }
void AudioLayerWidget::pause() void AudioLayerWidget::pause()
@ -202,6 +260,9 @@ void AudioLayerWidget::watchDMXExpired() {
m_progressSlider->setValue(0); m_progressSlider->setValue(0);
break; break;
} }
//m_loopCheck->blockSignals(true);
//m_loopCheck->setChecked(m_music.getLoop());
//m_loopCheck->blockSignals(false);
} }
void AudioLayerWidget::toggleSuspendResume() void AudioLayerWidget::toggleSuspendResume()

View file

@ -35,7 +35,7 @@ public:
/** /**
* @brief play * @brief play
*/ */
void play(); void play(bool loop);
/** /**
* @brief stop * @brief stop
@ -58,6 +58,16 @@ public:
*/ */
void resume(); void resume();
void setPan(qreal pan);
void setPitch(qreal pitch);
void setLoop(bool on);
//void setEntryPoint(qreal entry);
//void setEndPoint(qreal end);
public slots: public slots:
/** /**
@ -66,10 +76,13 @@ public slots:
void toggleSuspendResume(); void toggleSuspendResume();
/** /**
* @brief Conencted with the slider * @brief Connected with the slider
* @param volume 0 -100 range * @param volume 0 -100 range
*/ */
void volumeChanged(int vol); void volumeChanged(int vol);
void panChanged(int vol);
void pitchChanged(int vol);
void loopChanged(int vol);
private: private:
@ -81,6 +94,15 @@ private:
QLabel *m_volumeLabel; QLabel *m_volumeLabel;
QSlider *m_volumeSlider; QSlider *m_volumeSlider;
QLabel *m_panLabel;
QSlider *m_panSlider;
QLabel *m_pitchLabel;
QSlider *m_pitchSlider;
QLabel *m_loopCheckLabel;
QCheckBox *m_loopCheck;
QLabel * m_progressLabel; QLabel * m_progressLabel;
QSlider *m_progressSlider; QSlider *m_progressSlider;
@ -96,7 +118,7 @@ private:
QLabel * m_folderLabel; QLabel * m_folderLabel;
QLabel * m_folderValue; QLabel * m_folderValue;
QCheckBox *m_receiveDMX; //QCheckBox *m_receiveDMX;
QTimer *m_watchDMX; QTimer *m_watchDMX;
QString m_currentMedia; QString m_currentMedia;
@ -125,6 +147,4 @@ private slots:
void watchDMXExpired(); void watchDMXExpired();
}; };
#endif // AUDIOLAYERWIDGET_H #endif // AUDIOLAYERWIDGET_H

View file

@ -4,25 +4,24 @@
AudioMasterWidget::AudioMasterWidget(QWidget *parent) : AudioMasterWidget::AudioMasterWidget(QWidget *parent) :
QGroupBox(parent) QGroupBox(parent)
, m_file(new QLabel) //, m_file(new QLabel)
, m_folder(new QLabel) //, m_folder(new QLabel)
, m_vol(new QSlider) //, m_vol(new QSlider)
, m_mute(new QCheckBox) //, m_mute(new QCheckBox)
, m_status(new QLabel) //, m_status(new QLabel)
, m_receiveDMX(new QCheckBox) , m_receiveDMX(new QCheckBox)
, m_watchDMX(new QTimer) , m_watchDMX(new QTimer)
{ {
QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox = new QVBoxLayout;
// vbox->addWidget(status); //vbox->addWidget(m_status);
// vbox->addWidget(vol); //vbox->addWidget(m_vol);
// vbox->addWidget(mute); //vbox->addWidget(m_mute);
m_receiveDMX->setText("Receiving DMX"); m_receiveDMX->setText("Receiving DMX");
vbox->addWidget(m_receiveDMX); vbox->addWidget(m_receiveDMX);
this->setLayout(vbox); this->setLayout(vbox);
connect(m_watchDMX, SIGNAL(timeout()), connect(m_watchDMX, SIGNAL(timeout()),
this, SLOT(watchDMXExpired())); this, SLOT(watchDMXExpired()));
m_watchDMX->start(1000); m_watchDMX->start(1000);
} }
AudioMasterWidget::~AudioMasterWidget() AudioMasterWidget::~AudioMasterWidget()

View file

@ -28,11 +28,11 @@ public slots:
void updateWatchDMX(); void updateWatchDMX();
private: private:
QLabel *m_file; //QLabel *m_file;
QLabel *m_folder; //QLabel *m_folder;
QSlider *m_vol; //QSlider *m_vol;
QCheckBox *m_mute; //QCheckBox *m_mute;
QLabel *m_status; //QLabel *m_status;
QCheckBox *m_receiveDMX; QCheckBox *m_receiveDMX;
QTimer *m_watchDMX; QTimer *m_watchDMX;

View file

@ -37,12 +37,22 @@ void AudioWidget::volChanged(int layer, qreal vol) {
} }
void AudioWidget::panChanged(int layer, qreal vol) {
QLayoutItem * const item = layout->itemAt(layer);
dynamic_cast<AudioLayerWidget *>(item->widget())->setPan(vol);
}
void AudioWidget::pitchChanged(int layer, qreal vol) {
QLayoutItem * const item = layout->itemAt(layer);
dynamic_cast<AudioLayerWidget *>(item->widget())->setPitch(vol);
}
void AudioWidget::playbackChanged(int layer, Status status) void AudioWidget::playbackChanged(int layer, Status status)
{ {
QLayoutItem * const item = layout->itemAt(layer); QLayoutItem * const item = layout->itemAt(layer);
switch (status) { switch (status) {
case Playing: case PlayingOnce:
dynamic_cast<AudioLayerWidget *>(item->widget())->play(); dynamic_cast<AudioLayerWidget *>(item->widget())->play(false);
break; break;
case Stopped: case Stopped:
dynamic_cast<AudioLayerWidget *>(item->widget())->stop(); dynamic_cast<AudioLayerWidget *>(item->widget())->stop();
@ -50,6 +60,9 @@ void AudioWidget::playbackChanged(int layer, Status status)
case Paused: case Paused:
dynamic_cast<AudioLayerWidget *>(item->widget())->pause(); dynamic_cast<AudioLayerWidget *>(item->widget())->pause();
break; break;
case PlayingLoop:
dynamic_cast<AudioLayerWidget *>(item->widget())->play(true);
break;
} }
} }
/* /*

View file

@ -24,6 +24,8 @@ protected:
static AudioWidget *getInstance(); static AudioWidget *getInstance();
void mediaLoaded(int layer, QString media ); void mediaLoaded(int layer, QString media );
void volChanged(int layer, qreal vol); void volChanged(int layer, qreal vol);
void panChanged(int layer, qreal pan);
void pitchChanged(int layer, qreal pitch);
void playbackChanged(int layer, Status status); void playbackChanged(int layer, Status status);
private: private:

View file

@ -5,7 +5,7 @@
#define COPYRIGHT "(C) 2014-2024 Santi Norena lms@criptomart.net" #define COPYRIGHT "(C) 2014-2024 Santi Norena lms@criptomart.net"
#define LICENSE "GPL 3 License. See LICENSE.txt and credits.txt for details" #define LICENSE "GPL 3 License. See LICENSE.txt and credits.txt for details"
#define LAYERS_NUMBER 3 #define LAYERS_NUMBER 4 // esto tiene que desaparecer
#define DEFAULT_FILE "lms-audio.xlm" #define DEFAULT_FILE "lms-audio.xlm"
@ -29,7 +29,7 @@ const int BufferSize = 262144;
#define TOTAL_TIME_LABEL "Total" #define TOTAL_TIME_LABEL "Total"
#define FILE_LABEL "File:" #define FILE_LABEL "File:"
#define FOLDER_LABEL "Folder:" #define FOLDER_LABEL "Folder:"
#define STATUS_LABEL " Status: " #define STATUS_LABEL "Status: "
#define NOTIFY_INTERVAL 150 #define NOTIFY_INTERVAL 150
#define PULL_TIMER_INTERVAL 10 #define PULL_TIMER_INTERVAL 10
@ -59,9 +59,10 @@ struct MediaFolder {
enum Status enum Status
{ {
Stopped, ///< Sound is not playing Stopped,
Paused, ///< Sound is paused Paused,
Playing ///< Sound is playing PlayingOnce,
PlayingLoop,
}; };
#endif // DEFINES_H #endif // DEFINES_H

View file

@ -9,13 +9,16 @@
3 - Folder 3 - Folder
4 - File 4 - File
5 - Playback 5 - Playback
0-24 : Play. Reproduce desde el inicio del fichero. 0-24 : Play once.
25-49: Stop. 25-49: Stop. Returns to start of file.
50-74: Resume. Reproduce desde el punto desde el que se paró, o desde el punto designado por Entry Point. 50-74: Pause. It keeps the time of reproductions.
75-99: Play loop.
6 - Control - Reservado, sin uso en este momento. 6 - Control - Reservado, sin uso en este momento.
7 - Volume Fine 7 - Volume Fine
8 - Entry Point Coarse - Punto de entrada de reproducción. 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. 9 - Entry Point Fine - El valor de estos dos canales en centésimas de segundo.
10 - Pan
11 - Pitch
*/ */
// ToDo: Tiene bastante sentido cambiar estos defines por un enum // ToDo: Tiene bastante sentido cambiar estos defines por un enum
@ -30,7 +33,8 @@
#define VOLUME_FINE 6 #define VOLUME_FINE 6
#define ENTRY_POINT_COARSE 7 #define ENTRY_POINT_COARSE 7
#define ENTRY_POINT_FINE 8 #define ENTRY_POINT_FINE 8
#define PITCH 9
#define LAYER_CHANNELS 4 // ToDo: esto tiene que desaparecer #define LAYER_CHANNELS 10
#endif // DMXPERSONALITY_H #endif // DMXPERSONALITY_H

View file

@ -22,6 +22,9 @@
<height>31</height> <height>31</height>
</rect> </rect>
</property> </property>
<property name="maximum">
<number>64</number>
</property>
</widget> </widget>
<widget class="QSpinBox" name="address"> <widget class="QSpinBox" name="address">
<property name="geometry"> <property name="geometry">
@ -35,6 +38,35 @@
<property name="accessibleDescription"> <property name="accessibleDescription">
<string>Address</string> <string>Address</string>
</property> </property>
<property name="maximum">
<number>497</number>
</property>
</widget>
<widget class="QLabel" name="universe_2">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Universe</string>
</property>
</widget>
<widget class="QLabel" name="address_label">
<property name="geometry">
<rect>
<x>110</x>
<y>0</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Address</string>
</property>
</widget> </widget>
</widget> </widget>
<resources/> <resources/>

View file

@ -1,7 +1,7 @@
/* /*
Libre Media Server - A Media Server Sotfware for stage and performing Libre Media Server - A Media Server Sotfware for stage and performing
Copyright (C) 2012-2014 Santi Noreña libremediaserver@gmail.com Copyright (C) 2012-2024 Santi Noreña lms@criptomart.net
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -181,7 +181,10 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
AudioWidget::getInstance()->volChanged(layer, f / 655.35); AudioWidget::getInstance()->volChanged(layer, f / 655.35);
break; break;
case PAN: case PAN:
f = (float)value / 255; AudioWidget::getInstance()->panChanged(layer, value);
break;
case PITCH:
AudioWidget::getInstance()->pitchChanged(layer, value);
break; break;
case PLAYBACK: case PLAYBACK:
if (value == 0) if (value == 0)
@ -189,7 +192,7 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
aux = value / 25; aux = value / 25;
switch (aux) { switch (aux) {
case 0 : case 0 :
AudioWidget::getInstance()->playbackChanged(layer, Playing); AudioWidget::getInstance()->playbackChanged(layer, PlayingOnce);
break; break;
case 1 : case 1 :
AudioWidget::getInstance()->playbackChanged(layer, Stopped); AudioWidget::getInstance()->playbackChanged(layer, Stopped);
@ -197,6 +200,9 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
case 2 : case 2 :
AudioWidget::getInstance()->playbackChanged(layer, Paused); AudioWidget::getInstance()->playbackChanged(layer, Paused);
break; break;
case 3 :
AudioWidget::getInstance()->playbackChanged(layer, PlayingLoop);
break;
} }
default: default:
break; break;