MIC接收声音输出PDM信号,STM32的MDF模块接受PDM信号转为PCM数据,然后USB音频类传输给PC,PC进行录音。 目前我用STM32U575芯片做一个功能,将MIC采集的数据通过MDF滤波,然后DMA将MDF滤波的数据传输到USB AUDIO的音频帧,通过USB传输到电脑。 目前可以传输,4通道(声道),采样深度16bit,采样频率22050,已经成功。 但是想要采样深度从16bit修改为24bit的,修改了音频搬运方式,但失败了。我进行了如下修改 1.【修改描述符为24bit和3字节】 修改 #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.SrcDataWidth和DestDataWidth都修改为WORD。 失败,录音的时候,录音进度条直接在最开始卡住。 2.仅SrcDataWidth修改为WORD。 失败,MCU卡死。 3.仅DestDataWidth 修改为WORD。 失败,录音的时候,录音进度条直接在最开始卡住。 然后修改
DMALConfig.MsbOnly = ENABLE; 这个配置只会将MDF数据寄存器的高16bit取出来,所以我将这个配置改成DISABLE。 可以正常SrcDataWidth和DestDataWidth都修改为WORD不会卡死了,可以在24bit的情况下录音,但是杂音极大,大概覆盖了说话声音的80% 然后进行如下修改
#define MIC_ALL_CH_RES_BYTE (MIC_CH_NUM * 3) //这个是通道数4*字节数3 #define MIC_RES_BYTE 4//这应该是4,每隔4字节是一个样本。 //字节顺序应该是只搬运高24bit,也就是下面的宏定义不应该是0、1、2,而是1、2、3 #define MIC_BUFF_BYTE_OFFSET_1 1 #define MIC_BUFF_BYTE_OFFSET_2 2 #define MIC_BUFF_BYTE_OFFSET_3 3 HAL_MDF_AcqHalfCpltCallback和HAL_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,然后正常录音?有做过类似的吗?
|