Como as seções de biquad em cascata para filtros de ordem superior funcionam?

20

Estou tentando implementar um filtro IIR de 8ª ordem e todas as anotações e livros didáticos que li dizem que é melhor implementar qualquer filtro de ordem superior a 2 como seções de segunda ordem. Eu usei tf2sosno MATLAB para obter os coeficientes para seções de segunda ordem, o que me deu coeficientes 6x4 para seções de 4 segunda ordem, conforme o esperado. Antes da implementação como SOS, o filtro de 8ª ordem exigia que 7 valores de amostra anteriores fossem armazenados (e também valores de saída). Agora, ao implementar como seções de segunda ordem, como o fluxo funciona da entrada para a saída, preciso armazenar apenas 2 valores de amostra anteriores? Ou a saída do primeiro filtro é alimentada como x_ino segundo filtro e assim por diante?

anasimtiaz
fonte
u precisa armazenar estados anteriores para cada etapa, dependendo da ordem do filtro nessa fase para que ele não seria apenas 2 como u mencionado

Respostas:

13

É a última coisa que você disse ("Ou a saída do primeiro filtro é alimentada como x_in no segundo filtro e assim por diante?"). A idéia é simples: você trata os biquads como filtros de segunda ordem separados que estão em cascata. A saída do primeiro filtro é a entrada para o segundo, e assim por diante, para que as linhas de atraso se espalhem entre os filtros. Se você precisar otimizar a estrutura em um ambiente com restrição de memória, observe que biquads adjacentes possuem memória de atraso redundante (ou seja, as últimas amostras de saída do estágio 1 são iguais às últimas amostras de entrada do estágio 2, portanto, você não deve é necessário armazená-los separadamente, como você faria se apenas implementasse os filtros isoladamente).

Jason R
fonte
Obrigado! Eu apenas consegui fazê-lo rapidamente no MATLAB. A causa da confusão no início foi que eu esqueci de multiplicar o ganho (ugh!) E, logo, todos os tipos de idéias começou a rastejar dentro.
anasimtiaz
Se você não se importa em pedir o ganho como argumento de saída do tf2sos (como no meu código de exemplo publicado), não precisa se preocupar em multiplicá-lo novamente.
Aprendi
9

Na verdade, existem duas maneiras de implementar seções de segunda ordem: paralela e serial. Na versão serial, as saídas da seção N são as entradas da seção N + 1. Na versão paralela, todas as seções têm a mesma entrada (e apenas um zero real em vez de um par de zeros complexo conjugado) e a saída de cada seção é simplesmente resumida. Os dois métodos estão relacionados através da expansão de fração parcial da função de transferência do domínio Z. AVISO: esse é um problema numericamente complicado, e a implementação padrão do Matlab "residuez" pode ter erros numéricos muito grandes para filtros de áudio típicos que possuem pólos próximos ao círculo da unidade.

Hilmar
fonte
6

Aqui está um pouco de código de demonstração para mostrar por que você é melhor em cascata de seções de 2ª ordem.

clc

sr = 44100;
order = 13;

[b,a] = butter(order,1000/(sr/2),'low');
[sos] = tf2sos(b,a);

x = [1; zeros(299,1)]; %impulse


% all in one
Y = filter(b,a,x);

% cascaded biquads
Z = x;
for nn = 1:size(sos,1);
    Z = filter(sos(nn,1:3),sos(nn,4:6), Z );
end


cla; plot(Y, 'k'); hold on; plot(Z,':r'); hold off

Para o filtro passa-baixo fornecido no exemplo acima, por ordens de cerca de 12 a 13, os erros numéricos são acumulados para fornecer uma resposta de impulso visivelmente diferente para a implementação que não usa biquads em cascata. Dependendo do filtro, sua milhagem varia.

ORDEM = 10

insira a descrição da imagem aqui

PEDIDO = 13

insira a descrição da imagem aqui

learnvst
fonte
@learvst Corrija-me se estiver errado, mas o seu código perde os ganhos. Não deveria ser:[sos gain] = tf2sos(b,a); // Rest of code for nn = 1:size(sos,1); Z = filter(sos(nn,1:3),sos(nn,4:6), Z ); end Z = filter(gain,1,Z);
user915783