@@ -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 }
0 commit comments