DAC+DMA+TIM实现音频播放问题记录

这篇具有很好参考价值的文章主要介绍了DAC+DMA+TIM实现音频播放问题记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 概述

本文主要记录下音频播放实现过程中遇到的问题。音频文件存储在外部FLASH中,SPI+DMA读取到MCU中,然后进行DAC转换后输入到NS4165B音频功率放大器(数据手册)。第一次接触音频,遇到很多零碎问题,有些问题很基础,主要是学习单片机时不够扎实,统一记录在这里。

先贴三篇参考的文章,都是此方案的实现:
基于STM32的DAC实现音频波形的输出
STM32F103使用TIM DMA DAC实现播放WAV音乐
基于STM32F103C8T6片内Flash的音频播放(DAC通道)
通过这三篇文章,有了一个整体的概念。

2. 音频采样率

2.1 定时器触发周期

DAC使用定时器作为触发源,参考的三篇文章,对定时器的周期设置描述比较少。定时器的周期应该设置多少呢?
定时器计时时间到,进行一次DAC转换,所以应该与音频的采样速率相同。
DAC+DMA+TIM实现音频播放问题记录
更多时候是采用DAC,使用I2S通信,可以直接设置音频采样率:
DAC+DMA+TIM实现音频播放问题记录
而定时器,则需要自己计算下预分频和计数值:
仿真查看系统时钟0x44AA200 = 72M,修改为预分频12M,再750计数,正好是16K
使用正弦进行测试,每一小段正好为16K

2.2 音频文件的格式

在音频文件的头信息中,包括了单双声道、采样速率等信息。
从第45字节开始,才是采样的音频数据:
DAC+DMA+TIM实现音频播放问题记录
具体描述如下:
DAC+DMA+TIM实现音频播放问题记录
扩展链接:
1.多媒体文件格式(五):PCM / WAV 格式。
2.PCM音频数据。

3. DAC的左对齐和右对齐

以往ADC也好,DAC也好,以往都是用右对齐,也没关注过左对齐有什么用,使用上有什么区别。

3.1 为什么要使用左对齐

在8位单片机中,超过8位的数据,就要占用H和L两个寄存器。左、右对齐,就对应了H存放高八位和L存放低八位。当对转换精度要求不高时,通过设置左对齐,只读H寄存器取高八位,加快速度。
而在32位单片机,寄存器基本是16位和32位,都是读取一次寄存器,并不存在上述的只读一次H加快速度了。那么左对齐是不是就没用了呢?在这里恰巧用到了左对齐。

参考链接:ADC数据存储:左对齐和右对齐。

3.2 左对齐数据的读写

最常用的是右对齐,数据寄存器如下:
DAC+DMA+TIM实现音频播放问题记录DAC+DMA+TIM实现音频播放问题记录
使用时直接对寄存器进行读取即可。而左对齐数据寄存器如下:
DAC+DMA+TIM实现音频播放问题记录
设置为左对齐模式,在数据处理时需要进行处理。若寄存器里左对齐的数据值X,则X>>4才是实际的数据。
单片机是按照地址进行读写,并不会因为我们设置了左右对齐,直接将我们的数据放到有效位。

3.3 音频数据的使用

3.3.1 16bit数据和12位DAC的失真问题

我的音频文件是16位,而DAC是12位,那么就要对16位数据进行取舍,所以转换音频数据的高12位。
这个时候如果使用右对齐,需要对每一个音频数据进行移位操作,因为音频数据很大,是比较浪费时间的。那么使用左对齐,就不必进行移位,直接赋值音频数据就可以了。
经过这样处理后,有明显噪音。将音频重新采样为8bit后,能够正常播放,怀疑是16bit忽略低4位导致的。但实际并不是,这个失真是相对使用16位DAC,而使用精度较差的DAC,高精度采样数据,并不会失真,反而可能会更好。这一点,可以通过简单计算理解:

  1. 假设参考电压3V,实际电压2V,计算12位DAC和16位DAC的采样值。
  2. 然后忽略16位采样值的低四位,也就是>> 4,与12位DAC的采样值对比。

3.3.2 音频数据的符号位处理

上一小节提到16bit有杂音,改为8bit重新对音频采样,就可以正常播放了。这是因为16位音频数据是有符号的,在使用DAC进行转换时,需要考虑去除符号位。
STM32F103.12位DAC输出16位WAV语音文件
简单的程序将int16_t数组转换为uint16_t

4. 单双声道的理解

单双声道 – DMA每传输一次,地址偏移size,所以配置中size改为字

下一次传输的地址将是前一次传输的地址递增 1个数据宽度、2个数据宽度或 4个数据宽度
【STM32】 DMA原理,步骤超细详解,一文看懂DMA

5. DMA无法进入中断

调试DMA+TIM+DAC实现音频输出,发现无法进入DMA中断,芯片为国民技术N32G45。
一定要先使能DMA通道中断,再使能DMA通道。

6. 测试播放效果

直接播放flash存放的开机音乐等,噪音较大,且波形不是规律的,不易分析。

6.1 测试单音

直接测试flash内的音频,无法播放可能有很多原因。可以先测试单音:通过调整正弦的频率,让喇叭发出不同的声音。
在1 2 3 4 5 6 7的在声乐中的的频率各是多少?帖子中,得到以下频率:

	A:440Hz 		a:880Hz 	
	B:493.88Hz 	b:987.76Hz	
	C∶523.25Hz 	c:1046.50Hz	
	D: 587.33Hz 	d:1174.66Hz	
	E∶659.25Hz 	e:1318.51Hz	
	F∶698.46Hz 	f:1396.92Hz	
	G∶783.99Hz 	g:1567.98Hz	

再看正弦数组:
DAC+DMA+TIM实现音频播放问题记录
一个正弦周期是32个采样点,那么要发哪个声音,就用频率 * 32得到DAC用作触发的定时器频率。定时器预分频为12M,所以再用12M/频率,就得到计数值。

							A * 32		12M/(A * 32)	a * 32	12M/(a * 32)
A:440Hz 	a:880Hz 		14080			852			28160		426.13
B:493.88Hz b:987.76Hz		15804.16		759			31608		379.65
C∶523.25Hz c:1046.50Hz		16744			716.67		33488		358.33
D: 587.33Hz d:1174.66Hz		18794.56		638.48		37589		319.24
E∶659.25Hz e:1318.51Hz		21096			568.82		42192		284.41
F∶698.46Hz f:1396.92Hz		22350.72		536.91		44701		268.45
G∶783.99Hz g:1567.98Hz		25087.68		478.31		50175		239.16

只要传入计数值即可:
DAC+DMA+TIM实现音频播放问题记录

6.2 测试播放人声

为了能够容易感受到调试过程中声音的变化效果,需要使用人声。
在线文字转语音,语音合成,真人语音合成-在线工具
生成后将数据放到const数组即可进行测试。

7. 音频文件制作

自己选一个音乐片段,生成音频文件:Goldwave生成wave音频数据。文章来源地址https://www.toymoban.com/news/detail-420705.html

到了这里,关于DAC+DMA+TIM实现音频播放问题记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python音频播放问题解决方法

    只是为了验证问题存在,所以就提供了一个获取音频的方法,就是白嫖了。 根据有道翻译的发音获取到地址: https://dict.youdao.com/dictvoice?le=autoaudio=大家好 播放音频通过两种方式,分别通过 playsound 和 pyaudio 两种库,具体使用哪个看个人爱好,两个在使用过程中都遇到过一点小

    2023年04月08日
    浏览(47)
  • STM32配置ADC2(DMA)进行采集 DAC 输出-1

    在正点原子的ADC(DMA)例程上,将ADC1改成ADC2来采集电压,并且进行测试 开发板:正点原子探索者STM32F407ZG 2.1 ADC相关 通过查看开发指南我们发现,ADC1 和 ADC2 的通道 5 都是采用的 PA5 引脚,就意味着我们修改为 ADC2 后还是可以通过 PA5 来进行电压的测量。 对应的我们在adc.h中

    2024年02月02日
    浏览(63)
  • STM32配置ADC2(DMA)进行采集 DAC 输出-2

    在上一节的基础上,我们把 DAC(三角波)给集成进来,实现按下按键输出三角波,通过串口发送数据给电脑,分析然后画出电压的波形并且展示出来 开发板:正点原子探索者STM32F407ZG 2.1 DAC部分 这里我们采用 实验22-2 DAC输出三角波实验 的例程,查看主函数找中和 DAC 相关的代

    2024年02月01日
    浏览(37)
  • 解决浏览器无法自动播放音频的问题

    项目场景:要求根据后台返回数据做一个语音提示功能 浏览器报Uncaught (in promise) DOMException: play() failed because the user didn’t interact with the document first. 由于浏览器为了避免自动播放音频打扰用户,因此浏览器做出了限制,只有用户与浏览器交互,如点击事件等等,才会播放音频

    2024年02月12日
    浏览(52)
  • 关于STM32利用TIM+PWM+DMA控制WS2812

    MCU:STM32F103c8t6 开发工具:STM32CubeMX  使用板子参考原理图:STM32F103C8T6最小系统板开源链接 脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输

    2024年02月01日
    浏览(53)
  • STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

    本文主要讲解定时器触发ADC去采集交流信号,DMA把数据搬移到内存。 所需工具: 开发板:STM32F103C8T6 STM32CubeMX IDE: Keil-MDK 相关文章: STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx(二) STM32cubemx ADC+TIM+DMA超频采样 ADC+TIM+DMA采集交流信号是电赛中使用范围最为广泛的一个技术。这个模

    2024年02月03日
    浏览(53)
  • js实现点击音频实现播放功能

    html: css: js:

    2024年02月02日
    浏览(37)
  • 微信小程序音频播放问题createInnerAudioContext为何不调用onTimeUpdate

    废话不多说,直接这么写就可以解决:     innerAudioContext.play();          innerAudioContext.onCanplay(() = {       innerAudioContext.play();         console.log(\\\'开始播放\\\')     });     innerAudioContext.onWaiting(() = {         innerAudioContext.pause()     }); 主要涉及这几个方法

    2024年02月15日
    浏览(42)
  • ZYNQ AXI_DMA_UDP以太网传输(二)问题记录

    上一篇文章只是简单的记录一下调试成功的代码 但调试成功这个过程很痛苦,踩了很多坑,特此记录,留眼以后查看 参考博客 xilinx dma调试笔记 ZYNQ AXI DMA调试细节 在调试过程中出现这类问题基本上都是这一句代码出了问题: 再往里面跳可以看见这样一个函数,在正点原子提

    2024年03月14日
    浏览(66)
  • Matlab实现音频录制和播放

    Matlab实现音频录制和播放 在Matlab中,我们可以使用内置的函数轻松地对音频进行录制和播放。本文将介绍如何使用Matlab实现音频录制和播放。 录制音频 首先,我们需要创建一个录音对象并进行设置。我们可以使用audiorecorder函数来创建录音对象。我们可以通过设定采样率、比

    2024年02月04日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包