OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 263|回复: 0

音频的24bit采样精度。MIC接收声音输出PDM信号,STM32的MDF模块接受PDM信号转为PCM数据,然后USB音频类传输给PC,PC录音。

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2021-6-18
在线时间
4 小时
发表于 2025-2-24 10:54:05 | 显示全部楼层 |阅读模式
1金钱
MIC接收声音输出PDM信号,STM32MDF模块接受PDM信号转为PCM数据,然后USB音频类传输给PCPC进行录音。
目前我用STM32U575芯片做一个功能,将MIC采集的数据通过MDF滤波,然后DMAMDF滤波的数据传输到USB AUDIO的音频帧,通过USB传输到电脑。
目前可以传输,4通道(声道),采样深度16bit,采样频率22050,已经成功。
但是想要采样深度从16bit修改为24bit的,修改了音频搬运方式,但失败了。我进行了如下修改
1.【修改描述符为24bit3字节】
修改
#define USB_AUDIO_CONFIG_MIC_RES_BIT                 16   /* 16 bit per sample */
#define USB_AUDIO_CONFIG_MIC_RES_BYTE                2    /* 2 bytes */
修改为
#define USB_AUDIO_CONFIG_MIC_RES_BIT                 24   /* 16 bit per sample */
#define USB_AUDIO_CONFIG_MIC_RES_BYTE                3    /* 2 bytes */
这个宏定义用于音频描述符
pMicASFormatDesc->bSubFramSize = USB_AUDIO_CONFIG_MIC_RES_BYTE;
pMicASFormatDesc->bBitResolution = USB_AUDIO_CONFIG_MIC_RES_BIT;
2.MDF传输半完成回调HAL_MDF_AcqHalfCpltCallback,和传输全完成回调HAL_MDF_AcqCpltCallback里,4个通道都【修改数据搬运方式为每次3字节】
原本的16bit:(这里for循环次数为96/2=48
            for(int i=0;i<96/2;i++)
            {
                frame_buffer[8*i+0]=RecLeftChBuff[2*i];      
                frame_buffer[8*i+1]=RecLeftChBuff[2*i+1];   
            }
修改为24bit:(这里for循环次数设置为48,这样每个通道就是搬运48*3字节=144字节)
            for(int i=0;i<144/3;i++)
            {
                frame_buffer[12*i+0]=RecLeftChBuff[3*i];      
                frame_buffer[12*i+1]=RecLeftChBuff[3*i+1];   
                frame_buffer[12*i+2]=RecLeftChBuff[3*i+2];
            }
3.【修改USB音频端点最大包大小为(144*4)
原本
#define USBD_AUDIO_EPIN_FS_MPS                        (96*4)
修改为
#define USBD_AUDIO_EPIN_FS_MPS                        (144*4)
宏定义用于
ux_device_class_audio_stream_parameter_max_frame_buffer_size = USBD_AUDIO_EPIN_FS_MPS;
4.也已经考虑了usb端点传输内存大小,并进行了设置
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0xA0);//0xA0*4(WORD)=640字节
足以容纳
#define USBD_AUDIO_EPIN_FS_MPS                        (144*4)576字节
结果失败了。现象是,在电脑上对这个MIC进行录音操作时,播放出来后的声音,是小声的类似于外星人一样的杂音,根本没有录下我说话的声音,完全没有我说话的声音的任何特征。比如我说“ABC”,但播放出来的声音之中完全没有任何近似“ABC”的声音。
尝试1:调换字节顺序,一共6种可能性,
012,021,102,120,201,210
例如
                frame_buffer[12*i+0]=RecLeftChBuff[3*i];      
                frame_buffer[12*i+1]=RecLeftChBuff[3*i+1];   
                frame_buffer[12*i+2]=RecLeftChBuff[3*i+2];
                frame_buffer[12*i+0]=RecLeftChBuff[3*i];      
                frame_buffer[12*i+1]=RecLeftChBuff[3*i+2];   
                frame_buffer[12*i+2]=RecLeftChBuff[3*i+1];
。。。等等6种可能性,都试过了,现象一样,失败。
尝试2:尝试在高字节添0
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+0]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_1];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+1]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_2];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+2]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_3];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+3]=0;
也就是最后填一个0,并且以下每个通道都填0,同时frame_buffer+x的这个偏移量也往下延顺地增加。同时半传输回调和全传输回调都修改。
失败。结果是录音的时候,录音进度条直接在最开始的时候卡住。
尝试3:尝试在低字节添0
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+0]=0;
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+1]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_1];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+2]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_2];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+3]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_3];
也就是第一个最低位填一个0,并且以下每个通道都填0,同时frame_buffer+x的这个偏移量也往下延顺地增加。同时半传输回调和全传输回调都修改。
失败。结果是录音的时候,录音进度条直接在最开始的时候卡住。
尝试4:修改DMA搬运字节数为WORD
根据手册的这个

原本是HALFWORD
  pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;// 源数据位宽16
  pNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;// 目标数据位宽16
修改为
1.SrcDataWidthDestDataWidth都修改为WORD
失败,录音的时候,录音进度条直接在最开始卡住。
2.SrcDataWidth修改为WORD
失败,MCU卡死。
3.DestDataWidth 修改为WORD
失败,录音的时候,录音进度条直接在最开始卡住。
然后修改
DMALConfig.MsbOnly = ENABLE;
这个配置只会将MDF数据寄存器的高16bit取出来,所以我将这个配置改成DISABLE。
可以正常SrcDataWidthDestDataWidth都修改为WORD不会卡死了,可以在24bit的情况下录音,但是杂音极大,大概覆盖了说话声音的80%
然后进行如下修改

#define MIC_ALL_CH_RES_BYTE  (MIC_CH_NUM * 3) //这个是通道数4*字节数3
#define MIC_RES_BYTE 4//这应该是4,每隔4字节是一个样本。
//字节顺序应该是只搬运高24bit,也就是下面的宏定义不应该是012,而是123
#define MIC_BUFF_BYTE_OFFSET_1 1
#define MIC_BUFF_BYTE_OFFSET_2 2
#define MIC_BUFF_BYTE_OFFSET_3 3
HAL_MDF_AcqHalfCpltCallbackHAL_MDF_AcqCpltCallback里都修改搬运方式如下
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+0]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_1];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+1]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_2];
                                frame_buffer[MIC_ALL_CH_RES_BYTE*i+2]=RecLeftChBuff[MIC_RES_BYTE*i+MIC_BUFF_BYTE_OFFSET_3];

杂音覆盖说话声音的30%,而且说话声音变成类似机器人的声音,畸变严重,不正常,但是可以大概听出来说的是什么。

请问,进行什么修改可以将原本的采样频率16bit改成24bit,然后正常录音?有做过类似的吗?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-25 09:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表