
Uma biblioteca de filtro de resposta a impulso infinito (IIR) para filtros Linux, Mac OSX e Windows, que implementa os filtros Butterworth, RBJ, Chebychev e pode facilmente importar coeficientes gerados pelo Python (SCIPY).
O filtro processa a amostra de dados por amostra para processamento em tempo real.
Ele usa modelos para alocar a memória necessária para que possa ser executado sem nenhum comando malloc / novos. A memória é alocada no tempo de compilação, para que nunca haja o risco de vazamentos de memória.
Todo o código do filtro em tempo real está nos arquivos de cabeçalho que garante integração eficiente no programa principal e o compilador pode otimizar o código do filtro e o programa principal ao mesmo tempo.
Adicione o seguinte inclua declaração ao seu código:
#include "Iir.h"
A abordagem de codificação geral é que, primeiro, o filtro é instanciado especificando seu pedido, os parâmetros são definidos com a setup da função e, em seguida, está pronto para ser usado para amostra por amostra em tempo real.
A idéia é alocar a memória do filtro no momento da compilação com um argumento de modelo para evitar novos comandos. Isso evita vazamentos de memória e pode ser otimizado no momento da compilação. O order fornecido ao modelo (por exemplo, aqui para um filtro de pasta baixa):
Iir::Butterworth::LowPass<order> f;
é usado como o pedido padrão pelo comando setup abaixo, mas pode ser substituído por uma ordem inferior, se necessário.
setupTodos os filtros estão disponíveis como filtros LowPass, HighPass, BandPass e Bandstop/Notch. Butterworth/Chebyshev também oferecem-shelves baixas/altas/de banda com ganho de banda passante especificada e ganho de 0DB na faixa de parada.
As frequências podem ser analógicas contra a taxa de amostragem ou as normalizadas entre 0..1/2, onde 1/2 é a frequência nyquista. Observe que as frequências normalizadas são simplesmente f = f/fs e estão em unidades de 1/amostras. Internamente, a biblioteca usa frequências normalizadas e os comandos de configuração simplesmente se dividem pela taxa de amostragem, se fornecida. Escolha entre:
setup : taxa de amostragem e as frequências de corte analógicassetupN : frequências normalizadas em 1/amostras entre f = 0..1/2 onde 1/2 = nyquist. Por padrão, setup usa a ordem fornecida pelo argumento do modelo, mas pode ser substituída por pedidos de filtro inferior.
Consulte os arquivos de cabeçalho em iir ou a documentação para os argumentos dos comandos setup .
Os exemplos abaixo são para filtros LowPass:
Butterworth.h Filtro padrão adequado para a maioria das aplicações. Resposta 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);
ou especifique uma frequência normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency);
ChebyshevI.h com ondulação permitida de banda passada em dB. Iir::ChebyshevI::LowPass<order> f;
const float passband_ripple_in_db = 5;
f.setup (samplingrate,
cutoff_frequency,
passband_ripple_in_dB);
ou especifique uma frequência normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency,passband_ripple_in_dB);
ChebyshevII.h com pior rejeição de banda de parada permitida em dB. Iir::ChebyshevII::LowPass<order> f;
double stopband_ripple_in_dB = 20;
f.setup (samplingrate,
cutoff_frequency,
stopband_ripple_in_dB);
ou especifique uma frequência normalizada entre 0..1/2:
f.setupN(norm_cutoff_frequency,stopband_ripple_in_dB);
RBJ.h FILTROS DE 2ª ORDEM com corte e fator Q. Iir::RBJ::LowPass f;
const float cutoff_frequency = 100;
const float Q_factor = 5;
f.setup (samplingrate, cutoff_frequency, Q_factor);
ou especifique uma frequência 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);
As amostras são processadas uma a uma. No exemplo abaixo, uma amostra x é processada com o comando filter e salva em y . Os tipos de x e y podem ser flutuantes ou duplos (também é permitido o número inteiro, mas ainda é processado internamente como ponto flutuante):
y = f.filter(x);
Isso é repetido para cada amostra recebida em um loop ou manipulador de eventos.
Os valores inválidos fornecidos para setup() lançarão uma exceção. Os parâmetros fornecidos para setup() que resultam em coeficientes sendo NAN também lançarão uma exceção.
Você pode desligar o manuseio de exepção definindo IIR1_NO_EXCEPTIONS via cMake ou em seu programa.
Se você usar o cmake como sistema de compilação, basta adicionar aos seus CMakeLists.txt as seguintes linhas para a biblioteca dinâmica:
find_package(iir)
target_link_libraries(... iir::iir)
ou para o estático:
find_package(iir)
target_link_libraries(... iir::iir_static)
Ligue -o na biblioteca dinâmica (Unix/Mac: -liir , Windows: iir.lib ) ou na biblioteca estática (Unix/Mac: libiir_static.a , windows: libiir_static.lib ).
Se você estiver usando o Ubuntu LTS, poderá instalar esta biblioteca como um pacote pré-compilado.
Adicione este repositório ao seu sistema:
sudo add-apt-repository ppa:berndporr/dsp
Em seguida, instale os pacotes:
sudo apt install iir1sudo apt install iir1-devEstá disponível para Intel de 64 bits e braço de 32,64 bits (Raspberry Pi etc). A documentação do pacote de desenvolvimento e os programas de exemplo estão em:
/usr/share/doc/iir1-dev/
A ferramenta Build é cmake , que gera os arquivos de maquiagem ou projeto para as diferentes plataformas. cmake está disponível para Linux, Windows e Mac. Ele também compila diretamente em um Raspberry Pi.
Correr
cmake .
que gera o makefile. Em seguida, corra:
make
sudo make install
que o instala em /usr/local/lib e /usr/local/include .
Tanto o GCC quanto o clang foram testados.
cmake -G "Visual Studio 16 2019" -A x64 .
Veja cmake para as diferentes opções de construção. Acima é para uma construção de 64 bits. Em seguida, inicie o Visual C ++ e abra a solução. Isso criará os arquivos DLL e Lib. No Windows, é altamente recomendável usar a biblioteca estática e vinculá -la ao programa de aplicativos.
Execute testes de unidade digitando make test ou apenas ctest . Esse teste, se após um pulso delta, todos os filtros relaxam para zero, que suas saídas nunca se tornarão NAN e se os filtros Direct I e II calcularem as sequências esperadas comparando -as dos resultados criados pela saída do sosfilt do SCIPY.
Você pode desativar a geração de testes definindo IIR1_BUILD_TESTING para desligar.
A maneira mais fácil de aprender é com os exemplos que estão no diretório demo . Um pulso delta como sinal de teste é enviado para os diferentes filtros e salvo em um arquivo. Com o script python plot_impulse_fresponse.py você pode plotar as respostas de frequência.
Você pode desativar a compilação das demos, definindo IIR1_BUILD_DEMO para desligar.
Além disso, o diretório que contém os testes de unidade fornece exemplos para cada tipo de filtro.
Um PDF de todas as classes, métodos e, em particular, funções setup está no diretório docs/pdf .
A documentação on -line está aqui: http://berndporr.github.io/iir1
Essas respostas foram geradas pelo iirdemo.cpp no diretório /demo/ e depois plotadas com plot_impulse_fresponse.py .







Esta biblioteca foi desenvolvida a partir do ótimo trabalho original de Vinnie Falco, que pode ser encontrado aqui:
https://github.com/vinnieftalco/dspfilters
Enquanto a biblioteca original processa matrizes de áudio, essa biblioteca foi adaptada para fazer amostra de processamento rápida em tempo real por amostra. O comando setup não exigirá a ordem do filtro e, em vez disso, lembra -o do argumento do modelo. A estrutura da classe foi simplificada e todas as funções documentadas para doxygen. Em vez de ter declarações assert (), este Libary lança exceções, caso um parâmetro esteja errado. Qualquer design de filtro que requer otimização (por exemplo, filtros elípicos) foi removido e, em vez disso, foi adicionada uma função que pode importar coeficientes facilmente do SCIPY.
Bernd Porr - http://www.berndpor.me.uk