STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)续-音质问题解决总结

news2024/10/7 0:27:53

一、前言

之前进行了STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)的研究总结:
https://juejin.cn/post/7339016190612881408#heading-34

后续音质问题解决了,目前测试下来48khz的双声道使用效果很好,由于比较重要,这里单独补充总结一下可能音质原因(包括杂音),这对于调试stm32的i2s录放音很有帮助,不管stm32作为i2s从模式还在作为i2s主模式都是有用的,上述总结的全双工DMA回调处理接口是不需要变的。

二、资料收集

https://blog.csdn.net/Fairchild_1947/article/details/123391638?spm=1001.2014.3001.5501

这里的时钟配置对我有很大的启发,对应f4的芯片对应i2s的时钟配置必须是按照这样固定的,否则音质一定会打折扣。

三、音质问题可能原因总结(重要)

  • 1、是采样率匹配问题,采样率设置不对一定会导致杂音、快进慢放等问题;
  • 2、一个是单双声道问题,生成wav文件时如果声卡设备转换为双声道但是按照单声道处理就会有问题,数据量是双声道的,但是存储时处理了一半;(部分声卡固定是双声道,即使你的播放文件是单声道的,但是经过声卡播放后就是双声道的音,这时单片机通过i2s接收和发送都必须是按照双声道处理
  • 3、还有一个可能就是声卡设备的干扰问题,比如声卡i2s或者某些引脚接线不对导致影响数字信号采集,比如单片机作为主模式可选配的主时钟接入了声卡导致音质影响,实际声卡有其自己的主时钟mclk,声卡的该引脚就不能接入单片机了,否则单片机的i2s的mclk和声卡的mclk互相影响会导致音质问题;
  • 4、还有发现一个问题,声卡i2s的收和发的数据长度设置不一致,比如发设置了标准的16位长度,而接收设置了16位扩展32位长度,导致i2s初始化后接收可能正常,但是发送时声卡收不到数据从而导致录音没有声音,这一点也是很奇怪的,目前猜测可能是声卡双声道传输的问题导致的,所以一般出现设置16位数据长度16位数据帧接收没问题但是发送发送没有声音的话可以试着设置成16位数据32位帧;
  • 5、如果使用spi flash+fatfs进行音频文件写入的,那么音频波形快进样式也可能是spi flash的驱动问题导致的,正片擦除后写入时写入速度快就不会有这个问题,需要在写入前先擦除,如果写入时再擦除会影响写入速度从而影响录音;(调试时可以用示波器先确认硬件对应引脚输出的频率是否符合预期)
    采样率的时钟频率F4按照下图配置即可(比如48khz的固定为258的PLLI2SN和3的PLLi2SR,不同外部输入时钟可以设置对应分频后为1MHZ,比如8MHZ的则设置8分频,25MHZ的设置为25):spi flash理论上是不适合实时读写的,一般开机时写入一次,后续读取即可,因为spi flash的擦除是很耗时的,所以音频文件的实时读写在方案设计之初就需要考虑这一点,对于实时音频存储一定要注意这一点(目前考虑可以直接通过usb3.0等高速接口透传出来音频输出或者使用SD卡等方式);
  • 6、时钟配置配置这里给出一个参考,外部高速时钟不同可能会有一些差异,但是一定要按照固定的时钟分频去配置,比如我这里是25MHZ的:(如果是8MHZ的则M设置为8,后面N和R固定为258和3)

如下是参考网友的i2s时钟分频:

对于不同的HSE,我们为了达到上述一样的i2s时钟分频,需要根据25或8MHZ的不同HSE做不同的分频系数,比如25MHZ的HSE则对应的PLLM分频系统设置25,8MHZ的设置8,这样后面的PLLI2SN和PLLI2SR就能像上图一样固定了(HAL库的一般STM32CubeMX会自动配置时钟,这里往往自动配置的是不对的,要注意这一点)。

参考非HAL库中设置采样率的这一段代码可以更好的理解上面这一配置:

//采样率计算公式:Fs=I2SxCLK/[256*(2*I2SDIV+ODD)]
//I2SxCLK=(HSE/pllm)*PLLI2SN/PLLI2SR
//一般HSE=8Mhz 
//pllm:在Sys_Clock_Set设置的时候确定,一般是8
//PLLI2SN:一般是192~432 
//PLLI2SR:2~7
//I2SDIV:2~255
//ODD:0/1
//I2S分频系数表@pllm=8,HSE=8Mhz,即vco输入频率为1Mhz
//表格式:采样率/10,PLLI2SN,PLLI2SR,I2SDIV,ODD
const u16 I2S_PSC_TBL[][5]=
{
	{800 ,100,2,24,0},		//8Khz采样率
	{1102,429,4,19,0},		//11.025Khz采样率 
	{1600,213,2,13,0},		//16Khz采样率
	{2205,429,4, 9,1},		//22.05Khz采样率
	{3200,213,2, 6,1},		//32Khz采样率
	{4410,271,2, 6,0},		//44.1Khz采样率
	{4800,100,2, 4,0},		//48Khz采样率
	{8820,316,2, 3,1},		//88.2Khz采样率
	{9600,344,2, 3,1},  	//96Khz采样率
	{17640,361,2,2,0},  	//176.4Khz采样率 
	{19200,393,2,2,0},  	//192Khz采样率
};  
//设置IIS的采样率(@MCKEN)
//samplerate:采样率,单位:Hz
//返回值:0,设置成功;1,无法设置.
u8 I2S2_SampleRate_Set(u32 samplerate)
{ 
	u8 i=0; 
	u32 tempreg=0;
	samplerate/=10;//缩小10倍   
	
	for(i=0;i<(sizeof(I2S_PSC_TBL)/10);i++)//看看改采样率是否可以支持
	{
		if(samplerate==I2S_PSC_TBL[i][0])break;
	}
 
	RCC_PLLI2SCmd(DISABLE);//先关闭PLLI2S
	if(i==(sizeof(I2S_PSC_TBL)/10))return 1;//搜遍了也找不到
	RCC_PLLI2SConfig((u32)I2S_PSC_TBL[i][1],(u32)I2S_PSC_TBL[i][2]);//设置I2SxCLK的频率(x=2)  设置PLLI2SN PLLI2SR
 
	RCC->CR|=1<<26;					//开启I2S时钟
	while((RCC->CR&1<<27)==0);		//等待I2S时钟开启成功. 
	tempreg=I2S_PSC_TBL[i][3]<<0;	//设置I2SDIV
	tempreg|=I2S_PSC_TBL[i][4]<<8;	//设置ODD位
	tempreg|=1<<9;					//使能MCKOE位,输出MCK
	SPI2->I2SPR=tempreg;			//设置I2SPR寄存器 
	return 0;
}

四、最后

基本上stm32使用i2s的音视频总结这两篇文章就够用了,其它的stm32作为usb声卡或者录音也只是以stm32作为i2s主模式来驱动像wm8978这类音频编解码器即可,反而不会遇到这种直接和声卡交互stm32作为从模式可能引起的一些音质问题(调试过程中使用示波器来测量引脚频率可以帮助排除一些硬件问题,这样更能明确问题处理方向)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1634039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mySQL商城项目实战 (终)(全部表)(1-88张)

本章无sql语句&#xff0c;直接放转出的sql文件。 88张表结果如图! 资源在已经与文章绑定&#xff0c; 在navicat工具中&#xff0c;执行以下步骤 在新建的数据库中右键,点击【运行sql文件】&#xff0c;运行绑定的资源&#xff0c;之后您就可以在您的navicat中看到我建好的8…

Python数据分析大作业(ARIMA 自回归积分滑动平均模型) 4000+字 图文分析文档 销售价格库存分析+完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 完整代码分析 ​ 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#x…

在Android中,如何通过Kotlin协程处理多个API调用

在Android中&#xff0c;如何通过Kotlin协程处理多个API调用 在Android开发中&#xff0c;如何使用Kotlin协程处理多个API调用的示例呢&#xff1f;假设我们已经对Kotlin协程有了一定的了解&#xff0c;包括定义、简单用例和示例等。现在&#xff0c;让我们来看一些真实的Andr…

AD21技巧[更加便捷的DRC检查][把线框转成Keep-Out Layer板框]

AD10用了好久,之所以换到AD21并不是因为AD10功能不够强,而且因为别人用高版本设计的软件到我这里竟然打不开了,这个是我不能够接受的,所以开始使用AD21,使用之后发现AD21好多使用习惯和AD10有很大的区别! 更加便捷的DRC检查 本文摘录于&#xff1a;https://www.cnblogs.com/U…

[Android14] SystemUI的启动

1. 什么是System UI SystemUI是Android系统级应用&#xff0c;负责反馈系统及应用状态并与用户保持大量的交互。业务主要涉及的组成部分包括状态栏(Status Bar)&#xff0c;通知栏(Notification Panel)&#xff0c;锁屏(Keyguard)&#xff0c;控制中心(Quick Setting)&#xff…

基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析

H.264视频流的RTP封装类型分析&#xff1a; 前言&#xff1a; NULL Hearder简介(结构如下)&#xff1a; ---------------|0|1|2|3|4|5|6|7|--------|F|NRI| Type |--------------- F&#xff1a;forbidden_zero_bit&#xff0c; 占1位&#xff0c;在 H.264 规范中规定了这…

RustGUI学习(iced)之小部件(四):如何使用单选框radio部件?

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…

【酱浦菌-爬虫技术细节】解决学术堂爬虫翻页(下一页)问题

首先我们通过css选择器获取页码信息&#xff0c;这里的css选择器&#xff0c;选择的是含有a标签的所有li标签&#xff0c;代码如下&#xff1a; li html_web.css(div.pd_c_xslb_left_fenye ul li>a) for li in li:li_url li.css(a::attr(href)).get()li_num li.css(a::t…

基于FPGA的数字信号处理(6)--如何确定Verilog表达式的符号

前言 尽管signed语法的使用能带来很多便利&#xff0c;但同时也给表达式的符号确定带来了更多的不确定性。比如一个有符号数和一个无符号数的加法/乘法结果是有符号数还是无符号数&#xff1f;一个有符号数和一个无符号数的比较结果是有符号数还是无符号数&#xff1f;等等。接…

IOT病毒分析

前言&#xff1a; 最近审计报警日志&#xff0c;发现了一个IOT病毒&#xff0c;利用的是CVE-2023-1389漏洞扫描tplink&#xff0c;进行攻击&#xff0c;有点意思&#xff0c;拿出来分析下。 发现&#xff1a; 查看流量日志&#xff0c;发现了一个有问题的访问&#xff1a; 访…

【架构】后端项目如何分层及分层领域模型简化

文章目录 一. 如何分层1. 阿里规范2. 具体案例分析 二. 分层领域模型的转换1. 阿里规范2. 模型种类简化分析 三. 小结 本文描述后端项目中如何进行分层&#xff0c;以及分层领域模型简化 一. 如何分层 1. 阿里规范 阿里的编码规范中约束分层逻辑如下: 开放接口层&#xff1a…

CSS实现各种优惠券效果

一、左半圆效果 <style style"text/css">.coupon {width: 240px;height: 100px;margin-top: 15px;background-color: #ff6347;-webkit-mask: radial-gradient(circle at left center, transparent 20px, red 20px); } </style><div class"coupon…

摩根大通推出创新工具 FlowMind,引领金融自动化新变革

近日&#xff0c;摩根大通人工智能研究部推出了一款极具创新性的工具——FlowMind&#xff0c;为金融行业带来了全新的工作模式和效率提升。 FlowMind 能够自动化金融工作流程&#xff0c;在信贷审批、风险评估、合规监测等重要任务中发挥着关键作用。它利用 GPT 自动生成工作…

张鸣独到政治观,规矩与自信新解

张鸣独解规矩与自信&#xff0c;社政新影响揭秘。张鸣独到政治观&#xff0c;规矩与自信新解在当今社会政治的大背景下&#xff0c;学者张鸣的每一次公开演讲无疑都是一次思想的盛宴。最近&#xff0c;他就当前的社会政治问题提出了自己独特的观点&#xff0c;特别是他对规矩和…

【网络原理】UDP协议 | UDP报文格式 | 校验和 | UDP的特点 | 应用层的自定义格式

文章目录 一、UDP协议1.UDP的传输流程发送方接收方 2.UDP协议报文格式&#xff1a;长度受限校验和如何校验&#xff1a;CRC算法&#xff1a;循环冗余算法md5算法&#xff1a; 2.UDP的特点 二、开发中常见的自定义格式1.xml&#xff08;古老&#xff09;2.json&#xff08;最流行…

头歌:Spark任务提交

第1关&#xff1a;spark-submit提交 任务描述 相关知识 spark-submit参数 计算圆周率 编程要求 测试说明 任务描述 本关任务&#xff1a;学会将程序提交到集群上执行。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.了解spark-submit的参数。2.学会提交Spar…

双目深度估计原理立体视觉

双目深度估计原理&立体视觉 0. 写在前面1. 双目估计的大致步骤2. 理想双目系统的深度估计公式推导3. 双目标定公式推导4. 极线校正理论推导 0. 写在前面 双目深度估计是通过两个相机的对同一个点的视差来得到给该点的深度。 标准系统的双目深度估计的公式推导需要满足:1)两…

按键的软件消抖

1.当出现物理情况比如单片机不小心摔了会发生灯亮的情况&#xff0c;所以我们得增加个延迟函数 2.这个错误是缺少头文件#include <intrins.h> 3. #include "reg52.h" #include <intrins.h>sbit key2 P2^0; sbit key1 P2^1; sbit ledone P3^7;voi…

稳扎稳打 部署丝滑 开源即时通讯(IM)项目OpenIM源码部署流程(linux windows mac)

背景 OpenIM包含多个关键组件&#xff0c;每个都是系统功能必不可少的一部分。具体来说&#xff0c;MongoDB 用于持久化存储&#xff1b;Redis 用作缓存&#xff1b;Kafka 用于消息队列&#xff1b;Zookeeper 用于服务发现&#xff1b;Minio 用于对象存储。这些组件的众多可能会…

用OpenCV先去除边框线,以提升OCR准确率

在OpenCV的魔力下&#xff0c;我们如魔法师般巧妙地抹去表格的边框线&#xff0c;让文字如诗如画地跃然纸上。 首先&#xff0c;我们挥动魔杖&#xff0c;将五彩斑斓的图像转化为单一的灰度世界&#xff0c;如同将一幅绚丽的油画化为水墨画&#xff0c;通过cv2.cvtColor()函数的…