Compare commits
2 commits
63f25e8209
...
3613d8fa51
Author | SHA1 | Date | |
---|---|---|---|
|
3613d8fa51 | ||
|
32a1e5cb0c |
15 changed files with 116 additions and 226 deletions
|
@ -16,6 +16,8 @@ v 0.2.0 Antigona (24/04/2024)
|
||||||
+ Refactor AudioMasterWidget to AudioDMXReceptionWidget.
|
+ Refactor AudioMasterWidget to AudioDMXReceptionWidget.
|
||||||
+ mp3, flac, wav (mp3 has given some errors seeking cursor...).
|
+ mp3, flac, wav (mp3 has given some errors seeking cursor...).
|
||||||
+ settings dialog not working, only read the conf file at startup.
|
+ settings dialog not working, only read the conf file at startup.
|
||||||
|
+ variable number of layers.
|
||||||
|
+ olathread, send double channels only once for each dmx frame buffer.
|
||||||
|
|
||||||
v 0.1.3 Unreleased (19/04/2024)
|
v 0.1.3 Unreleased (19/04/2024)
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,10 @@ v 0.2.2
|
||||||
|
|
||||||
v 0.2.1
|
v 0.2.1
|
||||||
- Multi devices output.
|
- Multi devices output.
|
||||||
- Rose noise and sine generator in menu to test system.
|
|
||||||
- Play Mode:
|
- Play Mode:
|
||||||
- Play all medias found in folder consecutevily or random, with loop.
|
- Play all medias found in folder consecutevily or random, with loop.
|
||||||
- Play all medias, consecutevily and random, with loop.
|
- Play all medias, consecutevily and random, with loop.
|
||||||
- mute/panic on layer.
|
- mute/panic on layer.
|
||||||
- number of layers configured in conf file, up to 256.
|
|
||||||
- Master Bus Layer:
|
- Master Bus Layer:
|
||||||
- each layer will have one "Gain" prefader that acts in source, "Vol" in v 1.3.
|
- each layer will have one "Gain" prefader that acts in source, "Vol" in v 1.3.
|
||||||
- each layer will have one volume dmx channel for each bus layer. One aux "Send" prefader.
|
- each layer will have one volume dmx channel for each bus layer. One aux "Send" prefader.
|
||||||
|
@ -42,13 +40,16 @@ v 0.2.1
|
||||||
- magicq .hed
|
- magicq .hed
|
||||||
- audio device linked, outputs will be redirected there.
|
- audio device linked, outputs will be redirected there.
|
||||||
- dmx address + universe settings.
|
- dmx address + universe settings.
|
||||||
|
- Rose noise and sine generator in menu to test system.
|
||||||
- Keyboards strokes, load media files from ui.
|
- Keyboards strokes, load media files from ui.
|
||||||
- Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante.
|
- Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante.
|
||||||
- LOGs y entrada de comandos.
|
- Logs, verbosity, timestamp.
|
||||||
- Bufgix: depurar errores cuando no carga la librería de medias, cambia el númmero de capas, cambia el universo, etc.
|
- Bufgix: depurar errores cuando no carga la librería de medias, cambia el númmero de capas, cambia el universo, etc.
|
||||||
- New control mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH
|
- New control 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.
|
||||||
- SettingsDialog.
|
- SettingsDialog.
|
||||||
- Load/save conf file.
|
- Load/save conf file.
|
||||||
- ¿stop offset? is it needed?
|
- ¿stop offset? is it needed?
|
||||||
- decouple MiniAudioEngine from AudioWidget, starts whith no gui or with gui in a dedicated thread.
|
- decouple MiniAudioEngine from AudioWidget, starts whith no gui or with audio in a dedicated thread.
|
||||||
|
- New Status "Iddle" in playbacks if is not loaded.
|
||||||
|
- check return errors, we are too happy....
|
||||||
|
|
|
@ -10,9 +10,6 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name, int layer):
|
||||||
QVBoxLayout *layout = new QVBoxLayout;
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
|
||||||
QHBoxLayout *progressTime = new QHBoxLayout;
|
QHBoxLayout *progressTime = new QHBoxLayout;
|
||||||
//m_progressTimeLabel = new QLabel;
|
|
||||||
//m_progressTimeLabel->setText(PROGRESS_TIME_LABEL);
|
|
||||||
//progressTime->addWidget(m_progressTimeLabel);
|
|
||||||
m_progressTime = new QTimeEdit;
|
m_progressTime = new QTimeEdit;
|
||||||
m_progressTime->text();
|
m_progressTime->text();
|
||||||
m_progressTime->setDisplayFormat("h:mm:ss:zzz");
|
m_progressTime->setDisplayFormat("h:mm:ss:zzz");
|
||||||
|
@ -21,9 +18,6 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name, int layer):
|
||||||
m_progressTime->setMaximumWidth(90);
|
m_progressTime->setMaximumWidth(90);
|
||||||
m_progressTime->setFocusPolicy(Qt::NoFocus);
|
m_progressTime->setFocusPolicy(Qt::NoFocus);
|
||||||
progressTime->addWidget(m_progressTime);
|
progressTime->addWidget(m_progressTime);
|
||||||
//m_totalTimeLabel = new QLabel;
|
|
||||||
//m_totalTimeLabel->setText(TOTAL_TIME_LABEL);
|
|
||||||
//progressTime->addWidget(m_totalTimeLabel);
|
|
||||||
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);
|
||||||
|
@ -49,19 +43,19 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, QString name, int layer):
|
||||||
layout->addLayout(status);
|
layout->addLayout(status);
|
||||||
|
|
||||||
QHBoxLayout *volumeBox = new QHBoxLayout;
|
QHBoxLayout *volumeBox = new QHBoxLayout;
|
||||||
m_volume = new SliderGroup("Vol", 0 , 100, NULL);
|
m_volume = new SliderGroup("Vol", 0 , 100, 2, NULL);
|
||||||
volumeBox->addWidget(m_volume);
|
volumeBox->addWidget(m_volume);
|
||||||
connect(m_volume, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));
|
connect(m_volume, SIGNAL(valueChanged(float)), this, SLOT(volumeChanged(float)));
|
||||||
m_pan = new SliderGroup("Pan", 0 , 255, NULL);
|
m_pan = new SliderGroup("Pan", 0 , 255, 0, NULL);
|
||||||
volumeBox->addWidget(m_pan);
|
volumeBox->addWidget(m_pan);
|
||||||
connect(m_pan, SIGNAL(valueChanged(int)), this, SLOT(panChanged(int)));
|
connect(m_pan, SIGNAL(valueChanged(float)), this, SLOT(panChanged(float)));
|
||||||
m_pitch = new SliderGroup("Pitch", 0 , 255, NULL);
|
m_pitch = new SliderGroup("Pitch", 0 , 255, 0, NULL);
|
||||||
volumeBox->addWidget(m_pitch);
|
volumeBox->addWidget(m_pitch);
|
||||||
connect(m_pitch, SIGNAL(valueChanged(int)), this, SLOT(pitchChanged(int)));
|
connect(m_pitch, SIGNAL(valueChanged(float)), this, SLOT(pitchChanged(float)));
|
||||||
layout->addLayout(volumeBox);
|
layout->addLayout(volumeBox);
|
||||||
|
|
||||||
m_suspendResumeButton = new QPushButton(this);
|
m_suspendResumeButton = new QPushButton(this);
|
||||||
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
|
m_suspendResumeButton->setText(StatusStr[Status::Stopped]);
|
||||||
connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
|
connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
|
||||||
layout->addWidget(m_suspendResumeButton);
|
layout->addWidget(m_suspendResumeButton);
|
||||||
|
|
||||||
|
@ -74,17 +68,17 @@ AudioLayerWidget::~AudioLayerWidget()
|
||||||
}
|
}
|
||||||
|
|
||||||
// From UI.
|
// From UI.
|
||||||
void AudioLayerWidget::volumeChanged(int value)
|
void AudioLayerWidget::volumeChanged(float value)
|
||||||
{
|
{
|
||||||
emit(uiSliderChanged(m_layer, Slider::Volume, value));
|
emit(uiSliderChanged(m_layer, Slider::Volume, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::panChanged(int value)
|
void AudioLayerWidget::panChanged(float value)
|
||||||
{
|
{
|
||||||
emit(uiSliderChanged(m_layer, Slider::Pan, value));
|
emit(uiSliderChanged(m_layer, Slider::Pan, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::pitchChanged(int value)
|
void AudioLayerWidget::pitchChanged(float value)
|
||||||
{
|
{
|
||||||
emit(uiSliderChanged(m_layer, Slider::Pitch, value));
|
emit(uiSliderChanged(m_layer, Slider::Pitch, value));
|
||||||
}
|
}
|
||||||
|
@ -106,21 +100,21 @@ void AudioLayerWidget::toggleSuspendResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
// from DMX signals
|
// from DMX signals
|
||||||
void AudioLayerWidget::setVol(qreal vol)
|
void AudioLayerWidget::setVol(float vol)
|
||||||
{
|
{
|
||||||
m_volume->blockSignals(true);
|
m_volume->blockSignals(true);
|
||||||
m_volume->setValue(vol);
|
m_volume->setValue(vol);
|
||||||
m_volume->blockSignals(false);
|
m_volume->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::setPan(qreal pan)
|
void AudioLayerWidget::setPan(int pan)
|
||||||
{
|
{
|
||||||
m_pan->blockSignals(true);
|
m_pan->blockSignals(true);
|
||||||
m_pan->setValue(pan);
|
m_pan->setValue(pan);
|
||||||
m_pan->blockSignals(false);
|
m_pan->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::setPitch(qreal pitch)
|
void AudioLayerWidget::setPitch(int pitch)
|
||||||
{
|
{
|
||||||
m_pitch->blockSignals(true);
|
m_pitch->blockSignals(true);
|
||||||
m_pitch->setValue(pitch);
|
m_pitch->setValue(pitch);
|
||||||
|
@ -144,33 +138,25 @@ void AudioLayerWidget::setPlaybackStatus(Status status)
|
||||||
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0));
|
m_progressTime->setTime(QTime::fromMSecsSinceStartOfDay(0));
|
||||||
m_statusValue->blockSignals(true);
|
m_statusValue->blockSignals(true);
|
||||||
m_suspendResumeButton->blockSignals(true);
|
m_suspendResumeButton->blockSignals(true);
|
||||||
|
m_statusValue->setText(StatusStr[status]);
|
||||||
|
m_suspendResumeButton->setText(StatusStr[status]);
|
||||||
switch (m_status) {
|
switch (m_status) {
|
||||||
case Status::Paused:
|
case Status::Paused:
|
||||||
m_statusValue->setText("Pause");
|
|
||||||
m_statusValue->setStyleSheet("QLabel { color : red; }");
|
m_statusValue->setStyleSheet("QLabel { color : red; }");
|
||||||
m_suspendResumeButton->setText("Pause");
|
|
||||||
break;
|
break;
|
||||||
case Status::PlayingLoop:
|
case Status::PlayingLoop:
|
||||||
m_statusValue->setText("Play Loop");
|
|
||||||
m_statusValue->setStyleSheet("QLabel { color : green; }");
|
|
||||||
m_suspendResumeButton->setText("Play Loop");
|
|
||||||
break;
|
|
||||||
case Status::PlayingOnce:
|
case Status::PlayingOnce:
|
||||||
m_statusValue->setText("Play One");
|
|
||||||
m_statusValue->setStyleSheet("QLabel { color : green; }");
|
m_statusValue->setStyleSheet("QLabel { color : green; }");
|
||||||
m_suspendResumeButton->setText("Play One");
|
|
||||||
break;
|
break;
|
||||||
case Status::Stopped:
|
case Status::Stopped:
|
||||||
m_statusValue->setText("Stop");
|
|
||||||
m_statusValue->setStyleSheet("QLabel { color : red; }");
|
m_statusValue->setStyleSheet("QLabel { color : red; }");
|
||||||
m_suspendResumeButton->setText("Stop");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_statusValue->blockSignals(false);
|
m_statusValue->blockSignals(false);
|
||||||
m_suspendResumeButton->blockSignals(false);
|
m_suspendResumeButton->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioLayerWidget::durationChanged(qint64 dur)
|
void AudioLayerWidget::durationChanged(float dur)
|
||||||
{
|
{
|
||||||
dur *= 1000;
|
dur *= 1000;
|
||||||
m_progressSlider->setMaximum(dur);
|
m_progressSlider->setMaximum(dur);
|
||||||
|
|
|
@ -26,10 +26,10 @@ class AudioLayerWidget : public QGroupBox
|
||||||
public:
|
public:
|
||||||
explicit AudioLayerWidget(QWidget *parent = 0, QString name = "Layer", int layer = 0);
|
explicit AudioLayerWidget(QWidget *parent = 0, QString name = "Layer", int layer = 0);
|
||||||
~AudioLayerWidget();
|
~AudioLayerWidget();
|
||||||
void setVol(qreal vol);
|
void setVol(float vol);
|
||||||
void resume();
|
void resume();
|
||||||
void setPan(qreal pan);
|
void setPan(int pan);
|
||||||
void setPitch(qreal pitch);
|
void setPitch(int pitch);
|
||||||
void setLoop(bool on);
|
void setLoop(bool on);
|
||||||
void setPlaybackStatus(Status status);
|
void setPlaybackStatus(Status status);
|
||||||
inline Status getPlaybackStatus() { return m_status; }
|
inline Status getPlaybackStatus() { return m_status; }
|
||||||
|
@ -38,29 +38,23 @@ private:
|
||||||
Status m_status;
|
Status m_status;
|
||||||
int m_layer;
|
int m_layer;
|
||||||
QPushButton *m_suspendResumeButton;
|
QPushButton *m_suspendResumeButton;
|
||||||
QLabel *m_statusLabel;
|
|
||||||
QLabel * m_statusValue;
|
QLabel * m_statusValue;
|
||||||
QLabel *m_fileLabel;
|
|
||||||
QLabel *m_fileValue;
|
QLabel *m_fileValue;
|
||||||
QLabel * m_folderLabel;
|
|
||||||
QLabel * m_folderValue;
|
QLabel * m_folderValue;
|
||||||
SliderGroup *m_volume;
|
SliderGroup *m_volume;
|
||||||
SliderGroup *m_pan;
|
SliderGroup *m_pan;
|
||||||
SliderGroup *m_pitch;
|
SliderGroup *m_pitch;
|
||||||
QLabel * m_progressLabel;
|
|
||||||
QSlider *m_progressSlider;
|
QSlider *m_progressSlider;
|
||||||
QLabel *m_progressTimeLabel;
|
|
||||||
QTimeEdit *m_progressTime;
|
QTimeEdit *m_progressTime;
|
||||||
QLabel *m_totalTimeLabel;
|
|
||||||
QTimeEdit *m_totalTimeValue;
|
QTimeEdit *m_totalTimeValue;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleSuspendResume();
|
void toggleSuspendResume();
|
||||||
void volumeChanged(int vol);
|
void volumeChanged(float vol);
|
||||||
void panChanged(int vol);
|
void panChanged(float pan);
|
||||||
void pitchChanged(int vol);
|
void pitchChanged(float pitch);
|
||||||
void fileLoaded(QString file);
|
void fileLoaded(QString file);
|
||||||
void durationChanged(qint64 dur);
|
void durationChanged(float dur);
|
||||||
void refreshUi(float progress);
|
void refreshUi(float progress);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -56,19 +56,19 @@ void AudioWidget::mediaLoaded(int layer, QString file)
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->durationChanged(pLength);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->durationChanged(pLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::volChanged(int layer, qreal vol) {
|
void AudioWidget::volChanged(int layer, float vol) {
|
||||||
m_mae.volChanged(layer, vol);
|
m_mae.volChanged(layer, vol);
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
QLayoutItem * const item = m_layout->itemAt(layer);
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setVol(vol);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->setVol(vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::panChanged(int layer, qreal pan) {
|
void AudioWidget::panChanged(int layer, int pan) {
|
||||||
m_mae.panChanged(layer, pan);
|
m_mae.panChanged(layer, pan);
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
QLayoutItem * const item = m_layout->itemAt(layer);
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setPan(pan);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->setPan(pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioWidget::pitchChanged(int layer, qreal pitch) {
|
void AudioWidget::pitchChanged(int layer, int pitch) {
|
||||||
m_mae.pitchChanged(layer, pitch);
|
m_mae.pitchChanged(layer, pitch);
|
||||||
QLayoutItem * const item = m_layout->itemAt(layer);
|
QLayoutItem * const item = m_layout->itemAt(layer);
|
||||||
dynamic_cast<AudioLayerWidget *>(item->widget())->setPitch(pitch);
|
dynamic_cast<AudioLayerWidget *>(item->widget())->setPitch(pitch);
|
||||||
|
|
|
@ -27,9 +27,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mediaLoaded(int layer, QString media );
|
void mediaLoaded(int layer, QString media );
|
||||||
void volChanged(int layer, qreal vol);
|
void volChanged(int layer, float vol);
|
||||||
void panChanged(int layer, qreal pan);
|
void panChanged(int layer, int pan);
|
||||||
void pitchChanged(int layer, qreal pitch);
|
void pitchChanged(int layer, int pitch);
|
||||||
void playbackChanged(int layer, Status status);
|
void playbackChanged(int layer, Status status);
|
||||||
void entryPointChanged(int layer, int cursor);
|
void entryPointChanged(int layer, int cursor);
|
||||||
|
|
||||||
|
|
|
@ -9,23 +9,8 @@
|
||||||
#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 DEFAULT_FILE "lms-audio.xlm"
|
#define DEFAULT_FILE "lms-audio.xlm"
|
||||||
#define SUSPEND_LABEL "Pause"
|
|
||||||
#define RESUME_LABEL "Resume"
|
|
||||||
#define PLAY_LABEL "Play"
|
|
||||||
#define STOP_LABEL "Stop"
|
|
||||||
#define PAUSE_LABEL "Pause"
|
|
||||||
#define IDDLE_LABEL "Iddle playback"
|
|
||||||
#define VOLUME_LABEL "Vol"
|
|
||||||
#define PROGRESS_LABEL "Progress"
|
|
||||||
#define PROGRESS_TIME_LABEL "Current"
|
|
||||||
#define REMAINING_TIME "Remaining"
|
|
||||||
#define TOTAL_TIME_LABEL "Total"
|
|
||||||
#define NOTIFY_INTERVAL 150
|
|
||||||
#define PULL_TIMER_INTERVAL 10
|
|
||||||
#define MAX_DEVICES 16
|
|
||||||
#define MAX_SOUNDS 4096
|
|
||||||
#define MAX_LAYERS 16
|
#define MAX_LAYERS 16
|
||||||
#define UI_REFRESH_TIME 100
|
#define UI_REFRESH_TIME 200
|
||||||
|
|
||||||
// struct where save the DMX settings for each layer
|
// struct where save the DMX settings for each layer
|
||||||
struct dmxSetting {
|
struct dmxSetting {
|
||||||
|
@ -58,6 +43,15 @@ enum Status
|
||||||
PlayingLoop,
|
PlayingLoop,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* StatusStr[] =
|
||||||
|
{
|
||||||
|
"Stop",
|
||||||
|
"Pause",
|
||||||
|
"Playing One",
|
||||||
|
"Playing Loop",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
enum Slider
|
enum Slider
|
||||||
{
|
{
|
||||||
Volume,
|
Volume,
|
||||||
|
|
|
@ -48,12 +48,12 @@ libreMediaServerAudio::libreMediaServerAudio(QStringList args, QWidget *parent)
|
||||||
connect(set, SIGNAL(registerUniverse(int)), ola, SLOT(registerUniverse(int)));
|
connect(set, SIGNAL(registerUniverse(int)), ola, SLOT(registerUniverse(int)));
|
||||||
connect(ola, SIGNAL (universeReceived(int)), m_dmxWidget, SLOT(updateWatchDMX(int)));
|
connect(ola, SIGNAL (universeReceived(int)), m_dmxWidget, SLOT(updateWatchDMX(int)));
|
||||||
connect(ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int)));
|
connect(ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int)));
|
||||||
connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup()));
|
|
||||||
ola->registerUniverse();
|
ola->registerUniverse();
|
||||||
ola->start(QThread::TimeCriticalPriority );
|
ola->start(QThread::TimeCriticalPriority );
|
||||||
connect(ui.actionOpen_conf, SIGNAL(triggered()), this, SLOT(openFile()));
|
connect(ui.actionOpen_conf, SIGNAL(triggered()), this, SLOT(openFile()));
|
||||||
connect(ui.actionSave_conf, SIGNAL(triggered()), this, SLOT(saveFile()));
|
connect(ui.actionSave_conf, SIGNAL(triggered()), this, SLOT(saveFile()));
|
||||||
connect(ui.action_Settings, SIGNAL(triggered()), this, SLOT(settings()));
|
connect(ui.action_Settings, SIGNAL(triggered()), this, SLOT(settings()));
|
||||||
|
connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup()));
|
||||||
aw->startEngine();
|
aw->startEngine();
|
||||||
qDebug("Init Complete.");
|
qDebug("Init Complete.");
|
||||||
ola->blockSignals(false);
|
ola->blockSignals(false);
|
||||||
|
@ -107,8 +107,6 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
return;
|
return;
|
||||||
QString mediaFile = NULL;
|
QString mediaFile = NULL;
|
||||||
int aux;
|
int aux;
|
||||||
qreal f;
|
|
||||||
int r;
|
|
||||||
switch(channel){
|
switch(channel){
|
||||||
case DMX_FOLDER:
|
case DMX_FOLDER:
|
||||||
aux = ola->getValue(layer, DMX_FILE);
|
aux = ola->getValue(layer, DMX_FILE);
|
||||||
|
@ -123,12 +121,8 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
aw->mediaLoaded(layer, mediaFile);
|
aw->mediaLoaded(layer, mediaFile);
|
||||||
break;
|
break;
|
||||||
case VOLUME_COARSE:
|
case VOLUME_COARSE:
|
||||||
f = ( value * 0x100 ) + ola->getValue(layer, VOLUME_FINE);
|
|
||||||
aw->volChanged(layer, (f / 655.35));
|
|
||||||
break;
|
|
||||||
case VOLUME_FINE:
|
case VOLUME_FINE:
|
||||||
f = ( ola->getValue(layer, VOLUME_COARSE) * 0x100 ) + value;
|
aw->volChanged(layer, (value / 65025.0f));
|
||||||
aw->volChanged(layer, (f / 655.35));
|
|
||||||
break;
|
break;
|
||||||
case PAN:
|
case PAN:
|
||||||
aw->panChanged(layer, value);
|
aw->panChanged(layer, value);
|
||||||
|
@ -137,12 +131,8 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
||||||
aw->pitchChanged(layer, value);
|
aw->pitchChanged(layer, value);
|
||||||
break;
|
break;
|
||||||
case ENTRY_POINT_COARSE:
|
case ENTRY_POINT_COARSE:
|
||||||
r = ( value * 0x100 ) + ola->getValue(layer, ENTRY_POINT_FINE);
|
|
||||||
aw->entryPointChanged(layer, r);
|
|
||||||
break;
|
|
||||||
case ENTRY_POINT_FINE:
|
case ENTRY_POINT_FINE:
|
||||||
r = ( ola->getValue(layer, ENTRY_POINT_COARSE) * 0x100 ) + value;
|
aw->entryPointChanged(layer, value);
|
||||||
aw->entryPointChanged(layer, r);
|
|
||||||
break;
|
break;
|
||||||
case PLAYBACK:
|
case PLAYBACK:
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
|
|
125
src/main.cpp
125
src/main.cpp
|
@ -20,133 +20,11 @@
|
||||||
|
|
||||||
#include "libremediaserver-audio.h"
|
#include "libremediaserver-audio.h"
|
||||||
|
|
||||||
// Handler for pipe the stderr to a log file and texEdit
|
|
||||||
//bool initMessageHandler = false;
|
|
||||||
//QFile outFile;
|
|
||||||
//QMutex mutex;
|
|
||||||
//QMutexLocker mutexLocker(mutex);
|
|
||||||
/*
|
|
||||||
void MessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
|
||||||
{
|
|
||||||
Q_UNUSED(context);
|
|
||||||
// mutex.lock();
|
|
||||||
// Create the log dir and log file
|
|
||||||
if (!initMessageHandler) {
|
|
||||||
QDir dir;
|
|
||||||
if (!dir.exists("log")) {
|
|
||||||
if (!dir.mkdir("log")) {
|
|
||||||
qDebug()<<"MessageHandler: Can not create log folder";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QString filename;
|
|
||||||
QDate date = QDate::currentDate();
|
|
||||||
QTime time = QTime::currentTime();
|
|
||||||
filename.append("./log/log_");
|
|
||||||
filename.append(date.toString("ddMMyy-"));
|
|
||||||
filename.append(time.toString("hhmmss.txt"));
|
|
||||||
outFile.setFileName(filename);
|
|
||||||
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
|
||||||
qWarning("main/MessageHandler/Qfile::open: can not open log file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
initMessageHandler = true;
|
|
||||||
}
|
|
||||||
QTextStream ts(&outFile);*/
|
|
||||||
/* if (libreMediaServerAudio::textEdit == 0)
|
|
||||||
{
|
|
||||||
QByteArray localMsg = msg.toLocal8Bit();
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
|
||||||
break;
|
|
||||||
case QtWarningMsg:
|
|
||||||
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
|
||||||
break;
|
|
||||||
case QtCriticalMsg:
|
|
||||||
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
|
||||||
break;
|
|
||||||
case QtFatalMsg:
|
|
||||||
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QString txt;
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
txt.append("Debug from File: ");
|
|
||||||
txt.append(context.file);
|
|
||||||
txt.append(" Line: ");
|
|
||||||
txt.append(QString::number(context.line));
|
|
||||||
// txt.append(" Function: ");
|
|
||||||
// txt.append(context.function);
|
|
||||||
txt.append(" Message: ");
|
|
||||||
txt.append(msg);
|
|
||||||
// libreMediaServerAudio::textEdit->append(msg);, context.file, context.line, context.function);
|
|
||||||
libreMediaServerAudio::textEdit->append(txt);
|
|
||||||
break;
|
|
||||||
case QtWarningMsg:
|
|
||||||
txt.append("Warning from File: ");
|
|
||||||
txt.append(context.file);
|
|
||||||
txt.append(" Line: ");
|
|
||||||
txt.append(QString::number(context.line));
|
|
||||||
txt.append(" Function: ");
|
|
||||||
txt.append(context.function);
|
|
||||||
txt.append(" Message: ");
|
|
||||||
txt.append(msg);
|
|
||||||
// libreMediaServerAudio::textEdit->append(msg);, context.file, context.line, context.function);
|
|
||||||
libreMediaServerAudio::textEdit->append(txt);
|
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
case QtCriticalMsg:
|
|
||||||
// txt.append("Critical from File: ");
|
|
||||||
txt.append(context.file);
|
|
||||||
txt.append(" Line: ");
|
|
||||||
txt.append(QString::number(context.line));
|
|
||||||
txt.append(" Function: ");
|
|
||||||
txt.append(context.function);
|
|
||||||
txt.append(" Message ");
|
|
||||||
txt.append(msg);
|
|
||||||
// libreMediaServerAudio::textEdit->append(msg);, context.file, context.line, context.function);
|
|
||||||
libreMediaServerAudio::textEdit->append(txt);
|
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
case QtFatalMsg:
|
|
||||||
// txt.append("Fatal from File: ");
|
|
||||||
txt.append(context.file);
|
|
||||||
txt.append(" Line: ");
|
|
||||||
txt.append(QString::number(context.line));
|
|
||||||
txt.append(" Function: ");
|
|
||||||
txt.append(context.function);
|
|
||||||
txt.append(" Message: ");
|
|
||||||
txt.append(msg);
|
|
||||||
// libreMediaServerAudio::textEdit->append(msg);, context.file, context.line, context.function);
|
|
||||||
libreMediaServerAudio::textEdit->append(txt);// ts << txt << endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
// outFile.write(txt.toLatin1().constData(), txt.size());
|
|
||||||
// ts << txt << endl;
|
|
||||||
// libreMediaServerAudio::textEdit->append(txt);
|
|
||||||
}
|
|
||||||
// mutex.unlock();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
// ToDo: discriminar niveles de log y log a fichero segúna argumentos
|
|
||||||
/*
|
|
||||||
if (args.contains("-log"))
|
|
||||||
{
|
|
||||||
qInstallMessageHandler(MessageHandler);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
QStringList args = app.arguments();
|
QStringList args = app.arguments();
|
||||||
|
|
||||||
if (args.size() > 1)
|
if (args.size() > 1)
|
||||||
{
|
{
|
||||||
if (args.contains("-v"))
|
if (args.contains("-v"))
|
||||||
|
@ -163,7 +41,6 @@ int main(int argc, char *argv[])
|
||||||
qDebug() << LICENSE;
|
qDebug() << LICENSE;
|
||||||
qDebug() << "Help for command line options:";
|
qDebug() << "Help for command line options:";
|
||||||
qDebug() << "-v show the version and exits";
|
qDebug() << "-v show the version and exits";
|
||||||
qDebug() << "-log write the debug information to a log file instead stderr";
|
|
||||||
qDebug() << "-h this help";
|
qDebug() << "-h this help";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -172,5 +49,3 @@ int main(int argc, char *argv[])
|
||||||
libreMediaServerAudio.show();
|
libreMediaServerAudio.show();
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,15 +183,16 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expects between 0 and 100 vol value in db
|
// Expects between 0 and 1 vol value in db
|
||||||
void MiniAudioEngine::volChanged(int layer, float vol)
|
void MiniAudioEngine::volChanged(int layer, float vol)
|
||||||
{
|
{
|
||||||
float result;
|
//float result;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
result = ma_volume_linear_to_db(1.00000000 + (vol / 800.0));
|
//result = ma_volume_linear_to_db(1.00000000 + (vol / 8.0));
|
||||||
ma_sound_group_set_volume(&m_currentSound[layer], result);
|
//qInfo("vol %f %f", vol, result);
|
||||||
|
ma_sound_group_set_volume(&m_currentSound[layer], vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::panChanged(int layer, float value)
|
void MiniAudioEngine::panChanged(int layer, float value)
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
|
|
||||||
#include "defines.h" //MAX_LAYERS
|
#include "defines.h" //MAX_LAYERS
|
||||||
#include <stdio.h> // for printf
|
#include <stdio.h> // for printf
|
||||||
|
|
||||||
|
@ -18,7 +17,6 @@ public:
|
||||||
static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
|
static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// slots for DMX input
|
|
||||||
ma_result loadMedia(int layer, char *media );
|
ma_result loadMedia(int layer, char *media );
|
||||||
void volChanged(int layer, float vol);
|
void volChanged(int layer, float vol);
|
||||||
void panChanged(int layer, float pan);
|
void panChanged(int layer, float pan);
|
||||||
|
|
|
@ -38,6 +38,7 @@ void olaThread::init()
|
||||||
m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx));
|
m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void olaThread::run()
|
void olaThread::run()
|
||||||
|
@ -62,19 +63,50 @@ void olaThread::stop()
|
||||||
void olaThread::NewDmx(const ola::client::DMXMetadata &data,
|
void olaThread::NewDmx(const ola::client::DMXMetadata &data,
|
||||||
const ola::DmxBuffer &buffer)
|
const ola::DmxBuffer &buffer)
|
||||||
{
|
{
|
||||||
m_counter++;
|
bool volSent = false;
|
||||||
gettimeofday(&m_last_data, NULL);
|
bool entrySent = false;
|
||||||
foreach (const dmxSetting &i, Settings::getInstance()->getDmxSettings()) {
|
|
||||||
|
foreach (const dmxSetting &i, m_dmxSettings) {
|
||||||
if(i.universe == data.universe && i.address > -1) {
|
if(i.universe == data.universe && i.address > -1) {
|
||||||
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;
|
||||||
emit dmxOutput(i.layer,j,value);
|
switch (j) {
|
||||||
|
case 0:
|
||||||
|
value = (value * 0x100) + buffer.Get(i.address + 6);
|
||||||
|
emit dmxOutput(i.layer,j,value);
|
||||||
|
volSent = true;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
value = (value * 0x100) + buffer.Get(i.address + 8);
|
||||||
|
emit dmxOutput(i.layer,j,value);
|
||||||
|
entrySent = true;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (volSent == false)
|
||||||
|
{
|
||||||
|
value = (buffer.Get(i.address) * 0x100) + value;
|
||||||
|
emit dmxOutput(i.layer,j,value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (entrySent == false)
|
||||||
|
{
|
||||||
|
value = (buffer.Get(i.address + 7) * 0x100) + value;
|
||||||
|
emit dmxOutput(i.layer,j,value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
emit dmxOutput(i.layer,j,value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_counter++;
|
||||||
|
gettimeofday(&m_last_data, NULL);
|
||||||
emit universeReceived(data.universe);
|
emit universeReceived(data.universe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
struct timeval m_last_data; // Last DMX frame received
|
struct timeval m_last_data; // Last DMX frame received
|
||||||
int m_layers;
|
int m_layers;
|
||||||
int m_dmx[MAX_LAYERS][LAYER_CHANNELS];
|
int m_dmx[MAX_LAYERS][LAYER_CHANNELS];
|
||||||
|
QList<dmxSetting> m_dmxSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback from ola. Control de errores en el registro de Universos en OLA
|
* @brief Callback from ola. Control de errores en el registro de Universos en OLA
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
SliderGroup::SliderGroup(const QString &title, \
|
SliderGroup::SliderGroup(const QString &title, \
|
||||||
int min,
|
int min,
|
||||||
int max,
|
int max,
|
||||||
|
int decimals,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QGroupBox(title, parent)
|
: QGroupBox(title, parent)
|
||||||
{
|
{
|
||||||
|
@ -14,17 +15,31 @@ SliderGroup::SliderGroup(const QString &title, \
|
||||||
slider->setTickInterval((max - min) / 11);
|
slider->setTickInterval((max - min) / 11);
|
||||||
slider->setSingleStep(1);
|
slider->setSingleStep(1);
|
||||||
slider->setRange(min, max);
|
slider->setRange(min, max);
|
||||||
//slider->setInvertedAppearance(false);
|
valueBox = new QDoubleSpinBox();
|
||||||
//slider->setInvertedControls(false);
|
|
||||||
valueBox = new QSpinBox();
|
|
||||||
valueBox->setFocusPolicy(Qt::NoFocus);
|
valueBox->setFocusPolicy(Qt::NoFocus);
|
||||||
valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||||
valueBox->setMaximumWidth(40);
|
valueBox->setMaximumWidth(45);
|
||||||
valueBox->setRange(min, max);
|
valueBox->setRange(min, max);
|
||||||
connect(slider, &QSlider::valueChanged, valueBox, &QSpinBox::setValue);
|
valueBox->setDecimals(decimals);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
|
||||||
QVBoxLayout *slidersLayout = new QVBoxLayout();
|
QVBoxLayout *slidersLayout = new QVBoxLayout();
|
||||||
slidersLayout->addWidget(valueBox);
|
slidersLayout->addWidget(valueBox);
|
||||||
slidersLayout->addWidget(slider);
|
slidersLayout->addWidget(slider);
|
||||||
setLayout(slidersLayout);
|
setLayout(slidersLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SliderGroup::sliderValueChanged(int 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);
|
||||||
|
}
|
||||||
|
|
|
@ -21,18 +21,19 @@ public:
|
||||||
SliderGroup(const QString &title,
|
SliderGroup(const QString &title,
|
||||||
int min,
|
int min,
|
||||||
int max,
|
int max,
|
||||||
|
int decimals,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void valueChanged(int value);
|
void valueChanged(float value);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
inline void setValue(int value) { slider->setValue(value); };
|
void setValue(float value);
|
||||||
inline void sliderValueChanged(int value) { emit valueChanged(value); };
|
void sliderValueChanged(int value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSlider *slider;
|
QSlider *slider;
|
||||||
QSpinBox *valueBox;
|
QDoubleSpinBox *valueBox;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue