硬件——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 ChunkFact Chunk(可选)Data Chunk。每个 Chunk 由块标识符、数据大小和数
据三部分组成,如图 50.1.1 所示:

 

上图是每个chunk块都要遵守的结构.

其中块标识符由 4 ASCII 码构成,数据大小则标出紧跟其后的数据的长度(单位为字节),
注意这个长度不包含块标识符和数据大小的长度,即不包含最前面的 8 个字节。所以实际 Chunk
的大小为数据大小加 8

 

 

 

 

 

 

 

通过以上学习,我们对 WAVE 文件有了个大概了解。接下来,我们看看如何使用 VS1053

实现 WAVPCM 格式)录音。

 

 

 

 

 

 

posted @ 2018-01-08 11:27  GXTon  阅读(4643)  评论(11编辑  收藏  举报