goodman

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman  发布于  2016-05-17 16:22:50
采纳率 0%
30个问答
wooshang@126.com
11009

【已解决】Hi3531立体声(双声道)采集问题

 
本帖最后由 goodman 于 2016-5-19 10:22 编辑

先决条件:

  • Hi3531 平台uclibc
  • 使用SIO4 I2S连接 TLV320AIC31 48K采样 STEROR(立体声) u32ChnCnt=2通道
海思关于立体声这有这么一个简单的说明:
对于双声道模式,只应对左声道(即编号小于设备属性中通道数 u32ChnCnt 一半的通 道)进行操作, SDK 内部会自动对右声道也进行相应的操作。
那么问题来了(AI通道为0,1):

  • 数据是走通道的,双声道是的数据都走通道0 还是左声道走Aich0,右声道走Aich1
  • AI(4,0)--->AENC(0) 有数据
    AI(4,1)--->AENC(1) 无数据 (我现在就是走2个通道的,但是通道1没有数据)
  • 如果是只操作通道0保存PCM播放还是单通道的
AI 调试信息:



海思的双通道数据数据到底该怎么用?
====================================
经过2天的调试立体声的数据可以出来了,下面和大家分享下调试的过程
我这里使用的是LPCM格式,原始的未压缩的PCM格式.


1.确定你使用的SIO口,这个是硬件连接请确保你使用的是正确的

[code]#define SAMPLE_AUDIO_PTNUMPERFRM   320
#if HICHIP == HI3531_V100
#define SAMPLE_AUDIO_AI_DEV 4  // 硬件确定后该这里,我使用的是SIO4
#else
#define SAMPLE_AUDIO_AI_DEV 0
#endif
#define SAMPLE_AUDIO_AO_DEV 4[/code]

2. 确定AI属性是立体声

/* init stAio. all of cases will use it */
    stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_48000; // 48K sample
    stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
    stAioAttr.enWorkmode = AIO_MODE_I2S_SLAVE;
    stAioAttr.enSoundmode =  AUDIO_SOUND_MODE_STEREO; //立体声
    stAioAttr.u32EXFlag = 1;
    stAioAttr.u32FrmNum = 30;
    stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
    stAioAttr.u32ChnCnt = 2; // 只使用2个AI通道,最大支持16个通道
    stAioAttr.u32ClkSel = 1;

3.只使能stAioAttr.u32ChnCnt 小于 stAioAttr.u32ChnCnt/2的ai通道

原因是这个:
[quote]对于双声道模式,只应对左声道(即编号小于设备属性中通道数 u32ChnCnt 一半的通 道)进行操作, SDK 内部会自动对右声道也进行相应的操作。[/quote]
4.使用UserGetMode方式取数据
[code]HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,
AUDIO_FRAME_S *pstFrm, AEC_FRAME_S *pstAecFrm, HI_BOOL bBlock);


typedef struct hiAUDIO_FRAME_S
{
AUDIO_BIT_WIDTH_E enBitwidth; /*audio frame bitwidth*/
AUDIO_SOUND_MODE_E enSoundmode; /*audio frame momo or stereo mode*/
HI_VOID *pVirAddr[2];// 双声道下pVirAddr[0]表示左声道,pVirAddr[1]表示右声道
HI_U32 u32PhyAddr[2];
HI_U64 u64TimeStamp;/*audio frame timestamp*/
HI_U32 u32Seq; /*audio frame seq*/
HI_U32 u32Len; /*data lenth per channel in frame*/
HI_U32 u32PoolId[2];
}AUDIO_FRAME_S;[/code]
最为关键的就是数据的存储问题,一开始我是这样存储数据的。

[code]fwrite(stFrame.pVirAddr[0],  1 ,stFrame.u32Len , pstAiCtl->pfd);
fwrite(stFrame.pVirAddr[1],  1 ,stFrame.u32Len , pstAiCtl->pfd);[/code]
写成文件怎么也不对,后来Google了下PCM格式才知道是数据格式问题,改成这样

[code]for(i=0; i     fwrite(stFrame.pVirAddr[0]+i,  1 ,2 , pstAiCtl->pfd);               
    fwrite(stFrame.pVirAddr[1]+i,  1 ,2 , pstAiCtl->pfd);               
}[/code]
LPCM各个模式下的数据存储格式:

也就是说数据是交错排放的,有点类似于YUV里面的packed模式。

一个遗留的问题是不管使用SYS_BIND的方式还是在AiChn里面使用 HI_MPI_AENC_SendFrame发送编码真,使用HI_MPI_AENC_GetStream取得的数据始终是mono的,不知道为什么。
如果有知道的朋友麻烦分享下。


最后丢个测试的图片和我录的PCM(48k 16bit STEREO)数据给大家,需要的下载测试

[url=http://pan.baidu.com/s/1o8aRqXG]audio_ai_chn0.zip[/url]
我来回答
回答19个
时间排序
认可量排序

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-05-17 17:25:46
认可0
AI(4,1)是版主调用HI_MPI_AI_EnableChn(4, 1)启用的吗?

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-17 17:58:43
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30130&ptid=11337]zhuangweiye 发表于 2016-5-17 17:25[/url]
AI(4,1)是版主调用HI_MPI_AI_EnableChn(4, 1)启用的吗?[/quote]

没有使能channel1,只调用了HI_MPI_AI_EnableChn(4, 0)后直接使用channel1的。

HI_MPI_AI_EnableChn(4, 1) 使能channel1的话会报错的

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-05-18 08:49:30
认可0
试试 HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,AUDIO_FRAME_S *pstFrm, AEC_FRAME_S *pstAecFrm, HI_BOOL bBlock);

这个AUDIO_FRAME_S里面是有两个buffer的,不知道是不是可以

falloutmx

1个粉丝

15

问答

0

专栏

0

资料

falloutmx 2016-05-18 09:19:30
认可0
你是想要1路立体声还是2路单声道。1路立体声对应stereo,只会从一个chn出来。2路单声道对应mono,分别从各自的chn出来

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-18 10:04:35
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30162&ptid=11337]zhuangweiye 发表于 2016-5-18 08:49[/url]
试试 HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,AUDIO_FRAME_S *pstFrm, AEC_FRAME_S ...[/quote]

还不清楚,我测试下。

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-18 10:14:37
认可0
本帖最后由 goodman 于 2016-5-18 10:19 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=30171&ptid=11337]falloutmx 发表于 2016-5-18 09:19[/url]
你是想要1路立体声还是2路单声道。1路立体声对应stereo,只会从一个chn出来。2路单声道对应mono,分别从各 ...[/quote]

我是想要1路带左右声道的立体声,你的意思他的AI channel 1里面就是没有数据出来的?

对于只使用channel 0 我也怀疑过并且测试过,在AUDIO_FRAME_S结构体里面有这么个说明


  • u32Len(音频帧长度)指单个声道的数据长度。
  • 单声道数据直接存放,采样点数为 ptnum,长度为 len;立体声数据按左右声道分开存放,先存放采样点为 ptnum、长度为 len 的左声道数据,然后存放采样点为ptnum,长度为 len 的右声道数据


所以我在编码后取的数据后:
[code]            /* get stream from aenc chn */
            s32Ret = HI_MPI_AENC_GetStream(pstAencCtl->AeChn, &stStream, HI_FALSE);

            fwrite(stStream.pStream,1,stStream.u32Len, pstAencCtl->pfd); // 左声道(有效数据,保存后以mono打开声音是对的)
            fwrite(stStream.pStream+stStream.u32Len ,1,stStream.u32Len, pstAencCtl->pfd);  // 右声道 (数据不对,杂音)

            HI_MPI_AENC_ReleaseStream(pstAencCtl->AeChn, &stStream);[/code]

但是很遗憾的是,保存成文件,以双声道,播放的话声音就完全不对,只有杂音

falloutmx

1个粉丝

15

问答

0

专栏

0

资料

falloutmx 2016-05-18 14:45:12
认可0
我很久没用过立体声了,我自己的记录文档里提到一句
“如果需要立体声,软件编码时候需要使用同一个设备的2个通道,即
AiDev=0, AiChn=0 为左声道
AiDev=0, AiChn=2 为右声道
输出通道同理可得。一个编码通道只能处理一个声道,处理左右声道需要开通2个编码通道。
enSoundmode = AUDIO_SOUND_MODE_MOMO 不需要改变。如果改成AUDIO_SOUND_MODE_STEREO则变成一个通道同时传送左右声道。

同时我建议音源选择左右声道不同声音的文件

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-18 16:03:33
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30162&ptid=11337]zhuangweiye 发表于 2016-5-18 08:49[/url]
试试 HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,AUDIO_FRAME_S *pstFrm, AEC_FRAME_S ...[/quote]

HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,AUDIO_FRAME_S *pstFrm, AEC_FRAME_S *pstAecFrm, HI_BOOL bBlock);
取出一帧音频数据 pstFrm
使用这个接口 在mono(单声道)下 pstFrm->pVirAddr[0] 里面数据是对的,pstFrm->pVirAddr[1] 是空的
                         stereo(双声道)下 pstFrm->pVirAddr[0]有数据 (单存是以Adobe Audition 3.0打开是OK的),同时pstFrm->pVirAddr[1]也是有数据的,但是纯成文件就不对,我打赢了数据感觉数据是对的。

打印的数据为:
[code]stFrame.enSoundmode=1, enBitwidth=1, stFrame.u32Len=640
pVirAddr[0] :
01 00 ff ff fd ff f9 ff fc ff 00 00 01 00 00
00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00
00 00 fe ff 00 00 01 00 00 00 00 00 02 00 01
00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
ff ff 00 00

pVirAddr[1] :
00 00 01 00 fd ff f8 ff fd ff 00 00 00 00 00
00 ff ff 00 00 00 00 ff ff fe ff 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 fe ff 00 00
00 00 00 00
[/code]

写文件的方式为:
                fwrite(stFrame.pVirAddr[0],  1 ,stFrame.u32Len , pstAiCtl->pfd);
                    fwrite(stFrame.pVirAddr[1],  1 ,stFrame.u32Len , pstAiCtl->pfd);   

//这样写数据对吗?我去的是raw数据,LPCM格式的数据,我感觉是数据的格式存储不对,不知道是怎样的,我再从网上搜下

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-18 16:15:47
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30216&ptid=11337]falloutmx 发表于 2016-5-18 14:45[/url]
我很久没用过立体声了,我自己的记录文档里提到一句
“如果需要立体声,软件编码时候需要使用同一个设备的 ...[/quote]

是的需要2个ai通道,但是只需要操作一个通道就可以了。这个文档有说明

“如果需要立体声,软件编码时候需要使用同一个设备的2个通道,即
AiDev=0, AiChn=0 为左声道
AiDev=0, AiChn=2 为右声道"
这个根据你AI属性设置,
stAioAttr.u32ChnCnt = 2; // 我这边设置的是2,所以是AiDev0 AiChn0 ,AiChn1
如果是 stAioAttr.u32ChnCnt = 4;就是你说的情况,可以支持2路双声道,AiChn 02一组  Aichn13一组

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-05-18 16:22:53
认可0
先考虑分两个文件存,看看stFrame.pVirAddr[1]中的数据做为单声道是否对

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2016-05-19 10:16:16
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30226&ptid=11337]zhuangweiye 发表于 2016-5-18 16:22[/url]
先考虑分两个文件存,看看stFrame.pVirAddr[1]中的数据做为单声道是否对[/quote]

stFrame.pVirAddr[1]单独写成文件不知道为什么也放不了,很奇怪

kg123456

0个粉丝

14

问答

0

专栏

3

资料

kg123456 2016-08-23 11:59:04
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=30221&ptid=11337]goodman 发表于 2016-5-18 16:03[/url]
HI_S32 HI_MPI_AI_GetFrame(AUDIO_DEV AudioDevId, AI_CHN AiChn,AUDIO_FRAME_S *pstFrm, AEC_FRAME_S *p ...[/quote]

好男人大大    弱弱地问下   你这音频数据怎么打印出来的  
想知道printf() 里面的内容:$

moonlqer

0个粉丝

3

问答

0

专栏

0

资料

moonlqer 2016-11-08 16:28:14
认可0
楼主用的是什么PCM播放器,另外楼主是怎么把音频传输到板子的输入端的?

wuqingwei

0个粉丝

9

问答

0

专栏

0

资料

wuqingwei 2017-04-07 16:27:20
认可0
标题是已解决,看了半天也不知道是怎么解决的

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2017-04-17 11:15:39
认可0
就是资料排列改为 左右左右左右左右 这样抓取资料

bigbao

0个粉丝

0

问答

0

专栏

0

资料

bigbao 2017-05-27 17:28:52
认可0
单声道配置:使用AiDev=2(硬件只接了这个I2S)
        stAioAttr.enSamplerate   = AUDIO_SAMPLE_RATE_48000;
    stAioAttr.enBitwidth     = AUDIO_BIT_WIDTH_16;
    stAioAttr.enWorkmode     = AIO_MODE_I2S_SLAVE;
    stAioAttr.enSoundmode    = AUDIO_SOUND_MODE_MONO;
    stAioAttr.u32EXFlag      = 1;
    stAioAttr.u32FrmNum      = 30;
    stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
    stAioAttr.u32ChnCnt      = 1;
        stAioAttr.u32ClkChnCnt   = 1;
    stAioAttr.u32ClkSel      = 0;      
编码没有问题,声音也正常。

我需要立体声,按照楼主的方法:
        stAioAttr.enSamplerate   = AUDIO_SAMPLE_RATE_48000;
    stAioAttr.enBitwidth     = AUDIO_BIT_WIDTH_16;
    stAioAttr.enWorkmode     = AIO_MODE_I2S_SLAVE;
    stAioAttr.enSoundmode    = AUDIO_SOUND_MODE_STEREO; //这里修改成立体声
    stAioAttr.u32EXFlag      = 1;
    stAioAttr.u32FrmNum      = 30;
    stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
    stAioAttr.u32ChnCnt      = 2;  //这里修改成2
        stAioAttr.u32ClkChnCnt   = 1;
    stAioAttr.u32ClkSel      = 1;  //这里修改成1
       
才执行到第1个调用,HI_MPI_AI_SetPubAttr,就提示错误:SAMPLE_COMM_AUDIO_StartAi: HI_MPI_AI_SetPubAttr(2) failed with 0xa0158003
不知道这是怎么回事啊?跪求解答啊:'(,我都还没有到楼主的地方,我使用的是3531AV100。

lishiqi

0个粉丝

19

问答

0

专栏

0

资料

lishiqi 2017-08-09 15:04:06
认可0
参考楼主的帖子,解决了hi319双声道采集pcm数据,并在au软件成功播放了!:hug:

qn1525404324

0个粉丝

1

问答

0

专栏

0

资料

qn1525404324 2018-08-02 15:13:57
认可0
谢谢楼主,立体声 ai采集成功播放,主要是pcm左右声道保存不对

qn1518329580

0个粉丝

7

问答

0

专栏

0

资料

qn1518329580 2018-09-29 14:23:34
认可0
收藏了,谢谢楼主!
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区