Skip to content

Commit 5cb3848

Browse files
committed
feat: implement equalizer curves for all EQ types
1 parent c5cb1d5 commit 5cb3848

11 files changed

Lines changed: 168 additions & 18 deletions

File tree

libjamesdsp/JdspImpResToolbox.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,31 @@ int ComputeCompResponse(int n, const double* jfreq, const double* jgain, int que
555555
response[i] = (float)getValueAt(&lerpPtr->cb, dispFreq[i]);
556556
return 0;
557557
}
558+
559+
void ComputeIIREqualizerCplx(int srate, int order, const double* freqs, double* gains, int nPts, const double* dispFreq, double* cplxRe, double* cplxIm)
560+
{
561+
for (int i = 0; i < nPts; i++)
562+
{
563+
cplxRe[i] = 1;
564+
cplxIm[i] = 0;
565+
}
566+
567+
for (int i = 0; i < bandsNum() - 1; i++)
568+
{
569+
double dB = gains[i + 1] - gains[i];
570+
double designFreq;
571+
if (i)
572+
designFreq = (freqs[i + 1] + freqs[i]) * 0.5;
573+
else
574+
designFreq = freqs[i];
575+
double overallGain = i == 0 ? gains[i] : 0.0;
576+
HSHOResponse(48000, designFreq, order, dB, overallGain, nPts, dispFreq, cplxRe, cplxIm);
577+
}
578+
}
579+
580+
void ComputeIIREqualizerResponse(int nPts, const double* cplxRe, const double* cplxIm, float* response)
581+
{
582+
for(int i = 0; i < nPts; i++) {
583+
response[i] = 20.0f * log10f(hypot(cplxRe[i], cplxIm[i]));
584+
}
585+
}

libjamesdsp/JdspImpResToolbox.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
extern float* ReadImpulseResponseToFloat(const char* mIRFileName, int targetSampleRate, int* jImpInfo, int convMode, int* javaAdvSetPtr);
55
extern int ComputeEqResponse(const double* jfreq, double* jgain, int interpolationMode, int queryPts, double* dispFreq, float* response);
66
extern int ComputeCompResponse(int n, const double* jfreq, const double* jgain, int queryPts, const double* dispFreq, float* response);
7-
7+
extern void ComputeIIREqualizerCplx(int srate, int order, const double* freq, double* gains, int nPts, const double* dispFreq, double* cplxRe, double* cplxIm);
8+
extern void ComputeIIREqualizerResponse(int nPts, const double* cplxRe, const double* cplxIm, float* response);
89
#endif // JDSPIMPRESTOOLBOX_H

libjamesdsp/subtree/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/multimodalEQ.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ void MultimodalEqualizerAxisInterpolation(JamesDSPLib *jdsp, int interpolationMo
221221
jdsp->mEQ.operatingMode = operatingMode;
222222
jdsp->mEQ.currentInterpolationMode = interpolationMode;
223223
}
224+
224225
void MultimodalEqualizerEnable(JamesDSPLib *jdsp, char enable)
225226
{
226227
if (jdsp->equalizerForceRefresh)
@@ -279,4 +280,4 @@ void MultimodalEqualizerProcess(JamesDSPLib *jdsp, size_t n)
279280
jdsp->tmpBuffer[1][smp] = x2;
280281
}
281282
}
282-
}
283+
}

libjamesdsp/subtree/Main/libjamesdsp/jni/jamesdsp/jdsp/jdsp_header.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,4 +609,5 @@ extern void MultimodalEqualizerAxisInterpolation(JamesDSPLib *jdsp, int interpol
609609
extern void MultimodalEqualizerEnable(JamesDSPLib *jdsp, char enable);
610610
extern void MultimodalEqualizerDisable(JamesDSPLib *jdsp);
611611
extern void MultimodalEqualizerProcess(JamesDSPLib *jdsp, size_t n);
612+
extern void HSHOResponse(double fs, double fc, unsigned int filterOrder, double gain, double overallGainDb, unsigned int queryPts, double *dispFreq, double *cplxRe, double *cplxIm);
612613
#endif

src/MainWindow.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -667,12 +667,7 @@ void MainWindow::loadConfig()
667667
ui->enable_comp->setChecked(DspConfig::instance().get<bool>(DspConfig::compander_enable));
668668
ui->comp_granularity->setValueA(DspConfig::instance().get<int>(DspConfig::compander_granularity));
669669
ui->comp_timeconstant->setValueA(100 * DspConfig::instance().get<float>(DspConfig::compander_timeconstant));
670-
int companderTrans = DspConfig::instance().get<int>(DspConfig::compander_time_freq_transforms);
671-
int companderTransIdx = ui->crossfeed_mode->findData(companderTrans);
672-
if(companderTransIdx < 0)
673-
Log::error(QString("Compander TF transform index for value %1 not found").arg(companderTrans));
674-
else
675-
ui->comp_tf_transforms->setCurrentIndex(companderTransIdx);
670+
ui->comp_tf_transforms->setCurrentIndex(DspConfig::instance().get<int>(DspConfig::compander_time_freq_transforms));
676671

677672
{
678673
// Parse compander response
@@ -728,7 +723,11 @@ void MainWindow::loadConfig()
728723

729724
ui->enable_eq->setChecked(DspConfig::instance().get<bool>(DspConfig::tone_enable));
730725
ui->eqinterpolator->setCurrentIndex(DspConfig::instance().get<int>(DspConfig::tone_interpolation));
731-
ui->eqfiltertype->setCurrentIndex(DspConfig::instance().get<int>(DspConfig::tone_filtertype));
726+
727+
int filterType = DspConfig::instance().get<int>(DspConfig::tone_filtertype);
728+
if(ui->eqfiltertype->currentIndex() != filterType)
729+
onEqTypeUpdated(filterType);
730+
ui->eqfiltertype->setCurrentIndex(filterType);
732731

733732
// Parse EQ String to QMap
734733
QString rawEqString = chopDoubleQuotes(DspConfig::instance().get<QString>(DspConfig::tone_eq));
@@ -1230,6 +1229,29 @@ void MainWindow::onEqModeUpdated()
12301229
setEqMode(isFixed ? 0 : 1);
12311230
}
12321231

1232+
void MainWindow::onEqTypeUpdated(int index)
1233+
{
1234+
ui->eq_widget->setMode(index == 0 ? LiquidMultiEqualizerWidget::FIR : LiquidMultiEqualizerWidget::IIR);
1235+
ui->eqinterpolator->setEnabled(index == 0);
1236+
switch(index) {
1237+
case 1:
1238+
ui->eq_widget->setIirOrder(4);
1239+
break;
1240+
case 2:
1241+
ui->eq_widget->setIirOrder(6);
1242+
break;
1243+
case 3:
1244+
ui->eq_widget->setIirOrder(8);
1245+
break;
1246+
case 4:
1247+
ui->eq_widget->setIirOrder(10);
1248+
break;
1249+
case 5:
1250+
ui->eq_widget->setIirOrder(12);
1251+
break;
1252+
}
1253+
}
1254+
12331255
void MainWindow::setEqMode(int mode)
12341256
{
12351257
ui->eq_holder->setCurrentIndex(mode);
@@ -1321,6 +1343,7 @@ void MainWindow::connectActions()
13211343
connect(ui->eq_r_flex, &QAbstractButton::clicked, this, &MainWindow::applyConfig);
13221344

13231345
connect(ui->eqfiltertype, qOverload<int>(&QComboBox::currentIndexChanged), this, &MainWindow::applyConfig);
1346+
connect(ui->eqfiltertype, qOverload<int>(&QComboBox::currentIndexChanged), this, &MainWindow::onEqTypeUpdated);
13241347
connect(ui->eqinterpolator, qOverload<int>(&QComboBox::currentIndexChanged), this, &MainWindow::applyConfig);
13251348
connect(ui->conv_ir_opt, qOverload<int>(&QComboBox::currentIndexChanged), this, &MainWindow::applyConfig);
13261349

src/MainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ private slots:
9090
void onReverbPresetUpdated();
9191
void onEqPresetUpdated();
9292
void onEqModeUpdated();
93+
void onEqTypeUpdated(int index);
9394

9495
void restoreGraphicEQView();
9596
void saveGraphicEQView();

src/MainWindow.ui

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
<item>
7575
<widget class="QStackedWidget" name="tabhost">
7676
<property name="currentIndex">
77-
<number>0</number>
77+
<number>3</number>
7878
</property>
7979
<widget class="QWidget" name="tabHostPage1">
8080
<layout class="QVBoxLayout" name="verticalLayout_6">
@@ -1181,7 +1181,7 @@
11811181
<number>0</number>
11821182
</property>
11831183
<item>
1184-
<widget class="LiquidEqualizerWidget" name="eq_widget" native="true"/>
1184+
<widget class="LiquidMultiEqualizerWidget" name="eq_widget" native="true"/>
11851185
</item>
11861186
</layout>
11871187
</widget>
@@ -2211,12 +2211,6 @@
22112211
<header>interface/FileSelectionWidget.h</header>
22122212
<container>1</container>
22132213
</customwidget>
2214-
<customwidget>
2215-
<class>LiquidEqualizerWidget</class>
2216-
<extends>QWidget</extends>
2217-
<header location="global">LiquidEqualizerWidget.h</header>
2218-
<container>1</container>
2219-
</customwidget>
22202214
<customwidget>
22212215
<class>QAnimatedSlider</class>
22222216
<extends>QSlider</extends>
@@ -2251,6 +2245,12 @@
22512245
<header location="global">LiquidCompanderWidget.h</header>
22522246
<container>1</container>
22532247
</customwidget>
2248+
<customwidget>
2249+
<class>LiquidMultiEqualizerWidget</class>
2250+
<extends>QWidget</extends>
2251+
<header>interface/LiquidMultiEqualizerWidget.h</header>
2252+
<container>1</container>
2253+
</customwidget>
22542254
</customwidgets>
22552255
<tabstops>
22562256
<tabstop>cpreset</tabstop>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "LiquidMultiEqualizerWidget.h"
2+
3+
extern "C" {
4+
#include <JdspImpResToolbox.h>
5+
}
6+
7+
LiquidMultiEqualizerWidget::LiquidMultiEqualizerWidget(QWidget* parent) : BaseLiquidEqualizerWidget(15, 24, 20000, -12.0, 12.0, 128, 3, parent)
8+
{
9+
cplxRe = new double[resolution()];
10+
cplxIm = new double[resolution()];
11+
}
12+
13+
LiquidMultiEqualizerWidget::~LiquidMultiEqualizerWidget()
14+
{
15+
delete [] cplxRe;
16+
delete [] cplxIm;
17+
}
18+
19+
LiquidMultiEqualizerWidget::Mode LiquidMultiEqualizerWidget::getMode() const
20+
{
21+
return mode;
22+
}
23+
24+
void LiquidMultiEqualizerWidget::setMode(Mode newMode)
25+
{
26+
mode = newMode;
27+
emit redrawRequired();
28+
}
29+
30+
int LiquidMultiEqualizerWidget::getIirOrder() const
31+
{
32+
return iirOrder;
33+
}
34+
35+
void LiquidMultiEqualizerWidget::setIirOrder(int newIirOrder)
36+
{
37+
iirOrder = newIirOrder;
38+
emit redrawRequired();
39+
}
40+
41+
QVector<double> LiquidMultiEqualizerWidget::getFrequencyPoints()
42+
{
43+
return QVector<double>({ 25.0f, 40.0f, 63.0f, 100.0f, 160.0f, 250.0f, 400.0f, 630.0f, 1000.0f, 1600.0f, 2500.0f, 4000.0f, 6300.0f, 10000.0f, 16000.0f });
44+
}
45+
46+
void LiquidMultiEqualizerWidget::computeCurve(const double *freqs, double *gains, int resolution, double *dispFreq, float *response)
47+
{
48+
switch(mode) {
49+
case FIR:
50+
ComputeEqResponse(freqs, gains, 1, resolution, dispFreq, response);
51+
break;
52+
53+
case IIR:
54+
ComputeIIREqualizerCplx(48000, iirOrder, freqs, gains, resolution, dispFreq, cplxRe, cplxIm);
55+
ComputeIIREqualizerResponse(resolution, cplxRe, cplxIm, response);
56+
break;
57+
}
58+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef LIQUIDMULTIEQUALIZERWIDGET_H
2+
#define LIQUIDMULTIEQUALIZERWIDGET_H
3+
4+
#include <LiquidEqualizerWidget.h>
5+
#include <QObject>
6+
7+
class LiquidMultiEqualizerWidget : public BaseLiquidEqualizerWidget
8+
{
9+
Q_OBJECT
10+
public:
11+
enum Mode {
12+
FIR = 0,
13+
IIR = 1
14+
};
15+
16+
LiquidMultiEqualizerWidget(QWidget* parent = nullptr);
17+
~LiquidMultiEqualizerWidget();
18+
virtual void computeCurve(const double *freqs, double *gains, int resolution, double *dispFreq, float *response) override;
19+
virtual QVector<double> getFrequencyPoints() override;
20+
21+
Mode getMode() const;
22+
void setMode(Mode newMode);
23+
24+
int getIirOrder() const;
25+
void setIirOrder(int newIirOrder);
26+
27+
private:
28+
Mode mode = Mode::FIR;
29+
int iirOrder = 2;
30+
31+
double *cplxRe = nullptr;
32+
double *cplxIm = nullptr;
33+
};
34+
35+
#endif // LIQUIDMULTIEQUALIZERWIDGET_H

src/src.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ SOURCES += \
7272
interface/CTableView.cpp \
7373
interface/FadingLabel.cpp \
7474
interface/FileSelectionWidget.cpp \
75+
interface/LiquidMultiEqualizerWidget.cpp \
7576
interface/LiveprogSelectionWidget.cpp \
7677
interface/TrayIcon.cpp \
7778
interface/dialog/PaletteEditor.cpp \
@@ -141,6 +142,7 @@ HEADERS += \
141142
interface/CTableView.h \
142143
interface/FadingLabel.h \
143144
interface/FileSelectionWidget.h \
145+
interface/LiquidMultiEqualizerWidget.h \
144146
interface/LiveprogSelectionWidget.h \
145147
interface/QMessageOverlay.h \
146148
interface/TrayIcon.h \

0 commit comments

Comments
 (0)