Bagaimana cara kerja filter low-pass secara programatik?


9

Saya telah mengerjakan filter low pass sederhana untuk pengukuran <100 Hz dalam aplikasi saya. Namun sejauh ini, saya berjuang dengan teori di balik itu semua. Sangat keren saya membuatnya bekerja, tetapi saya akan benar-benar menikmatinya jika saya tahu bagaimana / mengapa itu bekerja.

Saya menemukan kode berikut:

void getLPCoefficientsButterworth2Pole(const int samplerate, const double cutoff, double* const ax, double* const by)
{
    double PI = M_PI;
    double sqrt2 = sqrt(2);

    double QcRaw  = (2 * PI * cutoff) / samplerate; // Find cutoff frequency in [0..PI]
    double QcWarp = tan(QcRaw); // Warp cutoff frequency

    double gain = 1 / ( 1 + sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) );

    by[2] = ( 1 - sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) ) * gain;
    by[1] = ( 2 - 2 * 2 / ( QcWarp * QcWarp ) ) * gain;
    by[0] = 1;

    ax[0] = 1 * gain;
    ax[1] = 2 * gain;
    ax[2] = 1 * gain;
}

Untuk menghitung Koefisien. Kemudian, dalam sampel audio, saya 'lulus rendah' ​​dengan cara ini:

        xv[2] = xv[1];
        xv[1] = xv[0];

        xv[0] = pData[j];
        yv[2] = yv[1];
        yv[1] = yv[0];

        yv[0] = (ax[0] * xv[0] + ax[1] * xv[1] + ax[2] * xv[2]
                   - by[1] * yv[0]
                   - by[2] * yv[1]);

        pData[j] = yv[0];

Untuk mendapatkan desain lowpass.

Saya bertanya-tanya beberapa hal:

  1. Saya menerima sampel audio dalam float * array sederhana. Berapa nomor float itu? Satu-satunya hal yang saya lihat adalah angka, bagaimana itu sepotong suara?
  2. Kode menggunakan perhitungan sebelumnya (tiga di antaranya) dalam perhitungan baru per sampel. Apakah itu berarti bahwa 2 sampel data pertama tidak difilter dengan benar? (Bukan berarti itu penting karena hanya 2 sampel, tetapi hanya ingin tahu)
  3. Mencoba mempelajari semuanya, saya menemukan beberapa formula untuk filter Butterworth (2nd Pole). Bagaimana rumus-rumus itu tercermin dalam kode ini? Tidak ada rumus yang saya temukan memiliki perhitungan ini yang dapat Anda lihat di fungsi 'getLPCoefficientsButterworth2Pole ()'.

1
Saya tidak mencoba untuk tidak sopan di sini, tetapi pernyataan Anda "bagaimana itu sepotong suara?" tampaknya menunjukkan bahwa Anda tidak memahami prinsip dasar pemrosesan diskrit waktu. Akan sangat sulit untuk mengatasi masalah DSP tanpa memahami dasar-dasar seperti teorema pengambilan sampel, kuantisasi, sistem LTI, dll. Saya akan merekomendasikan beberapa waktu dengan buku teks yang bagus. Yang ini gratis dspguide.com/pdfbook.htm
Hilmar

Jawaban:


6
  1. Nomor float * array adalah penunjuk ke array. Ini adalah nomor tunggal yang berisi alamat elemen pertama dari array nilai float.

  2. Biasanya, kondisi awal (yaitu elemen 'masa lalu' awal dari x dan y) adalah 0, tetapi jika nilainya tidak sama dengan 0 maka tidak ada masalah besar juga, karena setelah beberapa saat kondisi awal tidak berpengaruh pada output sinyal untuk setiap filter stabil. Dan filter Anda jelas stabil.

  3. Fungsi transfer lowpass urutan kedua dengan karakteristik Butterworth dan frekuensi cut-off (dengan dalam Hertz) diberikan olehωSebuah=2πfSebuahfSebuah

(1)H(s)=ωSebuah2s2+2ωSebuahs+ωSebuah2
Ini adalah hasil standar yang dapat Anda temukan dengan mudah di web . Untuk mendapatkan filter waktu diskrit, Anda dapat menerapkan apa yang disebut transformasi bilinear:

(2)s=2fsz-1z+1

di mana adalah frekuensi sampling. Ini diperlukan karena sumbu frekuensi dari sinyal analog ( ) perlu dipetakan ke rentang frekuensi yang diizinkan untuk sinyal waktu diskrit ( ). Karena transformasi ini mengurangi frekuensi, kita perlu menghitung frekuensi cut-off analog yang diinginkan dari frekuensi cut-off yang diberikan dalam domain waktu diskrit:fs0f0ffs/2fd

ωSebuah=2fsberjemur(ωd2) dengan ωd=2πfd/fs

Jika Anda memasukkan (2) ke dalam (1) Anda dapatkan

(3)H(z)=kz2+b1z+b2z2+Sebuah1z+Sebuah2

dengan

k=α21+2α+α2 (mendapatkan)
Sebuah1=2(α2-1)1+2α+α2,Sebuah2=1-2α+α21+2α+α2,b1=2,b2=1

tempat saya menggunakan . Fungsi transfer (3) sesuai dengan persamaan domain waktuα=berjemur(ωd2)

y(n)=kx(n)+kb1x(n-1)+kb2x(n-2)-Sebuah1y(n-1)-Sebuah2y(n-2)

Seperti yang Anda lihat, ada beberapa kemiripan dengan kode Anda. Namun, ada beberapa perbedaan juga dan Anda harus memeriksa respons frekuensi filter Anda. Saya pikir persamaan di atas benar, tetapi terserah Anda untuk memeriksanya dan memutuskan versi mana yang benar.


Terima kasih. Yang pertama, saya mengerti. Tapi itu masih berbagai pelampung. Maksud saya: apa yang diwakili oleh nilai float tunggal?
Niek van der Steen

2
Nilai float tunggal adalah salah satu sampel input Anda.
Matt L.

3
Singkatnya: suara adalah variasi dari tekanan udara, yang diubah oleh transduser (mikrofon) menjadi sinyal listrik variasi yang mengikuti pola yang sama dengan tekanan udara. Amplitudo sinyal listrik diukur N kali (= samplerate) setiap detik untuk menghasilkan urutan angka yang Anda lihat dalam array float * Anda. Ada lusinan presentasi online tentang pemrosesan (audio) digital yang menjelaskan proses ini secara lebih rinci.
pichenettes

Saya telah mengedit jawaban saya untuk menjawab bagian terakhir dari pertanyaan Anda.
Matt L.

Anda menggunakan x (n - sesuatu), apa itu x? Saya berasumsi bahwa 'n' adalah sampel input? Jawaban bagus!
Niek van der Steen

11

Anda bertanya bagaimana filter low pass bekerja dan menyebutkan bahwa filter menggunakan nilai sebelumnya dari data Anda. Ini adalah diskusi non-teknis tentang apa yang terjadi pada filter low pass.

Filter low pass mengambil tampilan berbeda (bergeser dalam waktu) dari sinyal Anda, menskala mereka dan menambahkannya bersama-sama. Anda dapat membayangkan menggambar sinyal Anda 3 kali, satu menjadi arus, yang kedua digeser oleh satu waktu sampel, yang ketiga digeser oleh 2 kali sampel.

Pada frekuensi rendah, semua tampilan tampak sangat mirip (bergeser oleh sampel tunggal nyaris tidak mengubah di mana Anda berada pada sinyal kapan saja dalam waktu singkat). Dalam hal ini, ketiga versi akan ditambahkan bersama dengan cara yang konstruktif (atau setidaknya tidak merusak), sehingga sinyal melewati filter.

Sekarang pindah ke frekuensi yang lebih tinggi, setiap versi sinyal yang bergeser menjadi lebih berbeda pada setiap saat (titik sampel) tertentu dan bahkan mungkin terbalik dalam tanda. Pada frekuensi yang lebih tinggi ini, tiga versi sinyal Anda cenderung untuk membatalkan (ditambahkan secara destruktif) sehingga sinyal menjadi dilemahkan.

Berbagai jenis filter mengatur jenis gangguan konstruktif / destruktif ini terjadi pada pita frekuensi yang sesuai untuk membuat filter low-pass, band-pass atau high-pass.


1

Itu tergantung pada bagaimana Anda menginginkannya. Bagi saya, saya telah menerapkan di C. Jadi, apa yang saya lakukan adalah saya membuat koefisien filter dalam matlabmenggunakan firls. Lalu saya menyimpan koefisien filter dalam array dan kemudian meneruskan koefisien filter ini ke fungsi filter dalam C. Di matlabdalamnya cukup mudah untuk menghasilkan koefisien filter, dan kemudian menggunakan operasi konvolusi atau menggunakan filter tertentu. Tetapi di dalam Ckamu harus menerapkan filter juga. Untuk bagian saya, saya harus melakukannya untuk DSP, jadi diimplementasikan dalam Cdan mendapatkan hasil dalam matlabmenggunakan fungsi mex. Untuk menghitung koefisien, gunakan perintah ini di matlab:

n=17                  %filter order
f=[0 0.167 0.333 1]   %Frequency band edges
a=[1 1 0 0]           %Desired amplitudes
fir= firls (n, f,a )
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.