最近在项目上遇到一个问题,也不能说是最近项目上的问题了,是之前一直存在的问题,但是对项目没什么影响,所以我就不怎么理会,直到最近,同事说这个杂音已经影响到了项目的开发,所以今天花了一天时间整理了下问题,不断的修改测试中,终于搞完了。
说个题外话,年前招了一个帅哥有了新的发展,离开了我们,我内心非常不舍,说不舍有点牵强,他特别喜欢踢足球⚽,平时交集不是特别多。但是他在技术上真的也是我学习的榜样,我喜欢看他对事情认真的样子,总结一个文档和技术也非常有条理,在面对新的问题和技术难点的时候,他总是能找到解决的办法。在这点上,我觉得自己确实从他身上吸收到了好的东西。
然后,他现在去做的也是音频相关的,希望他在新的岗位,新的企业能发展得更好。
之前音频相关的文章
音频系统,Alsa 里面的buff 是怎么计算的?
为什么需要超过48k的采样音频?
我在MTK平台下调试音频ALSA
音频几个重要的参数
openwrt 音频开发
(干货)Ai音箱和Linux音频驱动小谈
Android 音频数据流分析之程序员干架产品经理
Alsa里面恶心的DAPM
1、问题
正常使用tinycap录音,在音频的开始位置会有一段杂波,这段杂波让人看起来会非常不爽。
2、排查过程
先是排查了硬件,我担心是硬件的GPIO口模式不正确,这个也是同事提醒的,后面检查了下,发现这个GPIO口是特殊口,这个GPIO口就是干这个事情的,所以说没有模式正确不正确,它就只有这个功能。
然后检查了上电,因为DMIC有一个供电,之前的文章写过,我担心供电时间过慢导致,后面修改了代码让DMIC持续供电,不过测试几次录音的时候问题还是存在,所以排除了这个问题。
还有就是DMIC的特性了,查看了DMIC的上电特性,DMIC有一个上电的时间,也就是这个时间影响了稳定。
如下图
后面跟思必驰的技术沟通,跟他讨论了这个问题,他也说到他们在其他项目中也遇到过,解决的办法就是写0。
3、解决
上面已经说了解决办法了,就是在开始录音的时候写0,但是在哪里写成了问题,如果应用直接写0就好了,但是我不能直接修改应用的代码。所以只能在内核里面做手脚。
在HAL搞这个事情可能会标准化一些。
先是确定了读音频的函数,流程是
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的帧大小需要调试一下,这是我最后测试出来的结果。
修改后录音得到的音频频谱图如下
从之前的文章知道计算公式,从这里反推断mute写0的时间
跟上面截图看到的时间差不多。
完美~ 下班
推荐阅读:
专辑|Linux文章汇总
专辑|程序人生
专辑|C语言
我的知识小密圈