查看: 97|回复: 5

[资料] 【我爱DIY】简易WAV播放器

[复制链接]

主题

好友

5614

积分

状元

  • TA的每日心情

    2018-11-20 13:41
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2020-7-27 16:07:20 |显示全部楼层
    STM32F769-DISCO 上面有个WM8994可以用于音频解码。WM8994具有高性能低功耗体积小等优点,曾用在早期的三星安卓手机上用到。下面的测试主要是使用WM8994播放WAV文件。


    1、串行音频接口(SAI)
    SAI 接口(串行音频接口)灵活性高、配置多样,可支持多种音频协议。该接口适用于许多立体声或单声道应用。例如,它可配置为支持 I2S 标准、 LSB 或 MSB 对齐、 PCM/DSP、TDM 和 AC’97 等协议。将音频模块配置为发送器时, SAI 接口可提供 SPDIF 输出。SAI 通过两个完全独立的音频子模块来实现这种灵活性和可配置性。每个模块都有自己的时钟发生器和 I/O 线控制器。SAI 可以配置为主模式或配置为从模式。音频子模块既可作为接收器,又可作为发送器;既可与另一模块同步,又可以不同步。
    SAI 主要由两个各自带有时钟发生器的音频子模块组成,每个音频模块集成一个 32 位移位寄存器,该寄存器由模块自身的功能状态机控制。数据存储和读取都是通过专用的 FIFO 来完成。 FIFO 可通过 CPU 访问,也可通过 DMA 访问以减轻 CPU 的通信负担。每个音频模块是独立的。这两个音频子模块可彼此同步。SAI 中指定音频模块的 4 个专用引脚IO口( SD、 SCK、 FS、 MCLK)。


    功能框图如下:


    STM32F769-DISOC 上面的WM8994通过SAI1_Block_A和MCU进行解码数据通信,WM8994的初始化和各项配置则通过IIC实现。




    2、WAV格式文件
    WAVE文件是计算机领域最常用的数字化声音文件格式之一,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio)。WAVE是录音时用的标准的WINDOWS文件格式,文件的扩展名为“WAV”,数据本身的格式为PCM或压缩型。简单的理解WAV文件有一个文件头和数据部分组成,文件头里面包含该WAV的详细信息。一个典型的文件头格式如下:

    这个文件头共有44字节,不同的格式文件头可能长度不同,为了方便处理我使用开源软件Audacity将WAV的头文件格式都转为相同的44字节模式,其他的参数为立体声44.1KHZ.




    3、软件解码

       播放的WAV文件放在TF卡里面,文件系统使用开源的FATFS,为了支持较长的歌曲名字,需要在FATFS中打开长文件名支持模式。同时为了支持中文显示,我把汉字点阵放到了
    STM32F769-DISCO 的外置NORFLASH里面,具体的操作可以查看之前的帖子。

    WAV的播放是使用DMA 循环模式把数据从SD卡搬送到codec进行解码,其中DMA使能了HalfTransfer和TransferComplete来不断的更新要解码的数据文件。
    最开始的时候先将要解码的缓存写满,然后开始DMA传输,当传输完成一半时在使能标记开始更新前半部缓存,等传输完成继续更新后半部分缓存,这样可以实现更新缓存和
    界面数据“同时进行”,当然这样做的前提是更新缓存数据速度要快于解码的数据,通过测试STM32F7完全没有压力。

    程序的流程如下:
    • 先扫描SD卡找到WAV文件,将找到的WAV文件信息放入到一个链表中。
    • 显示找到的WAV文件名称到LCD上,并更新要播放的文件(名称为绿色字体)。
    • 根据预设的要播放的文件序号找到要要播放的WAV文件的信息,从SD卡里面读取填充播放缓存。
    • 开始播放WAV后不断的填充播放缓存直到播放完成。
    • 播放完成一个WAV文件后,根据播放模式(单曲循环、列表循环、随机循环)播放下一个WAV文件。
    • 播放的过程中可以通过用户按键切换下一个WAV文件进行播放。

    程序下载后的:



    使用按键切换歌曲:



    mian 函数如下:
    •     _listfile_list *playfile;
    •     CPU_CACHE_Enable();
    •     HAL_Init();
    •     SystemClock_Config();
    •     USART1_Init();
    •     HAL_Delay(200);
    •     BSP_LED_Init(LED_GREEN);
    •     BSP_LCD_Init();
    •     BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
    •     BSP_LCD_SetTextColor(LCD_COLOR_RED);
    •     BSP_LCD_SetBackColor(LCD_COLOR_BLACK);
    •     HAL_Delay(500);
    •     BSP_QSPI_Init();
    •     CopyFont2NorFlash();
    •     BSP_QSPI_EnableMemoryMappedMode();
    •     CheckGBKFont4NorFlash();
    •     BSP_LCD_Clear(LCD_COLOR_WHITE);
    •     FatFs_SD_Init();
    •     wavfilenum = ScanWavFiles("/");
    •     PrintfWavFileTest();
    •     UpdateWavFileColor(playfilepos,playfilepos);
    •     playfile = list_search(WavFileList, playfilepos);
    •     if(playfile == NULL)while(1);
    •     //´
    •     wavFileLen = OpendWavFile(playfile->filename);
    •     //
    •     ReadWaveFile(BuffHead, PLAY_HEADER);
    •     //
    •     ReadWaveFile((uint8_t *)PlayBuff, PLAY_BUFF_SIZE * 2);
    •     Playback_Init();
    •     /* Start the playback */
    •     if(0 != audio_drv->Play(AUDIO_I2C_ADDRESS, NULL, 0))
    •     {
    •         while(1);
    •     }
    •     if(HAL_OK != HAL_SAI_Transmit_DMA(&SaiHandle, (uint8_t *)PlayBuff, PLAY_BUFF_SIZE))
    •     {
    •         while(1);
    •     }

    [color=rgb(51, 102, 153) !important]复制代码

    需要注意的是程序里面默认播放是44.1KHZ立体声的WAV文件,如果是其他的格式的要在播放之前更新SAI的配置。
    •    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_44K;
    •     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);


    [color=rgb(51, 102, 153) !important]复制代码






    4、最后

         使用STM32F769-DISOC配合论坛之前送的小音箱,播放音乐的效果和我手机电脑播放的听不出区别。我用手机语音备忘录录制了一段放在附件里面,感兴趣可以试听下。


    PS:附件的源码里面我默认关闭了汉字库下载到NORFLASH,如果是第一次运行程序请打开相应的宏定义加载字库。
    游客,如果您要查看本帖隐藏内容请回复

    回复

    使用道具 举报

    主题

    好友

    175

    积分

    童生

    该用户从未签到

    发表于 2020-7-28 08:57:20 来自手机 |显示全部楼层
    谢谢分享!
    回复

    使用道具 举报

    主题

    好友

    42

    积分

    白丁

    该用户从未签到

    发表于 2020-7-28 08:57:35 |显示全部楼层
    谢谢群主的分享!
    回复

    使用道具 举报

    主题

    好友

    1316

    积分

    进士

  • TA的每日心情
    开心
    昨天 08:19
  • 签到天数: 29 天

    连续签到: 23 天

    [LV.4]偶尔看看III

    发表于 2020-7-28 08:57:35 |显示全部楼层
    感谢分享
    回复

    使用道具 举报

    主题

    好友

    64

    积分

    童生

    该用户从未签到

    发表于 2020-7-28 08:57:45 |显示全部楼层
    感谢楼主!!!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|电路城

    GMT+8, 2020-8-5 09:50 , Processed in 2.112608 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部