这里以官方例子为基础,看看怎么播放wav文件,以及如何改吧改吧播放别的wav文件
这个例子:
建议最好拷贝一个出来,免得不能还原,我是整个目录都有备份,所以直接在这上面改了.
打开项目,主要看这几个点:
- int main(void)
- {
- uint32_t PlaybackPosition = PLAY_BUFF_SIZE + PLAY_HEADER;
-
- /* Enable the CPU Cache */
- CPU_CACHE_Enable();
- /* STM32F7xx HAL library initialization:
- - Configure the Flash prefetch
- - Systick timer is configured by default as source of time base, but user
- can eventually implement his proper time base source (a general purpose
- timer for example or other time source), keeping in mind that Time base
- duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
- handled in milliseconds basis.
- - Set NVIC Group Priority to 4
- - Low Level Initialization
- */
- HAL_Init();
- /* Configure the system clock to have a frequency of 216 MHz */
- SystemClock_Config();
- /* Configure LED2 */
- BSP_LED_Init(LED2);
- /* Configure LED1 */
- BSP_LED_Init(LED1);
- /* Check if the buffer has been loaded in flash */
- // if(*((uint64_t *)AUDIO_FILE_ADDRESS) != 0x017EFE2446464952 ) Error_Handler();
这个上面最后一句,是检查wav文件头的,建议注释掉,因为wav文件头有几种变种, 如果用其他wav文件(非ST提供的),则这里很可能不通过,其实内容是可以播放的
main.c最上面几行有几个宏定义:
- #define AUDIO_FILE_ADDRESS 0x08010000
- //#define AUDIO_FILE_SIZE (180*1024)
- //#define AUDIO_FILE_SIZE (270852)
- #define AUDIO_FILE_SIZE (176444)
- #define PLAY_HEADER 0x2C
- #define PLAY_BUFF_SIZE 4096
AUDIO_FILE_ADDRESS这个宏定义的是wav文件在flash的存储位置,这个只要不跟你代码重合就可以了
AUDIO_FILE_SIZE定义你烧录的wav文件大小,整个F769NIHx的Flash有2M,但要扣除掉前面的64K代码空间,本例子中wav文件要小于等于2M-64K=1984K,如果先用ST提供的文件,大小定为180K即可
PLAY_HEADER是开始的偏移量,就是wav文件的头,wav格式在后面的帖子中介绍,此处跳过它即可
PLAY_BUFF_SIZE是缓冲区的大小,因为是DMA传输,这里大小不是很重要,宜大不宜小,别超过512K的SRAM空间即可
播放的基本流程就是先初始化好buffer,DMA,指针后面不停地把Flash中的内容搬运到SAI接口上循环播放
看看Playback_Init这个函数:SaiHandle.Init.AudioMode = SAI_MODEMASTER_TX;
- SaiHandle.Init.Synchro = SAI_ASYNCHRONOUS;
- SaiHandle.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
- SaiHandle.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
- SaiHandle.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
- SaiHandle.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_22K;
- SaiHandle.Init.Protocol = SAI_FREE_PROTOCOL;
- SaiHandle.Init.DataSize = SAI_DATASIZE_16;
- SaiHandle.Init.FirstBit = SAI_FIRSTBIT_MSB;
- SaiHandle.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
- SaiHandle.FrameInit.FrameLength = 32;
- SaiHandle.FrameInit.ActiveFrameLength = 16;
- SaiHandle.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
- SaiHandle.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
- SaiHandle.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
- SaiHandle.SlotInit.FirstBitOffset = 0;
- SaiHandle.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
- SaiHandle.SlotInit.SlotNumber = 2;
- SaiHandle.SlotInit.SlotActive = (SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1);
可以看出来,播放的设置是:22.05KHz, 双声道, 16bit每通道的音频数据. 官方提供的wav文件就这格式,如果你自己的wav文件不是这格式,这里要做相应修改
SAI初始化好之后还要设置外部Codec,这板子上就是WM8994片:
- /* Initialize audio driver */
- if(WM8994_ID != wm8994_drv.ReadID(AUDIO_I2C_ADDRESS))
- {
- Error_Handler();
- }
-
- audio_drv = &wm8994_drv;
- audio_drv->Reset(AUDIO_I2C_ADDRESS);
- if(0 != audio_drv->Init(AUDIO_I2C_ADDRESS, OUTPUT_DEVICE_HEADPHONE, 100, AUDIO_FREQUENCY_22K))
- {
- Error_Handler();
- }
我的耳机是放在桌子上的,如果戴着耳机做实验,请把音量减小一些(100是最大,0是最小,20,30比较适合),不然会很伤耳朵的.
以下是DMA的设置,设置成half word传输,和前面一至即可
- hSaiDma.Init.Channel = DMA_CHANNEL_10;
- hSaiDma.Init.Direction = DMA_MEMORY_TO_PERIPH;
- hSaiDma.Init.PeriphInc = DMA_PINC_DISABLE;
- hSaiDma.Init.MemInc = DMA_MINC_ENABLE;
- hSaiDma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
- hSaiDma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
- hSaiDma.Init.Mode = DMA_CIRCULAR;
- hSaiDma.Init.Priority = DMA_PRIORITY_HIGH;
- hSaiDma.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
- hSaiDma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
- hSaiDma.Init.MemBurst = DMA_MBURST_SINGLE;
- hSaiDma.Init.PeriphBurst = DMA_PBURST_SINGLE;
这个程序编译好烧进板子,之后烧录wav文件,这里先以官方提供的文件为例,他提供的文件在这里:
里面audio.bin在此,其实就是个22.05K的双声道wav文件,你把它改成audio.wav,什么播放器都能播放.但是STM32 ST-LINK Utility不支持任意文件名烧录,所以烧录的时还是要改成.bin
打开STM32 ST-LINK Utility,拖进文件audio.bin:
连接板子,Program时选择地址要跟之前AUDIO_FILE_ADDRESS要一样,千万不用默认的0x08000000,那样就跟程序重叠了,此例中使用0x08010000
烧写完复位,如果之前应用代码配置正确就可以听到播放了以上是用官方的wav文件,如果自己找wav文件,注意以下几点:
1.wav格式要22.05K采样, 双声道, 16bit,如果不是这格式请用工具转换成此格式
2.上述格式的文件大小不要超过1984K,官方文件180K大约2.04秒,所以这个例子最多播放22多秒内容,如果要改格式,改文件存放方式,跟代码有关,后面帖子再来说
3.改了文件后,这个宏要改 AUDIO_FILE_SIZE, 改成实际文件大小就可以了
4.如果直接用F769板上stlink烧写,文件后缀要改成.bin
|