本帖最后由 okwh 于 2017-7-17 14:21 编辑
【LPC54114双核任务四】――D0、音频库使用 本周任务: 了解并熟悉LPC54114的音频处理库的工作原理 任务要求:
移植上述音频处理库,并使用M4内核进行音频编解码处理,为了直观显示结果,可酌情添加屏幕显示功能。
开源提供的音频库基于RT-thread嵌入实时操作系统,有关观察是针对LPC54101的。 从内容来看,这个库可分作两个部分,一个是RT-thread嵌入实时操作系统,一个是bsp目录下的音频库和例程。音频库提供了wav/mp3/ogg/flac/ape/ape2/wma等几种音频编码的初步支持。 一、 RT-thread嵌入实时操作系统 开源嵌入式实时操作系统,由国内一些专业开发人员从2006年开始,目前由上海睿赛德电子科技有限公司维护。从内容和而计划看,这个OS已经比较完善,最小配置时,内核体积可以到 3k ROM、1k RAM占用。 嵌入操作系统的核心就是线程(任务)及管理、共享数据通讯和管理。其时间片通常基于系统tick计数器,每片一般为10毫秒。操作系统需要所有资源进行管理,主要是内存和外设,RT-thread对外设进行同一管理,所有设备有统一标准和使用方法。对于需要丰富界面、需要管理大量设备和大量慢速通讯的大批量产品,确定一个嵌入系统,有助与产品赝品的规范和稳定。
二、 RT-thread系统下软件开发 主要分为,1) 按RT-thread要求规划设计有关外设驱动;2) 基于任务分工,设计需要的线程及其序列关系和数据在线程间的共享传递;3) 调试,主要是用各种标志和共享数据来解决线程间的关系。 main主函数的核心是 rtthread_start(),在那里进行各种初始化(如系统定时器、堆栈、线程调度、各种外设),然后是用户应用初始化rt_application_init()。值得赞赏的是RT-thread提供了一个很好的调试和双向通讯支持finsh。 通常用户主要完成的是rt_application_init(),在其中创建线程即可。 其实这个库,只是准备好了分析处理各种音频格式文件的代码,尚未提供任何使用的例子。
三、音频处理库使用 我做过的事情都是没有界面、对时间要求达到微秒精度的,所以几乎没使用过嵌入操作系统。试验了一下,仅仅改为LPC54114支持,就出现了堆栈溢出,堆栈的错误是最难查的问题之一,这里就先放弃rt_thread吧。 于是,放弃rt_thread软件, 改用以万利的程序为基础,把音频库中处理wav格式的提取移植出来(库中各种音频格式的处理很相似),融入万利的程序实现sd卡上wav音频文件的边读出边播放。
基本方法就是原g_music数据改为用来自sd卡上的文件数据流。 第一步,先试验读区sd卡上的文本文件,用串口调试检查保证文件读写功能正常。 第二步,读取sd卡上一个约29M的wav文件,以1`4个各种大小(128字节~16K)的读取缓冲区,试验文件数据流的方式,结果发现:sd卡文件读取太慢,虽然成功播放,但音频播放出来已经变形走样,不忍卒听。
优化: 1) 提高系统时钟(原默认是48M),去除调试编译 BOARD_InitPins();
//BOARD_BootClockRUN();
BOARD_BootClockHSRUN();
//BOARD_InitDebugConsole();
2) 在application.c主程序中,直接用多个缓冲区读SD卡文件,用DMA方式发送到I2S的TX,便读边播放。 (在DMA发完后的中 断中处理更慢,因为读取文件是最慢的关键步骤,所以就直接在程序中发送DMA了) ret = f_read(&file, (char*)wav_buf2, swave,&br); //读文件 fatfs支持
StartPlayWav1(wav_buf2,br) ; //发送 代码在app_wm8904.c 发送DMA
3) 编译优化
去除C++ Asm编译参数 DEBUG
设置C++编译优化 Optimize for time 和 level 3 (-O3)
然后:使用两个16K 缓冲区(试验了128字节~16K不同大小缓冲区),才能勉强听到断续的音乐。
结论:仅仅M4和简单SPI接口的sd卡,可能不足以保证来自文件的音频流保证播放质量。看来要实现SD卡wav文件的播放,要么用SPIFI接口,要么双核配合。
调试串口:
附件: |