Skip to content

Commit 49d4542

Browse files
committed
feat: add UI support for the new compander effect
1 parent 52ff20e commit 49d4542

File tree

11 files changed

+241
-99
lines changed

11 files changed

+241
-99
lines changed

resources/assets/default.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
bass_enable=false
22
bass_maxgain=5
3+
compander_enable=false
4+
compander_granularity=2
5+
compander_timeconstant=0.22
6+
compander_time_freq_transforms=0
7+
compander_response="95.0;200.0;400.0;800.0;1600.0;3400.0;7500.0;0;0;0;0;0;0;0"
38
compression_aggressiveness=800
49
compression_enable=false
510
compression_maxatk=30

src/MainWindow.cpp

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ MainWindow::MainWindow(bool statupInTray,
155155
onConvolverInfoChanged(ciArgs);
156156
connect(_audioService, &IAudioService::convolverInfoChanged, this, &MainWindow::onConvolverInfoChanged);
157157

158-
_eelEditor->attachHost(_audioService);
159-
connect(_eelEditor, &EELEditor::executionRequested, [this](QString path){
158+
_eelEditor->attachHost(_audioService);
159+
connect(_eelEditor, &EELEditor::executionRequested, [this](QString path){
160160
if (QFileInfo::exists(path) && QFileInfo(path).isFile())
161161
{
162162
ui->liveprog->setCurrentLiveprog(path);
@@ -319,6 +319,7 @@ MainWindow::MainWindow(bool statupInTray,
319319
{
320320
_styleHelper->SetStyle();
321321
ui->eq_widget->setAccentColor(palette().highlight().color());
322+
ui->comp_response->setAccentColor(palette().highlight().color());
322323
}
323324

324325
// Extract default EEL files if missing
@@ -379,6 +380,7 @@ MainWindow::MainWindow(bool statupInTray,
379380
ui->tabhost->setStyleSheet(QString("QWidget#tabHostPage1,QWidget#tabHostPage2,QWidget#tabHostPage3,QWidget#tabHostPage4,QWidget#tabHostPage5,QWidget#tabHostPage6,QWidget#tabHostPage7{background-color: %1;}").arg(qApp->palette().window().color().lighter().name()));
380381
ui->tabbar->redrawTabBar();
381382
ui->eq_widget->setAccentColor(palette().highlight().color());
383+
ui->comp_response->setAccentColor(palette().highlight().color());
382384
});
383385

384386
connect(&AppConfig::instance(), &AppConfig::updated, this, &MainWindow::onAppConfigUpdated);
@@ -388,6 +390,7 @@ MainWindow::MainWindow(bool statupInTray,
388390
{
389391
restoreGraphicEQView();
390392
ui->eq_widget->setAlwaysDrawHandles(AppConfig::instance().get<bool>(AppConfig::EqualizerShowHandles));
393+
ui->comp_response->setAlwaysDrawHandles(AppConfig::instance().get<bool>(AppConfig::EqualizerShowHandles));
391394

392395
ui->tabbar->setAnimatePageChange(true);
393396
ui->tabbar->setCustomStackWidget(ui->tabhost);
@@ -525,14 +528,15 @@ void MainWindow::onAppConfigUpdated(const AppConfig::Key &key, const QVariant &v
525528
{
526529
switch(key)
527530
{
528-
case AppConfig::EqualizerShowHandles:
529-
ui->eq_widget->setAlwaysDrawHandles(value.toBool());
530-
break;
531-
case AppConfig::TrayIconEnabled:
532-
_trayIcon->setTrayVisible(value.toBool());
533-
break;
534-
default:
535-
break;
531+
case AppConfig::EqualizerShowHandles:
532+
ui->eq_widget->setAlwaysDrawHandles(value.toBool());
533+
ui->comp_response->setAlwaysDrawHandles(value.toBool());
534+
break;
535+
case AppConfig::TrayIconEnabled:
536+
_trayIcon->setTrayVisible(value.toBool());
537+
break;
538+
default:
539+
break;
536540
}
537541
}
538542

@@ -655,10 +659,49 @@ void MainWindow::loadConfig()
655659
ui->bs2b_fcut->setValueA(DspConfig::instance().get<int>(DspConfig::crossfeed_bs2b_fcut));
656660
ui->bs2b_custom_box->setEnabled(bs2bMode == 99);
657661

658-
ui->enable_comp->setChecked(DspConfig::instance().get<bool>(DspConfig::compression_enable));
659-
ui->comp_maxattack->setValueA(DspConfig::instance().get<int>(DspConfig::compression_maxatk));
660-
ui->comp_maxrelease->setValueA(DspConfig::instance().get<int>(DspConfig::compression_maxrel));
661-
ui->comp_aggressiveness->setValueA(DspConfig::instance().get<int>(DspConfig::compression_aggressiveness));
662+
ui->enable_comp->setChecked(DspConfig::instance().get<bool>(DspConfig::compander_enable));
663+
ui->comp_granularity->setValueA(DspConfig::instance().get<int>(DspConfig::compander_granularity));
664+
ui->comp_timeconstant->setValueA(100 * DspConfig::instance().get<float>(DspConfig::compander_timeconstant));
665+
int companderTrans = DspConfig::instance().get<int>(DspConfig::compander_time_freq_transforms);
666+
int companderTransIdx = ui->crossfeed_mode->findData(companderTrans);
667+
if(companderTransIdx < 0)
668+
Log::error(QString("Compander TF transform index for value %1 not found").arg(companderTrans));
669+
else
670+
ui->comp_tf_transforms->setCurrentIndex(companderTransIdx);
671+
672+
{
673+
// Parse compander response
674+
QVector<float> rawCompanderData;
675+
676+
for (const auto &val : chopDoubleQuotes(DspConfig::instance().get<QString>(DspConfig::compander_response)).split(";"))
677+
{
678+
rawCompanderData.push_back(val.isEmpty() ? 0.f : val.toFloat());
679+
}
680+
681+
// TODO: This needs to be cleaned up and put into LiquidEq subproject instead
682+
int it = 7;
683+
bool eqReloadRequired = false;
684+
for (auto cur_data : ui->comp_response->getBands())
685+
{
686+
if (it >= rawCompanderData.count())
687+
{
688+
break;
689+
}
690+
691+
bool equal = isApproximatelyEqual<float>(cur_data, rawCompanderData.at(it));
692+
if (eqReloadRequired == false)
693+
{
694+
eqReloadRequired = !equal;
695+
}
696+
697+
it++;
698+
}
699+
700+
if (eqReloadRequired && rawCompanderData.length() >= 14)
701+
{
702+
ui->comp_response->setBands(QVector<double>(rawCompanderData.cbegin() + 7, rawCompanderData.constEnd()), false);
703+
}
704+
}
662705

663706
ui->limthreshold->setValueA(DspConfig::instance().get<int>(DspConfig::master_limthreshold));
664707
ui->limrelease->setValueA(DspConfig::instance().get<int>(DspConfig::master_limrelease));
@@ -806,10 +849,31 @@ void MainWindow::applyConfig()
806849
DspConfig::instance().set(DspConfig::convolver_file, QVariant(_currentImpulseResponse));
807850
DspConfig::instance().set(DspConfig::convolver_waveform_edit, QVariant(_currentConvWaveformEdit));
808851

809-
DspConfig::instance().set(DspConfig::compression_enable, QVariant(ui->enable_comp->isChecked()));
810-
DspConfig::instance().set(DspConfig::compression_maxatk, QVariant(ui->comp_maxattack->valueA()));
811-
DspConfig::instance().set(DspConfig::compression_maxrel, QVariant(ui->comp_maxrelease->valueA()));
812-
DspConfig::instance().set(DspConfig::compression_aggressiveness, QVariant(ui->comp_aggressiveness->valueA()));
852+
DspConfig::instance().set(DspConfig::compander_enable, QVariant(ui->enable_comp->isChecked()));
853+
DspConfig::instance().set(DspConfig::compander_granularity, QVariant(ui->comp_granularity->valueA()));
854+
DspConfig::instance().set(DspConfig::compander_timeconstant, QVariant(ui->comp_timeconstant->valueA() / 100.0f));
855+
DspConfig::instance().set(DspConfig::compander_time_freq_transforms, QVariant(ui->comp_tf_transforms->currentIndex()));
856+
// TODO: this needs to be moved into LiquidEQ subproject too
857+
{
858+
QVector<double> compBands = ui->comp_response->getBands();
859+
QString rawCompString = "95.0;200.0;400.0;800.0;1600.0;3400.0;7500.0;";
860+
int counter = 0;
861+
862+
for (auto band : compBands)
863+
{
864+
rawCompString.append(QString::number(band));
865+
866+
if (counter < 6)
867+
{
868+
rawCompString.append(';');
869+
}
870+
871+
counter++;
872+
}
873+
874+
DspConfig::instance().set(DspConfig::compander_response, QVariant(rawCompString));
875+
}
876+
813877

814878
DspConfig::instance().set(DspConfig::tone_enable, QVariant(ui->enable_eq->isChecked()));
815879
DspConfig::instance().set(DspConfig::tone_filtertype, QVariant(ui->eqfiltertype->currentIndex()));
@@ -961,12 +1025,13 @@ void MainWindow::installUnitData()
9611025
ui->rev_osf->setProperty("unit", "x");
9621026

9631027
QList<QAnimatedSlider*> div100({ui->rev_era, ui->rev_erf, ui->rev_erw, ui->rev_width, ui->rev_bass, ui->rev_spin, ui->rev_wander, ui->rev_decay,
964-
ui->analog_tubedrive});
1028+
ui->analog_tubedrive, ui->comp_timeconstant});
9651029

9661030
QList<QAnimatedSlider*> div10({ui->bs2b_feed, ui->rev_delay, ui->rev_wet, ui->rev_finalwet, ui->rev_finaldry, ui->rev_width});
9671031

9681032
QList<QAnimatedSlider*> unitDecibel({ui->bs2b_feed, ui->rev_wet, ui->rev_finalwet, ui->rev_finaldry, ui->analog_tubedrive, ui->postgain, ui->bass_maxgain});
969-
QList<QAnimatedSlider*> unitMs({ui->rev_delay, ui->comp_maxattack, ui->comp_maxrelease, ui->limrelease});
1033+
QList<QAnimatedSlider*> unitMs({ui->rev_delay, ui->limrelease});
1034+
QList<QAnimatedSlider*> unitS({ui->comp_timeconstant});
9701035
QList<QAnimatedSlider*> unitHz({ui->bs2b_fcut, ui->rev_lcb, ui->rev_lcd, ui->rev_lci, ui->rev_lco});
9711036

9721037
foreach(auto w, div100)
@@ -978,8 +1043,12 @@ void MainWindow::installUnitData()
9781043
w->setProperty("unit", "dB");
9791044
foreach(auto w, unitMs)
9801045
w->setProperty("unit", "ms");
1046+
foreach(auto w, unitS)
1047+
w->setProperty("unit", "s");
9811048
foreach(auto w, unitHz)
9821049
w->setProperty("unit", "Hz");
1050+
1051+
ui->comp_granularity->setCustomValueStrings({tr("Very low"), tr("Low"), tr("Medium"), tr("High"), tr("Extreme")});
9831052
}
9841053

9851054
// DDC
@@ -1217,20 +1286,20 @@ void MainWindow::saveGraphicEQView()
12171286
void MainWindow::connectActions()
12181287
{
12191288
QList<QAnimatedSlider*> sliders({
1220-
ui->stereowide_level, ui->bs2b_fcut, ui->bs2b_feed, ui->rev_osf, ui->rev_erf, ui->rev_era, ui->rev_erw,
1221-
ui->rev_lci, ui->rev_lcb, ui->rev_lcd, ui->rev_lco, ui->rev_finalwet, ui->rev_finaldry, ui->rev_wet, ui->rev_width, ui->rev_spin,
1222-
ui->rev_wander, ui->rev_decay, ui->rev_delay, ui->rev_bass, ui->analog_tubedrive, ui->limthreshold,
1223-
ui->limrelease, ui->comp_maxrelease, ui->comp_maxattack, ui->comp_aggressiveness,
1224-
ui->bass_maxgain, ui->postgain
1225-
});
1289+
ui->stereowide_level, ui->bs2b_fcut, ui->bs2b_feed, ui->rev_osf, ui->rev_erf, ui->rev_era, ui->rev_erw,
1290+
ui->rev_lci, ui->rev_lcb, ui->rev_lcd, ui->rev_lco, ui->rev_finalwet, ui->rev_finaldry, ui->rev_wet, ui->rev_width, ui->rev_spin,
1291+
ui->rev_wander, ui->rev_decay, ui->rev_delay, ui->rev_bass, ui->analog_tubedrive, ui->limthreshold,
1292+
ui->limrelease, ui->comp_granularity, ui->comp_timeconstant,
1293+
ui->bass_maxgain, ui->postgain
1294+
});
12261295

12271296
QList<QWidget*> registerClick({
1228-
ui->bassboost, ui->bs2b, ui->stereowidener, ui->analog, ui->reverb, ui->enable_eq, ui->enable_comp, ui->ddc_enable, ui->conv_enable,
1229-
ui->graphicEq->chk_enable
1230-
});
1297+
ui->bassboost, ui->bs2b, ui->stereowidener, ui->analog, ui->reverb, ui->enable_eq, ui->enable_comp, ui->ddc_enable, ui->conv_enable,
1298+
ui->graphicEq->chk_enable
1299+
});
12311300

12321301
foreach(QAnimatedSlider* w, sliders)
1233-
{
1302+
{
12341303
connect(w, &QAnimatedSlider::stringChanged, ui->info, qOverload<const QString&>(&FadingLabel::setAnimatedText));
12351304
connect(w, &QAnimatedSlider::valueChangedA, this, &MainWindow::applyConfig);
12361305
}
@@ -1257,6 +1326,9 @@ void MainWindow::connectActions()
12571326
connect(ui->eq_widget, &LiquidEqualizerWidget::bandsUpdated, this, &MainWindow::applyConfig);
12581327
connect(ui->eq_widget, &LiquidEqualizerWidget::mouseReleased, this, &MainWindow::determineEqPresetName);
12591328

1329+
connect(ui->comp_response, &LiquidCompanderWidget::bandsUpdated, this, &MainWindow::applyConfig);
1330+
connect(ui->comp_tf_transforms, qOverload<int>(&QComboBox::currentIndexChanged), this, &MainWindow::applyConfig);
1331+
12601332
connect(ui->conv_adv_wave_edit, &QAbstractButton::clicked, this, &MainWindow::onConvolverWaveformEdit);
12611333

12621334
connect(ui->graphicEq, &GraphicEQFilterGUI::mouseUp, this, &MainWindow::applyConfig);

src/MainWindow.ui

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
<x>0</x>
88
<y>0</y>
99
<width>700</width>
10-
<height>410</height>
10+
<height>430</height>
1111
</rect>
1212
</property>
1313
<property name="minimumSize">
1414
<size>
1515
<width>700</width>
16-
<height>410</height>
16+
<height>430</height>
1717
</size>
1818
</property>
1919
<property name="maximumSize">
@@ -308,10 +308,10 @@
308308
<item>
309309
<widget class="QGroupBox" name="enable_comp">
310310
<property name="whatsThis">
311-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Dynamic range compressor&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Enables/disables the dynamic range compressor, an automatic dynamic range flattener that can flatten the signal spectral to reduce transient; it is like a drum volume reducer.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Max attack:&lt;/span&gt; adjusts how fast the Dynamic Range Compressor reacts.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Max release:&lt;/span&gt; adjusts how slow the Dynamic Range Compressor is performing gain decay.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline;&quot;&gt;Aggressiveness:&lt;/span&gt; adjusts how strong the spectral flattening is going to be&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
311+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Dynamic range compander&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Enables/disables the dynamic range compander.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
312312
</property>
313313
<property name="title">
314-
<string>Dynamic range compressor</string>
314+
<string>Dynamic range compander</string>
315315
</property>
316316
<property name="checkable">
317317
<bool>true</bool>
@@ -321,14 +321,14 @@
321321
</property>
322322
<layout class="QVBoxLayout" name="verticalLayout_4">
323323
<item>
324-
<widget class="QLabel" name="comp_atk_label">
324+
<widget class="QLabel" name="comp_timeconst_label">
325325
<property name="text">
326-
<string>Maximum attack</string>
326+
<string>Time constant</string>
327327
</property>
328328
</widget>
329329
</item>
330330
<item>
331-
<widget class="QAnimatedSlider" name="comp_maxattack">
331+
<widget class="QAnimatedSlider" name="comp_timeconstant">
332332
<property name="sizePolicy">
333333
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
334334
<horstretch>0</horstretch>
@@ -342,10 +342,13 @@
342342
</size>
343343
</property>
344344
<property name="minimum">
345-
<number>0</number>
345+
<number>6</number>
346346
</property>
347347
<property name="maximum">
348-
<number>400</number>
348+
<number>30</number>
349+
</property>
350+
<property name="pageStep">
351+
<number>5</number>
349352
</property>
350353
<property name="orientation">
351354
<enum>Qt::Horizontal</enum>
@@ -358,20 +361,23 @@
358361
<item>
359362
<widget class="QLabel" name="label_7">
360363
<property name="text">
361-
<string>Maximum release</string>
364+
<string>Granularity</string>
362365
</property>
363366
</widget>
364367
</item>
365368
<item>
366-
<widget class="QAnimatedSlider" name="comp_maxrelease">
369+
<widget class="QAnimatedSlider" name="comp_granularity">
367370
<property name="minimum">
368371
<number>0</number>
369372
</property>
370373
<property name="maximum">
371-
<number>400</number>
374+
<number>4</number>
375+
</property>
376+
<property name="pageStep">
377+
<number>1</number>
372378
</property>
373379
<property name="value">
374-
<number>200</number>
380+
<number>0</number>
375381
</property>
376382
<property name="orientation">
377383
<enum>Qt::Horizontal</enum>
@@ -381,39 +387,42 @@
381387
<item>
382388
<widget class="QLabel" name="label_5">
383389
<property name="text">
384-
<string>Aggressiveness</string>
390+
<string>Time-frequency transforms</string>
385391
</property>
386392
</widget>
387393
</item>
388394
<item>
389-
<widget class="QAnimatedSlider" name="comp_aggressiveness">
390-
<property name="minimum">
391-
<number>10</number>
392-
</property>
393-
<property name="maximum">
394-
<number>1000</number>
395-
</property>
396-
<property name="value">
397-
<number>800</number>
398-
</property>
399-
<property name="orientation">
400-
<enum>Qt::Horizontal</enum>
395+
<widget class="QComboBox" name="comp_tf_transforms">
396+
<item>
397+
<property name="text">
398+
<string>Uniform (Short-time Fourier)</string>
399+
</property>
400+
</item>
401+
<item>
402+
<property name="text">
403+
<string>Multiresolution (Continuous wavelet)</string>
404+
</property>
405+
</item>
406+
<item>
407+
<property name="text">
408+
<string>Multiresolution (Time domain)</string>
409+
</property>
410+
</item>
411+
</widget>
412+
</item>
413+
<item>
414+
<widget class="LiquidCompanderWidget" name="comp_response" native="true">
415+
<property name="minimumSize">
416+
<size>
417+
<width>0</width>
418+
<height>145</height>
419+
</size>
401420
</property>
402421
</widget>
403422
</item>
404423
</layout>
405424
</widget>
406425
</item>
407-
<item>
408-
<widget class="LiquidCompanderWidget" name="widget" native="true">
409-
<property name="minimumSize">
410-
<size>
411-
<width>0</width>
412-
<height>150</height>
413-
</size>
414-
</property>
415-
</widget>
416-
</item>
417426
<item>
418427
<spacer name="verticalSpacer_4">
419428
<property name="orientation">

0 commit comments

Comments
 (0)