2013-10-17 43 views
0

我想寫一個執行實時降噪的Android程序。整個源代碼太長,但要點如下:
mic - > FFT - >降噪和增益計算 - > IFFT - >揚聲器
如果我繞過中間的降噪功能,揚聲器會通過任何在麥克風處輸入。在這種情況下聲音很清晰。但是如果我啓用了降噪功能,實際的降噪功能似乎正在起作用,因爲來自我啓動的真空吸塵器的聲音被抑制,而我可以聽到身邊的人說話。然而,產量似乎扭曲了。某些失真可能是由降噪算法本身引起的,但如果我仔細聆聽聲音,我可以注意到礫石般的失真,就好像聲音是「跳幀」一樣。在我已經實現應用於聲音的一些其他類型的數字濾波器的實驗之後,我知道這是因爲FFT,IFFT和降噪功能所需的非常長的循環而發生的。由於程序卡在for循環中,因此在此期間沒有揚聲器輸出。由於有很多for循環,這種破損很明顯,輸出聽起來很碎。加速循環在一個線程中有很多(在Android中)

有沒有辦法加快速度,讓程序在for循環中花費的時間越少越好?任何其他類型的循環會有所作爲嗎?如果我能以某種方式找到一種方法,將噪聲降低功能中的操作分解爲獨立的部分,然後在單獨的線程中計算,是否有助於消除失真?或者會增加線程數量導致類似的問題?

回答

0

降低分辨率,內聯你所能做的一切。在java gc可以真正減慢實時操作,所以儘早分配並重用eveything。

除此之外,如果速度慢,速度會變慢。那麼,還可以加快/剖析循環內部並減少瓶頸。

+0

是否有可能在java中進行內聯函數呢? – user13267

+0

@ user13267:是,否。在普通的Java中(特別是對於服務器JVM),你從不關心,因爲JVM需要關心內聯。 Android JVM並不是那麼聰明,優化器要弱得多(儘管新版本會更好)。它可以內聯,但不是那麼好,所以取決於你。 – maaartinus

+0

通過內聯我只是指展開你的循環,但顯然沒有必要。我將重點關注GC並對您的代碼進行剖析以優化。 – HaMMeReD

0

預計輸入和過濾聲音之間的固定延遲。每幀的處理時間可能不同,因此處理後的部分應該不是立即發送,而是在預定時間到來時輸出。

+0

與輸入相比,輸出總是聽起來稍微延遲,我相信這是我無法避免的。然而,在輸出的連續聲音中似乎存在「破損」,我認爲這是由於循環過多導致的 – user13267

+0

確實無法避免,因此您必須使每幀的延遲相等。目前「破損」是因爲延誤不相等。 –