
Una biblioteca de filtro de respuesta de impulso infinito (IIR) para Linux, Mac OSX y Windows que implementa los filtros de Butterworth, RBJ, Chebychev y puede importar fácilmente coeficientes generados por Python (SciPY).
El filtro procesa la muestra de datos por muestra para el procesamiento en tiempo real.
Utiliza plantillas para asignar la memoria requerida para que pueda ejecutarse sin ningún comandos malloc / nuevos. La memoria se asigna en el momento de la compilación para que nunca haya el riesgo de filtraciones de memoria.
Todo el código de filtro en tiempo real se encuentra en los archivos de encabezado que garantizan una integración eficiente en el programa principal y el compilador puede optimizar tanto el código de filtro como el programa principal al mismo tiempo.
Agregue la siguiente declaración de inclusión a su código:
#include "Iir.h"
El enfoque de codificación general es que primero el filtro se instancia especificando su orden, luego los parámetros se establecen con la setup la función y luego está listo para usarse para la muestra mediante un filtrado en tiempo real de muestra.
La idea es asignar la memoria del filtro en el momento de la compilación con un argumento de plantilla para evitar cualquier comando nuevo. Esto evita las fugas de memoria y se puede optimizar en el momento de la compilación. El order proporcionado a la plantilla (por ejemplo aquí para un filtro de paso bajo):
Iir::Butterworth::LowPass<order> f;
se usa como el orden predeterminado por el comando setup a continuación, pero se puede anular por un orden inferior si es necesario.
setupTodos los filtros están disponibles como filtros de paso bajo, paso alto, paso de banda y parada de banda/muesca. Butterworth/Chebyshev ofrece también con capas de banda baja/alta/con ganancia de banda de paso especificada y ganancia de 0dB en la banda de parada.
Las frecuencias pueden ser análogas contra la velocidad de muestreo o las normalizadas entre 0..1/2, donde 1/2 es la frecuencia nyquist. Tenga en cuenta que las frecuencias normalizadas son simplemente F = F/FS y están en unidades de 1/muestras. Internamente, la biblioteca utiliza frecuencias normalizadas y los comandos de configuración simplemente dividen por la tasa de muestreo si se da. Elegir entre:
setup : velocidad de muestreo y las frecuencias de corte analógicassetupN : frecuencias normalizadas en 1/muestras entre F = 0..1/2 donde 1/2 = nyquist. La setup de forma predeterminada utiliza el orden suministrado por el argumento de la plantilla, pero puede ser anulado por órdenes de filtro más bajas.
Vea los archivos de encabezado en iir o la documentación para los argumentos de los comandos setup .
Los ejemplos a continuación son para filtros de paso bajo:
Butterworth.h Filtro estándar adecuado para la mayoría de las aplicaciones. Respuesta monotónica. const int order = 4; // 4th order (=2 biquads)
Iir::Butterworth::LowPass<order> f;
const float samplingrate = 1000; // Hz
const float cutoff_frequency = 5; // Hz
f.setup (samplingrate, cutoff_frequency);
o especificar una frecuencia normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency);
ChebyshevI.h con Ripple de banda de pases permisible en DB. Iir::ChebyshevI::LowPass<order> f;
const float passband_ripple_in_db = 5;
f.setup (samplingrate,
cutoff_frequency,
passband_ripple_in_dB);
o especificar una frecuencia normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency,passband_ripple_in_dB);
ChebyshevII.h con el peor rechazo de la banda de parada permitida en DB. Iir::ChebyshevII::LowPass<order> f;
double stopband_ripple_in_dB = 20;
f.setup (samplingrate,
cutoff_frequency,
stopband_ripple_in_dB);
o especificar una frecuencia normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency,stopband_ripple_in_dB);
RBJ.h Filtros de segundo orden con corte y factor Q. Iir::RBJ::LowPass f;
const float cutoff_frequency = 100;
const float Q_factor = 5;
f.setup (samplingrate, cutoff_frequency, Q_factor);
o especificar una frecuencia normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency, Q_factor);
Custom.h ########
# Python
# See "elliptic_design.py" for the complete code.
from scipy import signal
order = 4
sos = signal.ellip(order, 5, 40, 0.2, 'low', output='sos')
print(sos) # copy/paste the coefficients over & replace [] with {}
///////
// C++
// part of "iirdemo.cpp"
const double coeff[][6] = {
{1.665623674062209972e-02,
-3.924801366970616552e-03,
1.665623674062210319e-02,
1.000000000000000000e+00,
-1.715403014004022175e+00,
8.100474793174089472e-01},
{1.000000000000000000e+00,
-1.369778997100624895e+00,
1.000000000000000222e+00,
1.000000000000000000e+00,
-1.605878925999785656e+00,
9.538657786383895054e-01}
};
const int nSOS = sizeof(coeff) / sizeof(coeff[0]); // here: nSOS = 2 = order / 2
Iir::Custom::SOSCascade<nSOS> cust(coeff);
Las muestras se procesan una por una. En el ejemplo a continuación, una muestra x se procesa con el comando filter y luego se guarda en y . Los tipos de x e y pueden ser flotantes o dobles (también se permite el entero, pero aún se procesa internamente como punto flotante):
y = f.filter(x);
Esto se repite para cada muestra entrante en un bucle o controlador de eventos.
Los valores no válidos proporcionados a setup() lanzarán una excepción. Los parámetros proporcionados a setup() que dan como resultado que los coeficientes sean nan también lanzarán una excepción.
Puede apagar el manejo de la exepción definiendo IIR1_NO_EXCEPTIONS a través de CMake o en su programa.
Si usa CMake como su sistema de compilación, simplemente agregue a sus CMakeLists.txt las siguientes líneas para la biblioteca dinámica:
find_package(iir)
target_link_libraries(... iir::iir)
o para el estático:
find_package(iir)
target_link_libraries(... iir::iir_static)
Enlace con la biblioteca dinámica (Unix/Mac: -liir , Windows: iir.lib ) o la biblioteca estática (Unix/Mac: libiir_static.a , Windows: libiir_static.lib ).
Si está utilizando Ubuntu LTS, puede instalar esta biblioteca como un paquete precompilado.
Agregue este repositorio a su sistema:
sudo add-apt-repository ppa:berndporr/dsp
Luego instale los paquetes:
sudo apt install iir1sudo apt install iir1-devEstá disponible para Intel de 64 bits y 32,64 bits Arm (Raspberry Pi, etc.). La documentación del paquete de desarrollo y los programas de ejemplo están en:
/usr/share/doc/iir1-dev/
La herramienta de compilación es cmake que genera los archivos de marca o proyecto para las diferentes plataformas. cmake está disponible para Linux, Windows y Mac. También se compila directamente en una Raspberry Pi.
Correr
cmake .
que genera el makefile. Luego corre:
make
sudo make install
que lo instala debajo /usr/local/lib y /usr/local/include .
Tanto GCC como Clang han sido probados.
cmake -G "Visual Studio 16 2019" -A x64 .
Ver cmake para las diferentes opciones de construcción. Arriba es para una construcción de 64 bits. Luego inicie Visual C ++ y abra la solución. Esto creará los archivos DLL y Lib. En Windows se recomienda usar la biblioteca estática y vincularla al programa de aplicaciones.
Ejecute las pruebas unitarias escribiendo make test o simplemente ctest . Estos prueban si después de un pulso delta todos los filtros se relajan a cero, que sus salidas nunca se vuelven nan y si los filtros de forma directa I y II calculan las secuencias esperadas comparándolas a partir de los resultados creados por la salida de sosfilt de Scipy.
Puede deshabilitar la generación de pruebas configurando IIR1_BUILD_TESTING en OFF.
La forma más fácil de aprender es de los ejemplos que se encuentran en el directorio demo . Un pulso delta como señal de prueba se envía a los diferentes filtros y se guarda en un archivo. Con el script de Python plot_impulse_fresponse.py puede trazar las respuestas de frecuencia.
Puede deshabilitar la compilación de las demostraciones configurando IIR1_BUILD_DEMO en OFF.
También el directorio que contiene las pruebas unitarias proporciona ejemplos para cada tipo de filtro.
Un PDF de todas las clases, métodos y, en particular, las funciones setup se encuentra en el directorio docs/pdf .
La documentación en línea está aquí: http://berndporr.github.io/iir1
Estas respuestas han sido generadas por iirdemo.cpp en el directorio /demo/ y luego se han trazado con plot_impulse_fresponse.py .







Esta biblioteca se ha desarrollado aún más el gran trabajo original de Vinnie Falco que se puede encontrar aquí:
https://github.com/vinniefalco/dspfilters
Mientras que la biblioteca original procesa matrices de audio, esta biblioteca se ha adaptado para hacer una muestra rápida de procesamiento en tiempo real por muestra. El comando setup no requerirá el orden de filtro y, en su lugar, lo recuerda del argumento de plantilla. La estructura de clase se ha simplificado y todas las funciones documentadas para Doxygen. En lugar de tener declaraciones de afirmar (), esta Libary arroja excepciones en caso de que un parámetro esté mal. Se ha eliminado cualquier diseño de filtro que requiera optimización (por ejemplo, filtros elípicos) y, en cambio, se ha agregado una función que puede importar coeficientes fácilmente de SciPY.
Bernd Porr - http://www.berndporr.me.uk