本帖最后由 tianxin19 于 2017-2-3 13:18 编辑
怀疑采样率解析不正确,对程序进行跟踪调试。跟踪发现采样率解析正常,而能正常播放的音频是双声道的,单声道的不能正常播放。检查代码发现,在函数wav_buffill()里没有对单声道的情况进行处理。 [mw_shl_code=c,true]//填充buf
//buf:数据区
//size:填充数据量
//bits:位数(16/24)
//返回值:读到的数据个数
u32 wav_buffill(u8 *buf,u16 size,u8 bits)
{
u16 readlen=0;
u32 bread;
u16 i;
u8 *p;
if(bits==24)//24bit音频,需要处理一下
{
readlen=(size/4)*3; //此次要读取的字节数
f_read(audiodev.file,audiodev.tbuf,readlen,(UINT*)&bread); //读取数据
p=audiodev.tbuf;
for(i=0;i<size;)
{
buf[i++]=p[1];
buf=p[2];
i+=2;
buf[i++]=p[0];
p+=3;
}
bread=(bread*4)/3; //填充后的大小.
}else
{
f_read(audiodev.file,buf,size,(UINT*)&bread);//16bit音频,直接读取数据
if(bread<size)//不够数据了,补充0
{
for(i=bread;i<size-bread;i++)buf=0;
}
}
return bread;
} [/mw_shl_code] 依据参考资料显示,在飞利浦(I2S)标准模式下,一个采样周期(1/fs)内,左右声道数据分时传输。那么单声道音频文件,没有右声道的数据,将被强制拆分成左右声道数据输出,所以只能听到杂音。
如何去处理?在论坛里查找了许久我得到了一种思路:对wav_buffill()进行修改,当文件解析到声道数为单声道时,将单声道的数据复制给别一声道,使左右声道输出一样的音频就可以正常播放。
[mw_shl_code=c,true]u32 wav_buffill(u8 *buf,u16 size,u8 bits,u8 nch)
{
u16 readlen=0;
u32 bread;
u16 i;
u8 *p;
if(bits==24)//24bit音频,需要处理一下
{
readlen=(size/4)*3; //此次要读取的字节数
f_read(audiodev.file,audiodev.tbuf,readlen,(UINT*)&bread); //读取数据
p=audiodev.tbuf;
for(i=0;i<size;)
{
buf[i++]=p[1];
buf=p[2];
i+=2;
buf[i++]=p[0];
p+=3;
}
bread=(bread*4)/3; //填充后的大小.
}
else
{
if(nch==2)
{
f_read(audiodev.file,buf,size,(UINT*)&bread);//16bit音频,直接读取数据
}
else //对单声道的进行扩充
{
readlen=size/2;
f_read(audiodev.file,audiodev.tbuf,readlen,(UINT*)&bread); //读取数据
p=audiodev.tbuf;
for(i=0;i<readlen;i++)
{
buf[4*i+0]=p[0];
buf[4*i+1]=p[1];
buf[4*i+2]=p[0];
buf[4*i+3]=p[1];
p+=2;
}
bread=bread*2;
}
if(bread<size)//不够数据了,补充0
{
for(i=bread;i<size-bread;i++)buf=0;
}
}
return bread;
} [/mw_shl_code]
|