Apakah valid untuk meningkatkan amplitudo (dan mungkin kualitas FFT) hanya dengan menskala data?

10

Saya menggunakan versi "KISS FFT" oleh Mark Borgerding. Ini menerima array nilai input titik tetap 16-bit dan menghasilkan array hasil float 32-bit.

Saya telah menemukan bahwa jika amplitudo input rendah, banyak nilai hasil float keluar nol, tetapi jika saya hanya skala input (oleh, katakanlah, faktor 16) maka nilai output lebih sedikit nol dan oleh karena itu output tampaknya mengandung lebih detail. (Bukan berarti itu penting untuk tujuan saya, tetapi untuk konsistensi saya kemudian membagi nilai float yang dihasilkan oleh faktor penskalaan yang sama.)

Bagaimanapun, ini tampaknya berhasil, dalam hal menghasilkan hasil ketika sebelumnya saya baru saja mendapatkan buffer hampir semua nol, tapi saya bertanya-tanya apakah ada beberapa alasan itu mungkin bukan pendekatan yang valid.

(Perhatikan bahwa pendekatan ini berarti bahwa ada lebih banyak "kekasaran" / rincian data, dan, khususnya, kebisingan tingkat rendah yang biasanya hadir tidak. Saya hampir bertanya-tanya apakah akan bijaksana untuk menyuntikkan beberapa noise tingkat rendah untuk menggantikan nilai nol pada input.)

Daniel R Hicks
sumber
"Saya hampir bertanya-tanya apakah akan lebih bijaksana untuk menyuntikkan noise tingkat rendah untuk mengganti nilai nol pada input." = en.wikipedia.org/wiki/Dither
endolith

Jawaban:

7

Ini bisa menjadi pendekatan yang valid. Anda mengamati masalah yang sangat praktis yang sering muncul ketika menggunakan aritmatika titik tetap (yaitu integer) (meskipun itu juga bisa terjadi pada titik apung). Ketika format numerik yang Anda gunakan untuk melakukan perhitungan tidak memiliki cukup presisi untuk mengekspresikan rentang nilai penuh yang dapat muncul dari perhitungan Anda, beberapa bentuk pembulatan diperlukan (misalnya pemotongan, bulat ke yang terdekat, dan sebagainya di). Ini sering dimodelkan sebagai kesalahan kuantisasi aditif pada sinyal Anda.

Namun, untuk beberapa kombinasi algoritma dan skema pembulatan, ketika besarnya sinyal input sangat rendah, dimungkinkan untuk mendapatkan apa yang Anda amati: sejumlah besar output nol. Pada dasarnya, di suatu tempat dalam urutan operasi, hasil antara menjadi cukup kecil untuk tidak melanggar ambang batas yang diperlukan untuk kuantisasi ke tingkat bukan nol. Nilai ini kemudian dibulatkan menjadi nol, yang seringkali dapat merambat ke depan ke output. Hasilnya adalah, seperti yang Anda catat, sebuah algoritma yang menghasilkan banyak nol keluaran.

Jadi bisakah Anda menyiasati hal ini dengan meningkatkan data? Terkadang (ada beberapa teknik yang bekerja sepanjang waktu!). Jika sinyal input Anda dibatasi dengan nilai di bawah skala penuh format numerik (bilangan bulat bertanda 16-bit dijalankan dari -32768 hingga +32767), maka Anda dapat mengatur sinyal input hingga lebih penuh menggunakan rentang yang tersedia untuk Itu. Ini dapat membantu mengurangi efek kesalahan putaran, karena besarnya kesalahan putaran menjadi lebih kecil dibandingkan dengan sinyal yang diinginkan. Jadi, dalam kasus di mana semua output Anda dibulatkan menjadi nol secara internal ke algoritma, ini dapat membantu.

Kapan teknik seperti itu bisa melukai Anda? Bergantung pada struktur perhitungan algoritme, menaikkan sinyal input ke atas dapat membuat Anda mengalami luapan numerik. Juga, jika sinyal mengandung gangguan latar belakang atau gangguan yang lebih besar besarnya daripada kesalahan pembulatan algoritma, maka kualitas apa yang Anda dapatkan pada output akan biasanya dibatasi oleh lingkungan, bukan kesalahan yang dimasukkan dalam perhitungan.

Jason R
sumber
Saya menggunakan teknik dinamis untuk penskalaan yang tampaknya bekerja cukup baik. Dan, seperti keberuntungan, transien ekstrem diperlakukan sebagai kebisingan dan terpotong pula, sehingga kliping sesekali tidak menjadi masalah. Apakah Anda pikir itu valid untuk "menghilangkan nilai" output dengan membaginya dengan faktor skala input?
Daniel R Hicks
1

Cara bukti termudah dan paling bodoh untuk menangani ini adalah untuk mengkonversi data ke floating point SEBELUM FFT dan menggunakan FFT floating point. Satu-satunya downside ke pendekatan ini adalah bahwa Anda dapat mengkonsumsi lebih banyak prosesor dan memori. Karena output Anda adalah floating point, mungkin ada sedikit perbedaan praktis.

Hilmar
sumber
Saya diberikan proyek ini dengan algoritma FFT saat ini sudah di tempat, dan saya enggan untuk mengerjakannya pada saat ini. Dan ini semua terjadi di telepon, secara real time, jadi kinerja jelas merupakan masalah.
Daniel R Hicks
Dimengerti Apakah Anda tahu jika internal FFT sudah diperbaiki atau floating point? Jika sudah diperbaiki, Anda perlu khawatir tentang kliping, overflow, dan underflow
Hilmar
Dokumentasi dan komentar luar biasa karena tidak ada, tetapi saya melihat banyak ints dalam kode dan beberapa mengapung dan menggandakan. Tampaknya menyertakan kerangka kerja kasar #ifdef untuk beralih dari 16-bit ke 32-bit atau mengambang, tetapi kerangka kerja tersebut tampaknya telah lama dinonaktifkan.
Daniel R Hicks
IPhone (ARM + NEON CPU) dapat melakukan float FFT lebih cepat (melalui kerangka Akselerasi) daripada FFT integer di C.
hotpaw2