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

一、前言

之前进行了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);//先关闭PLLI2Sif(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 PLLI2SRRCC->CR|=1<<26;					//开启I2S时钟while((RCC->CR&1<<27)==0);		//等待I2S时钟开启成功. tempreg=I2S_PSC_TBL[i][3]<<0;	//设置I2SDIVtempreg|=I2S_PSC_TBL[i][4]<<8;	//设置ODD位tempreg|=1<<9;					//使能MCKOE位,输出MCKSPI2->I2SPR=tempreg;			//设置I2SPR寄存器 return 0;
}

四、最后

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch学习笔记——TensorBoard的初使用

1、TensorBoard介绍 TensorBoard是TensorFlow的可视化工具&#xff0c;但它也可以与PyTorch结合使用。TensorBoard提供了一个Web界面&#xff0c;可以展示你训练过程中的各种信息&#xff0c;如损失值、准确度、权重分布等&#xff0c;更好地帮助开发者理解和调试模型。 Tenso…

BJFUOJ-C++程序设计-实验3-继承和虚函数

A TableTennisPlayer 答案&#xff1a; #include<iostream> #include<cstring> using namespace std;class TableTennisPlayer{ private:string firstname;string lastname;bool hasTable;public:TableTennisPlayer(const string &, const string &, bool…

深入剖析Tomcat(五) 剖析Servlet容器并实现一个简易Context与Wrapper容器

上一章介绍了Tomcat的默认连接器&#xff0c;后续程序都会使用默认连接器。前面有讲过Catalina容器的两大块内容就是连接器与Servlet容器。不同于第二章的自定义丐版Servlet容器&#xff0c;这一章就来探讨下Catalina中的真正的Servlet容器究竟长啥样。 四种容器 在Catalina中…

实现优先队列——C++

目录 1.优先队列的类模板 2.仿函数的讲解 3.成员变量 4.构造函数 5。判空&#xff0c;返回size&#xff0c;返回队头 6.插入 7.删除 1.优先队列的类模板 我们先通过模板来进行初步了解 由上图可知&#xff0c;我们的模板里有三个参数&#xff0c;第一个参数自然就是你要存储的数…

读天才与算法:人脑与AI的数学思维笔记16_音乐图灵测试

1. 艾米 1.1. 人工智能作曲家 1.1.1. 分析机可能会生成任意复杂程度、精细程度的科学的音乐作品 1.1.1.1. 阿达洛夫莱斯 1.1.2. 巴赫的作品是大多数作曲家开始学习创作的起点&#xff0c;也是大多数计算机开始学习作曲的起点…

uniapp 短视频浏览组件(仿抖音、上滑下滑)组件 Ba-VideoSView

简介&#xff08;下载地址&#xff09; Ba-VideoSView 是一款uniapp短视频上划浏览组件&#xff0c;支持无限滑动加载&#xff0c;支持自定义界面&#xff08;功能遮罩&#xff09;,支持点播、直播。 支持无限滑动加载支持自定义界面&#xff08;遮罩&#xff09;支持监听上滑…

第 8 章 机器人平台设计(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 学习到当前阶段大家对ROS已经有一定的认知了&#xff0c;但是之前的内容更偏理论&#xff0c;尤其是介绍完第6…

KKView远程控制2.0版本发布,TeamViewer面临巨大挑战

KKView远程控制2.0版本发布&#xff0c;TeamViewer面临巨大挑战 近日&#xff0c;备受瞩目的远程控制软件KKView发布了其全新2.0版本&#xff0c;KKView以其独特的创新性和用户友好的设计&#xff0c;为远程办公、远程培训等领域提供了更加高效、便捷的解决方案。 KKView远程…

K8S 哲学 - deployment -- kubectl【create 、 rollout 、edit、scale、set】

kubectl create kubectl rollout kubectl edit kubectl set kubectl scale 1、创建与配置文件解析 2、deploy 滚动更新 &#xff1a;template 里面的内容改变触发滚动更新 编辑该 deploy 的 配置文件 &#xff0c;加入一个 label 不会触发滚动更新 改变 nginx镜…

分布式与一致性协议之Raft算法(一)

Raft算法 概述 Raft算法属于Multi-Paxos算法&#xff0c;它在兰伯特Multi-Paxos思想的基础上做了一些简化和限制&#xff0c;比如日志必须是连续的&#xff0c;只支持领导者(Leader)、跟随者(Follwer)和候选人(Candidate)3种状态。在理解和算法实现上&#xff0c;Raft算法相对…

Python语言零基础入门——文件

目录 一、文件的基本概念 1.文件 2.绝对路径与相对路径 3.打开文件的模式 二、文件的读取 三、文件的追加 四、文件的写入 五、with语句 六、csv文件 1.csv文件的读取 2.csv文件的写入 七、练习题&#xff1a;实现日记本 一、文件的基本概念 1.文件 文件是以计算…

浏览器安装路径位置的查看、指定网址快捷方式的创建

浏览器安装路径位置的查看、指定网址快捷方式的创建 浏览器安装路径位置的查看 法一、属性查看法 右键点击浏览器的桌面图标&#xff0c;选择“属性”&#xff0c;“快捷方式”页中的“目标”框中可见. 以Microsoft Edge浏览器为例&#xff0c;参见下图&#xff1a; 法二、地…

免费开源语音克隆-GPT-SoVITS-WebUI只需 5 秒的声音样本

语音克隆-GPT-SoVITS-WebUI 强大的少样本语音转换与语音合成Web用户界面。 功能&#xff1a; 零样本文本到语音&#xff08;TTS&#xff09;&#xff1a; 输入 5 秒的声音样本&#xff0c;即刻体验文本到语音转换。 少样本 TTS&#xff1a; 仅需 1 分钟的训练数据即可微调模型…

LabVIEW换智能仿真三相电能表研制

LabVIEW换智能仿真三相电能表研制 在当前电力工业飞速发展的背景下&#xff0c;确保电能计量的准确性与公正性变得尤为重要。本文提出了一种基于LabVIEW和单片机技术&#xff0c;具有灵活状态切换功能的智能仿真三相电能表&#xff0c;旨在通过技术创新提高电能计量人员的培训…

基于SpringBoot+Vue的旅游网站系统

初衷 在后台收到很多私信是咨询毕业设计怎么做的&#xff1f;有没有好的毕业设计参考?能感觉到现在的毕业生和当时的我有着同样的问题&#xff0c;但是当时的我没有被骗&#xff0c;因为现在很多人是被骗的&#xff0c;还没有出学校还是社会经验少&#xff0c;容易相信别人。…

项目管理-项目进度管理2/3

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 项目进度管理&#xff1a;需掌握 ITTO, 搞懂计算图&#xff0c;问题和解决方案。 项目进度管理6个过程&#xff0c;包括&#xff08;口…

机器学习:深入解析SVM的核心概念【二、对偶问题】

对偶问题 **问题一&#xff1a;什么叫做凸二次优化问题&#xff1f;而且为什么符合凸二次优化问题&#xff1f;**为什么约束条件也是凸的半空间&#xff08;Half-Space&#xff09;凸集&#xff08;Convex Set&#xff09;半空间是凸集的例子SVM 约束定义的半空间总结 **问题二…

nginx的前世今生(二)

书接上回&#xff1a; 上回书说到&#xff0c;nginx的前世今生&#xff0c;这回我们继续说 3.缓冲秘籍&#xff0c;洪流控水 Nginx的缓冲区是其处理数据传输和提高性能的关键设计之一&#xff0c;主要用于暂存和管理进出的数据流&#xff0c;以应对不同组件间速度不匹配的问题…

Dokcer容器分布式搭建LNMP+wordpress论坛

目录 引言 一、架构环境 二、搭建容器 &#xff08;一&#xff09;自定义网络 &#xff08;二&#xff09;搭建nginx容器 1.文件准备 2.查看与编辑文件 3.生成镜像 4.创建容器 &#xff08;三&#xff09;搭建MySQL容器 1.文件准备 2.查看与编辑文件 3.生成镜像 …

基于Unity+Vue通信交互的WebGL项目实践

unity-webgl 是无法直接向vue项目进行通信的&#xff0c;需要一个中间者 jslib 文件 jslib当作中间者&#xff0c;unity与它通信&#xff0c;前端也与它通信&#xff0c;在此基础上三者之间进行了通信对接 看过很多例子&#xff1a;介绍的都不是很详细&#xff0c;不如自己写&…