Skip to content

Commit d1e0f41

Browse files
author
andriy.malyshenko
committed
Added bq high/low shelf filters
1 parent 1723272 commit d1e0f41

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

components/bq_calc/bq_calc.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,64 @@ int bq_calc(bq_filter_type_t type,
112112
break;
113113
}
114114

115+
/*
116+
* Low-shelf — lowShelfCalc() from biquad.model.js.
117+
*
118+
* ao = (A+1) + (A-1)·cos(wo) + 2·sqrt(A)·alpha (note: + sign before (A-1))
119+
*
120+
* JS returns A1/A2 in TAS5805M adding-form convention; negate for standard:
121+
* a1 = -2·[(A-1) + (A+1)·cos(wo)] / ao
122+
* a2 = [(A+1) + (A-1)·cos(wo) - 2·sqrt(A)·alpha] / ao
123+
*/
124+
case BQ_FILTER_LOW_SHELF: {
125+
double A = sqrt(pow(10.0, gain_db / 20.0));
126+
double wo = 2.0 * M_PI * freq_hz / (double)fs;
127+
double cos_wo = cos(wo);
128+
double sin_wo = sin(wo);
129+
double alpha = sin_wo / (2.0 * q);
130+
double sqrtA = sqrt(A);
131+
double ao = (A + 1.0) + (A - 1.0) * cos_wo + 2.0 * sqrtA * alpha;
132+
133+
c->b0 = A * ((A + 1.0) - (A - 1.0) * cos_wo + 2.0 * sqrtA * alpha) / ao;
134+
c->b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * cos_wo) / ao;
135+
c->b2 = A * ((A + 1.0) - (A - 1.0) * cos_wo - 2.0 * sqrtA * alpha) / ao;
136+
c->a1 = -2.0 * ((A - 1.0) + (A + 1.0) * cos_wo) / ao;
137+
c->a2 = ((A + 1.0) + (A - 1.0) * cos_wo - 2.0 * sqrtA * alpha) / ao;
138+
break;
139+
}
140+
141+
/*
142+
* High-shelf — highShelfCalc() from biquad.model.js.
143+
*
144+
* A = sqrt(10^(gain_db/20))
145+
* wo = 2π·f/fs
146+
* alpha = sin(wo) / (2·Q)
147+
* ao = (A+1) - (A-1)·cos(wo) + 2·sqrt(A)·alpha
148+
*
149+
* JS returns A1/A2 in TAS5805M adding-form convention (+2, -1 region).
150+
* JS A1 = -2·[(A-1) - (A+1)·cos(wo)] / ao
151+
* JS A2 = -[(A+1) - (A-1)·cos(wo) - 2·sqrt(A)·alpha] / ao
152+
* Standard form (negate JS A1, JS A2):
153+
* a1 = 2·[(A-1) - (A+1)·cos(wo)] / ao
154+
* a2 = [(A+1) - (A-1)·cos(wo) - 2·sqrt(A)·alpha] / ao
155+
*/
156+
case BQ_FILTER_HIGH_SHELF: {
157+
double A = sqrt(pow(10.0, gain_db / 20.0));
158+
double wo = 2.0 * M_PI * freq_hz / (double)fs;
159+
double cos_wo = cos(wo);
160+
double sin_wo = sin(wo);
161+
double alpha = sin_wo / (2.0 * q);
162+
double sqrtA = sqrt(A);
163+
double ao = (A + 1.0) - (A - 1.0) * cos_wo + 2.0 * sqrtA * alpha;
164+
165+
c->b0 = A * ((A + 1.0) + (A - 1.0) * cos_wo + 2.0 * sqrtA * alpha) / ao;
166+
c->b1 = -2.0 * A * ((A - 1.0) + (A + 1.0) * cos_wo) / ao;
167+
c->b2 = A * ((A + 1.0) + (A - 1.0) * cos_wo - 2.0 * sqrtA * alpha) / ao;
168+
c->a1 = 2.0 * ((A - 1.0) - (A + 1.0) * cos_wo) / ao;
169+
c->a2 = ((A + 1.0) - (A - 1.0) * cos_wo - 2.0 * sqrtA * alpha) / ao;
170+
break;
171+
}
172+
115173
default:
116174
return -1;
117175
}

components/bq_calc/include/bq_calc.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ extern "C" {
1313
*/
1414
typedef enum {
1515
BQ_FILTER_EQ_Q_FACTOR = 0, /*!< Parametric EQ (uses gain_db and q) */
16-
BQ_FILTER_LOW_PASS, /*!< Second-order low-pass (gain_db ignored) */
17-
BQ_FILTER_HIGH_PASS, /*!< Second-order high-pass (gain_db ignored) */
16+
BQ_FILTER_LOW_PASS, /*!< Second-order low-pass (gain_db ignored) */
17+
BQ_FILTER_HIGH_PASS, /*!< Second-order high-pass (gain_db ignored) */
18+
BQ_FILTER_HIGH_SHELF, /*!< Second-order high-shelf (uses gain_db and q) */
19+
BQ_FILTER_LOW_SHELF, /*!< Second-order low-shelf (uses gain_db and q) */
1820
} bq_filter_type_t;
1921

2022
/** Common sample-rate constants. */

0 commit comments

Comments
 (0)