本帖最后由 胡斯哲 于 2016-11-27 16:04 编辑
刚开始以为MP3解码会很简单,搞成功后,没那么难,分享下
开发板是原子的探索者,需要例程综合实验中的AUDIOCODEC中的MP3文件和wav解码试验程序。1、将MP3文件考进“音乐 播放器实验”中
2、主程序不需要改动,将auioplay.c中的u8 audio_play_song(u8* fname)程序里头改为如下
//²¥·Åij¸öÒôƵÎļþ
u8 audio_play_song(u8* fname)
{
u8 res;
res=f_typetell(fname);
switch(res)
{
// case T_WAV:
// res=wav_play_song(fname);
// break;
<font color="#ff0000"> case T_MP3:
res=mp3_play_song(fname);</font>
break;
default://ÆäËûÎļþ,×Ô¶¯Ìøתµ½ÏÂÒ»Çú
printf("can't play:%s\r\n",fname);
res=KEY0_PRES;
break;
}
return res;
}
加入mp3play.h的头文件
3、在mp3play.c中将u8 mp3_play_song(u8* fname)改动红色地方
u8 mp3_play_song(u8* fname)
{
HMP3Decoder mp3decoder;
MP3FrameInfo mp3frameinfo;
u8 res,key;
u8* buffer; //ÊäÈëbuffer
u8* readptr; //MP3½âÂë¶ÁÖ¸Õë
int offset=0; //Æ«ÒÆÁ¿
int outofdata=0;//³¬³öÊý¾Ý·¶Î§
int bytesleft=0;//buffer»¹Ê£ÓàµÄÓÐЧÊý¾Ý
u32 br=0;
int err=0;
mp3ctrl=mymalloc(SRAMIN,sizeof(__mp3ctrl));
buffer=mymalloc(SRAMIN,MP3_FILE_BUF_SZ); //ÉêÇë½âÂëbuf´óС
audiodev.file=(FIL*)mymalloc(SRAMIN,sizeof(FIL));
audiodev.i2sbuf1=mymalloc(SRAMIN,2304*2);
audiodev.i2sbuf2=mymalloc(SRAMIN,2304*2);
audiodev.tbuf=mymalloc(SRAMIN,2304*2);
audiodev.file_seek=mp3_file_seek;
if(!mp3ctrl||!buffer||!audiodev.file||!audiodev.i2sbuf1||!audiodev.i2sbuf2||!audiodev.tbuf)//ÄÚ´æÉêÇëʧ°Ü
{
myfree(SRAMIN,mp3ctrl);
myfree(SRAMIN,buffer);
myfree(SRAMIN,audiodev.file);
myfree(SRAMIN,audiodev.i2sbuf1);
myfree(SRAMIN,audiodev.i2sbuf2);
myfree(SRAMIN,audiodev.tbuf);
return AP_ERR; //´íÎó
}
memset(audiodev.i2sbuf1,0,2304*2); //Êý¾ÝÇåÁã
memset(audiodev.i2sbuf2,0,2304*2); //Êý¾ÝÇåÁã
memset(mp3ctrl,0,sizeof(__mp3ctrl));//Êý¾ÝÇåÁã
res=mp3_get_info(fname,mp3ctrl);
if(res==0)
{
printf(" title:%s\r\n",mp3ctrl->title);
printf(" artist:%s\r\n",mp3ctrl->artist);
printf(" bitrate:%dbps\r\n",mp3ctrl->bitrate);
printf("samplerate:%d\r\n", mp3ctrl->samplerate);
printf(" totalsec:%d\r\n",mp3ctrl->totsec);
WM8978_I2S_Cfg(2,0); //·ÉÀûÆÖ±ê×¼,16λÊý¾Ý³¤¶È
I2S2_Init(I2S_Standard_Phillips,I2S_Mode_MasterTx,I2S_CPOL_Low,I2S_DataFormat_16bextended); //·ÉÀûÆÖ±ê×¼,Ö÷»ú·¢ËÍ,ʱÖӵ͵çƽÓÐЧ,16λÀ©Õ¹Ö¡³¤¶È
I2S2_SampleRate_Set(mp3ctrl->samplerate); //ÉèÖòÉÑùÂÊ
I2S2_TX_DMA_Init(audiodev.i2sbuf1,audiodev.i2sbuf2,mp3ctrl->outsamples);//ÅäÖÃTX DMA
i2s_tx_callback=mp3_i2s_dma_tx_callback; //»Øµ÷º¯ÊýÖ¸Ïòmp3_i2s_dma_tx_callback
mp3decoder=MP3InitDecoder(); //MP3½âÂëÉêÇëÄÚ´æ
res=f_open(audiodev.file,(char*)fname,FA_READ); //´ò¿ªÎļþ
}
if(res==0&&mp3decoder!=0)//´ò¿ªÎļþ³É¹¦
{
f_lseek(audiodev.file,mp3ctrl->datastart); //Ìø¹ýÎļþÍ·ÖÐtagÐÅÏ¢
audio_start(); //¿ªÊ¼²¥·Å
while(res==0)
{
readptr=buffer; //MP3¶ÁÖ¸ÕëÖ¸Ïòbuffer
offset=0; //Æ«ÒÆÁ¿Îª0
outofdata=0; //Êý¾ÝÕý³£
bytesleft=0;
res=f_read(audiodev.file,buffer,MP3_FILE_BUF_SZ,&br);//Ò»´Î¶ÁÈ¡MP3_FILE_BUF_SZ×Ö½Ú
if(res)//¶ÁÊý¾Ý³ö´íÁË
{
res=AP_ERR;
break;
}
if(br==0) //¶ÁÊýΪ0,˵Ã÷½âÂëÍê³ÉÁË.
{
res=AP_OK; //²¥·ÅÍê³É
break;
}
bytesleft+=br; //bufferÀïÃæÓжàÉÙÓÐЧMP3Êý¾Ý?
err=0;
while(!outofdata)//ûÓгöÏÖÊý¾ÝÒì³£(¼´¿É·ñÕÒµ½Ö¡Í¬²½×Ö·û)
{
offset=MP3FindSyncWord(readptr,bytesleft);//ÔÚreadptrλÖÃ,¿ªÊ¼²éÕÒͬ²½×Ö·û
if(offset<0) //ûÓÐÕÒµ½Í¬²½×Ö·û,Ìø³öÖ¡½âÂëÑ»·
{
outofdata=1;//ûÕÒµ½Ö¡Í¬²½×Ö·û
}else //ÕÒµ½Í¬²½×Ö·ûÁË
{
readptr+=offset; //MP3¶ÁÖ¸ÕëÆ«ÒƵ½Í¬²½×Ö·û´¦.
bytesleft-=offset; //bufferÀïÃæµÄÓÐЧÊý¾Ý¸öÊý,±ØÐë¼õȥƫÒÆÁ¿
err=MP3Decode(mp3decoder,&readptr,&bytesleft,(short*)audiodev.tbuf,0);//½âÂëÒ»Ö¡MP3Êý¾Ý
if(err!=0)
{
printf("decode error:%d\r\n",err);
break;
}else
{
MP3GetLastFrameInfo(mp3decoder,&mp3frameinfo); //µÃµ½¸Õ¸Õ½âÂëµÄMP3Ö¡ÐÅÏ¢
if(mp3ctrl->bitrate!=mp3frameinfo.bitrate) //¸üÐÂÂëÂÊ
{
mp3ctrl->bitrate=mp3frameinfo.bitrate;
}
mp3_fill_buffer((u16*)audiodev.tbuf,mp3frameinfo.outputSamps,mp3frameinfo.nChans);//Ìî³äpcmÊý¾Ý
}
if(bytesleft<MAINBUF_SIZE*2)//µ±Êý×éÄÚÈÝСÓÚ2±¶MAINBUF_SIZEµÄʱºò,±ØÐë²¹³äеÄÊý¾Ý½øÀ´.
{
memmove(buffer,readptr,bytesleft);//Òƶ¯readptrËùÖ¸ÏòµÄÊý¾Ýµ½bufferÀïÃæ,Êý¾ÝÁ¿´óСΪ:bytesleft
f_read(audiodev.file,buffer+bytesleft,MP3_FILE_BUF_SZ-bytesleft,&br);//²¹³äÓàϵÄÊý¾Ý
if(br<MP3_FILE_BUF_SZ-bytesleft)
{
memset(buffer+bytesleft+br,0,MP3_FILE_BUF_SZ-bytesleft-br);
}
bytesleft=MP3_FILE_BUF_SZ;
readptr=buffer;
}
while(audiodev.status&(1<<1))//Õý³£²¥·ÅÖÐ
{
delay_ms(1000/200);
mp3_get_curtime(audiodev.file,mp3ctrl);
audiodev.totsec=mp3ctrl->totsec; //²ÎÊý´«µÝ
audiodev.cursec=mp3ctrl->cursec;
audiodev.bitrate=mp3ctrl->bitrate;
audiodev.samplerate=mp3ctrl->samplerate;
audiodev.bps=16;//MP3½öÖ§³Ö16λ
if(audiodev.status&0X01)break;//ûÓа´ÏÂÔÝÍ£
}
if((audiodev.status&(1<<1))==0)//ÇëÇó½áÊø²¥·Å/²¥·ÅÍê³É
{
res=AP_NEXT;//Ìø³öÉÏÉϼ¶Ñ»·
outofdata=1;//Ìø³öÉÏÒ»¼¶Ñ»·
break;
}
while(1)
{
key=KEY_Scan(0);
if(key==WKUP_PRES)//ÔÝÍ£
{
if(audiodev.status&0X01)audiodev.status&=~(1<<0);
else audiodev.status|=0X01;
}
if(key==KEY2_PRES||key==KEY0_PRES)//ÏÂÒ»Çú/ÉÏÒ»Çú
{
audio_stop_req(&audiodev);
res=key;
audio_stop();//¹Ø±ÕÒôƵÊä³ö
f_close(audiodev.file);
MP3FreeDecoder(mp3decoder); //ÊÍ·ÅÄÚ´æ
myfree(SRAMIN,mp3ctrl);
myfree(SRAMIN,buffer);
myfree(SRAMIN,audiodev.file);
myfree(SRAMIN,audiodev.i2sbuf1);
myfree(SRAMIN,audiodev.i2sbuf2);
myfree(SRAMIN,audiodev.tbuf);
return res;
//break;
}
mp3_get_curtime(audiodev.file,mp3ctrl);//µÃµ½×Üʱ¼äºÍµ±Ç°²¥·ÅµÄʱ¼ä
audio_msg_show(mp3ctrl->totsec,mp3ctrl->cursec,mp3ctrl->bitrate);
if((audiodev.status&0X01)==0)delay_ms(10);
else break;
}
}
}
}
audio_stop();//¹Ø±ÕÒôƵÊä³ö
}////////////////////////////////////////////////////////////////////////////////else res=AP_ERR;//´íÎó
f_close(audiodev.file);
MP3FreeDecoder(mp3decoder); //ÊÍ·ÅÄÚ´æ
myfree(SRAMIN,mp3ctrl);
myfree(SRAMIN,buffer);
myfree(SRAMIN,audiodev.file);
myfree(SRAMIN,audiodev.i2sbuf1);
myfree(SRAMIN,audiodev.i2sbuf2);
myfree(SRAMIN,audiodev.tbuf);
return res=KEY0_PRES;
}
4.编译一下,会有两个错误,是综合试验中MP3play.c的两个延时到ucos的两个常量,统统改为delay_ms(5);
就这么简单,自己够不敢相信,自己绕了那么多弯路。
不过能听到声音也是蛮开心的
再加上wav文件那也简单了 2016.11.27
|
|