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:
- Saya menerima sampel audio dalam float * array sederhana. Berapa nomor float itu? Satu-satunya hal yang saya lihat adalah angka, bagaimana itu sepotong suara?
- 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)
- 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 ()'.
lowpass-filter
c
Niek van der Steen
sumber
sumber
Jawaban:
Nomor float * array adalah penunjuk ke array. Ini adalah nomor tunggal yang berisi alamat elemen pertama dari array nilai float.
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.
Fungsi transfer lowpass urutan kedua dengan karakteristik Butterworth dan frekuensi cut-off (dengan dalam Hertz) diberikan olehωSebuah= 2 ∗ π∗fSebuah fSebuah
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:fs 0 ≤ f≤ ∞ 0 ≤ f≤fs/ 2 fd
Jika Anda memasukkan (2) ke dalam (1) Anda dapatkan
dengan
tempat saya menggunakan . Fungsi transfer (3) sesuai dengan persamaan domain waktuα = tan(ωd2)
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.
sumber
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.
sumber
Itu tergantung pada bagaimana Anda menginginkannya. Bagi saya, saya telah menerapkan di
C
. Jadi, apa yang saya lakukan adalah saya membuat koefisien filter dalammatlab
menggunakanfirls
. Lalu saya menyimpan koefisien filter dalam array dan kemudian meneruskan koefisien filter ini ke fungsi filter dalamC
. Dimatlab
dalamnya cukup mudah untuk menghasilkan koefisien filter, dan kemudian menggunakan operasi konvolusi atau menggunakan filter tertentu. Tetapi di dalamC
kamu harus menerapkan filter juga. Untuk bagian saya, saya harus melakukannya untuk DSP, jadi diimplementasikan dalamC
dan mendapatkan hasil dalammatlab
menggunakan fungsi mex. Untuk menghitung koefisien, gunakan perintah ini dimatlab
:sumber