ViPERFX_RE/src/viper/utils/MinPhaseIIRCoeffs.cpp

215 lines
4.6 KiB
C++
Raw Normal View History

2022-09-18 03:38:22 +02:00
#include "MinPhaseIIRCoeffs.h"
2022-09-23 04:15:43 +02:00
#include <cmath>
2022-12-14 02:56:26 +01:00
// Iscle: Verified with the latest version at 13/12/2022
2022-12-13 03:10:29 +01:00
2022-09-25 02:02:07 +02:00
static const float MIN_PHASE_IIR_COEFFS_FREQ_10BANDS[] = {
2022-09-23 04:15:43 +02:00
31.0,
62.0,
125.0,
250.0,
500.0,
1000.0,
2000.0,
4000.0,
8000.0,
16000.0
};
2022-09-25 02:02:07 +02:00
static const float MIN_PHASE_IIR_COEFFS_FREQ_15BANDS[] = {
2022-09-23 04:15:43 +02:00
25.0,
40.0,
63.0,
100.0,
160.0,
250.0,
400.0,
630.0,
1000.0,
1600.0,
2500.0,
4000.0,
6300.0,
10000.0,
16000.0
};
2022-09-25 02:02:07 +02:00
static const float MIN_PHASE_IIR_COEFFS_FREQ_25BANDS[] = {
2022-09-23 04:15:43 +02:00
20.0,
31.5,
40.0,
50.0,
80.0,
100.0,
125.0,
160.0,
250.0,
315.0,
400.0,
500.0,
800.0,
1000.0,
1250.0,
1600.0,
2500.0,
3150.0,
4000.0,
5000.0,
8000.0,
10000.0,
12500.0,
16000.0,
20000.0
};
2022-09-25 02:02:07 +02:00
static const float MIN_PHASE_IIR_COEFFS_FREQ_31BANDS[] = {
2022-09-23 04:15:43 +02:00
20.0,
25.0,
31.5,
40.0,
50.0,
63.0,
80.0,
100.0,
125.0,
160.0,
200.0,
250.0,
315.0,
400.0,
500.0,
630.0,
800.0,
1000.0,
1250.0,
1600.0,
2000.0,
2500.0,
3150.0,
4000.0,
5000.0,
6300.0,
8000.0,
10000.0,
12500.0,
16000.0,
20000.0
};
MinPhaseIIRCoeffs::MinPhaseIIRCoeffs() {
this->coeffs = nullptr;
2022-09-25 02:02:07 +02:00
this->bands = 0;
2022-09-23 04:15:43 +02:00
}
MinPhaseIIRCoeffs::~MinPhaseIIRCoeffs() {
2022-10-06 03:37:22 +02:00
delete[] this->coeffs;
2022-09-23 04:15:43 +02:00
}
2022-09-25 00:46:32 +02:00
void MinPhaseIIRCoeffs::Find_F1_F2(double param_2, double param_3, double *param_4, double *param_5) {
2022-09-23 04:15:43 +02:00
double x = pow(2.0, param_3 / 2.0);
2022-12-13 03:10:29 +01:00
*param_4 = param_2 / x;
*param_5 = param_2 * x;
2022-09-23 04:15:43 +02:00
}
2022-10-11 03:07:11 +02:00
double *MinPhaseIIRCoeffs::GetCoefficients() {
2022-09-23 04:15:43 +02:00
return this->coeffs;
}
float MinPhaseIIRCoeffs::GetIndexFrequency(uint32_t index) {
2022-09-25 02:02:07 +02:00
switch (this->bands) {
2022-09-23 04:15:43 +02:00
case 10:
2022-09-25 02:02:07 +02:00
return MIN_PHASE_IIR_COEFFS_FREQ_10BANDS[index];
2022-09-23 04:15:43 +02:00
case 15:
2022-09-25 02:02:07 +02:00
return MIN_PHASE_IIR_COEFFS_FREQ_15BANDS[index];
2022-09-23 04:15:43 +02:00
case 25:
2022-09-25 02:02:07 +02:00
return MIN_PHASE_IIR_COEFFS_FREQ_25BANDS[index];
2022-09-23 04:15:43 +02:00
case 31:
2022-09-25 02:02:07 +02:00
return MIN_PHASE_IIR_COEFFS_FREQ_31BANDS[index];
2022-09-23 04:15:43 +02:00
default:
return 0.0;
}
}
int MinPhaseIIRCoeffs::SolveRoot(double param_2, double param_3, double param_4, double *param_5) {
2022-11-24 01:17:13 +01:00
double x = (param_4 - (param_3 * param_3) / (param_2 * 4.0)) / param_2;
2022-12-13 03:10:29 +01:00
double y = param_3 / (param_2 + param_2);
2022-09-23 04:15:43 +02:00
if (x >= 0.0) {
return -1;
}
double z = sqrt(-x);
double a = -y - z;
double b = z - y;
if (a > b) {
*param_5 = b;
} else {
*param_5 = a;
}
return 0;
}
2022-09-25 02:02:07 +02:00
int MinPhaseIIRCoeffs::UpdateCoeffs(uint32_t bands, uint32_t samplingRate) {
if (bands != 10 && bands != 15 && bands != 25 && bands != 31) {
2022-09-23 04:15:43 +02:00
return 0;
}
2022-09-25 02:02:07 +02:00
this->bands = bands;
2022-09-23 04:15:43 +02:00
2022-10-06 03:37:22 +02:00
delete[] this->coeffs;
2022-10-11 03:07:11 +02:00
this->coeffs = new double[bands * 4](); // TODO: Check this array size, original type: float
2022-09-23 04:15:43 +02:00
2022-12-13 03:10:29 +01:00
const float *bandFreqs;
2022-09-25 00:46:32 +02:00
double tmp;
2022-09-25 02:02:07 +02:00
switch (bands) {
2022-09-25 00:46:32 +02:00
case 10:
2022-12-13 03:10:29 +01:00
bandFreqs = MIN_PHASE_IIR_COEFFS_FREQ_10BANDS;
2022-09-25 00:46:32 +02:00
tmp = 3.0 / 3.0;
break;
case 15:
2022-12-13 03:10:29 +01:00
bandFreqs = MIN_PHASE_IIR_COEFFS_FREQ_15BANDS;
2022-09-25 00:46:32 +02:00
tmp = 2.0 / 3.0;
break;
case 25:
2022-12-13 03:10:29 +01:00
bandFreqs = MIN_PHASE_IIR_COEFFS_FREQ_25BANDS;
2022-09-25 00:46:32 +02:00
tmp = 1.0 / 3.0;
break;
case 31:
2022-12-13 03:10:29 +01:00
bandFreqs = MIN_PHASE_IIR_COEFFS_FREQ_31BANDS;
2022-09-25 00:46:32 +02:00
tmp = 1.0 / 3.0;
break;
}
2022-09-25 02:02:07 +02:00
for (uint32_t i = 0; i < bands; i++) {
2022-09-25 00:46:32 +02:00
double ret1;
double ret2;
2022-10-11 00:36:38 +02:00
2022-12-13 03:10:29 +01:00
Find_F1_F2(bandFreqs[i], tmp, &ret2, &ret1);
2022-09-25 00:46:32 +02:00
double x = (2.0 * M_PI * (double) bandFreqs[i]) / (double) samplingRate;
double y = (2.0 * M_PI * ret2) / (double) samplingRate;
2022-09-25 00:46:32 +02:00
double cosX = cos(x);
double cosY = cos(y);
double sinY = sin(y);
double a = cosX * cosY;
2022-12-13 03:10:29 +01:00
double b = cosX * cosX / 2.0;
double c = sinY * sinY;
2022-09-25 00:46:32 +02:00
2022-10-11 00:36:38 +02:00
double d = ((b - a) + 0.5) - c;
2022-12-13 03:10:29 +01:00
double e = c + (((b + cosY * cosY) - a) - 0.5);
2022-11-24 01:17:13 +01:00
double f = (((cosX * cosX) * 0.125 - cosX * cosY * 0.25) + 0.125) - c * 0.25;
2022-10-11 00:36:38 +02:00
if (SolveRoot(d, e, f, &ret1) == 0) {
2022-12-13 03:10:29 +01:00
this->coeffs[i * 4] = ret1 + ret1;
this->coeffs[i * 4 + 1] = 0.5 - ret1;
this->coeffs[i * 4 + 2] = (ret1 + 0.5) * cosX * 2.0;
2022-09-25 00:46:32 +02:00
}
}
return 1;
2022-09-23 04:15:43 +02:00
}