干货,记一次解决录音杂音问题
最近在項(xiàng)目上遇到一個(gè)問題,也不能說是最近項(xiàng)目上的問題了,是之前一直存在的問題,但是對(duì)項(xiàng)目沒什么影響,所以我就不怎么理會(huì),直到最近,同事說這個(gè)雜音已經(jīng)影響到了項(xiàng)目的開發(fā),所以今天花了一天時(shí)間整理了下問題,不斷的修改測(cè)試中,終于搞完了。
說個(gè)題外話,年前招了一個(gè)帥哥有了新的發(fā)展,離開了我們,我內(nèi)心非常不舍,說不舍有點(diǎn)牽強(qiáng),他特別喜歡踢足球?,平時(shí)交集不是特別多。但是他在技術(shù)上真的也是我學(xué)習(xí)的榜樣,我喜歡看他對(duì)事情認(rèn)真的樣子,總結(jié)一個(gè)文檔和技術(shù)也非常有條理,在面對(duì)新的問題和技術(shù)難點(diǎn)的時(shí)候,他總是能找到解決的辦法。在這點(diǎn)上,我覺得自己確實(shí)從他身上吸收到了好的東西。
然后,他現(xiàn)在去做的也是音頻相關(guān)的,希望他在新的崗位,新的企業(yè)能發(fā)展得更好。
之前音頻相關(guān)的文章
音頻系統(tǒng),Alsa 里面的buff 是怎么計(jì)算的?
為什么需要超過48k的采樣音頻?
我在MTK平臺(tái)下調(diào)試音頻ALSA
音頻幾個(gè)重要的參數(shù)
openwrt 音頻開發(fā)
(干貨)Ai音箱和Linux音頻驅(qū)動(dòng)小談
Android 音頻數(shù)據(jù)流分析之程序員干架產(chǎn)品經(jīng)理
Alsa里面惡心的DAPM
1、問題
正常使用tinycap錄音,在音頻的開始位置會(huì)有一段雜波,這段雜波讓人看起來會(huì)非常不爽。
2、排查過程
先是排查了硬件,我擔(dān)心是硬件的GPIO口模式不正確,這個(gè)也是同事提醒的,后面檢查了下,發(fā)現(xiàn)這個(gè)GPIO口是特殊口,這個(gè)GPIO口就是干這個(gè)事情的,所以說沒有模式正確不正確,它就只有這個(gè)功能。
然后檢查了上電,因?yàn)镈MIC有一個(gè)供電,之前的文章寫過,我擔(dān)心供電時(shí)間過慢導(dǎo)致,后面修改了代碼讓DMIC持續(xù)供電,不過測(cè)試幾次錄音的時(shí)候問題還是存在,所以排除了這個(gè)問題。
還有就是DMIC的特性了,查看了DMIC的上電特性,DMIC有一個(gè)上電的時(shí)間,也就是這個(gè)時(shí)間影響了穩(wěn)定。
如下圖
后面跟思必馳的技術(shù)溝通,跟他討論了這個(gè)問題,他也說到他們?cè)谄渌?xiàng)目中也遇到過,解決的辦法就是寫0。
3、解決
上面已經(jīng)說了解決辦法了,就是在開始錄音的時(shí)候?qū)?,但是在哪里寫成了問題,如果應(yīng)用直接寫0就好了,但是我不能直接修改應(yīng)用的代碼。所以只能在內(nèi)核里面做手腳。
在HAL搞這個(gè)事情可能會(huì)標(biāo)準(zhǔn)化一些。
先是確定了讀音頻的函數(shù),流程是
snd_pcm_capture_ioctl1() ->snd_pcm_lib_read() -->snd_pcm_lib_read_transfer()修改的patch如下
diff?--git?a/kernel-4.4/include/sound/pcm.h?b/kernel-4.4/include/sound/pcm.h old?mode?100644 new?mode?100755 index?b0be092799..ecaca74273 ---?a/kernel-4.4/include/sound/pcm.h +++?b/kernel-4.4/include/sound/pcm.h @@?-460,6?+460,7?@@?struct?snd_pcm_substream?{/*?--?assigned?files?--?*/void?*file;int?ref_count; +???????int?once_f;/*weiqifa?modify*/atomic_t?mmap_count;unsigned?int?f_flags;void?(*pcm_release)(struct?snd_pcm_substream?*); diff?--git?a/kernel-4.4/sound/core/pcm_lib.c?b/kernel-4.4/sound/core/pcm_lib.c old?mode?100644 new?mode?100755 index?17e69848d3..8a057f1445 ---?a/kernel-4.4/sound/core/pcm_lib.c +++?b/kernel-4.4/sound/core/pcm_lib.c @@?-2220,6?+2220,11?@@?static?int?snd_pcm_lib_read_transfer(struct?snd_pcm_substream?*substream,return?err;}?else?{char?*hwbuf?=?runtime->dma_area?+?frames_to_bytes(runtime,?hwoff); +???????????????if(substream->once_f?<?1) +???????????????{ +???????????????????????memset(hwbuf,0,frames_to_bytes(runtime,?frames)); +???????????????????????substream->once_f++; +???????????????}if?(copy_to_user(buf,?hwbuf,?frames_to_bytes(runtime,?frames)))return?-EFAULT;} diff?--git?a/kernel-4.4/sound/core/pcm_native.c?b/kernel-4.4/sound/core/pcm_native.c old?mode?100644 new?mode?100755 index?3de88974ee..0ead670a38 ---?a/kernel-4.4/sound/core/pcm_native.c +++?b/kernel-4.4/sound/core/pcm_native.c @@?-2229,6?+2229,7?@@?static?void?pcm_release_private(struct?snd_pcm_substream?*substream)void?snd_pcm_release_substream(struct?snd_pcm_substream?*substream){ +???????substream->once_f?=?0;substream->ref_count--;if?(substream->ref_count?>?0)return; @@?-2277,6?+2278,7?@@?int?snd_pcm_open_substream(struct?snd_pcm?*pcm,?int?stream,goto?error;substream->hw_opened?=?1; +???????substream->once_f?=?0;err?=?snd_pcm_hw_constraints_complete(substream);if?(err?<?0)?{里面寫0的幀大小需要調(diào)試一下,這是我最后測(cè)試出來的結(jié)果。
修改后錄音得到的音頻頻譜圖如下
從之前的文章知道計(jì)算公式,從這里反推斷mute寫0的時(shí)間
跟上面截圖看到的時(shí)間差不多。
完美~ 下班
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識(shí)小密圈
總結(jié)
以上是生活随笔為你收集整理的干货,记一次解决录音杂音问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Servlet常见面试题
- 下一篇: Java面试题日积月累(jsp/Serv