搜索
bottom↓
回复: 44

AVR32B0256软件解码MP3论证 helix方案

[复制链接]

出0入0汤圆

发表于 2010-10-7 22:25:23 | 显示全部楼层 |阅读模式
没做过,总觉得MP3解码应该是很简单的事情,还有过用AVR解MP3的想法,现在看来真正的觉得可笑。
查了一些关于软件解MP3的资料,决定用helix 方案试一下,让我们算一下用helix 解MP3最少要多少的资源:
1.MP3是一帧为单位进行解码,也就是说,必须至少读入一帧的数据以准备解码,一帧有多少的数据呢?看看:
数据帧大小:

FrameSize = (((MpegVersion == MPEG1 ? 144 : 72) * Bitrate) / SamplingRate) + PaddingBit

例如: Bitrate = 128000, a SamplingRate =44100, and PaddingBit = 1

FrameSize = (144 * 128000) / 44100 + 1 = 417 bytes
也就是说,想解码一个比特率为128K,采样率为44.1K的MP3文件,最少一次读入内存417 bytes 以准备解码。

2.helix 在运行解码程序的时候要24K的RAM内存,这个是官方给的数据这个就是最大的门槛

3.解码输出,这个也是要内存的,别告诉我你一输出就直接给DAC不用缓冲区,这个是跑不掉的,要多少呢,
PCM音频信号进行MP3压缩时,以1152个PCM采样值为单位,封装成具有固定长度的MP3数据帧。
在解码时,利用数据帧里的信息可以恢复出1152个PCM采样值
也就是说,helix 在进入一帧解码完成后,会输出1152个PCM数据,这个是16位的用于直接输出到DAC的数据

算一下,现在要多少内存了,假设我们想解码320K码率的MP3文件,那么按上面的算,我们至少要:
1047 + 24k + 1152 bytes = 26.2K

等等,这里还没有算上文件系统FAT还有堆栈占用的内存呢,那它们到底还要多少呢?
什么都别说,单是堆栈,在进入如些复杂的DSP运算,为了保证程序的可靠运行,官方建议4K ,综合以上,已用30.2K

到这里,AVR32B0256还剩下多少内存呢,我们知道这个片子有片内RAM 32K  那还有32-30.2=1.8K的内存

我的天呀,似乎刚刚好。。。

-----------------------------------------------------------------------------------------------------

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2010-10-7 22:34:20 | 显示全部楼层
上传一下用helix方案 做的MP3,已经做成了,使用:
AVR32B1128  32KRAM 用PWM做DAC输出,定时器产生时序,中断里修改PWM值以输出PCM数据。

国外牛人用B1128做的MP3电路图和程序包ourdev_588129R4IGPT.zip(文件大小:1.50M) (原文件名:UC3B-MP3.zip)

出0入0汤圆

发表于 2010-10-7 22:34:50 | 显示全部楼层
avrfreaks上有人用UC3B1256做出来了,也是用HELIX解码的

出0入0汤圆

 楼主| 发表于 2010-10-7 22:52:19 | 显示全部楼层
嗯,是的,我贴的压缩包就是从avrfreaks上下载来的,里面有完整的电路和工程目录,

出0入0汤圆

发表于 2010-10-8 18:16:49 | 显示全部楼层
楼主 PWM DAC 效果怎么样?
是1K、255K电阻RC网络,分别两个8-bit PWM组合成16-bit的方案吗?
我去年测试了下这样的pwm dac,效果奇差,基本上只能听到而已。不晓得哪里误了。

出0入0汤圆

 楼主| 发表于 2010-10-8 22:04:28 | 显示全部楼层
LS,
是1K、255K电阻RC网络,分别两个8-bit PWM组合成16-bit的方案,这样的DAC有噪音是跑不掉的,只能用来验证软件解码是否成功
但是我没有用PWMDAC,硬件方面,我使用了:
WM8978 CODEC,这个芯片工作在主模式,自动产生MCLK时序,不需要AVR32用另外的时钟来产生时序。
使用TWI总线来设置 WM8978 的采样率和音量。
电路参考了,RT-Thread 网络收音机。

出0入0汤圆

发表于 2010-10-9 15:33:08 | 显示全部楼层
哦,原来这样,明白。
atmel的SSC还是很好用的,灵活配置成 I2S、AC97、PCM 等各种帧格式,接codec,绝对秒杀NXP、ST、LM3S。

出0入0汤圆

发表于 2010-10-9 15:43:02 | 显示全部楼层
回复【6楼】huatuizh  
哦,原来这样,明白。
atmel的ssc还是很好用的,灵活配置成 i2s、ac97、pcm 等各种帧格式,接codec,绝对秒杀nxp、st、lm3s。
-----------------------------------------------------------------------

在玩AVR32的表示对其SSC外设很满意.搭配PDCA使用一个字爽

出0入0汤圆

 楼主| 发表于 2010-10-17 20:53:12 | 显示全部楼层
经过几天的努力,终于做好了。


B0256+CODEC+SD (原文件名:SAM_0387.jpg)


正在播放...320Kbps@44100 (原文件名:SAM_0391.jpg)

出0入0汤圆

 楼主| 发表于 2010-10-17 21:06:35 | 显示全部楼层
授之以鱼不如授之以渔。
下面简单讲一下使用helix进行软解MP3的大概流程。
1.首先找到MP3格式的文件,这个需要文件系统的协助,我的代码使用了SOFTWARE_FRAMEWORK里面的文件系统
直接通过
if(nav_file_checkext((FS_STRING)"MP3"));进行判断这个文件的后缀是否是MP3文件夹
2.读取文件,找到MP3的帧起始标志,这个helix已经帮我们写好了
/**************************************************************************************
* Function:    MP3FindSyncWord
*
* Description: locate the next byte-alinged sync word in the raw mp3 stream
*
* Inputs:      buffer to search for sync word
*              max number of bytes to search in buffer
*
* Outputs:     none
*
* Return:      offset to first sync word (bytes from start of buf)
*              -1 if sync not found after searching nBytes
**************************************************************************************/
int MP3FindSyncWord(unsigned char *buf, int nBytes)
这个子程序的输入unsigned char *buf 是指读入文件数据的起始指针,
int nBytes 这个是指输入缓冲区的大小。
3.找到帧同步后就可以调用MP3Decode 来进行解码了
4.解码完成后,得到的PCM数据会存放在outBuf[] 这个缓冲区里面 详见SUBBAND.c
5.把得到的PCM数据输出到DAC。

出0入0汤圆

发表于 2010-10-19 15:49:30 | 显示全部楼层
伸个爪子学习, 谢谢!

出0入0汤圆

 楼主| 发表于 2010-10-19 21:17:42 | 显示全部楼层
感兴趣的可以一起讨论,我现在正尝试修改源码,以播放U盘里的MP3文件。
SOFTWARE_FRAMEWORK 的FAT文件系统不能同时打开两个文件,所以不能打开字库文件以支持中文显示,郁闷~~

做好了,公布代码,同时详细说明一下整个MP3工作流程

出0入0汤圆

发表于 2010-10-19 21:57:34 | 显示全部楼层
算一下,现在要多少内存了,假设我们想解码320K码率的MP3文件,那么按上面的算,我们至少要:
1047 + 24k + 1152 bytes = 26.2K
             ~~~~~~~~~~1152是MP3一帧的采样数,常见的双声道、16bit采样MP3一帧解出来的PCM数据是4608Bytes,开两个buffer就是8216Bytes!

MP3解码速度不是问题,跑5xMHz的44B0就能搞定,关键在于RAM要够,类似问题对于FLAC和WMA都存在。

出0入0汤圆

发表于 2010-10-19 22:01:54 | 显示全部楼层
以前我也想移植MP3解码进CM3,就查了以下几种

mpg123(mpg321)公认声音是最好的(MP3解码器),但是我记得以前看的时候发现里面带了SRC......内存占用很大。
libmad,这个调试了下,不知道为何解不成功。


helix,这个是real公司的代码吧,我记得好象是。

出0入0汤圆

发表于 2010-10-19 22:22:59 | 显示全部楼层
回复【11楼】lisn3188 龙南
感兴趣的可以一起讨论,我现在正尝试修改源码,以播放u盘里的mp3文件。
software_framework 的fat文件系统不能同时打开两个文件,所以不能打开字库文件以支持中文显示,郁闷~~
做好了,公布代码,同时详细说明一下整个mp3工作流程
-----------------------------------------------------------------------

每个NAV只能打开一个文件,但是你可以同时有多个NAV,迂回实现打开多个文件

出0入618汤圆

发表于 2010-10-19 22:37:55 | 显示全部楼层
helix代码比libmad小很多,不过helix是16位的,libmad是24位的,估计helix对几个常量表做了简化。
STM32 Radio项目就是用helix的,72M CM3解320k MP3大概占60-70%。

出0入0汤圆

发表于 2010-10-20 00:51:35 | 显示全部楼层
回复【15楼】gzhuli  咕唧霖
helix代码比libmad小很多,不过helix是16位的,libmad是24位的,估计helix对几个常量表做了简化。
stm32 radio项目就是用helix的,72m cm3解320k mp3大概占60-70%。
-----------------------------------------------------------------------

移植到汇编也许会快点。

做一台功能类似D50(仅放音)的机器出来也不是没可能的。

话说D50的LCD好象是STN的点阵?

出0入618汤圆

发表于 2010-10-20 01:34:30 | 显示全部楼层
回复【16楼】90999 张耀扬
-----------------------------------------------------------------------

helix的核心部分已经是汇编的了,目前这个效能已经比较合理。AVR32官方的UC3A0512 demo是用libmad的,精度也是裁剪为16位。
类似D50的机器,MP3貌似可有可无吧,集中火力处理APE和FLAC更好。

出0入0汤圆

发表于 2010-10-20 01:46:43 | 显示全部楼层
是么,我去看看。

出0入0汤圆

发表于 2010-10-20 07:59:54 | 显示全部楼层
回复【17楼】 gzhuli 咕唧霖
---------------------------------------
APE需要占用系统更高频率和更大数据处理量的浮点运算, AVR32浮点运算可行吗?

出0入0汤圆

发表于 2010-10-20 07:59:55 | 显示全部楼层
libmad用过,蛮方便的。

出0入0汤圆

发表于 2010-10-20 08:49:26 | 显示全部楼层
回复【8楼】lisn3188  龙南
-----------------------------------------------------------------------

这个显示屏的效果很不错,,字体也很好看,,

出0入0汤圆

发表于 2010-10-20 08:55:22 | 显示全部楼层
显示屏是OLED吧

出0入618汤圆

发表于 2010-10-20 09:24:57 | 显示全部楼层
回复【19楼】piccode
回复【17楼】 gzhuli 咕唧霖
---------------------------------------
ape需要占用系统更高频率和更大数据处理量的浮点运算, avr32浮点运算可行吗?
-----------------------------------------------------------------------

其实一直很奇怪,是谁说APE需要浮点运算的?连MP3都能用整形运算解码,APE会在哪里需要用浮点?而且理论上看,用浮点运算会有精度损失问题,难以保证无损吧。
我看官方的SDK,除了计算播放进度之类的无关紧要功能外,暂时没看到核心部分用浮点运算的,有知道的麻烦帮忙指出具体在哪个文件的哪一行,大家一起看看能不能改成整形的。

出0入0汤圆

发表于 2010-10-20 10:39:34 | 显示全部楼层
回复【22楼】piccode  
显示屏是oled吧
-----------------------------------------------------------------------

蛮多坏的mp3上面都有这个oled的,单买oled也不贵,
老外很喜欢用oled。。

谁能做一个支持mp3,wma,aac/m4a的解码库,就牛叉大发了,,,比较非主流的ogg,和asf就算了吧。rm不开源也算了。高端的ape,flac,wav基本上也不太指望能解码了。
要是都能支持?估计有人说不如买现成的产品了,,少了很多乐趣啊。

出0入618汤圆

发表于 2010-10-20 10:44:14 | 显示全部楼层
回复【24楼】reloaded 电子浪人
回复【22楼】piccode   
显示屏是oled吧
-----------------------------------------------------------------------
谁能做一个支持mp3,wma,aac/m4a的解码库,就牛叉大发了,,,比较非主流的ogg,和asf就算了吧。rm不开源也算了。高端的ape,flac,wav基本上也不太指望能解码了。
-----------------------------------------------------------------------

主要是内存问题,单片机内存太小,做起来很麻烦。如果上ARM9,那直接用Linux就啥都有了,也没必要自己折腾。
APE, FLAC, WAV很高端么?WAV完全不需要解码呀。

出0入0汤圆

发表于 2010-10-20 11:28:23 | 显示全部楼层
内存几个办法外挂SRAM
或者用B0512 96K SRAM.....

出0入0汤圆

发表于 2010-10-20 11:55:41 | 显示全部楼层
大师,不好意思,还真不知道wav不要解码,,业余玩家见谅见谅~~~
arm9核心板也得250吧~~还不算布线的人工费~~(鉴于自己不会画多层板和使用pads)
~~~还不算学习linux系统的时间

以前有用7s64做的wav解码器,好像是哪位大虾的作品来着,,
现在64kram的mcu也就40元左右,96kram没仔细找过,128kram貌似就要70元++了。。
算算貌似也快到200了一共(加制版费的话)


回复【25楼】gzhuli  咕唧霖
回复【24楼】reloaded 电子浪人
回复【22楼】piccode   
显示屏是oled吧
-----------------------------------------------------------------------
谁能做一个支持mp3,wma,aac/m4a的解码库,就牛叉大发了,,,比较非主流的ogg,和asf就算了吧。rm不开源也算了。高端的ape,flac,wav基本上也不太指望能解码了。
-----------------------------------------------------------------------
主要是内存问题,单片机内存太小,做起来很麻烦。如果上arm9,那直接用linux就啥都有了,也没必要自己折腾。
ape, flac, wav很高端么?wav完全不需要解码呀。
-----------------------------------------------------------------------

出0入0汤圆

发表于 2010-10-20 11:58:32 | 显示全部楼层
回复【23楼】 gzhuli 咕唧霖
---------------------------------------------
http://www.monkeysaudio.com/developers.html上面的好像是浮点运算进入处理,没有细看
有没有谁有移植好的APE Library? (不知有没有其它的source code)

回复【26楼】 kingofkings 技术火
------------------------
内存几个办法外挂SRAM
或者用B0512 96K SRAM.....
------------------------------------
也不是做市场卖方案,自已玩的话APE/FLAC 其中之一就行了,WAV的话功耗还能下来呢, PIC32自已就有128K RAM

出0入0汤圆

发表于 2010-10-20 12:00:44 | 显示全部楼层
楼住的屏在那买的,是少脚位的话给个连接好不?

出0入0汤圆

 楼主| 发表于 2010-10-20 20:06:59 | 显示全部楼层
哇,好多大牛都出来了。。。

【12楼】 ForNever
谢谢你的指正,MP3一帧的采样数确实是1152个,解码出来的缓冲区必须要1152*2 bytes

【14楼】 mowin 雾湾
谢谢你的指点,可是多个NAV 是如何创建呢,迂回打开文件后会不会是从文件的起始打开?

【29楼】 piccode
屏是TAOBAO上买的。30个脚,关键字:“0.96寸 OLED”自己搜一下就出来了

出0入0汤圆

发表于 2010-10-20 23:36:11 | 显示全部楼层
举例说明吧

enum {
NAV_ID_0 = 0,
NAV_ID_1
}

在NAV_ID_0打开file_name_0
nav_select(NAV_ID_0);
nav_drive_set(nav_drive_nb() -1);
nav_partition_mount();
nav_checkdisk_disable(); /* Skip fat_check_device() for every read */
nav_filelist_reset();
nav_filelist_findname("file_name_0", FALSE));
file_open(FOPEN_MODE_R);

在NAV_ID_1打开file_name_1
nav_select(NAV_ID_1);
nav_drive_set(nav_drive_nb() -1);
nav_partition_mount();
nav_checkdisk_disable(); /* Skip fat_check_device() for every read */
nav_filelist_reset();
nav_filelist_findname("file_name_1", FALSE));
file_open(FOPEN_MODE_R);

读file_name_0
nav_select(NAV_ID_0);
file_seek(offset, FS_SEEK_SET);
file_read_buf(buf, BYTE_CNT);

读file_name_1
nav_select(NAV_ID_1);
file_seek(offset, FS_SEEK_SET);
file_read_buf(buf, BYTE_CNT);


以上是菜鸟代码,望大牛斧正,谢谢

出0入0汤圆

发表于 2010-11-30 20:57:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-30 21:15:04 | 显示全部楼层
mark,好贴,学习了

出0入0汤圆

发表于 2011-1-17 21:37:27 | 显示全部楼层
MP3论证 helix方案

出0入0汤圆

发表于 2011-1-22 18:41:26 | 显示全部楼层
这个应该是不用DSP的吧,怎么样把内部DSP利用起来呢?

出0入0汤圆

发表于 2011-3-19 10:53:50 | 显示全部楼层
回复【35楼】xiaob135 快乐青春
这个应该是不用dsp的吧,怎么样把内部dsp利用起来呢?
-----------------------------------------------------------------------

同问, 怎么把内部的DSP用于MP3解码呢?

出0入618汤圆

发表于 2011-3-19 13:52:35 | 显示全部楼层
AVR32没有“内部DSP”,只有DSP指令,编译器支持就可以了。

出0入0汤圆

发表于 2011-6-2 19:21:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-4 16:11:22 | 显示全部楼层
楼主,我的MP3 mp3FrameInfo.version=1 无法播放??
如果删掉声音断断续续.........


        // check if this is really a valid frame
        // (the decoder does not seem to calculate CRC, so make some plausibility checks)
        if (MP3GetNextFrameInfo(hMP3Decoder, &mp3FrameInfo, read_ptr) == 0 &&
                mp3FrameInfo.nChans == 2 &&
                mp3FrameInfo.version == 0) {
                debug_printf("Found a frame at offset %x\n", offset + read_ptr - mp3buf + mp3file->fptr);
        } else {
                puts("this is no valid frame");
                // advance data pointer
                // TODO: handle bytes_left == 0
                assert(bytes_left > 0);
                bytes_left -= 1;
                read_ptr += 1;
                return 0;
        }

出0入0汤圆

发表于 2011-6-28 14:20:44 | 显示全部楼层
好像很占内存呀,我编译后的结果如下,楼主编译结果怎样呀?

编译结果 (原文件名:未命名.jpg)

文件缓冲区我设置单位 char buffer[10000];    // file copy buffer

出0入0汤圆

发表于 2011-7-3 21:02:08 | 显示全部楼层
回复【楼主位】lisn3188  龙南
-----------------------------------------------------------------------

我关心功耗咋样?

出0入0汤圆

发表于 2012-7-9 22:36:51 | 显示全部楼层
正在学习,工作中要移植MP3解码。

出0入0汤圆

发表于 2012-7-20 15:34:57 | 显示全部楼层
很好。很强大 。。

出0入0汤圆

发表于 2014-2-24 22:51:45 | 显示全部楼层
mark!正打算做个mp3玩玩!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 10:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表