Audio EQ Cookbook sin deformación de frecuencia

7

El famoso http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt ofrece un conjunto de fórmulas de cálculo de filtro biquad [real] que generalmente funcionan bien.

Sin embargo, cuando la frecuencia del filtro se acerca a la frecuencia de Nyquist, la especificación Q (ancho de banda) de un filtro se distorsiona mucho, por lo general, se reduce mucho (aunque el autor mencionó que realizó un pre-warping necesario).

Estoy buscando fórmulas de filtro que no tengan una distorsión de ancho de banda tan fuerte. Necesito filtros de pico / campana, paso de banda, paso bajo, paso alto, estante alto y muesca. Sé que esto se puede hacer ya que anteriormente compré fórmulas de filtro de pico / campana / paso de banda con menos distorsión, pero todavía no son perfectas y necesito otros tipos de filtros.

Entonces, también estoy dispuesto a pagar por la solución si el precio es correcto.

Alternativamente, si uno pudiera señalarme un algoritmo de optimización que funcione con filtros de dominio Z, también sería genial. Desafortunadamente, los algoritmos de optimización más habituales no funcionan bien en el dominio Z: no pueden optimizar un conjunto de parámetros para que coincida con una respuesta de frecuencia deseada (probablemente debido a las funciones periódicas utilizadas para calcular la respuesta de frecuencia).

aleksv
fuente
1
Para compensar eficazmente los artefactos de alias y deformación para filtros discretos, debe usar órdenes muy altas. FIR facilitaría mucho el diseño, pero también hay otros métodos. Para darle una respuesta significativa, me gustaría saber cuáles son exactamente sus restricciones computacionales (incluida la plataforma) y cuáles son sus requisitos de procesamiento. ¿Por qué necesita este comportamiento, y el sobremuestreo no sería suficiente?
Jazzmaniac
2
bueno, hay un límite de lo que puedes obtener con un filtro IIR de segundo orden. hay otro artículo de Orfanidis que pone la ganancia en Nyquist en algo diferente a 0 dB (el Cookbook coloca la ganancia de Nyquist en 0 dB porque así es como la transforma la transformación bilineal). para una frecuencia de muestreo de 44.1 kHz y biquad de segundo orden, no creo que le vaya mucho mejor que el diseño de Orfanidis.
Robert Bristow-Johnson
1
El mejor método que conozco no es la asignación directa al dominio discreto, sino la aplicación de solucionadores ODE al prototipo analógico. Los solucionadores específicamente implícitos hacen un gran trabajo al preservar la respuesta de frecuencia.
Jazzmaniac
1
@Jazzmaniac: ¿Por qué usar un prototipo analógico en lugar de diseñar directamente en el dominio de tiempo discreto?
Matt L.
1
@aleksv: Podría publicar un problema de diseño concreto con todas las especificaciones y ver qué se nos ocurre.
Matt L.

Respuestas:

5

Aquí hay un vistazo rápido a cómo se pueden ver los 5 grados de libertad para el ecualizador paramétrico. Es mi opinión sobre lo que Knud Christensen de tc electronic ideó hace aproximadamente una década en una convención de AES y esta patente .

así que olvídate del Cookbook (y los problemas de Q y el ancho de banda que contiene) y considera (en el plano s) el EQ paramétrico como la suma de un filtro de paso de banda (con un Q valor) en paralelo con un cable:

H(s)=(solaumentar-1)1Qsω0 0(sω0 0)2+1Qsω0 0+1+1

solaumentar=10resi20 es la ganancia del pico (o valle, si resi<0 0) la ganancia en DC y en Nyquist es de 0 dB. ese es un IIR de segundo orden y hay 3 parámetros independientes. 2 más para ir. así que a continuación agregamos un parámetro de ganancia general:

H(s)=G0((Gboost1)1Qsω0(sω0)2+1Qsω0+1+1)

eso son 4 perillas para girar. una perilla más para agregar (sin aumentar el orden del filtro) y terminaremos agregando parámetros más independientes.

entonces lo que Knud hace aquí es reemplazar ese "cable" (ese final "1"en la función de transferencia) con un prototipo de filtro de estantería que debe tener los mismos polos, los mismosQ y ω0como el BPF, por lo que el denominador es el mismo. La función de transferencia de ese estante es:

Hestante(s)=R(sω0 0)2+RQsω0 0+1(sω0 0)2+1Qsω0 0+1

dónde R10tyolt20 y tyoltes el diferencial de ganancia de la plataforma en dB. Esto es lo que compensa la ganancia en Nyquist para ser diferente de la ganancia en DC. Después de la transformación bilineal, Nyquist se ve impulsado portyoltdB y la ganancia en DC permanece sin cambios. Como elresi parámetro de impulso, el tyolt El parámetro puede ser positivo o negativo. sol0 0R es la ganancia lineal en Nyquist.

pon todo junto y obtienes:

H(s)=sol0 0((solaumentar-1)1Qsω0 0(sω0 0)2+1Qsω0 0+1+Hestante(s))=sol0 0((solaumentar-1)1Qsω0 0(sω0 0)2+1Qsω0 0+1+R(sω0 0)2+RQsω0 0+1(sω0 0)2+1Qsω0 0+1)=sol0 0R(sω0 0)2+(solaumentar+R-1)1Qsω0 0+1(sω0 0)2+1Qsω0 0+1

no importa cómo lo veas, esto tiene 5 grados de libertad y esos 5 coeficientes biquad están completamente definidos a partir de estos 5 parámetros. no importa si haces un mapa desdes a zusando la transformación blinear o la regla trapezoidal (efectivamente la misma cosa) o cualquier otro método que no cambie el orden del filtro. puede que tengas que falsificar la definición deQ o ancho de banda, puede que tenga que compensar ω0 0 y / o Qpara efectos de deformación de frecuencia (como los que se obtienen con la transformación blinear), pero si pagó mucho dinero por algo que le proporciona un filtro IIR de segundo orden, no importa si lo implementa con cualquier Forma Directa o Forma Directa transpuesta o Lattice o Normalized Ladder o la variable de estado de Hal Chamberlin o Andrew Simpson de análogo lineal con integración trapezoidal, eventualmente se obtienen 5 coeficientes y se pueden asignar a estos 5 parámetros independientes. todo es lo mismo. si pagó o no dinero por una licencia o no. la matemática es más sólida que cualquier reclamo hecho por la persona de la que está otorgando la licencia

Para su información, he resuelto, donde el verdadero pico o valle de frecuencia es cuando no es unatyolteso no es cero. La frecuencia en la que el pico o el valle ha sido empujado por la inclinación es:

ωpico = ω0 0 Q2(R-1R)solaumentar2-R+2Q2(R-1)+solaumentar2-1R+2Q2(1R-1)solaumentar2-R+2Q2(R-1)+Q4 4(R-1R)2(solaumentar2-R+2Q2(R-1))2

puedes ver eso cuando tyolt=0 0, entonces R=1 y consecuentemente ωpico=ω0 0. la ganancia máximasolaumentartambién podría tener que ajustarse un poco y eso aún no se ha resuelto. una buena primera suposición seríasolaumentarsolaumentarR o tal vez solaumentarsolaumentar-(R-1).

robert bristow-johnson
fuente
¿No puedo entender lo que estás tratando de probar? El filtro IIR de segundo orden tiene 5 grados de libertad por definición. ¿Cómo su mapeo de parámetros a coeficientes biquad ayuda a responder la pregunta original?
aleksv
entonces, una vez que quedó claro que "por supuesto, estoy hablando del filtro IIR de segundo orden" , de modo que aumentar el orden del filtro "para compensar efectivamente los artefactos de alias y deformación para filtros discretos [usando] órdenes muy altos" no es en las tarjetas, entonces, lo mejor que puedo decir de lo que dijiste, es que pagaste dinero para otorgar la licencia de IP de alguien para definir esos 5 coeficientes. y todo lo que intento decir es que este es un problema completamente resuelto. si lo pagaste o no.
robert bristow-johnson
El código de cálculo del filtro de pico que tengo también utiliza 5 parámetros: ganancia en CC, frecuencia y ganancia del borde izquierdo, frecuencia y ganancia máximas. Creo que es importante especificar la frecuencia de borde para mantener un ancho de banda estable.
aleksv
Puede ser un problema resuelto, pero ¿dónde puedo encontrar una solución? ¿Se paga o no?
aleksv
Bien, ahora mira el papel de Orfanidis , pero usa los símbolos matemáticos de arriba. esto es tan bueno como puedes hacer, porque solo tienes esos 5 botones para girar. necesitas descubrir quésol0 0 y UNA son. sol0 0UNA es la ganancia de CC (tal vez quieras que sea 0 dB o sol0 0UNA=1, no se). UNA sol0 0 es la ganancia en ω=, pero, usando la transformación bilineal, esa es la ganancia en Nyquist. así que tienes que descubrir cuál quieres que sea la ganancia en Nyquist. Sófocles tiene una sugerencia. No sé si estoy de acuerdo con eso.
robert bristow-johnson
2

@Jazz, una de las cosas que aprendimos en ingeniería eléctrica es que cualquier orden de ecuación diferencial se puede dividir en un conjunto (o "sistema") de ecuaciones diferenciales de primer orden. así que si la integración trapezoidal, con el mismo "paso de tiempo"Δtestá siendo usado consistentemente para todas las integrales de tiempo continuo, para unNODE lineal de orden th, puede reventar eso en Necuaciones diferenciales de primer orden. entonces considere solo una de esas ecuaciones diferenciales de primer orden:

nuevamente, considere emular un condensador. deje que el período de muestreo seaT=1fs ser lo mismo que el "Δt"utilizado en la regla trapezoidal.

i(t)=Cdvdt

o

v(t)=1Cti(u) du

en el dominio s es

V(s)=1s(1CI(s))

entonces la integración trapazoidal en momentos discretos es:

v(norteT)=1C-norteTyo(tu) retu=1Ck=-nortekT-TkTyo(tu) retu1Ck=-norteT2(yo(kT-T)+yo(kT))=v((norte-1)T)+1CT2(yo((norte-1)T)+yo(norteT))

o como valores de muestra de tiempo discreto

v[norte]=v[norte-1]+T2C(yo[norte]+yo[norte-1])

aplicando la transformación Z

V(z)=z-1V(z) + T2C(yo(z)+z-1yo(z))

resolviendo para V

V(z)=T21+z-11-z-1(1Cyo(z))

parece que estamos sustituyendo

1sT21+z-11-z-1

o

s2Tz-1z+1

que es precisamente lo que hace el bilineal sin compensación por deformación de frecuencia.

robert bristow-johnson
fuente
Esto es lo que generalmente se llama "prueba con el ejemplo" y apenas general. También solo trata el caso que ya dije que era trivial en los comentarios anteriores. Nuevamente, estoy hablando de solucionadores implícitos de orden superior que no dan una recursión discreta simple. Tampoco es el lugar adecuado para esta discusión, ya que su respuesta no tiene nada que ver con la pregunta original. Si mueve esto a una nueva pregunta sobre la integración de ODE, estoy dispuesto a contribuir.
Jazzmaniac
1
no, es completamente general para las ecuaciones de diferencias lineales. Estás ignorando la declaración de apertura sobre lo que aprendimos hace mucho tiempo en las clases de ingeniería eléctrica. (tanto en métodos numéricos como en teoría de control, unnortela ecuación diferencial de orden th puede dividirse en norteecuaciones diferenciales de primer orden. y luego requiero consistencia; que la misma regla trapezoidal para la integración se utiliza en todas partes.)
Robert Bristow-Johnson el
Soy plenamente consciente de la transformación de las EDO de orden superior en sistemas de EDO de primer orden. Y de nuevo, es no lo que estoy hablando. Esta afirmación no hace que su prueba sea más general, ya que simplemente afirma que el mapeo bilineal trasciende a toda la clase mientras trata solo un simple ejemplo. Aún así, no digo que tu resultado sea incorrecto, estoy hablando de diferentes solucionadores. Los solucionadores de orden superior no son solucionadores de ED de orden superior.
Jazzmaniac
lo siento Andrew Eso es un fracaso . realmente no entiendes si continúas manteniendo ese modelado del comportamiento de tiempo continuo del lineal componentes analógicos utilizando la integración trapezoidal, con el tiempo de pasoΔt siendo igual al período de muestreo T=1Fs, Entonces esa es la muy misma cosa como el uso de la transformación bilineal sin compensación de la deformación de frecuencia. Lo mismo y la prueba está arriba.
Robert Bristow-Johnson
Lo siento Robert, no soy Andrew. Y su prueba anterior es como la siguiente. Tengo dos mapas A y B, y algunos x. Tanto A (x) = c como B (x) = c, por lo tanto A = B. Eso es obviamente incorrecto. Incluso si A y B son lineales, todavía está mal. Tiene razón en que un solucionador trapezoidal de primer orden en un sistema lineal generará un sistema discreto recursivo, pero ahí es donde termina. Sigue ignorando mis afirmaciones repetidas sobre integradores de orden superior (adaptativos / implícitos). Entonces veo el fracaso de tu lado.
Jazzmaniac
2

Usando métodos de optimización, podemos acercar la respuesta de frecuencia de un filtro digital al filtro analógico objetivo.

En el siguiente experimento, un filtro de paso de banda de 6 órdenes se optimiza usando Adam, un algoritmo de optimización que se usa a menudo en el aprendizaje automático. Las frecuencias por encima de la banda de paso están excluidas de la función de costo (peso cero asignado). La respuesta del filtro optimizado se vuelve más alta que el objetivo para frecuencias muy cercanas a Nyquist, pero esa diferencia puede ser compensada por el filtro anti-aliasing de la fuente de señal (ADC o convertidor de frecuencia de muestreo). ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as clr
from scipy import signal

import tensorflow as tf

# Number of sections
M = 3

# Sample rate
f_s = 24000

# Passband center frequency
f0 = 9000

# Number of frequencies to compute
N = 2048

section_colors = np.zeros([M, 3])
for k in range(M):
    section_colors[k] = clr.hsv_to_rgb([(k / (M - 1.0)) / 3.0, 0.5, 0.75])

# Get one of BP poles that maps to LP prototype pole.
def lp_to_bp(s, rbw, w0):
    return w0 * (s * rbw / 2 + 1j * np.sqrt(1.0 - np.power(s * rbw / 2, 2)))

# Frequency response

def freq_response(z, b, a):
    p = b[0]
    q = a[0]
    for k in range(1, len(b)):
        p += b[k] * np.power(z, -k)
    for k in range(1, len(a)):
        q += a[k] * np.power(z, -k)
    return p / q

# Absolute value in decibel

def abs_db(h):
    return 20 * np.log10(np.abs(h))

# Poles of analog low-pass prototype

none, S, none = signal.buttap(M)

# Band limits
c = np.power(2, 1 / 12.0)
f_l = f0 / c
f_u = f0 * c

# Analog frequencies in radians
w0 = 2 * np.pi * f0
w_l = 2 * np.pi * f_l
w_u = 2 * np.pi * f_u

# Relative bandwidth
rbw = (w_u - w_l) / w0

jw0 = 2j * np.pi * f0
z0 = np.exp(jw0 / f_s)

# 1. Analog filter parameters

bc, ac = signal.butter(M, [w_l, w_u], btype='bandpass', analog=True)
ww, H_a = signal.freqs(bc, ac, worN=N)
magnH_a = np.abs(H_a)
f = ww / (2 * np.pi)

omega_d = ww / f_s
z = np.exp(1j * ww / f_s)

# 2. Initial filter design

a = np.zeros([M, 3], dtype=np.double)
b = np.zeros([M, 3], dtype=np.double)
hd = np.zeros([M, N], dtype=np.complex)

# Pre-warp the frequencies

w_l_pw = 2 * f_s * np.tan(np.pi * f_l / f_s)
w_u_pw = 2 * f_s * np.tan(np.pi * f_u / f_s)
w_0_pw = np.sqrt(w_l_pw * w_u_pw)

rbw_pw = (w_u_pw - w_l_pw) / w_0_pw

poles_pw = lp_to_bp(S, rbw_pw, w_0_pw)

# Bilinear transform

T = 1.0 / f_s
poles_d = (1.0 + poles_pw * T / 2) / (1.0 - poles_pw * T / 2)

for k in range(M):
    p = poles_d[k]
    b[k], a[k] = signal.zpk2tf([-1, 1], [p, np.conj(p)], 1)

    g0 = freq_response(z0, b[k], a[k])
    g0 = np.abs(g0)
    b[k] /= g0
    none, hd[k] = signal.freqz(b[k], a[k], worN=omega_d)

plt.figure(2)
plt.title("Initial digital filter (bilinear)")

plt.axis([0, f_s / 2, -90, 10])

plt.plot(f, abs_db(H_a), label='Target response', color='gray', linewidth=0.5)

for k in range(M):
    label = "Section %d" % k
    plt.plot(f, abs_db(hd[k]), color=section_colors[k], alpha=0.5, label=label)

# Combined frequency response of initial digital filter

Hd = np.prod(hd, axis=0)
plt.plot(f, abs_db(Hd), 'k', label='Cascaded filter')
plt.legend(loc='upper left')

plt.figure(3)
plt.title("Initial filter - poles and zeros")
plt.axis([-3, 3, -2.25, 2.25])
unitcircle = plt.Circle((0, 0), 1, color='lightgray', fill=False)
ax = plt.gca()
ax.add_artist(unitcircle)

for k in range(M):
    zeros, poles, gain = signal.tf2zpk(b[k], a[k])
    plt.plot(np.real(poles), np.imag(poles), 'x', color=section_colors[k])
    plt.plot(np.real(zeros), np.imag(zeros), 'o', color='none', markeredgecolor=section_colors[k], alpha=0.5)

# Optimizing filter

tH_a = tf.constant(magnH_a, dtype=tf.float32)

# Assign weights

weight = np.zeros(N)
for i in range(N):
    # In the passband or below?
    if (f[i] <= f_u):
        weight[i] = 1.0

tWeight = tf.constant(weight, dtype=tf.float32)
tZ = tf.placeholder(tf.complex64, [1, N])

# Variables to be changed by optimizer
ta = tf.Variable(a)
tb = tf.Variable(b)
ai = a
bi = b

# TF requires matching types for multiplication;
# cast real coefficients to complex
cta = tf.cast(ta, tf.complex64)
ctb = tf.cast(tb, tf.complex64)

xb0 = tf.reshape(ctb[:, 0], [M, 1])
xb1 = tf.reshape(ctb[:, 1], [M, 1])
xb2 = tf.reshape(ctb[:, 2], [M, 1])

xa0 = tf.reshape(cta[:, 0], [M, 1])
xa1 = tf.reshape(cta[:, 1], [M, 1])
xa2 = tf.reshape(cta[:, 2], [M, 1])

# Numerator:   B = b₀z² + b₁z + b₂
tB = tf.matmul(xb0, tf.square(tZ)) + tf.matmul(xb1, tZ) + xb2

# Denominator: A = a₀z² + a₁z + a₂
tA = tf.matmul(xa0, tf.square(tZ)) + tf.matmul(xa1, tZ) + xa2

# Get combined frequency response
tH = tf.reduce_prod(tB / tA, axis=0)

iterations = 2000
learning_rate = 0.0005

# Cost function
cost = tf.reduce_mean(tWeight * tf.squared_difference(tf.abs(tH), tH_a))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

zz = np.reshape(z, [1, N])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    for epoch in range(iterations):
        loss, j = sess.run([optimizer, cost], feed_dict={tZ: zz})
        if (epoch % 100 == 0):
            print("  Cost: ", j)

    b, a = sess.run([tb, ta])

for k in range(M):
    none, hd[k] = signal.freqz(b[k], a[k], worN=omega_d)

plt.figure(4)
plt.title("Optimized digital filter")

plt.axis([0, f_s / 2, -90, 10])

# Draw the band limits
plt.axvline(f_l, color='black', linewidth=0.5, linestyle='--')
plt.axvline(f_u, color='black', linewidth=0.5, linestyle='--')

plt.plot(f, abs_db(H_a), label='Target response', color='gray', linewidth=0.5)

Hd = np.prod(hd, axis=0)
for k in range(M):
    label = "Section %d" % k
    plt.plot(f, abs_db(hd[k]), color=section_colors[k], alpha=0.5, label=label)

magnH_d = np.abs(Hd)
plt.plot(f, abs_db(Hd), 'k', label='Cascaded filter')
plt.legend(loc='upper left')

plt.figure(5)
plt.title("Optimized digital filter - Poles and Zeros")
plt.axis([-3, 3, -2.25, 2.25])
unitcircle = plt.Circle((0, 0), 1, color='lightgray', fill=False)
ax = plt.gca()
ax.add_artist(unitcircle)

for k in range(M):
    zeros, poles, gain = signal.tf2zpk(b[k], a[k])
    plt.plot(np.real(poles), np.imag(poles), 'x', color=section_colors[k])
    plt.plot(np.real(zeros), np.imag(zeros), 'o', color='none', markeredgecolor=section_colors[k], alpha=0.5)

plt.show()
igorinov
fuente
"Las frecuencias por encima de la banda de paso están excluidas de la función de costo (peso cero asignado)" ¿No hay peligro de que el filtro se convierta en una especie de filtro de paso alto? Las frecuencias superiores a la banda de paso podrían tener una gran ganancia sin penalización dada por dicha función de costo.
Olli Niemitalo
Bien, pensé que un método de regresión de símbolos produciría una ecuación finalizada ... probablemente para la mayoría de los casos, no todos. mientras que en tiempo real sin derivados? la optimización es un poco lenta
aleksv
1
@OlliNiemitalo: Para algunas frecuencias, cae a cero después de la banda de paso, como el filtro inicial.
igorinov
1
@aleksv: Hay otra solución de forma cerrada que no se ha mencionado aquí: khabdha.org/wp-content/uploads/2008/03/…
igorinov
1
Con tensorflow-gpu1.12.0 la optimización no es convergente, sino divergente. tensorflow1.12.0 funciona mejor pero la optimización no converge completamente, debido a la elección del optimizador (Adam) y su tasa de aprendizaje, y posiblemente debido a la forma en que se formula la función de costo. Otorgaré la recompensa por esta respuesta, porque muestra un enfoque moderno para la optimización de coeficientes: diferenciación automática. Todavía me gustaría ver: una optimización más estable y la organización de los coeficientes obtenidos para su uso en tiempo real (como barridos de parámetros).
Olli Niemitalo
1

Se me ocurrió un diseño para el ecualizador de pico de 10dB. Elegí 20 filtros con frecuencias centrales entre 500 Hz y 16 kHz (Fs = 48 kHz). La trama superior a continuación es el diseño de acuerdo con Audio-EQ-Cookbook de RBJ , que es bueno pero que conduce a una distorsión del ancho de banda cuando las frecuencias centrales se acercan a Nyquist. La trama inferior es el nuevo diseño donde los filtros coinciden muy estrechamente con los filtros prototipo analógicos: ingrese la descripción de la imagen aquí

Y así es como se ven los nuevos filtros de muesca en comparación con el Cookbook (ancho de banda = 4 octavas, el más alto F0 0=23 kHz): ingrese la descripción de la imagen aquí

La siguiente figura muestra un diseño de filtro de paso bajo (Q=2, F0 0=dieciséis kHz Fs=48kHz). Tenga en cuenta que el nuevo diseño se aproxima al prototipo analógico y, por esta razón, no funciona como un filtro de paso bajo convencional (no tiene cero en Nyquist):

ingrese la descripción de la imagen aquí

Matt L.
fuente
Matt, podría sugerir trazar el "peakingEQ" para, por ejemplo, un aumento de 10 dB con un valor fijo siW, digamos 1 octava, y para una variedad de frecuencias pico, acercándose a Nyquist. a pesar de que el Cookbook hace una compensación de primer orden ensiW multiplicando por ω0 0Tpecado(ω0 0T), todavía no puede cambiar el hecho de que la respuesta de frecuencia debe ser continua y tener derivadas continuas y debe ser simétrica respecto de Nyquist. incluso si aumenta la ganancia en Nyquist como lo hace Orfanidis. eso, en sí mismo, es la fuente de esta respuesta de frecuencia deformada.
Robert Bristow-Johnson
1
Creo que espera ver un filtro digital, con una frecuencia de muestreo tan baja como 44,1 kHz, que coincida con el filtro analógico, incluso si la frecuencia de resonancia está justo por debajo de Nyquist. Esto es algo de lo que me había estado preocupando hace 2 décadas y todo lo que puedo pensar en hacer fácilmente es simplemente compensar la reducción del ancho de banda que hace la transformación bilineal. entonces Orfanidis cambió una suposición (que la ganancia en Nyquist es 0 dB), y eso ayudó un poco más. pero lo que realmente ayuda es simplemente aumentar la frecuencia de muestreo.
Robert Bristow-Johnson
Gracias por un intento La primera trama de Cookbook es lo que quiero, pero como también señaló Robert, con la ganancia en Nyquist no es cero. También será beneficioso dibujar las respuestas en la escala logarítmica en el rango, por ejemplo, 20 Hz a Nyquist. Los ecualizadores de audio rara vez usan una escala de frecuencia lineal. Y el ancho de banda generalmente se especifica en octavas. Cualquier biquads no tiene problemas con la frecuencia de centro / esquina de hasta aproximadamente 300 Hz, pero ir más alto revela el problema.
aleksv
No, me refiero a 0 a 300 Hz, frecuencias más bajas. Por encima de 300 Hz hasta Nyquist, estas fórmulas de filtro de Cookbook producen una distorsión de forma de filtro que aumenta progresivamente. Por supuesto, la frecuencia de muestreo es 44100 o 48000 como de costumbre.
aleksv
Tienes que trazar el gráfico en la escala logarítmica. Es la distorsión del ancho de banda en la escala LOG lo que me molesta. No hay distorsión presente en las frecuencias más bajas cuando se ve en la escala logarítmica. Los filtros de muesca, de paso bajo, de estante alto siempre tienen una ganancia de 0 dB (unidad) en CC.
aleksv