目录

  • 1. 概述
  • 2. 音频采样率
    • 2.1 定时器触发周期
    • 2.2 音频文件的格式
  • 3. DAC的左对齐和右对齐
    • 3.1 为什么要使用左对齐
    • 3.2 左对齐数据的读写
    • 3.3 音频数据的使用
      • 3.3.1 16bit数据和12位DAC的失真问题
      • 3.3.2 音频数据的符号位处理
  • 4. 单双声道的理解
  • 5. DMA无法进入中断
  • 6. 测试播放效果
    • 6.1 测试单音
    • 6.2 测试播放人声
  • 7. 音频文件制作

1. 概述

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

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

2. 音频采样率

2.1 定时器触发周期

DAC使用定时器作为触发源,参考的三篇文章,对定时器的周期设置描述比较少。定时器的周期应该设置多少呢?
定时器计时时间到,进行一次DAC转换,所以应该与音频的采样速率相同。

更多时候是采用DAC,使用I2S通信,可以直接设置音频采样率:

而定时器,则需要自己计算下预分频和计数值:
仿真查看系统时钟0x44AA200 = 72M,修改为预分频12M,再750计数,正好是16K
使用正弦进行测试,每一小段正好为16K

2.2 音频文件的格式

在音频文件的头信息中,包括了单双声道、采样速率等信息。
从第45字节开始,才是采样的音频数据:

具体描述如下:

扩展链接:
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 左对齐数据的读写

最常用的是右对齐,数据寄存器如下:

使用时直接对寄存器进行读取即可。而左对齐数据寄存器如下:

设置为左对齐模式,在数据处理时需要进行处理。若寄存器里左对齐的数据值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

再看正弦数组:

一个正弦周期是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

只要传入计数值即可:

6.2 测试播放人声

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

7. 音频文件制作

自己选一个音乐片段,生成音频文件:Goldwave生成wave音频数据。

DAC+DMA+TIM实现音频播放问题记录相关推荐

  1. dma接收双缓存 stm32_STM32和WM8960 I2S 利用DMA双缓冲音频播放和录音(二)

    前面简单讲解了WM8960语音芯片工作方式,WM8960做master,之前参数配置ADC/DAC采样速率的是44.1K,有点问题,现在改为16K,下面会解释为什么要改成16K. WM8960参数配置 ...

  2. STM32 DAC + DMA + TIM 输出正弦波,三角波,方波信号

    硬件平台:STM32F4 库类型:标准库. 参考:[二代示波器教程]第12章 示波器设计-DAC信号发生器的实现 DAC框图如下: 通过TIM触发DAC转换,转换完成后通过DMA输出. DMA通道框图 ...

  3. STM32 DAC DMA 使用

    目的:STM32 DAC DMA 环形发送音频数据:(ffmpeg.exe 可以将一些常见的音频文件转为原始数据,很强大): 用到的外设:DAC ,TIM,DMA DCA配置 TIM配置 加入代码 H ...

  4. moodeaudio 源码_MoodeAudio 音频播放器上手配置

    MoodeAudio 是运行于树莓派等开发板的高品质音频播放系统.与 Volumio 类似,又有些许不同.它们声音表现是基本一致的,各种配置选项差别不大,MoodeAudio 所提供的选项稍多,播放功 ...

  5. 基于STM32F103C8T6片内Flash的音频播放(DAC通道)

    基于STM32F103C8T6片内Flash的音频播放(DAC通道) 一.STM32的DAC通道介绍 1.DAC 简介 2.STM32中的DAC主要特点 3.DAC 功能框图剖析 4.DAC配置 二. ...

  6. 原创:Android应用开发记录-Andorid歌词秀(3)使用的Service的音频播放器

    在下文中我们实现的简单的音乐播放功能. 原创:Android应用开发记录-Andorid歌词秀(2)先来一个音频播放器 但是这样的方式在程序退出后播放也会停止,为了解决这个问题,使用的Service类 ...

  7. 基于STM32的flash读写和DAC音频播放

    一.STM32的flash读写 1.利用STM32CUBEMX创建工程 之前有过很多次创建工程的例子,这里大致过程如下: 2.keil中添加代码及修改配置 在flash.c中添加如下代码, 在main ...

  8. DMA-DAC音频播放调试笔记

    文章目录 前言 一.工具 1.语音合成 2.语音格式转换 2.1 在线转换 2.2 Audition转换 2.3 [SOX工具](https://sourceforge.net/projects/so ...

  9. 第38章 I2S—音频播放与录音输入—零死角玩转STM32-F429系列

    第38章     I2S-音频播放与录音输入 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

最新文章

  1. 帧率配置_《骑马与砍杀2》配置探究:CPU显卡怎么搭配达到理想画质和帧数?...
  2. 升级oracle spu,Oracle 2017改变:新补丁更新(RU和RUR),新的版本(Release 18和19)
  3. 关于机器学习的一些推荐
  4. 对话:在敏捷中,是否可以仍然用需求来替代用户故事?
  5. 总结 | 计算机视觉领域最常见几中损失函数
  6. VTK:图片之ImageHybridMedian2D
  7. SQL Server配置支持中文
  8. 国防科技大学计算机学院少将,国防科技大学新任副校长兼教育长晋升少将,前任是计算机权威专家...
  9. msf实战提权windows_ATTamp;CK实战 | 红队评估一(上)
  10. JSK-369 字符逆序【入门】
  11. 电驴(easyMule)自动关机工具
  12. springboot test
  13. Java 接口编程题练习_JAVA学习日记每天进步一点点之接口再学习和内部类、编程题练习、异常学习...
  14. 腾讯云服务器架设mir2
  15. 微信小程序网易云音乐
  16. C#打开文件夹加载图片
  17. 利用selenium 爬取豆瓣 武林外传数据并且完成 数据可视化 情绪分析
  18. 101 Ruby Code Factoids
  19. 计量经济学(stata)笔记1 记录每天的进步
  20. C/C++,定时关机代码和取消定时关机(应用范畴)

热门文章

  1. springmvc返回html页面_深入浅出SpringMVC系列~
  2. java.sql 拒绝连接_java.sql.SQLException: ORA-01017: 用户名/口令无效; 登录被拒绝
  3. python操作库_python操作数据库
  4. md5修改工具_【q001】如何校验文件的MD5
  5. c语言解三元一次方程组_一次二次反比例,一山更比一山高?二次函数三大解析式详解...
  6. c语言10000以内最大的质数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
  7. linux查看u盘的分区,在Linux下访问windows分区以及U盘
  8. hessian无法获取连接_PPPoE拨号设置完成后无法上网解决方法【详解】
  9. vue获取接口数据_c#中HttpWebRequest调用接口获取数据
  10. ggplot2作图4