AUDIO Q&A

Q1:音频播放卡顿,并且log报:MI_AO_IMPL_SendFrame[2695]: Device 0 is empty

这个打印是因为hw缓存的数据播放完了,而又没有新的数据送到hw进行播放导致的,mi检测到hw没有数据播放的状态后就会有题中log的打印。

而发送数据是由上层决定的,所以这种情况,上层应该排查一下送流的速度。

Q2:音频报:[MI WRN ]: MI_AI_GetFrame[7280]: Dev0 Chn0 Buffer(s) is lost due to slow fetching!!!是什么问题?

说明有ai数据丢了,取到的音频数据听起来会卡顿感。原因有如下几种情况:

  1. 调用取流接口不及时;

  2. output depth太小;

  3. 启用了算法,算法耗时太长;

  4. ai-dev ai-out的buf设置太小。

如果是算法问题,可以先将将算法先关掉测试看一下情况;

如果还是有问题,再把output depth设置大一点(比如20)试试。

如果还是有问题,再在取流接口前后加打印系统时间,看看是不是取流不及时。

Q3:MI_AO_SendFrame接口调用的时候,传入的dev chn 都是0,但是报错 dev0 chn1 错误

这是因为调用 MI_AO_SetPubAttr (MI_AUDIO_DEV AoDevId, MI_AUDIO_Attr_t *pstAttr) 时MI_AUDIO_Attr_t.u32ChnCnt设为2导致;

这个u32ChnCnt代表输出的通道数,AO最大支持2;只有需要2个Mono的情况才设2,否则都设1;

设为2就代表有2个通道需要送数据,调用MI_AO_SendFrame (MI_AUDIO_DEV AoDevId, MI_AO_CHN AoChn, MI_AUDIO_Frame_t *pstData, MI_S32 s32MilliSec) 需要传入2个通道的数据,即apVirAddr[1]不能为空,u32Len[1]不能为0,否则会报上面错误。

typedef struct MI_AUDIO_Frame_s
 {
   MI_AUDIO_BitWidth_e eBitwidth; /* audio frame bitwidth */
   MI_AUDIO_SoundMode_e eSoundmode; /* audio frame momo or stereo mode */
   void *apVirAddr[MI_AUDIO_MAX_CHN_NUM];
   MI_U64 u64TimeStamp; /* audio frame timestamp */
   MI_U32 u32Seq; /* audio frame seq */
   MI_U32 u32Len[MI_AUDIO_MAX_CHN_NUM]; /* data lenth per channel in frame */
   MI_U32 au32PoolId[2];
   /* Only use for Ai */
   void *apSrcPcmVirAddr[MI_AUDIO_MAX_CHN_NUM]; /* Ai original pcm data from ai channel */
   MI_U32 u32SrcPcmLen[MI_AUDIO_MAX_CHN_NUM]; /* length of Ai original pcm data */

}MI_AUDIO_Frame_t;

Q4: AO dev4(HDMI音频输出)使用出现报错MI_AO_SetPubAttr[879]:Dev4 failed to set pub attr!!!error number:0xa0052003!!!

错误码0xa0052003表示音频输出参数设置无效,出现这个错误码是因为MI_AUDIO_Attr_t结构体中有参数设置不对,比如:u32PtNumPerFrm. eSamplerate. eWorkmode. eI2sBitWidth. u32ChnCnt。HDMI仅支持32k/48k采样率,曾有采样率设置为非法值而产生此错误。

Q5: AO dev4(HDMI音频输出)发现有杂音,并有声音变慢放的现象

此问题产生的背景是AI采样率设置为8k,AO采样率设置为HDMI支持的48k。根据声音变慢放现象描述,怀疑是音频输出之前并没有做重采样,而后求证的确是直接AI进来后就AO输出,没有做重采样。这里输入采样率和输出采样率不匹配是必须要做重采样的,另外因为AO是不支持重采样的,所以需要调另外的算法来做重采样以转换采样频率,参考MI SRC API说明文档即可。

Q6: AI的采样精度范围是多少?

目前采样精度仅支持16bit。

Q7: AI怎么获取到回声参考帧?

如果需要获取回声消除参考帧,在调用MI_AI_GetFrame 函数时,pstAecFrm 不能是空指针,如果不想获取回声抵消参考帧pstAecFrm置为空指针即可。

对应api:

MI_S32 MI_AI_GetFrame (MI_AUDIO_DEV AiDevId, MI_AI_CHN AiChn, MI_AUDIO_Frame_t*pstFrm, MI_AUDIO_AecFrame_t *pstAecFrm, MI_S32 s32MilliSec);

例:

MI_AUDIO_Frame_t stAiChFrame;

MI_AUDIO_AecFrame_t stAecFrame;

memset(&stAiChFrame, 0, sizeof(MI_AUDIO_Frame_t));

memset(&stAecFrame, 0, sizeof(MI_AUDIO_AecFrame_t));

MI_S32 s32Ret = MI_AI_GetFrame(pstChnPrivateData->AiDevId, pstChnPrivateData->AiChn, &stAiChFrame, &stAecFrame, -1) //获取回声参考帧

//MI_S32 s32Ret = MI_AI_GetFrame(pstChnPrivateData->AiDevId, pstChnPrivateData->AiChn, &stAiChFrame, NULL, -1)//不获取回声参考帧

if (MI_SUCCESS == s32Ret)
{

     .......

     MI_AI_ReleaseFrame(pstChnPrivateData->AiDevId, pstChnPrivateData->AiChn, &stAiChFrame, &stAecFrame);

//MI_AI_ReleaseFrame(pstChnPrivateData->AiDevId, pstChnPrivateData->AiChn, &stAiChFrame, NULL);  //没获取回声参考帧

}

Q8: AO lineout 输出没有声音

当发现没有声音时,可通过以下几点来确认:

  1. 首先确认功放设备正常,硬件连接正确
  2. 确认使用的Ao device ID是否为0或4
  3. 确认功放是否有在工作,确认控制功放的gpio电平是否切对,还可以通过测量功放前后的波形来确定,到底是LineOut本身没有输出还是功放原因导致没有声音。

Q9:在使能audio后,发现有某个pin脚突然工作不正常

因功放pin脚控制不当时,会造成喇叭噗声,故SDK中mhal在送AO数据时,会对功放pin脚进行管控。遇到此问题可进行以下步骤的排查:

  1. 单独跑audio相关功能看是否有异常
  2. 单独跑该pin脚对应的功能是否有异常
  3. 若只要两个一起跑就会出现pin脚功能异常,则需要检查对应chip的dts的设定(比如:kernel/arch/arm/boot/dts/mercury6.dtsi)
  4. 检查sound节点的amp-gpio项,看该配置中使用的amp gpio是否就是工作异常的pin脚
  5. 若不想控制功放的pin脚,则将功放pin脚以及其正常工作的电平状态填到amp-gpio中,若需要自己控制,则填入PAD_UNKNOWN 0,更新kernel

Q10:当播放较短的音频发现没有完全播出或对讲时由于网络原因经常出现断音需要如何改善?

在MI_AO_SetPubAttr的属性中有有一个u32PtNumPerFrame的值,这个值决定了一帧中有多少个采样点,即多少多少数据触发一次dma中断。

当数据量比较小的音频应将此值调小,以将所有数据都尽量丢出,保证音频全部播放完。

当对讲时经常出现断音应将此值调大,保证比较多的数据再触发dma中断,尽量避免频繁出现断音的情况。

Q11: Enable AO device 时候先enable dev0,再enable dev4出现错误AUDIO ERROR是什么原因?

dev4 是Hdmi+Line out,dev 0是line out,开了dev 4的同时line out也會开,但之前dev0已经enable,这就造成DMA和DAC的HW资源冲突。如果需要HDMI和Lineout都输出,直接开AO dev4就可以了。

Q12: ai amic 使用MI_AI_SetVqeVolume调整音量,声音还是太小,无法满足需求。

用 MI_AI_SetChnParam这个接口试试,MI_AI_SetChnParam里的 pstChnParam可以同时调整模拟GAIN和数字GAIN。

u16FrontGain 调整模拟Gain等同MI_AI_SetVqeVolume, u16RearGain 调整数字GAIN。

建议先模拟gain,数字gain会同时放大电源噪声。

改API具体使用方法及注意事项,请参考 MI_AI_API 文档

Q13:如果要动态调节apc的某些参数,可以直接调用IaaApc_Config吗,还是要销毁重建?

不能直接调用,要销毁重建。

Q14:AI和AO的多个device可以同时使用吗?

可以。一次最多同时使用2个。

AI

AMIC(ADC0/1)    dev0 - AUD_DMA_WRITER1  
Dmic    dev1 - AUD_DMA_WRITER1  dev6 - AUD_DMA_WRITER2
I2S Rx  dev2 - AUD_DMA_WRITER1  dev7 - AUD_DMA_WRITER2
Line in(ADC0/1) dev3 - AUD_DMA_WRITER1  
Amic(ADC2/3)    dev4 - AUD_DMA_WRITER2  
Amic(ADC0/1/2/3)    dev5 - AUD_DMA_WRITER2

AO

Line out(ADC0/1)    dev0 - AUD_DMA_READER1  
I2S TX  dev1 - AUD_DMA_READER2  
DAC0    dev2 - AUD_DMA_READER1  
DAC1    dev3 - AUD_DMA_READER2  
HDMI + Line out dev4 - AUD_DMA_READER1

AI和AO设备限制有2个点:

  1. 有硬件引脚限制(如上表),比如AI设备Line in和AMIC,都有ADC0/1.类似这样的组合是不能共用的。

  2. 代码内部DMA的限制,2个device必须走的是不同一组DMA(如上表),AI设备的Dmic,有2个device可以用,如果要同时打开Dmic和I2S Rx,不能用dev1和dev2,可以用dev1(DMA1)和dev7(DMA2)。