搜索
bottom↓
回复: 28

单片机内部AD实现录音wav文件

  [复制链接]

出0入85汤圆

发表于 2021-1-23 15:34:30 | 显示全部楼层 |阅读模式
1.硬件设计

        声音采集采用最简单的驻极体麦克风,将信号进行放大滤波后输入到单片机内部AD端口。电路图如下,第一级运放用于放大,第二级为低通滤波。(电阻电容参数仅供参考)。



        单片机采集声音数据后,将数据以WAV格式保存到SD卡中。

2.WAV文件格式说明

        WAV(Waveform audio format)是微软与IBM公司所开发的一种声音编码格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持。

        每个WAV文件的头四个字节便是“RIFF”。WAV文件由文件头和数据体两大部分组成。其中文件头又分为RIFF区块和FORMAT区块。WAV文件各部分内容及格式见下表。

RIFF区块



        其中Size是整个文件的长度减去ID和Size的长度

FORMAT区块


       其中音频格式可以是线性PCM或者ADPCM等,本例中使用线性PCM(非压缩)。

DATA区块


        其中Size表示音频数据的长度,单位字节。

        Data音频数据。

3.软件设计

        人耳朵能识别的声音范围为20-20kHz,若要采集20kHz以内频率的声音信号,则采样率至少要40kHz,数据量比较大,单片机资源受限时,可能无法完成数据的处理和存储。

        一般人说话(不唱歌)频率:男声50-500Hz,女声100-1kHz。考虑到谐波以及奈奎斯特采样定理的要求,8k采样率可以满足要求。这也是很多数字电话中的采样率。实际测试8k采样率能够比较清楚的还原语音。

        采样位数可以是8bits或16bits,单片机内部AD为12位,占2个字节,可以当做16位数据。为了减小数据量,舍去AD低4位,当做8位数据处理,实际测试8位数据效果可以。

        系统初始化

        使能单片机内部AD,通过定时器事件来触发AD采样,以保证采样率准确,同时使能DMA通道,降低CPU使用率。使能SPI接口用于驱动SD卡,并移植FatFs文件系统。具有步骤不在这里详细介绍,可参考公众化之前的文章。

        程序编写

        AD采样采用双缓冲的方式,当DMA完成缓冲区1后,将DMA的目标地址设置到缓冲区2继续采样,同时将缓冲区1的数据保存的文件,这样交替保存两个缓冲区数据,保证采样数据的连续性。

        将音频数据之前的数据定义为一个结构体,初始化并保存在文件开头,其中数据长度部分还未确定,需要最后重新计算后写入。

  1. //初始化WAV头.
  2. void recoder_wav_init(WaveHeader* wavhead) //初始化WAV头              
  3. {
  4.     wavhead->riff.ChunkID=0X46464952;    //"RIFF"
  5.     wavhead->riff.ChunkSize=0;           //还未确定,最后需要计算
  6.     wavhead->riff.Format=0X45564157;     //"WAVE"
  7.     wavhead->fmt.ChunkID=0X20746D66;     //"fmt "
  8.     wavhead->fmt.ChunkSize=0x10;           //大小为16个字节
  9.     wavhead->fmt.AudioFormat=0X01;       //0X01,表示PCM;0X11,表示IMA ADPCM
  10.     wavhead->fmt.NumOfChannels=1;        //单声道
  11.     wavhead->fmt.SampleRate=8000;        //8Khz采样率 采样速率
  12.     wavhead->fmt.ByteRate=8000;                                    //字节速率=采样率*通道数*(ADC位数/8)
  13.     wavhead->fmt.BlockAlign=1;           //块大小,1个字节为一个块
  14.     wavhead->fmt.BitsPerSample=8;       //8位PCM
  15.     wavhead->data.ChunkID=0X61746164;    //"data"
  16.     wavhead->data.ChunkSize=0;           //数据大小,还需要计算   

  17.     res=f_open(&file_rec,(const TCHAR*)FileName, FA_CREATE_ALWAYS | FA_WRITE);
  18.     if(res==FR_OK)
  19.     {      
  20.        res=f_write(&file_rec,(const void*)(&wavhead),sizeof(WaveHeader),&bw);//写入头数据
  21.     }
  22. }
复制代码


        之后每完成一次DMA,将数据保存一次。一般建议以SD卡扇区的整数倍进行写入操作,以提高写入速度。一次性写入的数据越多,平均写入速度越快。

  1. res=f_write(&file_rec,Databuf,512,&bw);//写入数据
复制代码


        录音结束后,重新计算文件长度并写入:

  1. wavhead.riff.ChunkSize=sectorsize*512+36;       //整个文件的大小-8;
  2. wavhead.data.ChunkSize=sectorsize*512;              //数据大小
  3. res = f_lseek(&file_rec,0);                                                 //偏移到文件头.
  4. res = f_write(&file_rec,(const void*)(&wavhead),sizeof(WaveHeader),&bw);//写入头数据
  5. res = f_close(&file_rec);
复制代码


​​​​​​

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入42汤圆

发表于 2021-1-23 16:41:12 | 显示全部楼层
楼主分享的资料都不错啊,感谢分享

出100入101汤圆

发表于 2021-1-23 19:31:03 来自手机 | 显示全部楼层
不错,学习

出0入85汤圆

 楼主| 发表于 2021-1-23 20:09:10 | 显示全部楼层
我是一个大白菜 发表于 2021-1-23 16:41
楼主分享的资料都不错啊,感谢分享

都是自己一些经验的总结,可能有一些不足和错误的地方,欢迎指正。

出0入8汤圆

发表于 2021-1-23 20:11:46 来自手机 | 显示全部楼层
讲的很详细,谢谢分享

出0入50汤圆

发表于 2021-1-23 20:18:06 | 显示全部楼层
谢谢分享

出0入79汤圆

发表于 2021-1-23 20:37:51 来自手机 | 显示全部楼层
讲的不错,谢谢!

出16170入6148汤圆

发表于 2021-1-24 14:42:28 | 显示全部楼层
发技术帖子欢迎。广告不欢迎,广告已经删除。

请以后不要再发广告,否则将封锁ID处理。

出0入0汤圆

发表于 2021-1-26 11:44:51 | 显示全部楼层
单片机内部AD实现录音wav文件  记号一下

出0入0汤圆

发表于 2021-1-26 17:18:38 | 显示全部楼层
讲的不错,谢谢!

出0入8汤圆

发表于 2021-1-26 18:21:32 | 显示全部楼层
这个不错,单片机内部AD实现录音wav文件,谢谢楼主

出0入32汤圆

发表于 2021-1-26 18:51:31 | 显示全部楼层
感谢分享。

出285入17汤圆

发表于 2021-1-26 18:59:11 | 显示全部楼层
声音又不是单频文件,这样采集出来的声音还原的话,能达达到多少分辨率。

出65入0汤圆

发表于 2021-2-21 10:01:00 来自手机 | 显示全部楼层
kokoc_power 发表于 2021-1-26 18:59
声音又不是单频文件,这样采集出来的声音还原的话,能达达到多少分辨率。 ...

8K采样,4K以内的信号基本可以有效复放。所以要加低通滤波,把4k以上的频率滤除。由于不是理想滤波器,所以模拟电路的低通滤波截止频率一般都低于所要求的4KHz。比如选取2K,3K等。

出0入0汤圆

发表于 2021-2-21 15:29:35 | 显示全部楼层
记号,有朋友需要

出50入0汤圆

发表于 2021-2-22 09:18:07 来自手机 | 显示全部楼层
内部ad实现wav   标记一下,感谢分享!

出0入0汤圆

发表于 2021-2-22 09:38:02 来自手机 | 显示全部楼层
LZ有完整程序吗?这里对单片机有什么要求?还有图上运放用lm358这种可以吗?

出0入85汤圆

 楼主| 发表于 2021-2-22 10:18:41 | 显示全部楼层
mangolu 发表于 2021-2-22 09:38
LZ有完整程序吗?这里对单片机有什么要求?还有图上运放用lm358这种可以吗? ...

程序在其他项目里,不方便发。单片机存储速度能跟上采集速度就行,我用的F103。运放用LM358可以,但不是轨至轨输出的运放,电源电压建议大一点。

出0入4汤圆

发表于 2021-2-22 10:40:26 | 显示全部楼层
LZ位的放大电路略复杂了些,直接用1个三极管就可以了,效果也不错。

出0入0汤圆

发表于 2021-2-22 11:59:55 来自手机 | 显示全部楼层
ZXF_CUG 发表于 2021-2-22 10:18
程序在其他项目里,不方便发。单片机存储速度能跟上采集速度就行,我用的F103。运放用LM358可以,但不是 ...

用1t 51速度是否可以?

出0入85汤圆

 楼主| 发表于 2021-2-22 15:51:56 | 显示全部楼层
mangolu 发表于 2021-2-22 11:59
用1t 51速度是否可以?

没试过,我也不清楚

出100入0汤圆

发表于 2021-2-22 22:06:21 来自手机 | 显示全部楼层
这份资料不错,感谢楼主,收藏备用!

出0入0汤圆

发表于 2021-2-23 09:20:25 | 显示全部楼层
收藏备用,感谢分享!

出0入0汤圆

发表于 2021-2-23 17:23:44 | 显示全部楼层
将数据保存一次。一般建议以SD卡扇区的整数倍进行写入操作,以提高写入速度
最好是8K的整数倍,不然会有问题

出0入85汤圆

 楼主| 发表于 2021-2-23 18:22:29 | 显示全部楼层
jjj 发表于 2021-2-23 17:23
将数据保存一次。一般建议以SD卡扇区的整数倍进行写入操作,以提高写入速度
最好是8K的整数倍,不然会有问 ...

为什么是8K的整数倍?

出0入0汤圆

发表于 2021-2-24 17:17:06 | 显示全部楼层
感谢分享,头像 佛 道  很有意思

出0入8汤圆

发表于 2022-7-25 00:15:56 | 显示全部楼层
WAV信号采集。
这份资料不错,感谢楼主,收藏备用!

出0入0汤圆

发表于 2022-9-7 13:17:55 | 显示全部楼层
MARK     音频采样

出100入312汤圆

发表于 2022-9-7 13:36:40 来自手机 | 显示全部楼层
不错,学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 17:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表