这个是STM32网络收音机v2版
其中使用RT-Thread做为RTOS,WM8978做为音频输出设备(用的RT-Thread设备模型),DFSFAT文件系统做为mp3文件的存取,LwIP做为TCP的协议栈,RT-Thread/GUI做为操作的图形用户界面。基本上RT-Thread0.3.0中能用到的组件都用到了。
wm8978注册成了RT-Thread的snd设备,上层应用可通过"snd"获得相应的设备,然后写入软件解压出的PCM数据实现音频播放。从软件上来说,如果底层换一个设备(例如STM32网络收音机v1版用的是wm8753,v2版使用wm8978),只需要在底层替换相应的驱动,上层依然只认"snd"设备,从而上层软件代码不需要做任何修改。
在实现的过程中还有一个小问题,一个线程进行mp3数据解压缩,它一直解压然后往设备中写入PCM音频数据,它如何知道PCM数据已经播放完毕,需要再解压更多的mp3呢?显然,如果是串行的做这件事,等PCM数据播放完毕再解压下一mp3数据,时间上肯定来不及,听到的肯定会是咔咔的杂音。而如果是并行做(边播放边解压),两者如何同步上?(当然还有一个前提,播放的速度肯定要小于解压的速度,否则播放完了还来不及解压,芯片的处理能力就不够,就不应该选取软解压的方案)
在这个实现中,使用了RT-Thread的memorypool方案,当解压线程工作时先向mp申请内存以放置解压出的PCM音频数据,如果mp没有内存块线程将自动挂起(等待有空闲的内存块)。而向snd设备写入PCM数据时,则只是把数据块放到设备的队列中(真实的写入是通过DMA方式传输),当数据真实地写完时,将释放数据块到mp中(这个过程是在中断中完成)。所以整个过程会是,如果解压线程领先播放时,将把mp中所有的内存块使用完,而后挂起。当播放一段完成时,释放相应的内存块,并唤醒解压线程让它继续工作。
这个播放器原型也用到了RT-Thread/GUI,初始画面是播放器,还包括功能画面,选择电台及选择SD卡上的文件进行播放。后续会添加上文件系统中图片的浏览,适当的优先(先想到的是泡泡龙游戏,因为播放器是带了五向导航键的)
所有的源代码(RTOS、文件系统、协议栈、GUI、播放器代码)都可以在RT-Thread的svn服务器中获得:
http://rt-thread.googlecode.com/svn/trunk/
(下载全部代码请使用svn客户端,具体请看svn的用法)
RT-Thread上这个开源项目的网址:
http://www.rt-thread.org/phpbb/viewforum.php?f=17 |