离线
https://github.com/torvalds/linux/blob/master/sound/soc/sunxi/sun8i-codec-analog.c
static int sun8i_headphone_amp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);if (SND_SOC_DAPM_EVENT_ON(event)) {
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN));
/*
* Need a delay to have the amplifier up. 700ms seems the best
* compromise between the time to let the amplifier up and the
* time not to feel this delay while playing a sound.
*/
msleep(700);
} else if (SND_SOC_DAPM_EVENT_OFF(event)) {
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
0x0);
}return 0;
}
离线
v3这么坑啊, 700ms,我还想用它做点音频相关的应用呢, 这样下来s3不能用了
离线
v3这么坑啊, 700ms,我还想用它做点音频相关的应用呢, 这样下来s3不能用了
连续播放不会酱紫,如果播放后停3秒(目测), 下一次播放又会延迟700ms, 如果播放间隔不超过3秒不会。
超过3秒,喇叭关闭的时候会播放 啵 的一声, 暂时不知道去哪里关闭,
有网友建议在 啵 一声前通过gpio关闭功放(mute引脚).
离线
dbskcnc 说:v3这么坑啊, 700ms,我还想用它做点音频相关的应用呢, 这样下来s3不能用了
连续播放不会酱紫,如果播放后停3秒(目测), 下一次播放又会延迟700ms, 如果播放间隔不超过3秒不会。
超过3秒,喇叭关闭的时候会播放 啵 的一声, 暂时不知道去哪里关闭,
有网友建议在 啵 一声前通过gpio关闭功放(mute引脚).
这样子已经是残废, 看样子还得另找其它芯片了
离线
晕哥 说:dbskcnc 说:v3这么坑啊, 700ms,我还想用它做点音频相关的应用呢, 这样下来s3不能用了
连续播放不会酱紫,如果播放后停3秒(目测), 下一次播放又会延迟700ms, 如果播放间隔不超过3秒不会。
超过3秒,喇叭关闭的时候会播放 啵 的一声, 暂时不知道去哪里关闭,
有网友建议在 啵 一声前通过gpio关闭功放(mute引脚).这样子已经是残废, 看样子还得另找其它芯片了
不知道是不是因为要省电,所以播放完之后关闭声卡???需要的时候再打开???
如果能一直开着,不知道能不能解决这个问题, 我们的产品是市电供电,不需要节电.
离线
dbskcnc 说:晕哥 说:连续播放不会酱紫,如果播放后停3秒(目测), 下一次播放又会延迟700ms, 如果播放间隔不超过3秒不会。
超过3秒,喇叭关闭的时候会播放 啵 的一声, 暂时不知道去哪里关闭,
有网友建议在 啵 一声前通过gpio关闭功放(mute引脚).这样子已经是残废, 看样子还得另找其它芯片了
不知道是不是因为要省电,所以播放完之后关闭声卡???需要的时候再打开???
如果能一直开着,不知道能不能解决这个问题, 我们的产品是市电供电,不需要节电.
能不能验证下这个问题,如果每次播放都要延时700ms, 真的很大问题, 按理不应该这样子才对
离线
晕哥 说:dbskcnc 说:这样子已经是残废, 看样子还得另找其它芯片了
不知道是不是因为要省电,所以播放完之后关闭声卡???需要的时候再打开???
如果能一直开着,不知道能不能解决这个问题, 我们的产品是市电供电,不需要节电.能不能验证下这个问题,如果每次播放都要延时700ms, 真的很大问题, 按理不应该这样子才对
验证过了, 如果每次播放间隔时间超过3秒(目测), 那么每次都是延迟 700ms.
上面是 linux4.13的结果,
不知道用bsp linux(3.4) 会不会这样.
离线
dbskcnc 说:晕哥 说:不知道是不是因为要省电,所以播放完之后关闭声卡???需要的时候再打开???
如果能一直开着,不知道能不能解决这个问题, 我们的产品是市电供电,不需要节电.能不能验证下这个问题,如果每次播放都要延时700ms, 真的很大问题, 按理不应该这样子才对
验证过了, 如果每次播放间隔时间超过3秒(目测), 那么每次都是延迟 700ms.
上面是 linux4.13的结果,
不知道用bsp linux(3.4) 会不会这样.
芯片内部功放启动的时候会相当于把音量“慢慢”调大,避免电平突然改变造成的咔嗒声。所以这个现象应该是驱动层把功放关闭了,再次启用的时候比较慢。
可以改驱动,一直不关闭功放。
或者,在播放完的时候,持续播放一段静音音频。
离线
晕哥 说:dbskcnc 说:能不能验证下这个问题,如果每次播放都要延时700ms, 真的很大问题, 按理不应该这样子才对
验证过了, 如果每次播放间隔时间超过3秒(目测), 那么每次都是延迟 700ms.
上面是 linux4.13的结果,
不知道用bsp linux(3.4) 会不会这样.芯片内部功放启动的时候会相当于把音量“慢慢”调大,避免电平突然改变造成的咔嗒声。所以这个现象应该是驱动层把功放关闭了,再次启用的时候比较慢。
可以改驱动,一直不关闭功放。
或者,在播放完的时候,持续播放一段静音音频。
https://github.com/torvalds/linux/blob/master/sound/soc/sunxi/sun8i-codec-analog.c
我看了一下代码,
没有找到不关功放的寄存器,
或许找的姿势不对.
持续播放一段静音音频这个倒是可以有,
在应用程序端做就可以了。
离线
https://github.com/torvalds/linux/blob/master/sound/soc/sunxi/sun8i-codec-analog.c
我看了一下代码,
没有找到不关功放的寄存器,
或许找的姿势不对.持续播放一段静音音频这个倒是可以有,
在应用程序端做就可以了。
貌似就是上边摘的那段代码,SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN,耳机功放使能。
把 else if (SND_SOC_DAPM_EVENT_OFF(event)) 这段 和上面一句 msleep(700) 注释掉试试?
static int sun8i_headphone_amp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
if (SND_SOC_DAPM_EVENT_ON(event)) {
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN));
/*
* Need a delay to have the amplifier up. 700ms seems the best
* compromise between the time to let the amplifier up and the
* time not to feel this delay while playing a sound.
*/
msleep(700);
} else if (SND_SOC_DAPM_EVENT_OFF(event)) {
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
0x0);
}
return 0;
}
离线
晕哥 说:https://github.com/torvalds/linux/blob/master/sound/soc/sunxi/sun8i-codec-analog.c
我看了一下代码,
没有找到不关功放的寄存器,
或许找的姿势不对.持续播放一段静音音频这个倒是可以有,
在应用程序端做就可以了。貌似就是上边摘的那段代码,SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN,耳机功放使能。
把 else if (SND_SOC_DAPM_EVENT_OFF(event)) 这段 和上面一句 msleep(700) 注释掉试试?static int sun8i_headphone_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); if (SND_SOC_DAPM_EVENT_ON(event)) { snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL, BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN), BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN)); /* * Need a delay to have the amplifier up. 700ms seems the best * compromise between the time to let the amplifier up and the * time not to feel this delay while playing a sound. */ msleep(700); } else if (SND_SOC_DAPM_EVENT_OFF(event)) { snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL, BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN), 0x0); } return 0; }
按这个分析那这个就是关
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
0x0);
这个是开,确实
snd_soc_component_update_bits(component, SUN8I_ADDA_PAEN_HP_CTRL,
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN),
BIT(SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN));
离线
[ 356.628202] ZZZZZZZZZZ 111111
[ 356.628252] ZZZZZZZZZZ 22222222222[ 362.408079] ZZZZZZZZZZ 111111
[ 362.408139] ZZZZZZZZZZ 33333333333333
试了一下 12# 朋友的方法, 把功放关闭的代码屏蔽起来, 然而并没有什么用.
离线
可惜了,还得再摸索, 应该是还有此道道, 如何得到官方的指导应该就很快
离线
https://github.com/Lichee-Pi/linux/blob/zero-4.13.y/arch/arm/boot/dts/sun8i-v3s.dtsi
codec: codec@01c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-v3s-codec";
reg = <0x01c22c00 0x400>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
clock-names = "apb", "codec";
resets = <&ccu RST_BUS_CODEC>;
dmas = <&dma 15>, <&dma 15>;
dma-names = "rx", "tx";
allwinner,codec-analog-controls = <&codec_analog>;
status = "disabled";
};codec_analog: codec-analog@01c23000 {
compatible = "allwinner,sun8i-v3s-codec-analog";
reg = <0x01c23000 0x4>;
};
不明白为什么 模拟音频寄存器有 0x18 个寄存器(1字节), 但是dts 里面只有四个字节?
离线
晕哥,现在v3s能录音了吗?我录到的是杂音
离线
额......这个问题有下文不,正要做V3S的音频 应用呢.....
离线
关注,我说为啥播放完音频,会响一声杂音来着,原来都是这
离线
会不会是硬件的原因,虽然codec内部是capless headphone ampilifier,已经抵消掉了直流部分。
但是作为强迫症患者,还是觉得HP_L,HP_R加个小的隔直电容会好一点。
licheepi zero电路(hp)
codec内部结构图:
关于capless headphone ampilifier讲解比较详细的文档
离线
直接用耳机输出没这事啊,耳机输出原来3.4 的驱动只要数据不足确实会设置寄存器静音,3.4 里没看到你这个。
离线
太好了, 感谢楼上各位, 我一会就试一试, 等会附上结果。
最后老哥找到真相了吗
离线
求更新啊,这个“叭叭”的问题,现在有更新了吗?
离线
最近公司拿了块V3S的开发板,刚好看到了这个问题,特地注册了用户上来回复一下。
这个音频延迟主要是两个地方,一个是音频播放开始的延迟,一个是结束后的延迟关功放。
走了下代码结合DS,这两个应该都不算问题:
开功放的延迟,来源于内置功放芯片的能力,会慢慢开功放,参考寄存器PA_ANTI_POP_CTRL,地址0x01c22c00 + 0x0E, mask: 0x03,参考值:
PA_ANTI_POP_CTRL, (slopelengthsel)
PA Anti-pop time Control
000: 131ms; 001: 262ms; 010: 393ms; 011: 524ms;
100: 655ms; 101: 786ms; 110: 786ms; 111: 1048ms;
默认值4,也就是100b,约655ms。
默认的声卡驱动代码没有拉出来control,可以自己加上,实测改成0,约200ms。
第二个是关功放的延迟,其实是PCM stream的 PMD delay时间,这个默认已经映射了一个配置到/sys/devices/platform/soc/1c22c00.codec/cdc/pmdown_time,默认5000,也就是5S,可以通过echo方式改大,最大估计是0x7FFFFFFF,要改代码的话在sound/soc/soc-core.c
/*
* This is a timeout to do a DAPM powerdown after a stream is closed().
* It can be used to eliminate pops between different playback streams, e.g.
* between two audio tracks.
*/
static int pmdown_time = 5000;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
要做音频类应用,可以将PA_ANTI_POP_CTRL改成0,大概能有不到200ms延迟,然后将pmdown_time改成最大,至少个把月不会关,基本能用了。
离线
延迟这么大吗?最近刚好在调试声卡,直接用I2S问题应该不大
离线
楼主说的不是音频数据延迟,应该是音频是立即开始的,但是输出功放的延迟打开会引起音频开始的前半部分的语音输出不出来。
离线
f1c也有这个问题,一直没搞定
离线
@Andy1234
多少年过去了。 感谢大侠分享。今天回去试试。
离线