硬件——STM32 , 录音,wav
详细的wav头文件解析,有例子:http://www.cnblogs.com/chulin/p/8918957.html
关于录音程序的编写:
我的思路是改写原子的程序,原子的程序需要借助VS1053 (这是一个语音芯片)来实现录音,
麦克风连接在VS1053 (这是一个语音芯片)芯片上,麦克风采集的声音电压会经过语音芯片处理存入语音芯片特定的寄存器中
,用stm32从那个语音芯片的寄存器里读音频数据,并通过FATFS文件系统制作WAV文件头,把数据存入文件头下就可以了.即:
生成最终的WAV文件. 一个文件其实就是由一个文件头和数据组成, 机器通过解读文件头,来按照文件头指定的方式读取数据,
我现在的工作是去掉这颗语音芯片,,用ADC来替代语音芯片的功能,,麦克风接在ADC的引脚上,,把声音电压采集出来,存到数组
或链表中,,,完成WAV文件的制作
步骤:
1,制作出一个音符的WAV文件,不通过ADC,直接用数组建出来, 调整音量大小
2,通过ADC进行声音采样,涉及到 "存" 和 "采" 两个过程,单片机每次只能做一件事,如何协调这两个的关系..
下面是用UltraEdit软件,打开WAV文件之后的截图:
分析一下上面两张图,,,找不同
代码部分WAV文件头如下::
//wav头
typedef __packed struct //关于结构体我用的还是很不熟练,,,,需要提升这部分,,,,这个是结构体的定义,定义在了.h文件中,,,,
//上面一大堆也是结构体,,, 其实这个结构体的元素也都是结构体,,,是结构体套结构体的...
{
ChunkRIFF riff; //riff块
ChunkFMT fmt; //fmt块
//ChunkFACT fact; //fact块 线性PCM,没有这个结构体,此次试验我们也不打算考虑这部分..
ChunkDATA data; //data块
}__WaveHeader;
把上面WAV头的每个元素找出来
每个元素都是chunk结构:即
//RIFF块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"RIFF",即0X46464952 (这个就是4bytes,,即4个ASCII码,,,bytes,,,,1byte=8bit 也就是一个字节是8位) 查看图片上的前四个:52 49 46 46
u32 ChunkSize ; //集合大小;文件总大小-8 这部分也是占固定的4bytes 0X24 DA 04 00 =317988约310K 0X24 84 03 00=230436约225K
u32 Format; //格式;WAVE,即0X45 56 41 57
}ChunkRIFF ;
//fmt块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"fmt ",即0X20746D66 66 6D 74 20
u32 ChunkSize ; //子集合大小(不包括ID和Size);这里为: 接下来4个字节是: 10 00 00 00 在这里表示 01,
//也就是16个字节 :01 00 02 00 80 BB 00 00 00 EE 02 00 04 00 10 00
//红色标注的数字,分别分配到下面:
u16 AudioFormat; //音频格式;0X01,表示线性PCM;0X11表示IMA ADPCM 01 00 pcm格式
u16 NumOfChannels; //通道数量;1,表示单声道;2,表示双声道; 02 00 双声道
u32 SampleRate; //采样率;0X1F40,表示8Khz 80 BB 00 00=4800 这个是采样率,能不能根据采样率,来计算定时器需要如何设定 如果我们设定的采样率是8000Hz即8KHz,,,那么也就是每秒8000次,,,,也就是0.000125s采集一次...125us一次中断采集....剩下就是配置定时器中断了
u32 ByteRate; //字节速率; 00 EE 02 00=750
u16 BlockAlign; //块对齐(字节); 04 00
u16 BitsPerSample; //单个采样数据大小;4位ADPCM,设置为4 10 00=16
// u16 ByteExtraData; //附加的数据字节;2个; 线性PCM,没有这个参数
// u16 ExtraData; //附加的数据,单个采样数据块大小;0X1F9:505字节 线性PCM,没有这个参数
}ChunkFMT;
最后一张图:网上得来:http://blog.csdn.net/gwhcsdn/article/details/70964342
根据上图的实例分析:
正点原子文档的主要部分在:recorder.c中
参考的<<STM32开发指南V1.0库函数版本>>
ALIENTEK 战舰 STM32 开发板板载的 VS1053 (这是一个语音芯片)支持 2 种格式的 WAV 录音:
PCM 格式或者 IMA ADPCM 格式, 其中 PCM(脉冲编码调制) 是最基本的 WAVE 文件格式,这种文件直
接存储采样的声音数据没有经过任何的压缩。而 IAM ADPCM 则是使用了压缩算法,压缩比率
为 4:1
.
本章,我们主要讨论 PCM,因为这个最简单。我们将利用 VS1053 实现 16 位, 8Khz 采
样率的单声道 WAV 录音(PCM 格式)。要想实现 WAV 录音得先了解一下 WAV 文件的格式,
WAVE 文件是由若干个 Chunk 组成的。按照在文件中的出现位置包括: RIFF WAVE Chunk、
Format Chunk、 Fact Chunk(可选)和 Data Chunk。每个 Chunk 由块标识符、数据大小和数
据三部分组成,如图 50.1.1 所示:
上图是每个chunk块都要遵守的结构.
其中块标识符由 4 个 ASCII 码构成,数据大小则标出紧跟其后的数据的长度(单位为字节),
注意这个长度不包含块标识符和数据大小的长度,即不包含最前面的 8 个字节。所以实际 Chunk
的大小为数据大小加 8。
通过以上学习,我们对 WAVE 文件有了个大概了解。接下来,我们看看如何使用 VS1053
实现 WAV(PCM 格式)录音。
硬件——STM32 , 录音,wav的更多相关文章
- 硬件——STM32 , 录音
战舰V3的录音程序解析 上一章,我们实现了一个简单的音乐播放器,本章我们将在上一章的基础上,实现一个简单的录音机,实现WAV录音.本章分为如下几个部: 50.1 WAV简介 50.2 硬件设计 50. ...
- 硬件——STM32,ADC篇
未完,待续...... 也就是stm32f10X系列的adc采集出来的结果是12位的 stm32f10X系列有两个16位adc 关于程序的编写方法:一般 “某某.c文件”:都是用来设置“某某”的一些 ...
- 硬件——STM32 , 软件框架
单片机应用程序的框架大概有三种: 1,简单的前后台顺序执行程序. 2,时间片轮询法. 3,应用操作系统. 下面我们主要来讲解时间片轮询法: 在这里我们先介绍一下定时器的复用功能.就是使用1个定时器,可 ...
- 硬件——STM32 , SN74HC573锁存器
74HC573是一款高速CMOS器件: 上图中:输出使能为:OE 锁存使能为:LE 典型电路: 上图中:PWR-AL-0,PWR-AL-1,PWR-AL-2:是单片机输出的高低电平给573 对应的 ...
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
[Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...
- Android录音--AudioRecord、MediaRecorder
Android提供了两个API用于实现录音功能:android.media.AudioRecord.android.media.MediaRecorder. 网上有很多谈论这两个类的资料.现在大致总结 ...
- 【录音】Android录音--AudioRecord、MediaRecorder
Android提供了两个API用于实现录音功能:android.media.AudioRecord.android.media.MediaRecorder. 网上有很多谈论这两个类的资料.现在大致总结 ...
- S3C2416裸机开发系列19_Fatfs播放录像wav音频文件
S3C2416裸机开发系列19 Fatfs播放录像wav音频文件 国际象棋男孩 1048272975 多媒体资源,一般都是以文件的形式存储在固化存储器中.Fatfs所支持的fat32为windo ...
- 关于STM32单片机的IAP实现
基于STM32F103单片机的IAP实现(虽然该篇文章不会详细写出实现细节,但是会从一个全局的角度讲述,实际的实现细节只需根据datasheet即可完成). 一.基础概念 什么是IAP?IAP即在应用 ...
随机推荐
- jQuery获取区间随机数
1.自定义函数 function getRandom(min,max){ //x上限,y下限 var x = max; var y = min; if(x<y){ ...
- 【Codeforces Round #425 (Div. 2) B】Petya and Exam
[Link]:http://codeforces.com/contest/832/problem/B [Description] *能代替一个字符串(由坏字母组成); ?能代替单个字符(由好字母组成) ...
- POJ 2185 正解 KMP
题意: 思路: 把每一行压成一个数 求一下 KMP 把每一列压成一个数 求一下KMP 答案就是两个周期之积 网上的好多题解都是错的---------.. //By SiriusRen #include ...
- javafx virtual keyboard
public class EffectTest extends Application { @Override public void start(final Stage stage) { final ...
- 在物理 Data Guard 中对异构主备系统的支持 (文档 ID 1602437.1)
Data Guard中主数据库与物理备用数据库(Redo Apply)之间可以有什么差别?本说明针对重做应用和 Oracle Data Guard 12 发行版 1 进行了更新.它适用于 Oracle ...
- docker的数据持久化
挂载宿主机的目录(实现很多容器共用一个宿主卷) [root@localhost ~]# docker run -itd --name web01 -v /var/www/html:/var/www/h ...
- 【hihocoder 1378】网络流二·最大流最小割定理
[Link]:http://hihocoder.com/problemset/problem/1378 [Description] [Solution] 在求完最小割(最大流)之后; 可以在剩余网络中 ...
- HDU 5188 zhx and contest(带限制条件的 01背包)
Problem Description As one of the most powerful brushes in the world, zhx usually takes part in all ...
- 72.挖掘CSDN密码到链表并统计密码出现次数生成密码库
list.h #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include & ...
- Day6上午解题
预计分数:100+100+30=230 实际分数:90+25+10=125 T1少判了一种情况,T2的贪心是错的,T3被卡了... T1 模拟水题,注意20的可以用3个5块的找 #include< ...