1.下载mad包。
libmad-0.15.1b
查阅一切资料,让其在PC上编译OK。
2.下载madlld-1.1p1。
所有的资料都可以在github 上找到。
https://download.youkuaiyun.com/download/C_ROOKIES/13260143
while(1){
if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN)
{
if(Stream.next_frame!=NULL)
{
Remaining=Stream.bufend-Stream.next_frame;
memmove(InputBuffer,Stream.next_frame,Remaining);
ReadStart=InputBuffer+Remaining;
ReadSize=INPUT_BUFFER_SIZE-Remaining;
}
else
{
ReadSize=INPUT_BUFFER_SIZE,
ReadStart=InputBuffer,
Remaining=0;
}
// 开始读取一段大的缓冲区
read_size = fread(ReadStart,1,ReadSize,fp);
if(read_size != ReadSize)
break;
mad_stream_buffer(&Stream,InputBuffer,ReadSize+Remaining);
}
// printf("code\n");
// 解码
mad_frame_decode(&Frame,&Stream);
// 得到PCM
mad_synth_frame(&Synth,&Frame);
mad_stream_buffer 组合数据
mad_frame_decode 真正的解码函数
mad_synth_frame 在里面可以提取PCM数据。
解码的数据为24位的PCM。
流程大概是 开始读取MP3数据,申请一段缓冲区,读取这部分MP3数据,但是不是全部都能接,或者是少了一部分,这个就是缓冲区申请的不够,如果够,那么后面不足一帧的数据需要重新读取 然后组成一个完成的缓冲区,就这样循环解码。
// 1.在移植过程中,需要生效config.h 在文件有一个模版 针对不同的平台 选用不同的头文件。
// 但是你突然会发现还有一个mad.h 头文件,其实这个相当于是一个 集合头文件,集中各个头文件
// 做一个接口 main.c 引用的时候比较简单。
// 2.在库中有有几个动态内存分配点,开始用malloc 经常会出错
// 后续改成静态变量就没有问题了。很多单片机用的库
// 都存在很多bug,不想Linux平台大多数拿过来编译就能用
// 3.开始遇到的bug 解码的时候发现过了几个帧就出现找不到同步帧
// 搞了三天,最后定位发现是SD卡部分问题。这个是必须四字节对齐访问,查询资料应该是DMA不支持 操作的内存最好也是四字节对齐
// 修改f_lseek为四字节对齐.
// 缓冲区同步的问题,设计一个双缓冲模式,一个写一个读,轮流切换
// 解码部分 解码成功一般 返回为MAD_ERROR_NONE
// 返回MAD_ERROR_BUFLEN 为当前的帧长度不够,需要重新读取
// 返回MAD_ERROR_LOSTSYNC 表示找不到同步帧,一般表示这段数据不是有用数据,或者就是读取的数据不对
// 返回MAD_ERROR_NOMEM 表示申请内存失败,这个一般是开了动态内存,注意动态内存是否申请成功。
最终MCU成功的跑起来了,能够正常解码MP3了。播放效果还可以。
测试解码一帧数据大概几ms.
200M的主频速度还是比较快,播放一帧需要26ms左右,CPU完全有时间做其他事情。