logo资料库

基于STM32的WAV音频格式播放器.docx

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
正在做的项目中需要 STM32 从 SD 卡中读取语音文件进行播放,因此需要对 语音进行解码,刚开始就一直使用 Speex 的音频压缩格式,最近发现,在进行语 音格式转换时,我们不能很好地分析 spx 格式音频文件的文件头,这样就会导致 语音的播放出现问题。由于 WAV 采用 PCM 编码,音质也十分不错,于是考虑用 STM32 对 WAV 格式音频文件进行解码,上周末开始找资料和编程,其中也遇到了 不少问题,不过功夫不负有心人,最终还是顺利的跑起来了。先将资料和编程过 程整理成本文,供大家一起学习和进步。 WAV 文件格式是一种重要的用于存放声音文件的文件格式,尽管现在有 MP3,RAM 等压缩效率更高的声音文件格式,并且广泛被音乐文件所采用,但是又很多的应 用程序仍然采用 WAV 文件格式。由于 WAV 文件没有采用压缩技术,所以它的文件 很庞大,一般都在几 MB 以上。但也正是因为没有采用压缩技术,声音的采样数 据很容易被读出来,便于用作其他的处理。 废话不多说了,我们直接去解析 WAV 文件格式吧。 WAV 格式符合 RIFF(Resource interchange File Format)规范。所有的 WAV 都有一个头文件,这个头文件音频流的编码参数。 表 1、WAV 文件的文件头 接下来我们用已经编好的程序来读取一个 WAV 文件的文件头和数据块,看看各个 表 2、WAV 声音文件的数据块 内容都表示什么含义。
图 1、WAV 源文件
图 2、用 WinHex 软件解析 WAV 图 3、STM32 读取 WAV 的信息 头文件样例说明: Ø “52 49 46 46”这个是 Ascii 字符“RIFF”,这部分是固定格式,表明这是一个 WAVE 文件头。 Ø “24 33 AE 00”这个是我的 WAV 文件的数据大小,这个大小包括除了前面 4 个字节的所有字节,也就是等于文件总字节数减去 8。得到图 3 中的 11416356。 11416356+8=11416364Byte=10.88Mb。 Ø “57 41 56 45 66 6D 74 20”,也是 Ascii 字符“WAVEfmt”,这部分是固定 格式。以后是 PCMWAVEFORMAT 部分。 Ø “10 00 00 00”,这是一个 DWORD,对应数字 16,这个对应定义中的 PCMWAVEFORMAT 部分的大小,可以看到后面的这个段内容正好是 16 个字节。 当为 16 时,最后是没有附加信息的,当为数字 18 时,最后多了两个字节的 附加信息。
Ø “01 00”,这是一个 WORD,对应定义为编码格式(WAVE_FORMAT_PCM 格式用 的就是这个)。 Ø “01 00”,这是一个 WORD,对应数字 1,表示声道数为 1,是个单声道 WAV, 当值为 2 时为立体声 WAV。 Ø “22 56 00 00”对应数字 22050,代表的是采样频率 220505,采样率(每秒 样本数)表示每个通道的播放速度。 Ø “44 AC 00 00”对应数字 44100,代表的是每秒的数据量,波形音频数据传 送数率,其值为通道数×每秒样本数×每个样本的数据位数/8。播放软件利 用此值可以估计缓冲区的大小。 Ø “02 00:”对应数字是 2,表示块对齐的内容。数据块的调整数(按字节算), 其值为通道数×每个样本的数据位置/8.播放软件需要一次处理多个改值大 小的字节数据,以便将其值用于缓冲区的调整。 Ø “10 00”,此数值为 16,采样大小为 16bits,每样本数据位数,表示每个声 道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都 一样。 Ø “64 61 74 61”,这个是 Ascii 字符“data”,表示头结束,开始数据区域。 Ø “00 33 AE 00”,十六进制数是“0xAE3300”,对应十进制 11416320,是数 据区的开头以后的数据总数。 再往后就是真正的 WAV 文件数据体了,头文件分析到此。 常见的声音文件主要有两种,分别对应单声道(11.025KHz 采样率、8Bit 的 采样值)和双声道(44.1KHz 采样率、16Bit 的采样值)。采样率是指:声 音信号在“模->数”转换过程中单位时间内采样的次数。采样值是指每一次 采样周期内声音模拟信号的积分值。 对于单声道声音文件,采样数据位 8 位的短整数;而对于双声道立体声声音 文件,每次采样数据位一个 16 位的整数,高 8 为和低 8 位分别代表左右两 个声道。 WAVE 文件数据块包含以脉冲编码调制(PCM)格式表示样本。WAVE 文件是由 样本组织而成的。在单声道 WAVE 文件中,声道 0 代表左声道,声道 1 代表 右声道。在多声道 WAVE 文件中,样本是交替出现的。 PCM 数据的存放方式: 样本 1 样本 2 8 位单声道 0 声道 0 声道
8 位立体声 0 声道(左)1 声道(右) 0 声道(左) 1 声道(右) 16 位单声道 0 声道低 0 声道高 0 声道低 0 声道高 16 位立体声 0 声道(左)低 0 声道(左)高 1 声道(右)低 1 声道(右)高 系统硬件组成比较简单,可以分为液晶显示,LED 指示,USB 输入,SD 卡, 电源供电,音频功放和按键等,如图 3-1 所示: 图 3-1 系统组成框图 SD 卡电路: SD 卡采用 SPI 驱动。 USB 电路:
采用 SGM7222 做转换开关,识别 ID 的电压值来选择是作为 IAP 下载还是用 于 USB 接口 音频功放电路: 充电和系统电源:
程序编写主要有三个部分:定时器初始化,DAC 初始化,定时器中断服务程序, WAV 播放程序。 定时器初始化: void Timerx_Init(u16 arr,u16 psc) { NVIC_InitTypeDef NVIC_InitStructure; RCC->APB1ENR|=1<<1;//TIM3 时钟使能 TIM3->ARR=arr; //设定计数器自动重装值 TIM3->PSC=psc; //预分频器 7200,得到 10KHz 的计数时钟 TIM3->DIER|=1<<0; //允许更新中断
TIM3->DIER|=1<<6; //允许触发中断 TIM3->CR1|=0x01; //使能定时器 3 //优先级设置 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } DAC 初始化: #include "dac.h" extern u16 digital; void MyDAC_Init(void)//DAC channel1 Configuration { unsigned int tmpreg1=0,tmpreg2=0; RCC->APB2ENR|=1<<2;//使能 PORTA 时钟 RCC->APB1ENR|=RCC_APB1Periph_DAC;//使能 DAC 时钟 GPIOA->CRL&=0XFFF0FFFF; GPIOA->CRL|=0X00040000;//PA4 浮空输入 tmpreg1=DAC->CR;//Get the DAC CR value tmpreg1&=~(CR_CLEAR_Mask<
分享到:
收藏