diff --git a/src/audiolayerwidget.cpp b/src/audiolayerwidget.cpp index 42c4838..0e9527b 100644 --- a/src/audiolayerwidget.cpp +++ b/src/audiolayerwidget.cpp @@ -13,21 +13,33 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): QVBoxLayout *layout = new QVBoxLayout; m_folderValue = new ClickableLabel; - m_folderValue->setMaximumWidth(300); m_folderValue->setAlignment(Qt::AlignLeft); + m_folderValue->setFocusPolicy(Qt::NoFocus); + m_folderValue->setMinimumWidth(MIN_WIDTH); + m_folderValue->setMaximumWidth(MAX_WIDTH); + m_folderValue->setContentsMargins(3,1,3,1); + m_folderValue->setText("Click to open media file (mp3, wav, flac)"); m_folderValue->setStyleSheet( + "margin: 0px;" "color: white;" "background-color: black;" + "font-size: 12px;" ); layout->addWidget(m_folderValue); m_fileValue = new ClickableLabel; + m_fileValue->setAlignment(Qt::AlignLeft); + m_fileValue->setFocusPolicy(Qt::NoFocus); + m_fileValue->setMinimumWidth(MIN_WIDTH); + m_fileValue->setMaximumWidth(MAX_WIDTH); + m_fileValue->setContentsMargins(3,1,3,1); + m_fileValue->setText("++ empty ++"); connect(m_fileValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); connect(m_folderValue, SIGNAL(clicked()), this, SLOT(openMediaDialog())); - m_fileValue->setMaximumWidth(300); - m_fileValue->setAlignment(Qt::AlignLeft); m_fileValue->setStyleSheet( + "margin: 0px;" "color: white;" "background-color: black;" + "font-size: 14px;" ); layout->addWidget(m_fileValue); @@ -38,9 +50,20 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progress = new QProgressBar(this); m_progress->setOrientation(Qt::Horizontal); + m_progress->setFocusPolicy(Qt::NoFocus); + m_progress->setAlignment(Qt::AlignHCenter); + m_progress->setContentsMargins(0, 1, 0, 1); + m_progress->setMinimumWidth(MIN_WIDTH); + m_progress->setMaximumWidth(MAX_WIDTH); + m_progress->setMaximumHeight(15); m_progress->setRange(0, 0); m_progress->setValue(0); m_progress->setFormat("%v / %m"); + m_progress->setStyleSheet( + "margin: 0px;" + "font-size: 13px;" + "background-color: black;" + ); layout->addWidget(m_progress); m_progressTime = new QTimeEdit; @@ -49,26 +72,30 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_progressTime->setDisplayFormat("mm:ss:zzz"); m_progressTime->setReadOnly(true); m_progressTime->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_progressTime->setMinimumWidth(80); m_progressTime->setFocusPolicy(Qt::NoFocus); m_progressTime->setAlignment(Qt::AlignHCenter); m_progressTime->setContentsMargins(0,0,0,0); + m_progressTime->setMinimumWidth(MIN_WIDTH); + m_progressTime->setMaximumWidth(MAX_WIDTH); m_totalTimeValue = new QTimeEdit; m_totalTimeValue->setObjectName("Track Length"); m_totalTimeValue->setToolTip("Track Length"); m_totalTimeValue->setDisplayFormat("mm:ss:zzz"); m_totalTimeValue->setReadOnly(true); m_totalTimeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); - m_totalTimeValue->setMinimumWidth(80); m_totalTimeValue->setFocusPolicy(Qt::NoFocus); m_totalTimeValue->setAlignment(Qt::AlignHCenter); m_totalTimeValue->setContentsMargins(0,0,0,0); + m_totalTimeValue->setMinimumWidth(MIN_WIDTH); + m_totalTimeValue->setMaximumWidth(MAX_WIDTH); QHBoxLayout *status = new QHBoxLayout; status->addWidget(m_progressTime); status->addWidget(m_totalTimeValue); layout->addLayout(status); m_filterBank = new FilterBankWidget(this); + m_filterBank->setMaximumWidth(MAX_WIDTH); + m_filterBank->setMinimumWidth(MIN_WIDTH); connect(m_filterBank, SIGNAL(setBypass(bool)), this, SLOT(setBypass(bool))); layout->addWidget(m_filterBank); m_pitch = new SliderGroup("Pitch", 0 , 255, 0, NULL); @@ -95,40 +122,45 @@ AudioLayerWidget::AudioLayerWidget(QWidget *parent, int layer): m_level = new QLabel("-inf"); m_level->setStyleSheet("border: 1px solid #CFB0C9;" "margin: 0px;" - "margin-right: 5px;" - "margin-left: 5px;" "background-color: black;" "color: white;" - "width:80px;" "text-align: center;" - ); - m_level->setMinimumWidth(80); - m_level->setMaximumWidth(80); - m_level->setMinimumHeight(20); + "font-size: 15px;"); + m_level->setMinimumWidth(MIN_WIDTH / 2); + m_level->setMaximumWidth(MAX_WIDTH / 3); + m_level->setMinimumHeight(25); m_level->setAlignment(Qt::AlignHCenter); + m_level->setContentsMargins(0, 4, 0, 4); labelsBox->addWidget(m_level); m_bus1Label = new QLabel("dummy"); - m_bus1Label->setMinimumWidth(80); + m_bus1Label->setAlignment(Qt::AlignHCenter); + m_bus1Label->setContentsMargins(0, 6, 0, 6); + m_bus1Label->setMinimumHeight(25); + m_bus1Label->setMinimumWidth(MIN_WIDTH / 4); + m_bus1Label->setMaximumWidth(MAX_WIDTH / 3); m_bus1Label->setStyleSheet("border: 1px solid #CFB0C9;" "margin: 0px;" "background-color: black;" "color: white;" - "font-size: 11px;"); + "font-size: 10px;"); labelsBox->addWidget(m_bus1Label); m_bus2Label = new QLabel("dummy"); - m_bus2Label->setMinimumWidth(80); + m_bus2Label->setAlignment(Qt::AlignHCenter); + m_bus2Label->setMinimumWidth(MIN_WIDTH / 4); + m_bus2Label->setMaximumWidth(MAX_WIDTH / 3); + m_bus2Label->setContentsMargins(0, 6, 0, 6); + m_bus2Label->setMinimumHeight(25); m_bus2Label->setStyleSheet("border: 1px solid #CFB0C9;" "margin: 0px;" "background-color: black;" "color: white;" - "font-size: 11px;"); + "font-size: 10px;"); labelsBox->addWidget(m_bus2Label); labelsBox->setSpacing(0); - labelsBox->setContentsMargins(0, 0, 0, 0); + layout->setContentsMargins(0, 0, 0, 0); layout->addLayout(labelsBox); layout->setAlignment(Qt::AlignHCenter); layout->setSpacing(0); - layout->setContentsMargins(1, 1, 1, 1); this->setLayout(layout); } @@ -230,8 +262,12 @@ void AudioLayerWidget::setMediaFile(QString file) QStringList list = file.split("/"); int size = list.size(); if (size >= 2) { - m_folderValue->setText(list.at(size - 2)); - m_fileValue->setText(list.at(size - 1)); + QString tmp = list.at(size - 2); + tmp.truncate(60); + m_folderValue->setText(tmp); + tmp = list.at(size - 1); + tmp.truncate(40); + m_fileValue->setText(tmp); } } @@ -288,8 +324,9 @@ void AudioLayerWidget::setFilterParam(int channel, int value) void AudioLayerWidget::setLevel(float db) { m_level->blockSignals(true); - if (db > -150) - m_level->setText(QString::number(db)); + if (db > -140) + + m_level->setText(QString::number(db, 'f', 2)); else m_level->setText("-inf"); m_level->blockSignals(false); @@ -297,6 +334,8 @@ void AudioLayerWidget::setLevel(float db) void AudioLayerWidget::setBusName(uint bus, char *name) { + if (name && strlen(name) > 17) + name[16] = '\0'; if (bus == 0) { m_bus1Label->blockSignals(true); m_bus1Label->setText(name); diff --git a/src/audiowidget.cpp b/src/audiowidget.cpp index 8d43127..ec96a9e 100644 --- a/src/audiowidget.cpp +++ b/src/audiowidget.cpp @@ -23,8 +23,9 @@ AudioWidget::AudioWidget(QWidget *parent) : for (int j = 0; j < FILTER_CHANNELS; j++) m_filtersUpdate[i][j] = -1; } - m_layout->setSpacing(2); - m_layout->setContentsMargins(2, 2, 2, 2); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + this->setStyleSheet("margin: 2px;"); setLayout(m_layout); m_refreshUi = new QTimer(this); connect(m_refreshUi, SIGNAL(timeout()), this, SLOT(refreshUi())); diff --git a/src/clickabledoublespinbox.cpp b/src/clickabledoublespinbox.cpp index b2b9c3a..76feb8b 100644 --- a/src/clickabledoublespinbox.cpp +++ b/src/clickabledoublespinbox.cpp @@ -11,11 +11,7 @@ ClickableDoubleSpinBox::ClickableDoubleSpinBox(QWidget *parent) setDecimals(1); setAlignment(Qt::AlignHCenter); setContentsMargins(0, 0, 0, 0); - setMaximumWidth(50); - this->setStyleSheet("border: 0px solid #5a4855;" - "width: 50px;" - "margin: 0px;" - "background-color: #383034;" - ); + setMaximumWidth(66); + setMinimumWidth(25); } diff --git a/src/defines.h b/src/defines.h index e19ecf7..e9d4bf2 100644 --- a/src/defines.h +++ b/src/defines.h @@ -11,8 +11,10 @@ #define CHANNELS 2 #define SAMPLE_RATE 48000 #define UI_REFRESH_TIME 123 -#define FADE_TIME 20 +#define FADE_TIME 25 #define FILTER_CHANNELS 16 // number of dmx channels dedicated to filters by layer +#define MAX_WIDTH 500 +#define MIN_WIDTH 50 struct dmxSetting { int address; diff --git a/src/filterbankwidget.cpp b/src/filterbankwidget.cpp index 4742af2..098e591 100644 --- a/src/filterbankwidget.cpp +++ b/src/filterbankwidget.cpp @@ -2,20 +2,22 @@ #include #include "dmxPersonality.h" +#include "defines.h" + +#define BORDER "#CFB0C9;" +#define BACK "#281024;" FilterBankWidget::FilterBankWidget(QWidget *parent) : QWidget{parent} { QHBoxLayout *layout = new QHBoxLayout; layout->setAlignment(Qt::AlignHCenter); - layout->setContentsMargins(0, 2, 0, 2); layout->setSpacing(0); - this->setStyleSheet("border: 2px solid #5a4855;" + layout->setContentsMargins(0, 0, 0, 0); + this->setStyleSheet("border: 1px solid #CFB0C9;" "margin: 0px;" - "margin-top: 3px;" - "margin-bottom: 3px;" - "background-color: #383034;" - ); + "background-color: #080402;" + "font-size: 13px;"); for (int i = 0; i < 13; i++) { fb[i] = new ClickableDoubleSpinBox; const char *name = dmxChannelToString(i + 9); @@ -27,10 +29,11 @@ FilterBankWidget::FilterBankWidget(QWidget *parent) m_bypass = new QCheckBox; master->addWidget(m_bypass); m_bypass->setText("Bypass"); - m_bypass->setStyleSheet("QCheckBox { border: 2px solid #2a0825;" + m_bypass->setMinimumWidth(MIN_WIDTH / 4); + m_bypass->setStyleSheet("QCheckBox { border: 1px solid #CFB0C9;" "margin: 0px;" - "background-color: #885074;" - "font-size: 7px;}"); + "background-color: #c82840;" + "font-size: 8px;}"); connect(m_bypass, SIGNAL(stateChanged(int)), this, SLOT(bypassChanged(int))); master->addWidget(fb[0]); layout->addLayout(master); diff --git a/src/libremediaserver-audio-gui.cpp b/src/libremediaserver-audio-gui.cpp index 22f673c..62b4544 100644 --- a/src/libremediaserver-audio-gui.cpp +++ b/src/libremediaserver-audio-gui.cpp @@ -35,10 +35,11 @@ libreMediaServerAudioUi::libreMediaServerAudioUi(QWidget *parent) topWidget->setContentsMargins(0, 0, 0, 0); addDockWidget(Qt::TopDockWidgetArea, topWidget); connect(ui.actionLaunch_OLA_Setup, SIGNAL(triggered()), this, SLOT(olasetup())); - this->setContentsMargins(3, 3, 3, 3); + this->setContentsMargins(0, 0, 0, 0); this->setStyleSheet( + "margin: 0px;" "color: white;" - "background-color: #4f4048;" + "background-color: #3f3038;" "selection-color: blue;" "selection-background-color: green" ); diff --git a/src/libremediaserver-audio-gui.ui b/src/libremediaserver-audio-gui.ui index c0f11ad..ad4c061 100644 --- a/src/libremediaserver-audio-gui.ui +++ b/src/libremediaserver-audio-gui.ui @@ -7,7 +7,7 @@ 0 0 - 500 + 400 400 @@ -32,7 +32,7 @@ 0 0 - 500 + 400 21 diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index d2ebc17..edc5f78 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -1,7 +1,7 @@ #include "miniaudioengine.h" #include "dmxPersonality.h" -#define BIAS 0.99f +#define BIAS 1.0f #define FILTER_ORDER 3 MiniAudioEngine::MiniAudioEngine() {} @@ -52,12 +52,13 @@ bool MiniAudioEngine::startEngine(uint layers, uint* audioDevicesId, uint audioD m_mae.audioDevicesId = audioDevicesId; m_mae.audioDevicesQty = audioDevicesQty; for (uint i =0; i < m_mae.layersQty; i++) { - m_mae.mediaLoaded[i] = false; + m_mae.mediaLoaded[i] = MA_FALSE; m_mae.currentStatus[i].status = Status::Iddle; m_mae.currentStatus[i].pan = 128; m_mae.currentStatus[i].pitch = 128; - m_mae.currentStatus[i].vol = 0; + m_mae.currentStatus[i].vol = 0.0f; m_mae.currentStatus[i].cursor = 0; + m_mae.currentStatus[i].updated = false; } result = this->startContext(); if (result != MA_SUCCESS) return false; @@ -278,7 +279,7 @@ ma_result MiniAudioEngine::startDevices() deviceConfig.dataCallback = audioDataCallback; engineConfig = ma_engine_config_init(); engineConfig.pResourceManager = &m_mae.resourceManager; - //engineConfig.defaultVolumeSmoothTimeInPCMFrames = SAMPLE_RATE / 20; + engineConfig.defaultVolumeSmoothTimeInPCMFrames = SAMPLE_RATE / 500; engineConfig.noAutoStart = MA_TRUE; for (uint internalId = 0; internalId < m_mae.audioDevicesQty; internalId++) { @@ -350,12 +351,12 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) { ma_result result; - if (m_mae.mediaLoaded[layer] == true) + if (m_mae.mediaLoaded[layer] == MA_TRUE) { + m_mae.mediaLoaded[layer] = MA_FALSE; ma_sound_set_volume(&m_mae.sounds[layer], 0.0f); ma_sound_stop(&m_mae.sounds[layer]); ma_sound_uninit(&m_mae.sounds[layer]); - m_mae.mediaLoaded[layer] = false; } ma_sound_config soundConfig = ma_sound_config_init(); soundConfig = ma_sound_config_init(); @@ -370,9 +371,10 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file) cout << "Error" << result << ": Failed to load file " << file << endl; return result; } - m_mae.mediaLoaded[layer] = true; - this->refreshValues(layer); m_mae.currentStatus[layer].media = file; + m_mae.currentStatus[layer].updated = true; + m_mae.mediaLoaded[layer] = MA_TRUE; + this->refreshValues(layer); return result; } @@ -431,7 +433,8 @@ ma_result MiniAudioEngine::printFormatInfo(int layer) // Expects between 0 and 65535 vol value void MiniAudioEngine::volChanged(int layer, int vol) { - if (m_mae.mediaLoaded[layer] == false) + m_mae.currentStatus[layer].vol = vol; + if (m_mae.mediaLoaded[layer] == MA_FALSE && m_mae.currentStatus[layer].updated) return; float db = ((float)vol / 771.0f) - 85.0f; if (db <= -85.0f) { @@ -439,70 +442,72 @@ void MiniAudioEngine::volChanged(int layer, int vol) } else db = ma_volume_db_to_linear(db); ma_sound_set_fade_in_milliseconds(&m_mae.sounds[layer], -1, db, FADE_TIME); - m_mae.currentStatus[layer].vol = vol; } void MiniAudioEngine::panChanged(int layer, float value) { float result; + m_mae.currentStatus[layer].pan = value; if (m_mae.mediaLoaded[layer] == false) return; result = (value / 128.0) - 1.0; ma_sound_group_set_pan(&m_mae.sounds[layer], result); - m_mae.currentStatus[layer].pan = value; } void MiniAudioEngine::pitchChanged(int layer, float value) { float pitch; + m_mae.currentStatus[layer].pitch = value; if (m_mae.mediaLoaded[layer] == false) return; pitch = value / 128.0; ma_sound_group_set_pitch(&m_mae.sounds[layer], pitch); - m_mae.currentStatus[layer].pitch = value; } ma_result MiniAudioEngine::playbackChanged(int layer, Status status) { ma_result result = MA_SUCCESS; - - if (m_mae.mediaLoaded[layer] == false) - return MA_DOES_NOT_EXIST; + float db = 0; bool loop = false; + + m_mae.currentStatus[layer].status = status; + if (m_mae.mediaLoaded[layer] == MA_FALSE) + return MA_DOES_NOT_EXIST; + m_mae.currentStatus[layer].updated = false; switch (status) { case Status::Paused: result = ma_sound_stop_with_fade_in_milliseconds(&m_mae.sounds[layer], FADE_TIME); break; case Status::Stopped: - ma_sound_stop_with_fade_in_milliseconds(&m_mae.sounds[layer], FADE_TIME); + ma_sound_stop_with_fade_in_milliseconds(&m_mae.sounds[layer], 0.0f); result = this->seekToCursor(layer, m_mae.currentStatus[layer].cursor); break; case Status::PlayingLoop: loop = true; - case Status::PlayingOnce: - ma_sound_set_looping(&m_mae.sounds[layer], loop); - if (m_mae.currentStatus[layer].cursor > 0) { - this->setRangePoint(layer, m_mae.currentStatus[layer].cursor); - this->setLoopPoint(layer, m_mae.currentStatus[layer].cursor); + if (m_mae.currentStatus[layer].cursor > 0) { + result = this->seekToCursor(layer, m_mae.currentStatus[layer].cursor); } + case Status::PlayingOnce: case Status::PlayingFolder: case Status::PlayingFolderLoop: case Status::PlayingFolderRandom: + ma_sound_set_looping(&m_mae.sounds[layer], loop); + if (ma_sound_is_playing(&m_mae.sounds[layer])) break; ma_sound_set_stop_time_in_milliseconds(&m_mae.sounds[layer], ~(ma_uint64)0); - float db = (m_mae.currentStatus[layer].vol / 771.0f) - 85.0f; - if (db <= -85.0f) { - db = 0; - } else - db = ma_volume_db_to_linear(db); + db = (m_mae.currentStatus[layer].vol / 771.0f) - 85.0f; + if (db <= -85.0f) db = 0; + else db = ma_volume_db_to_linear(db); result = ma_sound_start(&m_mae.sounds[layer]); - ma_sound_group_set_volume(&m_mae.sounds[layer], 0.0f); - ma_sound_set_fade_in_milliseconds(&m_mae.sounds[layer], 0, db, FADE_TIME); - ma_sound_group_set_volume(&m_mae.sounds[layer], 1.0f); + ma_sound_set_fade_in_milliseconds(&m_mae.sounds[layer], 0.000001f, 0.000000f, FADE_TIME); + if (m_mae.currentStatus[layer].cursor > 0) + usleep(FADE_TIME * 1500); // avoid glitch when load when seeking + ma_sound_set_fade_in_milliseconds(&m_mae.sounds[layer], 0, db, FADE_TIME * 2); + default: + break; } - if (result == MA_SUCCESS) - m_mae.currentStatus[layer].status = status; + m_mae.currentStatus[layer].updated = true; return result; } @@ -719,5 +724,5 @@ bool MiniAudioEngine::setBypass(int audioDevice, int layer, bool bypass) ma_node_set_output_bus_volume(&fb->input, 1, 0.0f); ma_node_set_output_bus_volume(&fb->input, 0, 1.0f); } - + return true; }