diff --git a/docs/changelog.txt b/docs/changelog.txt
index 22a7e1f..a69017b 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -27,6 +27,8 @@ v 0.2.0 Antígona (24/04/2024)
+ Compilation without GUI (-DNOGUI).
+ New Status "Iddle" in playbacks if is not loaded.
+ New DMX personality version, better sort for audio needs (first load media, set vol, pan, etc, last playback order);
++ Refresh layer values when it loads a new sound file.
++ No QtSignals for sending data, better performance about 20% in my machine. Now, libremediaserver only updates values in AudioWidget, ui refresh is doing with a timer in audiowidget, so there is not problems between graphical and ola thread (the callback).
v 0.1.3 Leúcade (19/04/2024)
diff --git a/docs/lms-audio.xlm b/docs/lms-audio.xlm
index cc498ca..4274267 100644
--- a/docs/lms-audio.xlm
+++ b/docs/lms-audio.xlm
@@ -1,8 +1,8 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/docs/roadmap.txt b/docs/roadmap.txt
index 894c32c..bd98089 100644
--- a/docs/roadmap.txt
+++ b/docs/roadmap.txt
@@ -45,9 +45,13 @@ v 0.2.1
- Ui/Ux: Dar la opción clickeando en el widget de tiempo de poner una cuenta atrás en vez de hacia delante.
- Logs, verbosity, timestamp.
- New play mode without pitch control, it saves resources. MA_SOUND_FLAG_NO_PITCH
-- Vumeter or indicator about audio output in layer and master.
+- Vumeter or indicator about audio output in layer and master, add to sliderGroup.
+- QSlider can not accept floats and it can no manage high frequency updates.
- SettingsDialog.
- Load/save conf file.
- ¿Exit Point? is it needed?
-- Hardening: check return errors, catch execptions, i'm too happy....
+- Hardening: check return errors, try/catch exceptions, i'm too happy....
- Tests: errors on wrong conf file.
+- BUGFIX: there are some small clicks when changing volume and play/stop/pause. vol 24 bits? microfades in engine? setVol 0 before changing playback state?
+- refactorize dmxInput: loadMedia, changePlayBack,
+- BUGFIX: in nogui mode we need more info print at terminal (load media, change playback status).
diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp
index 02da882..a22b2cc 100644
--- a/src/audiolayerwidget.cpp
+++ b/src/audiolayerwidget.cpp
@@ -52,6 +52,7 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer):
m_progressTime->setReadOnly(true);
m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons);
m_progressTime->setMinimumWidth(80);
+ m_progressTime->setMaximumWidth(80);
m_progressTime->setFocusPolicy(Qt::NoFocus);
m_progressTime->setAlignment(Qt::AlignHCenter);
m_progressTime->setContentsMargins(0,0,0,0);
@@ -138,7 +139,7 @@ void AudioLayerWidget::openMediaDialog()
QStringList fileNames;
fileNames = dialog.selectedFiles();
emit uiLoadMedia(m_layer, fileNames.at(0));
- this->fileLoaded(fileNames.at(0));
+ this->setMediaFile(fileNames.at(0));
}
// from DMX signals
@@ -163,7 +164,7 @@ void AudioLayerWidget::setPitch(int pitch)
m_pitch->blockSignals(false);
}
-void AudioLayerWidget::fileLoaded(QString file)
+void AudioLayerWidget::setMediaFile(QString file)
{
QStringList list = file.split("/");
int size = list.size();
@@ -174,19 +175,18 @@ void AudioLayerWidget::fileLoaded(QString file)
this->setPlaybackStatus(Status::Stopped);
}
-void AudioLayerWidget::setPlaybackStatus(Status status)
+void AudioLayerWidget::setPlaybackStatus(Status s)
{
- if (!strcmp(StatusStr[status], m_suspendResumeButton->text().toLatin1().constData()))
- return;
+ Status status = static_cast(s);
m_suspendResumeButton->blockSignals(true);
m_status = status;
- if (status == Status::Stopped)
- refreshCurrentTime(0);
+ //if (status == Status::Stopped)
+ // refreshCurrentTime(0);
m_suspendResumeButton->setText(StatusStr[status]);
m_suspendResumeButton->blockSignals(false);
}
-void AudioLayerWidget::durationChanged(float dur)
+void AudioLayerWidget::setDuration(float dur)
{
m_progress->blockSignals(true);
m_progressTime->blockSignals(true);
@@ -200,7 +200,7 @@ void AudioLayerWidget::durationChanged(float dur)
m_totalTimeValue->blockSignals(false);
}
-void AudioLayerWidget::refreshCurrentTime(float progress)
+void AudioLayerWidget::setCurrentTime(float progress)
{
progress *= 1000;
m_progress->blockSignals(true);
diff --git a/src/audiolayerwidget.h b/src/audiolayerwidget.h
index 1c0ee83..9380b81 100644
--- a/src/audiolayerwidget.h
+++ b/src/audiolayerwidget.h
@@ -18,13 +18,6 @@ class AudioLayerWidget : public QWidget
public:
explicit AudioLayerWidget(QWidget *parent = 0, int layer = 0);
~AudioLayerWidget();
- void setVol(float vol);
- void resume();
- void setPan(int pan);
- void setPitch(int pitch);
- void setLoop(bool on);
- void setPlaybackStatus(Status status);
- inline Status getPlaybackStatus() { return m_status; }
private:
Status m_status;
@@ -39,17 +32,23 @@ private:
QTimeEdit *m_totalTimeValue;
QProgressBar *m_progress;
+// From DMX
public slots:
+ void setMediaFile(QString file);
+ void setDuration(float dur);
+ void setCurrentTime(float progress);
+ void setPlaybackStatus(Status status);
+ void setVol(float vol);
+ void setPan(int pan);
+ void setPitch(int pitch);
+
+// From Ui
+private slots:
+ void openMediaDialog();
void toggleSuspendResume();
void volumeChanged(int vol);
void panChanged(int pan);
void pitchChanged(int pitch);
- void fileLoaded(QString file);
- void durationChanged(float dur);
- void refreshCurrentTime(float progress);
-
-private slots:
- void openMediaDialog();
signals:
void uiPlaybackChanged(int layer, Status s);
diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp
index 3d17c2d..ca2633a 100644
--- a/src/audiowidget.cpp
+++ b/src/audiowidget.cpp
@@ -1,5 +1,5 @@
#include "audiowidget.h"
-
+#include
AudioWidget::AudioWidget(QWidget *parent) :
QWidget(parent)
@@ -15,39 +15,79 @@ AudioWidget::AudioWidget(QWidget *parent) :
m_layout->setSpacing(0);
m_layout->setContentsMargins(1, 1, 1, 1);
setLayout(m_layout);
+ m_refreshUi = new QTimer(this);
+ connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi()));
+ m_refreshUi->start(UI_REFRESH_TIME * 2);
}
void AudioWidget::mediaLoaded(int layer, QString file, float duration)
{
- QLayoutItem * const item = m_layout->itemAt(layer);
- dynamic_cast(item->widget())->fileLoaded(file);
- dynamic_cast(item->widget())->durationChanged(duration);
+ m_layerUpdate[layer].media = file;
+ m_layerUpdate[layer].duration = duration;
+ m_layerUpdate[layer].updated = true;
}
void AudioWidget::volChanged(int layer, float vol) {
- QLayoutItem * const item = m_layout->itemAt(layer);
- dynamic_cast(item->widget())->setVol(vol);
+ m_layerUpdate[layer].vol = vol;
+ m_layerUpdate[layer].updated = true;
}
void AudioWidget::panChanged(int layer, int pan) {
- QLayoutItem * const item = m_layout->itemAt(layer);
- dynamic_cast(item->widget())->setPan(pan);
+ m_layerUpdate[layer].pan = pan;
+ m_layerUpdate[layer].updated = true;
}
void AudioWidget::pitchChanged(int layer, int pitch) {
- QLayoutItem * const item = m_layout->itemAt(layer);
- dynamic_cast(item->widget())->setPitch(pitch);
+
+ m_layerUpdate[layer].pitch = pitch;
+ m_layerUpdate[layer].updated = true;
}
void AudioWidget::playbackChanged(int layer, Status status)
{
- QLayoutItem * const item = m_layout->itemAt(layer);
- dynamic_cast(item->widget())->setPlaybackStatus(status);
+ m_layerUpdate[layer].status = status;
+ m_layerUpdate[layer].updated = true;
}
void AudioWidget::cursorChanged(int layer, float cursor)
{
- QLayoutItem * const item = m_layout->itemAt(layer);
- AudioLayerWidget *alw = dynamic_cast(item->widget());
- alw->refreshCurrentTime(cursor);
+ m_layerUpdate[layer].cursor = floor(cursor * 1000) / 1000;
+ m_layerUpdate[layer].updated = true;
+}
+
+void AudioWidget::refreshUi()
+{
+ for (int i = 0; i < MAX_LAYERS; i++)
+ {
+ if (m_layerUpdate[i].updated) {
+ QLayoutItem * const item = m_layout->itemAt(i);
+ AudioLayerWidget *alw = dynamic_cast(item->widget());
+ if (m_layerUpdate[i].vol > -1) {
+ alw->setVol(m_layerUpdate[i].vol);
+ m_layerUpdate[i].vol = -1;
+ }
+ if (m_layerUpdate[i].cursor > -1) {
+ alw->setCurrentTime(m_layerUpdate[i].cursor);
+ m_layerUpdate[i].cursor = -1;
+ }
+ if (m_layerUpdate[i].pan > -1) {
+ alw->setPan(m_layerUpdate[i].pan);
+ m_layerUpdate[i].pan = -1;
+ }
+ if (m_layerUpdate[i].pitch > -1) {
+ alw->setPitch(m_layerUpdate[i].pitch);
+ m_layerUpdate[i].pitch = -1;
+ }
+ if (m_layerUpdate[i].status != Status::Iddle) {
+ alw->setPlaybackStatus(m_layerUpdate[i].status);
+ m_layerUpdate[i].status = Status::Iddle;
+ }
+ if (m_layerUpdate[i].duration > -1) {
+ alw->setMediaFile(m_layerUpdate[i].media);
+ alw->setDuration(m_layerUpdate[i].duration);
+ m_layerUpdate[i].duration = -1;
+ }
+ m_layerUpdate[i].updated = false;
+ }
+ }
}
diff --git a/src/audiowidget.h b/src/audiowidget.h
index a293a0a..dd9b1f1 100644
--- a/src/audiowidget.h
+++ b/src/audiowidget.h
@@ -5,7 +5,6 @@
#include "audiolayerwidget.h"
#include "settings.h"
-#include "miniaudioengine.h"
#include "defines.h" // MAX_LAYERS
class AudioWidget : public QWidget
@@ -14,14 +13,22 @@ class AudioWidget : public QWidget
public:
AudioWidget(QWidget *parent = nullptr);
- void mediaLoaded(int layer, QString media, float duration);
+
+private:
+ QHBoxLayout *m_layout;
+ layerData m_layerUpdate[MAX_LAYERS];
+ QTimer *m_refreshUi;
+
+public slots:
void volChanged(int layer, float vol);
void panChanged(int layer, int pan);
void pitchChanged(int layer, int pitch);
- void playbackChanged(int layer, Status status);
void cursorChanged(int layer, float cursor);
- QHBoxLayout *m_layout;
+ void mediaLoaded(int layer, QString media, float duration);
+ void playbackChanged(int layer, Status status);
+private slots:
+ void refreshUi();
signals:
void uiPlaybackChanged(int layer, Status s);
void uiSliderChanged(int layer, Slider s, int vol);
diff --git a/src/defines.h b/src/defines.h
index f8a2312..6552d19 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -6,9 +6,10 @@
#define LICENSE "GPL 3 Licensed. See LICENSE.txt."
#define DEFAULT_FILE "lms-audio.xlm"
#define MAX_LAYERS 4
-#define UI_REFRESH_TIME 93
+#define MAX_AUDIODEVICES 8
+#define UI_REFRESH_TIME 77
+#define FADE_TIME 25 // DMX Frame time, 40 fps, avoid clicks
-// struct where save the DMX settings for each layer
struct dmxSetting {
int address;
unsigned int universe;
@@ -41,5 +42,15 @@ enum Slider
Pitch,
};
+#include
+struct layerData {
+ QString media;
+ Status status;
+ bool updated;
+ float vol;
+ float cursor;
+ int pan;
+ int pitch;
+ float duration;
+};
#endif // DEFINES_H
-
diff --git a/src/dmxPersonality.h b/src/dmxPersonality.h
index c56829e..82f9468 100644
--- a/src/dmxPersonality.h
+++ b/src/dmxPersonality.h
@@ -10,7 +10,6 @@
#define ENTRY_POINT_COARSE 5
#define ENTRY_POINT_FINE 4
#define PITCH 7
-
#define LAYER_CHANNELS 9
#endif // DMXPERSONALITY_H
diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp
index 2d92918..b769679 100644
--- a/src/libremediaserver-audio-gui.cpp
+++ b/src/libremediaserver-audio-gui.cpp
@@ -38,7 +38,7 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent)
this->setContentsMargins(5, 5, 5, 5);
this->setStyleSheet(
"color: white;"
- "background-color: gray;"
+ "background-color: #4f4048;"
"selection-color: blue;"
"selection-background-color: green"
);
diff --git a/src/libremediaserver-audio.cpp b/src/libremediaserver-audio.cpp
index 589c190..cb18dc2 100644
--- a/src/libremediaserver-audio.cpp
+++ b/src/libremediaserver-audio.cpp
@@ -21,11 +21,11 @@
#include "libremediaserver-audio.h"
-libreMediaServerAudio::libreMediaServerAudio(bool gui)
+libreMediaServerAudio::libreMediaServerAudio()
{
- m_ui = gui;
- Settings *set = Settings::getInstance();
- set->readFile();
+ m_settings = Settings::getInstance();
+ m_settings->readFile();
+ m_ui = m_settings->getShowUi();
m_mediaLibrary = new MediaLibrary;
m_mediaLibrary->initMediaLibrary();
for (int i = 0; i < MAX_LAYERS; i++) {
@@ -38,12 +38,11 @@ libreMediaServerAudio::libreMediaServerAudio(bool gui)
m_updateUi[i][3] = -1;
#endif
}
- m_ola = new olaThread(this, set->getLayersNumber());
+ m_ola = new olaThread(this, m_settings->getLayersNumber());
Q_CHECK_PTR(m_ola);
m_ola->blockSignals(true);
- connect(m_ola, SIGNAL(dmxOutput(int, int, int)), this, SLOT(dmxInput(int, int, int)));
m_ola->registerUniverse();
- m_mae.startEngine(set->getAudioDeviceId());
+ m_mae.startEngine(m_settings->getAudioDeviceId());
qDebug("Core init Complete. Start reading DMX.");
m_ola->blockSignals(false);
#ifdef NOGUI
@@ -57,27 +56,29 @@ libreMediaServerAudio::~libreMediaServerAudio()
m_mae.stopEngine();
}
+void libreMediaServerAudio::loadMedia(int layer, int folder, int file)
+{
+ QString mediaFile = m_mediaLibrary->requestNewFile(folder, file);
+ if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
+ return;
+ if (QFile::exists(mediaFile)){
+ m_mae.loadMedia(layer, mediaFile.toLatin1().data());
+ m_currentMedia[layer] = mediaFile;
+#ifndef NOGUI
+ if (m_ui)
+ m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));
+#endif
+ m_mae.printFormatInfo(layer);
+ }
+}
+
void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
{
if (layer >= MAX_LAYERS || channel >= LAYER_CHANNELS)
return;
QString mediaFile = NULL;
int aux;
- if (channel == DMX_FOLDER || channel == DMX_FILE){
- int folder = (value >> 8) & 0x000000FF;
- int file = value & 0x000000FF;
- mediaFile = m_mediaLibrary->requestNewFile(folder, file);
- if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
- return;
- if (QFile::exists(mediaFile)){
- m_mae.loadMedia(layer, mediaFile.toLatin1().data());
- m_currentMedia[layer] = mediaFile;
-#ifndef NOGUI
- if (m_ui)
- m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));
-#endif
- }
- } else if (channel == VOLUME_COARSE || channel == VOLUME_FINE) {
+ if (channel == VOLUME_COARSE || channel == VOLUME_FINE) {
float tmp = value / 65025.0f;
m_mae.volChanged(layer, tmp);
m_updateUi[layer][0] = tmp * 100.0f;
@@ -104,15 +105,17 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
m_mae.playbackChanged(layer, s);
m_currentStatus[layer] = s;
#ifndef NOGUI
- if (m_ui) m_lmsUi->m_aw->playbackChanged(layer, s);
+ if (m_ui) {
+ m_lmsUi->m_aw->playbackChanged(layer, s);
+ m_lmsUi->m_aw->cursorChanged(layer, m_mae.getCursor(layer));
+ }
#endif
}
}
-
#ifndef NOGUI
void libreMediaServerAudio::refreshUi() {
if (!m_ui) return;
- for (int i= 0; i < Settings::getInstance()->getLayersNumber(); i++ ) {
+ for (int i= 0; i < m_settings->getLayersNumber(); i++ ) {
if (m_updateUi[i][0] >= 0) {
m_lmsUi->m_aw->volChanged(i, m_updateUi[i][0]);
m_updateUi[i][0] = -1;
@@ -125,7 +128,9 @@ void libreMediaServerAudio::refreshUi() {
m_lmsUi->m_aw->pitchChanged(i, m_updateUi[i][2]);
m_updateUi[i][2] = -1;
}
- if (m_updateUi[i][3] >= 0) {
+ if (m_updateUi[i][3] >= 0 \
+ || m_currentStatus[i] == Status::PlayingOnce\
+ || m_currentStatus[i] == Status::PlayingLoop) {
m_lmsUi->m_aw->cursorChanged(i, m_mae.getCursor(i));
m_updateUi[i][3] = -1;
}
@@ -135,6 +140,7 @@ void libreMediaServerAudio::refreshUi() {
void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi)
{
m_lmsUi = lmsUi;
+ m_ui = true;
connect(m_ola, SIGNAL(universeReceived(int)), m_lmsUi->m_dmxWidget, SLOT(updateWatchDMX(int)));
connect(m_lmsUi->m_aw, SIGNAL(uiSliderChanged(int, Slider, int)), this, SLOT(uiSliderChanged(int, Slider, int)));
connect(m_lmsUi->m_aw, SIGNAL(uiPlaybackChanged(int, Status)), this, SLOT(uiPlaybackChanged(int, Status)));
@@ -145,6 +151,7 @@ void libreMediaServerAudio::setUi(libreMediaServerAudioUi *lmsUi)
m_ola->start(QThread::TimeCriticalPriority );
};
+// From Ui widgets
void libreMediaServerAudio::uiSliderChanged(int layer, Slider s, int value)
{
switch (s){
@@ -166,8 +173,12 @@ void libreMediaServerAudio::uiPlaybackChanged(int layer, Status s)
m_currentStatus[layer] = s;
}
-void libreMediaServerAudio::uiLoadMedia(int layer, QString s)
+void libreMediaServerAudio::uiLoadMedia(int layer, QString mediaFile)
{
- m_mae.loadMedia(layer, s.toLatin1().data());
+ if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
+ return;
+ m_mae.loadMedia(layer, mediaFile.toLatin1().data());
+ m_currentMedia[layer] = mediaFile;
+ m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));
}
#endif
diff --git a/src/libremediaserver-audio.h b/src/libremediaserver-audio.h
index 665f3e2..1af37df 100644
--- a/src/libremediaserver-audio.h
+++ b/src/libremediaserver-audio.h
@@ -21,6 +21,7 @@
#define LIBREMEDIASERVERAUDIO_H
#include "medialibrary.h"
+#include "miniaudioengine.h"
#include "olathread.h"
#include "settings.h"
#include "defines.h"
@@ -33,33 +34,35 @@ class libreMediaServerAudio : public QObject
Q_OBJECT
public:
- libreMediaServerAudio(bool gui = false);
+ libreMediaServerAudio();
virtual ~libreMediaServerAudio();
void dmxInput(int layer, int channel, int value);
+ void loadMedia(int layer, int folder, int file);
#ifndef NOGUI
void setUi(libreMediaServerAudioUi *lmsUi);
+ bool inline getShowUi() { return m_settings->getShowUi(); }
#endif
- //static void NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer);
+
private:
olaThread *m_ola;
MediaLibrary *m_mediaLibrary;
MiniAudioEngine m_mae;
+ Settings *m_settings;
QString m_currentMedia[MAX_LAYERS];
Status m_currentStatus[MAX_LAYERS];
- static QList m_dmxSettings;
-#ifndef NOGUI
+ QList m_dmxSettings;
bool m_ui;
+#ifndef NOGUI
QTimer *m_refreshUi;
libreMediaServerAudioUi *m_lmsUi;
float m_updateUi[MAX_LAYERS][4];
-#endif
private slots:
-#ifndef NOGUI
void refreshUi();
void uiSliderChanged(int layer, Slider s, int value);
void uiPlaybackChanged(int layer, Status s);
void uiLoadMedia(int layer, QString s);
+
#endif
};
diff --git a/src/main.cpp b/src/main.cpp
index eea3c29..79b7a91 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -32,9 +32,9 @@ bool hasUi(int &argc, char *argv[])
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- libreMediaServerAudio lms(hasUi(argc, argv));
+ libreMediaServerAudio lms;
#ifndef NOGUI
- if (hasUi(argc, argv))
+ if (hasUi(argc, argv) || lms.getShowUi())
{
libreMediaServerAudioUi *lmsUi = new libreMediaServerAudioUi();
lms.setUi(lmsUi);
diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp
index f65744d..c2d9a6d 100644
--- a/src/miniaudioengine.cpp
+++ b/src/miniaudioengine.cpp
@@ -4,6 +4,11 @@ MiniAudioEngine::MiniAudioEngine()
{
for (int i =0; i < MAX_LAYERS; i++) {
m_mediaLoaded[i] = false;
+ m_currentLayerValues[i].status = Status::Iddle;
+ m_currentLayerValues[i].pan = 128;
+ m_currentLayerValues[i].pitch = 128;
+ m_currentLayerValues[i].vol = 0;
+ m_currentLayerValues[i].cursor = 0;
}
}
@@ -79,8 +84,8 @@ ma_result MiniAudioEngine::startContext()
resourceManagerConfig = ma_resource_manager_config_init();
resourceManagerConfig.decodedFormat = ma_format_f32; /* ma_format_f32 should almost always be used as that's what the engine (and most everything else) uses for mixing. */
resourceManagerConfig.decodedChannels = 0;
- resourceManagerConfig.decodedSampleRate = 0;
- resourceManagerConfig.jobThreadCount = 0;
+ resourceManagerConfig.decodedSampleRate = ma_standard_sample_rate_48000;
+ resourceManagerConfig.jobThreadCount = 1;
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio resource manager.");
@@ -114,11 +119,9 @@ ma_result MiniAudioEngine::getAllAudioDevices()
ma_result MiniAudioEngine::loadMedia(int layer, char *file)
{
ma_result result;
- float vol = -1;
if (m_mediaLoaded[layer] == true)
{
- vol = ma_sound_get_volume(&m_currentSound[layer]);
ma_sound_uninit(&m_currentSound[layer]);
m_mediaLoaded[layer] = false;
}
@@ -133,10 +136,8 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file)
qWarning("Failed to load file %s", file);
else {
m_mediaLoaded[layer] = true;
- if (vol == -1)
- this->volChanged(layer, 0);
- else
- this->volChanged(layer, vol);
+ this->refreshValues(layer);
+ m_currentLayerValues[layer].media = file;
}
return result;
}
@@ -191,7 +192,7 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
qWarning("Failed to get data format %i\n", layer);
return MA_INVALID_DATA;
}
- qInfo("samples/sec: %u format: %u channels: %u", sampleRate, format, channels);
+ qInfo() << "name:" << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels;
return result;
}
@@ -200,9 +201,10 @@ void MiniAudioEngine::volChanged(int layer, float vol)
{
if (m_mediaLoaded[layer] == false)
return;
- if (vol > 1)
- vol = 1;
- ma_sound_group_set_volume(&m_currentSound[layer], vol);
+ if (vol >= 1)
+ vol = 0.99f;
+ ma_sound_group_set_fade_in_milliseconds(&m_currentSound[layer], -1, vol, FADE_TIME);
+ m_currentLayerValues[layer].vol = vol;
}
void MiniAudioEngine::panChanged(int layer, float value)
@@ -213,6 +215,7 @@ void MiniAudioEngine::panChanged(int layer, float value)
return;
result = (value / 128.0) - 1.0;
ma_sound_group_set_pan(&m_currentSound[layer], result);
+ m_currentLayerValues[layer].pan = value;
}
void MiniAudioEngine::pitchChanged(int layer, float value)
@@ -223,6 +226,7 @@ void MiniAudioEngine::pitchChanged(int layer, float value)
return;
result = value / 128.0;
ma_sound_group_set_pitch(&m_currentSound[layer], result);
+ m_currentLayerValues[layer].pitch = value;
}
void MiniAudioEngine::playbackChanged(int layer, Status status)
@@ -235,7 +239,7 @@ void MiniAudioEngine::playbackChanged(int layer, Status status)
break;
case Status::Stopped:
ma_sound_stop(&m_currentSound[layer]);
- ma_sound_seek_to_pcm_frame(&m_currentSound[layer], 0);
+ this->setCursor(layer, m_currentLayerValues[layer].cursor);
break;
case Status::PlayingLoop:
ma_sound_set_looping(&m_currentSound[layer], true);
@@ -248,30 +252,35 @@ void MiniAudioEngine::playbackChanged(int layer, Status status)
default:
break;
}
+ m_currentLayerValues[layer].status = status;
}
void MiniAudioEngine::setCursor(int layer, int cursor)
{
- ma_uint64 f;
+ ma_uint64 end;
+ m_currentLayerValues[layer].cursor = cursor;
if (m_mediaLoaded[layer] == false)
return;
- ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &f);
- f = (cursor * f) / 65025;
- ma_sound_seek_to_pcm_frame(&m_currentSound[layer], f);
- // ToDo: change the loop entry point too
+ ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end);
+ ma_uint64 start = (cursor * end) / 65025;
+ ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start);
+ ma_result result = ma_data_source_set_loop_point_in_pcm_frames(&m_currentSound[layer], start, end);
+ if (result != MA_SUCCESS) {
+ return; // Failed to set the loop point.
+ }
}
Status MiniAudioEngine::getStatus(int layer)
{
- if (m_mediaLoaded[layer] == false)
- return Status::Iddle;
- if (ma_sound_is_playing(&m_currentSound[layer])) {
- if (ma_sound_is_looping(&m_currentSound[layer]))
- return Status::PlayingLoop;
- return Status::PlayingOnce;
- }
- if (this->getDuration(layer) > 0)
- return Status::Paused;
- return Status::Stopped;
+ return m_currentLayerValues[layer].status;
+}
+
+void MiniAudioEngine::refreshValues(int layer)
+{
+ this->panChanged(layer, m_currentLayerValues[layer].pan);
+ this->volChanged(layer, m_currentLayerValues[layer].vol);
+ this->pitchChanged(layer, m_currentLayerValues[layer].pitch);
+ this->playbackChanged(layer, m_currentLayerValues[layer].status);
+ this->setCursor(layer, m_currentLayerValues[layer].cursor);
}
diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h
index 169d33b..2c3ec5a 100644
--- a/src/miniaudioengine.h
+++ b/src/miniaudioengine.h
@@ -40,10 +40,12 @@ private:
ma_context context;
ma_sound m_currentSound[MAX_LAYERS];
ma_bool8 m_mediaLoaded[MAX_LAYERS];
+ layerData m_currentLayerValues[MAX_LAYERS];
ma_result getAllAudioDevices();
ma_result startDevice(int id);
ma_result startContext();
+ void refreshValues(int layer);
};
#endif // MINIAUDIOENGINE_H
diff --git a/src/olathread.cpp b/src/olathread.cpp
index 409cf79..6ca9325 100644
--- a/src/olathread.cpp
+++ b/src/olathread.cpp
@@ -1,5 +1,4 @@
#include "libremediaserver-audio.h"
-//#include "olathread.h"
olaThread::olaThread(QObject *parent, int layers) :
m_counter(0)
@@ -36,7 +35,6 @@ void olaThread::init()
}
m_client = m_clientWrapper->GetClient();
m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx));
- //m_client->SetDMXCallback(ola::NewCallback((libreMediaServerAudio *)this->parent(), libreMediaServerAudio::NewDmx));
m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss));
m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed));
m_dmxSettings = Settings::getInstance()->getDmxSettings();
@@ -69,30 +67,31 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data,
bool volSent = false;
bool entrySent = false;
bool fileSent = false;
+ int aux;
for (int j = 0; j < LAYER_CHANNELS; j++){
int value = buffer.Get((i.address) + j);
if (m_dmx[i.layer][j] != value) {
m_dmx[i.layer][j] = value;
switch (j) {
case DMX_FOLDER:
- value *= 0x100;
- value += buffer.Get(i.address + DMX_FILE);
- qobject_cast(parent())->dmxInput(i.layer, j, value);
- m_dmx[i.layer][DMX_FILE] = buffer.Get(i.address + DMX_FILE);
+ aux = buffer.Get(i.address + DMX_FILE);
+ qobject_cast(parent())->loadMedia(i.layer, value, aux);
+ m_dmx[i.layer][DMX_FILE] = aux;
fileSent = true;
break;
case DMX_FILE:
if (fileSent)
break;
- value += buffer.Get(i.address + DMX_FOLDER) * 0x100;
- qobject_cast(parent())->dmxInput(i.layer, j, value);
- m_dmx[i.layer][DMX_FOLDER] = buffer.Get(i.address + DMX_FOLDER);
+ aux = buffer.Get(i.address + DMX_FOLDER);
+ qobject_cast(parent())->loadMedia(i.layer, aux, value);
+ m_dmx[i.layer][DMX_FOLDER] = aux;
fileSent = true;
break;
case VOLUME_FINE:
- value = (buffer.Get(i.address + VOLUME_COARSE) * 0x100) + value;
+ aux = buffer.Get(i.address + VOLUME_COARSE);
+ value += (aux * 0x100);
qobject_cast(parent())->dmxInput(i.layer, j, value);
- m_dmx[i.layer][VOLUME_COARSE] = buffer.Get(i.address + VOLUME_COARSE);
+ m_dmx[i.layer][VOLUME_COARSE] = aux;
volSent = true;
break;
case VOLUME_COARSE:
@@ -103,6 +102,9 @@ void olaThread::NewDmx(const ola::client::DMXMetadata &data,
m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE);
volSent = true;
break;
+ case PLAYBACK:
+ qobject_cast(parent())->dmxInput(i.layer, j, value);
+ break;
case ENTRY_POINT_FINE:
value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value;
qobject_cast(parent())->dmxInput(i.layer, j, value);
diff --git a/src/settings.cpp b/src/settings.cpp
index f664bb0..9e00914 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -15,6 +15,7 @@ Settings::Settings(QObject *parent) :
QObject(parent)
{
m_layersNumber = 0;
+ m_ui = false;
}
// Read the dmx settings for dmx.xml At the moment we need:
@@ -23,6 +24,7 @@ Settings::Settings(QObject *parent) :
// - The first DMX channel of each source/layer
// - The universe to bind in OLA
// - Audio device id
+// - Show the Ui or not
void Settings::readFromFile(QString file) {
QFile* xmlFile = new QFile(file);
if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -34,53 +36,56 @@ void Settings::readFromFile(QString file) {
exit(1);
}
QXmlStreamReader* xmlReader = new QXmlStreamReader(xmlFile);
- int counter = 0;
- //Parse the XML until we reach end of it
- while(!xmlReader->atEnd() && !xmlReader->hasError() && counter < MAX_LAYERS) {
- // Read next element
+ while(!xmlReader->atEnd() && !xmlReader->hasError()) {
QXmlStreamReader::TokenType token = xmlReader->readNext();
- //If token is just StartDocument - go to next
if(token == QXmlStreamReader::StartDocument) {
continue;
}
- //If token is StartElement - read it
if(token == QXmlStreamReader::StartElement) {
- if(xmlReader->name() == "dmxSettings") {
- int version = xmlReader->attributes().value("fileVersion").toLocal8Bit().toInt();
- if(version == 1) {
- m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt();
- m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit();
- continue;
- }
- }
- if(xmlReader->name() == "audioDevice") {
- m_audioDeviceId = xmlReader->attributes().value("id").toLocal8Bit().toInt();
+ if(xmlReader->name() == "lmsAudio") {
+ m_ui = xmlReader->attributes().value("ui").toLocal8Bit().toInt();
+ m_layersNumber = xmlReader->attributes().value("layersNumber").toLocal8Bit().toInt();
+ m_pathmedia = xmlReader->attributes().value("path").toLocal8Bit();
continue;
}
- QString add = "layer";
- add.append(QString("%1").arg(counter));
- if((xmlReader->name() == add)) {
+ if(xmlReader->name() == "audioDevice") {
+ m_audioDeviceQty = xmlReader->attributes().value("devicesNumber").toLocal8Bit().toInt();
+ for (uint i = 0; i < m_audioDeviceQty; i++)
+ {
+ m_audioDeviceId[i] = xmlReader->attributes().value(QString("id%1").arg(i)).toLocal8Bit().toInt();
+ }
+
+ }
+ if(xmlReader->name() == "layer") {
dmxSetting temp;
temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1;
temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt();
- temp.layer = counter;
+ temp.layer = xmlReader->attributes().value("id").toLocal8Bit().toInt();
m_settings.append(temp);
if (!m_universe.contains(temp.universe)) {
m_universe.insert(temp.universe);
}
- counter++;
}
}
}
if(xmlReader->hasError()) {
QMessageBox::critical(NULL,"File xml Parse Error ", xmlReader->errorString(), QMessageBox::Ok);
qWarning("File xml Parse Error %s", xmlReader->errorString().toLatin1().constData());
- return;
+ // ToDo: manage this, open a dialog to load a new file.
}
xmlReader->clear();
xmlFile->close();
delete xmlReader;
delete xmlFile;
+ this->printSettings();
+}
+
+void Settings::printSettings() {
+ qInfo() << "Settings read;\nShow Ui:" << m_ui << "Layers:" << m_layersNumber << "Path:" << m_pathmedia <<"Audio Device qty:" << m_audioDeviceQty;
+ for (uint i = 0; i < m_audioDeviceQty; i++)
+ qInfo() << "Audio device id:" << m_audioDeviceId[i];
+ for (int i = 0; i < m_layersNumber; i++)
+ qInfo() << "Layer:" << m_settings[i].layer << "Address:" << m_settings[i].address << "Universe:" << m_settings[i].universe;
}
void Settings::readFile() {
diff --git a/src/settings.h b/src/settings.h
index 8cd55bb..f27da6a 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include "medialibrary.h"
#include "audiowidget.h"
@@ -15,25 +16,27 @@ class Settings : public QObject
Q_OBJECT
public:
+ Settings(QObject *parent = 0);
static Settings *getInstance();
inline QSet getUniverses() { return m_universe; }
inline QString getPathMedia() { return m_pathmedia; }
inline QList getDmxSettings() { return m_settings; }
inline int getLayersNumber() { return m_layersNumber; }
+ inline int getAudioDeviceId() { return m_audioDeviceId[0]; }
+ inline bool getShowUi() { return m_ui; }
void readFile();
- inline int getAudioDeviceId() { return m_audioDeviceId; }
+ void readFromFile(QString file);
+ void printSettings();
private:
static Settings *_instance;
QList m_settings;
QString m_pathmedia;
- uint m_audioDeviceId;
+ uint m_audioDeviceId[MAX_AUDIODEVICES];
+ uint m_audioDeviceQty;
QSet m_universe;
int m_layersNumber;
-
- explicit Settings(QObject *parent = 0);
- void readFromFile(QString file);
-
+ bool m_ui;
};
#endif // SETTINGS_H
diff --git a/src/slidergroup.cpp b/src/slidergroup.cpp
index a488560..9ef9680 100644
--- a/src/slidergroup.cpp
+++ b/src/slidergroup.cpp
@@ -18,10 +18,11 @@ SliderGroup::SliderGroup(QString name,
slider->setMinimumHeight(0);
slider->setSingleStep(1);
slider->setRange(min, max);
+ slider->setValue(0);
slider->setMinimumWidth(50);
slider->setToolTip(name);
slider->setStyleSheet("QSlider {"
- "border: 2px solid #685060;"
+ "border: 1px solid #5a4855;"
"margin: 0px;"
"height: 200px;"
"width: 50px;}"
@@ -32,17 +33,20 @@ SliderGroup::SliderGroup(QString name,
valueBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
valueBox->setMinimumWidth(50);
valueBox->setRange(min, max);
+ valueBox->setValue(0);
valueBox->setDecimals(decimals);
valueBox->setObjectName(name);
valueBox->setToolTip(name);
valueBox->setAlignment(Qt::AlignHCenter);
valueBox->setContentsMargins(0, 0, 0, 0);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
+ //connect(slider, SIGNAL(mousePressEvent(QMouseEvent)), this, SLOT(mousePressEvent(QMouseEvent *)));
layout->addWidget(slider);
layout->addWidget(valueBox);
- this->setStyleSheet("border: 2px solid #685060;"
+ this->setStyleSheet("border: 1px solid #5a4855;"
"width: 50px;"
"margin: 0px;"
+ "background-color: #383034;"
);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
@@ -67,3 +71,11 @@ void SliderGroup::setValue(float value)
slider->blockSignals(false);
valueBox->blockSignals(false);
}
+
+void SliderGroup::mousePressEvent(QMouseEvent* event) {
+ Q_UNUSED(event);
+ if (slider->isEnabled())
+ slider->setDisabled(true);
+ else
+ slider->setDisabled(false);
+}
diff --git a/src/slidergroup.h b/src/slidergroup.h
index f597a5b..5bfeeb8 100644
--- a/src/slidergroup.h
+++ b/src/slidergroup.h
@@ -27,6 +27,8 @@ public slots:
private:
QSlider *slider;
QDoubleSpinBox *valueBox;
+
+ void mousePressEvent(QMouseEvent* event);
};
#endif