Согласно ответу hotpaw2, вот график ответа вашего фильтра:
from pylab import *
import scipy.signal as signal
def biquad_peak(omega, gain_db, bandwidth):
sn = sin(omega)
cs = cos(omega)
alpha = sn * sinh(log(2) / 2 * bandwidth * omega / sn)
gain_sqrt = 10.0 ** (gain_db / 40.0)
# feed-forward coefficients
b0 = 1.0 + alpha * gain_sqrt
b1 = -2.0 * cs
b2 = 1.0 - alpha * gain_sqrt
# feedback coefficients
a0 = 1.0 + (alpha / gain_sqrt)
a1 = -2.0 * cs
a2 = 1.0 - (alpha / gain_sqrt)
# normalize by a0
B = array([b0, b1, b2]) / a0
A = array([a0, a1, a2]) / a0
return B, A
omega = 2 * pi * 800.0 / 44100.0
gain_db = 1.0
bandwidth = 2.0
B, A = biquad_peak(omega, gain_db, bandwidth)
w, H = signal.freqz(B, A)
f = w / pi * 22050.0
plot(f, abs(H), 'r')
gain = 10.0 ** (gain_db / 20.0)
print "Gain:", gain
plot(f, gain*ones(len(f)), 'b--'); grid()
Пиковое усиление установлено на 1,1220184543 (т. Е. 1 дБ).Вы можете видеть, как фильтр вызывает усиление большей части звукового диапазона, превышающего 1.
Редактировать 2: Если это для регулируемого эквалайзера, то пользователь должен установить усиление, которое позволяет избежать искажений,Кроме того, я сомневаюсь, что крайняя проблема, которую вы описываете, будет вызвана небольшим усилением в 1 дБ в узкой полосе для типичной звуковой дорожки.Я думаю, что это потому, что в вашем аудио есть чередующиеся стереоданные.Каждый из этих каналов должен быть отфильтрован отдельно.Я предпринял попытку изменить ваш вложенный цикл, чтобы выполнить это:
a0 = 1.0 + alpha / A;
a1 = -2.0 * cs / a0;
a2 = (1.0 - alpha / A) / a0;
b0 = (1.0 + alpha * A) / a0;
b1 = -2.0 * cs / a0;
b2 = (1.0 - alpha * A) / a0;
double static x11, x12, x21, x22;
double static y11, y12, y21, y22;
double x0, y0;
for (int i = 0; i < ioData->mNumberBuffers; i++) {
AudioBuffer buffer = ioData->mBuffers[i];
AudioSampleType *outSample = buffer.mData;
for (int j = 0; j < inNumberFrames*2; j++) {
/* x0 is in the range of SInt16: -32768 to 32767 */
x0 = *musicPlaybackState->samplePtr++;
y0 = b0 * x0 +
b1 * x11 +
b2 * x12 -
a1 * y11 -
a2 * y12;
outSample[j] = fmax(fmin(y0, 32767.0), -32768.0);
x12 = x11;
x11 = x0;
y12 = y11;
y11 = y0
j++;
x0 = *musicPlaybackState->samplePtr++;
y0 = b0 * x0 +
b1 * x21 +
b2 * x22 -
a1 * y21 -
a2 * y22;
outSample[j] = fmax(fmin(y0, 32767.0), -32768.0);
x22 = x21;
x21 = x0;
y22 = y21;
y21 = y0;
}
}