Bagaimana cara kerja bagian cascading biquad untuk filter pesanan lebih tinggi?

20

Saya mencoba menerapkan filter IIR urutan ke-8 dan setiap catatan aplikasi dan buku teks yang saya baca mengatakan bahwa yang terbaik adalah menerapkan filter urutan apa pun lebih dari 2 sebagai bagian urutan kedua. Saya menggunakan tf2sosMATLAB untuk mendapatkan koefisien untuk bagian urutan kedua yang memberi saya koefisien 6x4 untuk bagian urutan kedua, seperti yang diharapkan. Sebelum diimplementasikan sebagai SOS, filter urutan 8 membutuhkan 7 nilai sampel sebelumnya untuk disimpan (dan juga nilai-nilai keluaran). Sekarang ketika menerapkan sebagai bagian urutan kedua bagaimana aliran bekerja dari input ke output, apakah saya harus menyimpan hanya 2 nilai sampel sebelumnya? Atau apakah output dari filter pertama x_inmasuk ke filter kedua dan seterusnya?

anasimtiaz
sumber
Anda perlu menyimpan status sebelumnya untuk setiap tahap, tergantung pada urutan filter pada tahap itu sehingga tidak hanya 2 seperti yang Anda sebutkan

Jawaban:

13

Ini adalah hal terakhir yang Anda katakan ("Atau apakah output dari umpan filter pertama sebagai x_in masuk ke filter kedua dan seterusnya?"). Idenya sederhana: Anda memperlakukan biquads sebagai filter orde kedua terpisah yang ada di kaskade. Output dari filter pertama adalah input ke filter kedua, dan seterusnya, sehingga garis penundaan tersebar di antara filter. Jika Anda perlu mengoptimalkan struktur dalam lingkungan yang dibatasi memori, Anda dapat mencatat bahwa biquads yang berdekatan memiliki memori tunda yang berlebihan (yaitu beberapa sampel keluaran terakhir dari tahap 1 sama dengan beberapa sampel masukan terakhir dari tahap 2, jadi Anda tidak perlu harus menyimpannya secara terpisah seperti yang Anda lakukan jika Anda hanya menerapkan filter secara terpisah).

Jason R
sumber
Terima kasih! Saya baru saja berhasil melakukannya dengan cepat di MATLAB. Penyebab kebingungan sebelumnya adalah bahwa saya lupa melipatgandakan perolehan (ugh!) Dan karenanya segala macam ide mulai merayap masuk.
anasimtiaz
Jika Anda tidak repot meminta gain sebagai argumen keluaran dari tf2sos (seperti pada contoh kode saya yang diposting) maka Anda tidak perlu repot-repot mengalikannya kembali.
learnvst
9

Sebenarnya ada dua cara untuk mengimplementasikan bagian urutan kedua: paralel dan serial. Dalam versi serial, output dari bagian N adalah input ke bagian N + 1. Dalam versi paralel semua bagian memiliki input yang sama (dan hanya satu nol nyata daripada pasangan konjugat nol nol) dan setiap output bagian diringkas secara sederhana. Kedua metode terkait melalui ekspansi sebagian-fraksi dari fungsi transfer Z-domain. PERINGATAN: ini adalah masalah yang rumit secara numerik dan implementasi Matlab standar "residuez" dapat memiliki kesalahan numerik yang sangat besar untuk filter audio tipikal yang memiliki kutub dekat dengan lingkaran unit.

Hilmar
sumber
6

Berikut adalah sedikit kode demo untuk menunjukkan mengapa Anda lebih baik membuat bagian urutan ke-2.

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

Untuk filter lowpass yang diberikan dalam contoh di atas, dengan pesanan sekitar 12 hingga 13, kesalahan numerik menumpuk untuk memberikan respons impuls yang tampak berbeda untuk implementasi yang tidak menggunakan biquad bertingkat. Tergantung pada filternya, jarak tempuh Anda akan bervariasi.

ORDER = 10

masukkan deskripsi gambar di sini

ORDER = 13

masukkan deskripsi gambar di sini

belajar
sumber
@learvst Perbaiki saya jika saya salah, tetapi kode Anda melewatkan keuntungan. Bukankah seharusnya:[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