Files
player/Project/Src/MP3/mp3play.c

693 lines
17 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "mp3play.h"
#include "stm32f4xx.h"
#include "dac.h"
#include "delay.h"
#include "mymem.h"
#include "usart.h"
#include "string.h"
#include "rtthread.h"
#include "ftfile.h"
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ת<EFBFBD><D7AA>
2025-06-27 00:32:57 +08:00
#include "char_encode.h"
//////////////////////////////////////////////////////////////////////////////////
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2>helix MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//ALIENTEK STM32F407<30><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//MP3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>@ALIENTEK
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳:www.openedv.com
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:2014/6/29
//<2F><EFBFBD><E6B1BE>V1.0
2025-06-27 00:32:57 +08:00
//********************************************************************************
2025-07-05 19:47:28 +08:00
//V1.0 ˵<><CBB5>
//1,֧<><D6A7>16λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MP3<50>Ľ<EFBFBD><C4BD><EFBFBD>
//2,֧<><D6A7>CBR/VBR<42><52>ʽMP3<50><33><EFBFBD><EFBFBD>
//3,֧<><D6A7>ID3V1<56><31>ID3V2<56><32>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD>
//4,֧<><D6A7><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>(MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>320Kbps)<29><><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
//////////////////////////////////////////////////////////////////////////////////
2025-07-05 19:47:28 +08:00
static __mp3ctrl * mp3ctrl; //mp3<70><33><EFBFBD>ƽ<C6BD><E1B9B9>
static __audiodev audiodev; //<2F><>Ƶ<EFBFBD><C6B5><EFBFBD>ƽ<C6BD><E1B9B9>
static vu8 g_buff_Invalid=0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ЧʱҪ<CAB1><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static vu8 g_buff_useing; //<2F><>ǰDMA<4D><41>ʹ<EFBFBD><CAB9><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static int g_vol=5; //<2F><><EFBFBD><EFBFBD> 0~10<31><30>
2025-06-27 00:32:57 +08:00
#define MP3_VOL_MAX 10
2025-07-05 19:47:28 +08:00
//MP3 DMA<4D><41><EFBFBD>ͻص<CDBB><D8B5><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static void dma_tx_callback(DAC_UserStruct *dac)
{
u16 i;
if (dac->buff_useing==1)
{
2025-07-05 19:47:28 +08:00
if((audiodev.status&0X01)==0)//<2F><>ͣ<EFBFBD><CDA3>,<2C><><EFBFBD><EFBFBD>0
2025-06-27 00:32:57 +08:00
{
for(i=0;i<2304*2;i++)audiodev.i2sbuf1[i]=0;
}
}else
{
2025-07-05 19:47:28 +08:00
if((audiodev.status&0X01)==0)//<2F><>ͣ<EFBFBD><CDA3>,<2C><><EFBFBD><EFBFBD>0
2025-06-27 00:32:57 +08:00
{
for(i=0;i<2304*2;i++)audiodev.i2sbuf2[i]=0;
}
}
g_buff_useing=dac->buff_useing;
g_buff_Invalid=1;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>PCM<43><4D><EFBFBD>ݵ<EFBFBD>DAC
//buf:PCM<43><4D><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
//size:pcm<63><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(16λΪ<CEBB><CEAA>λ)
//nch:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
2025-06-27 00:32:57 +08:00
void mp3_fill_buffer(u16* buf,u16 size,u8 nch)
{
u16 i;
s16 *p;
2025-07-05 19:47:28 +08:00
while(g_buff_Invalid==0)//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
rt_thread_delay(5);//
};
if(g_buff_useing==0)
{
p=(s16*)audiodev.i2sbuf2;
}else
{
p=(s16*)audiodev.i2sbuf1;
}
if(nch==2)
{
for(i=0;i<size;i++)
{
// p[i]=((buf[i]+0x8000)>>4);
int temp=(int16_t)buf[i];
temp=temp*g_vol/MP3_VOL_MAX;
p[i]=((temp+0x8000)>>4);
}
}
2025-07-05 19:47:28 +08:00
else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
for(i=0;i<size;i++)
{
int temp=(int16_t)buf[i];
temp=temp*g_vol/MP3_VOL_MAX;
p[2*i]=((temp+0x8000)>>4);
p[2*i+1]=p[2*i];
}
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>Ч
2025-06-27 00:32:57 +08:00
g_buff_Invalid=0;
}
static void mp3_get_string (u8 type,u8 *out,u8 *in,int size);
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ID3V1
//buf:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>(<28><>С<EFBFBD>̶<EFBFBD><CCB6><EFBFBD>128<32>ֽ<EFBFBD>)
//pctrl:MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>,<2C><>ȡʧ<C8A1><CAA7>
2025-06-27 00:32:57 +08:00
u8 mp3_id3v1_decode(u8* buf,__mp3ctrl *pctrl)
{
ID3V1_Tag *id3v1tag;
id3v1tag=(ID3V1_Tag*)buf;
2025-07-05 19:47:28 +08:00
if (strncmp("TAG",(char*)id3v1tag->id,3)==0)//<2F><>MP3 ID3V1 TAG
2025-06-27 00:32:57 +08:00
{
mp3_get_string(0,pctrl->title,id3v1tag->title,30);
mp3_get_string(0,pctrl->artist,id3v1tag->artist,30);
}else return 1;
return 0;
}
static void mp3_get_string (u8 type,u8 *out,u8 *in,int size)
{
if (type==1)//UNICODE16
{
u8 *char_uni=mymalloc (128);
mymemset(char_uni,0,128);
strncpy((char*)char_uni,(char*)(in),size);
2025-07-05 19:47:28 +08:00
//UnicodeתGBK
2025-06-27 00:32:57 +08:00
uni2gbk_str(char_uni,out);
myfree(char_uni);
}
else if (type==3)//UTF8
{
u8 *char_utf8=mymalloc (128);
mymemset(char_utf8,0,128);
strncpy((char*)char_utf8,(char*)(in),size);
2025-07-05 19:47:28 +08:00
//UTF8תGBK
2025-06-27 00:32:57 +08:00
utf82gbk_str (char_utf8,out);
myfree(char_utf8);
}
else //(type==0)//ASCII
{
strncpy((char*)out,(char*)(in),size);
}
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ID3V2
//buf:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
//size:<3A><><EFBFBD>ݴ<EFBFBD>С
//pctrl:MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>,<2C><>ȡʧ<C8A1><CAA7>
2025-06-27 00:32:57 +08:00
u8 mp3_id3v2_decode(u8* buf,u32 size,__mp3ctrl *pctrl)
{
ID3V2_TagHead *taghead;
ID3V23_FrameHead *framehead;
u32 t;
2025-07-05 19:47:28 +08:00
u32 tagsize; //tag<61><67>С
u32 frame_size; //֡<><D6A1>С
2025-06-27 00:32:57 +08:00
taghead=(ID3V2_TagHead*)buf;
2025-07-05 19:47:28 +08:00
if(strncmp("ID3",(const char*)taghead->id,3)==0)//<2F><><EFBFBD><EFBFBD>ID3?
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
tagsize=((u32)taghead->size[0]<<21)|((u32)taghead->size[1]<<14)|((u16)taghead->size[2]<<7)|taghead->size[3];//<2F>õ<EFBFBD>tag <20><>С
pctrl->datastart=tagsize; //<2F>õ<EFBFBD>mp3<70><33><EFBFBD>ݿ<EFBFBD>ʼ<EFBFBD><CABC>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
if(tagsize>size)tagsize=size; //tagsize<7A><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bufsize<7A><65>ʱ<EFBFBD><CAB1><><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size<7A><65>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if(taghead->mversion<3)
{
printf("not supported mversion!\r\n");
return 1;
}
t=10;
while(t<tagsize)
{
framehead=(ID3V23_FrameHead*)(buf+t);
2025-07-05 19:47:28 +08:00
frame_size=((u32)framehead->size[0]<<24)|((u32)framehead->size[1]<<16)|((u32)framehead->size[2]<<8)|framehead->size[3];//<2F>õ<EFBFBD>֡<EFBFBD><D6A1>С
if (strncmp("TT2",(char*)framehead->id,3)==0||strncmp("TIT2",(char*)framehead->id,4)==0)//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡,<2C><>֧<EFBFBD><D6A7>unicode<64><65>ʽ!!
2025-06-27 00:32:57 +08:00
{
u8 *dat_ptr=(buf+t+sizeof(ID3V23_FrameHead));
int size=AUDIO_MIN(frame_size-1,MP3_TITSIZE_MAX-1);
mp3_get_string(dat_ptr[0],pctrl->title,dat_ptr+1,size);
}
2025-07-05 19:47:28 +08:00
if (strncmp("TP1",(char*)framehead->id,3)==0||strncmp("TPE1",(char*)framehead->id,4)==0)//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
2025-06-27 00:32:57 +08:00
{
u8 *dat_ptr=(buf+t+sizeof(ID3V23_FrameHead));
int size=AUDIO_MIN(frame_size-1,MP3_ARTSIZE_MAX-1);
mp3_get_string(dat_ptr[0],pctrl->artist,dat_ptr+1,size);
}
// if (strncmp("APIC",(char*)framehead->id,4)==0)
// {
2025-07-05 19:47:28 +08:00
// //ר<><D7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
// u8 *dat_ptr=(buf+t+sizeof(ID3V23_FrameHead));
// if (pctrl->jpeg_data) myfree(pctrl->jpeg_data);
// pctrl->jpeg_data=mymalloc(frame_size);
// pctrl->jpeg_len=frame_size;
// mymemcpy (pctrl->jpeg_data,dat_ptr,frame_size);
// }
t+=frame_size+sizeof(ID3V23_FrameHead);
}
return 0;
}else
2025-07-05 19:47:28 +08:00
{ pctrl->datastart=0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID3,mp3<70><33><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD>0<EFBFBD><30>ʼ
2025-06-27 00:32:57 +08:00
return (u8)-1;
}
}
2025-07-05 19:47:28 +08:00
//<2F><>ȡMP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
//pname:MP3<50>ļ<EFBFBD>·<EFBFBD><C2B7>
//pctrl:MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><E1B9B9>
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>
// <20><><EFBFBD><EFBFBD><><CAA7>
2025-06-27 00:32:57 +08:00
u8 mp3_get_info(u8 *data,u32 size,__mp3ctrl* pctrl)
{
HMP3Decoder decoder={0};
MP3FrameInfo frame_info={0};
MP3_FrameXing* fxing=0;
MP3_FrameVBRI* fvbri=0;
u8 *buf=0;
u8 *data_ptr=0;
//u32 br;
u8 res=0;
int offset=0;
u32 p=0;
2025-07-05 19:47:28 +08:00
short samples_per_frame=0; //һ֡<D2BB>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
u32 totframes=0; //<2F><>֡<EFBFBD><D6A1>
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
buf=mymalloc(MP3_FILE_BUF_SZ); //<2F><><EFBFBD><EFBFBD>5K<35>ڴ<EFBFBD>
if(buf)//<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
2025-06-27 00:32:57 +08:00
{
data_ptr=data;
mymemcpy (buf,data_ptr,MP3_FILE_BUF_SZ);
2025-07-05 19:47:28 +08:00
if(res==0)//<2F><>ȡ<EFBFBD>ļ<EFBFBD><C4BC>ɹ<EFBFBD>,<2C><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ID3V2/ID3V1<56>Լ<EFBFBD><D4BC><EFBFBD>ȡMP3<50><33>Ϣ
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
if (mp3_id3v2_decode(buf,MP3_FILE_BUF_SZ,pctrl)!=0) //<2F><><EFBFBD><EFBFBD>ID3V2<56><32><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
data_ptr=data+size-128;
mymemcpy (buf,data_ptr,128);
2025-07-05 19:47:28 +08:00
mp3_id3v1_decode(buf,pctrl); //<2F><><EFBFBD><EFBFBD>ID3V1<56><31><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
decoder=MP3InitDecoder(); //MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
data_ptr=data+pctrl->datastart;
mymemcpy (buf,data_ptr,MP3_FILE_BUF_SZ);
2025-07-05 19:47:28 +08:00
offset=MP3FindSyncWord(buf,MP3_FILE_BUF_SZ); //<2F><><EFBFBD><EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD><EFBFBD>Ϣ
if(offset>=0&&MP3GetNextFrameInfo(decoder,&frame_info,&buf[offset])==0)//<2F>ҵ<EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>,<2C><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
p=offset+4+32;
fvbri=(MP3_FrameVBRI*)(buf+p);
2025-07-05 19:47:28 +08:00
if(strncmp("VBRI",(char*)fvbri->id,4)==0)//<2F><><EFBFBD><EFBFBD>VBRI֡(VBR<42><52>ʽ)
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
if (frame_info.version==MPEG1)samples_per_frame=1152;//MPEG1,layer3ÿ֡<C3BF><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1152
else samples_per_frame=576;//MPEG2/MPEG2.5,layer3ÿ֡<C3BF><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>576
totframes=((u32)fvbri->frames[0]<<24)|((u32)fvbri->frames[1]<<16)|((u16)fvbri->frames[2]<<8)|fvbri->frames[3];//<2F>õ<EFBFBD><C3B5><EFBFBD>֡<EFBFBD><D6A1>
pctrl->totsec=totframes*samples_per_frame/frame_info.samprate;//<2F>õ<EFBFBD><C3B5>ļ<EFBFBD><C4BC>ܳ<EFBFBD><DCB3><EFBFBD>
}else //<2F><><EFBFBD><EFBFBD>VBRI֡,<2C><><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD>Xing֡(VBR<42><52>ʽ)
2025-06-27 00:32:57 +08:00
{
if (frame_info.version==MPEG1) //MPEG1
{
p=frame_info.nChans==2?32:17;
2025-07-05 19:47:28 +08:00
samples_per_frame = 1152; //MPEG1,layer3ÿ֡<C3BF><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1152
2025-06-27 00:32:57 +08:00
}else
{
p=frame_info.nChans==2?17:9;
2025-07-05 19:47:28 +08:00
samples_per_frame=576; //MPEG2/MPEG2.5,layer3ÿ֡<C3BF><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>576
2025-06-27 00:32:57 +08:00
}
p+=offset+4;
fxing=(MP3_FrameXing*)(buf+p);
2025-07-05 19:47:28 +08:00
if(strncmp("Xing",(char*)fxing->id,4)==0||strncmp("Info",(char*)fxing->id,4)==0)//<2F><>Xng֡
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
if(fxing->flags[3]&0X01)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>frame<6D>ֶ<EFBFBD>
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
totframes=((u32)fxing->frames[0]<<24)|((u32)fxing->frames[1]<<16)|((u16)fxing->frames[2]<<8)|fxing->frames[3];//<2F>õ<EFBFBD><C3B5><EFBFBD>֡<EFBFBD><D6A1>
pctrl->totsec=totframes*samples_per_frame/frame_info.samprate;//<2F>õ<EFBFBD><C3B5>ļ<EFBFBD><C4BC>ܳ<EFBFBD><DCB3><EFBFBD>
}else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>frames<65>ֶ<EFBFBD>
2025-06-27 00:32:57 +08:00
{
pctrl->totsec=size/(frame_info.bitrate/8);
}
2025-07-05 19:47:28 +08:00
}else //CBR<42><52>ʽ<>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2><EFBFBD>ʱ<EFBFBD><CAB1>
2025-06-27 00:32:57 +08:00
{
pctrl->totsec=size/(frame_info.bitrate/8);
}
}
2025-07-05 19:47:28 +08:00
pctrl->bitrate=frame_info.bitrate; //<2F>õ<EFBFBD><C3B5><EFBFBD>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
mp3ctrl->samplerate=frame_info.samprate; //<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if(frame_info.nChans==2)mp3ctrl->outsamples=frame_info.outputSamps; //<2F><><EFBFBD><EFBFBD>PCM<43><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
else mp3ctrl->outsamples=frame_info.outputSamps*2; //<2F><><EFBFBD><EFBFBD>PCM<43><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С,<2C><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>MP3,ֱ<><D6B1>*2,<2C><><EFBFBD><EFBFBD>Ϊ˫<CEAA><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}else res=0XFE;//δ<>ҵ<EFBFBD>ͬ<EFBFBD><CDAC>֡
MP3FreeDecoder(decoder);//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
}
}else res=0XFF;
myfree(buf);
return res;
}
2025-07-05 19:47:28 +08:00
//<2F>õ<EFBFBD><C3B5><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
//fx:<3A>ļ<EFBFBD>ָ<EFBFBD><D6B8>
//mp3x:mp3<70><33><EFBFBD>ſ<EFBFBD><C5BF><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
//void mp3_get_curtime(FIL*fx, FILINFO *finfo,__mp3ctrl *mp3x)
//{
// u32 fpos=0;
2025-07-05 19:47:28 +08:00
// if(fx->fptr>mp3x->datastart)fpos=fx->fptr-mp3x->datastart; //<2F>õ<EFBFBD><C3B5><EFBFBD>ǰ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5>ĵط<C4B5>
// mp3x->cursec=fpos*mp3x->totsec/(finfo->fsize-mp3x->datastart); //<2F><>ǰ<EFBFBD><C7B0><EFBFBD>ŵ<EFBFBD><C5B5>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
2025-06-27 00:32:57 +08:00
//}
2025-07-05 19:47:28 +08:00
//mp3<70>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD><CBBA><EFBFBD>
//pos:<3A><>Ҫ<EFBFBD><D2AA>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>λ<EFBFBD><CEBB>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><>ǰ<EFBFBD>ļ<EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>)
2025-06-27 00:32:57 +08:00
u32 mp3_file_seek(u32 pos)
{
// if(pos>audiodev.file->fsize)
// {
// pos=audiodev.file->fsize;
// }
// f_lseek(audiodev.file,pos);
// return audiodev.file->fptr;
return pos;
}
2025-07-05 19:47:28 +08:00
//<2F>ж<EFBFBD>mp3<70>Ƿ<EFBFBD>֧<EFBFBD><D6A7>
//<2F><>ȡ MP3_FILE_BUF_SZ <20><>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD>ݾ<EFBFBD><DDBE><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>0 ֧<>֣<EFBFBD><D6A3><EFBFBD>0 <20><>֧<EFBFBD><D6A7>
2025-06-27 00:32:57 +08:00
int mp3_get_support (u8* data,u32 size)
{
int res=0;
__mp3ctrl *mp3ctrl=mymalloc(sizeof(__mp3ctrl));
2025-07-05 19:47:28 +08:00
mymemset(mp3ctrl,0,sizeof(__mp3ctrl));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
res=mp3_get_info(data,size,mp3ctrl);
if (mp3ctrl->jpeg_data) myfree(mp3ctrl->jpeg_data);
myfree(mp3ctrl);
mp3ctrl=0;
return res;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>0 ֧<>֣<EFBFBD><D6A3><EFBFBD>0 <20><>֧<EFBFBD><D6A7>
2025-06-27 00:32:57 +08:00
int mp3_get_support_name (const char *name)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>
2025-06-27 00:32:57 +08:00
int res=0;
2025-07-05 19:47:28 +08:00
//<2F><>ʼ<EFBFBD><CABC>mp3<70><EFBFBD><E1B9B9>
2025-06-27 00:32:57 +08:00
__mp3ctrl *mp3ctrl=mymalloc(sizeof(__mp3ctrl));
2025-07-05 19:47:28 +08:00
mymemset(mp3ctrl,0,sizeof(__mp3ctrl));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EBBBBA>
2025-06-27 00:32:57 +08:00
u32 buf_size=1024*5;
u8 *buf=mymalloc (buf_size);
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
2025-06-27 00:32:57 +08:00
ft_file_struct *file=ft_if_fopen(name,"rw");
2025-07-05 19:47:28 +08:00
//<2F><>ȡͷ<C8A1><CDB7>С
2025-06-27 00:32:57 +08:00
ft_if_fseek(file,0,SEEK_SET);
ft_if_fread(buf,1,buf_size,file);
ID3V2_TagHead *taghead;
2025-07-05 19:47:28 +08:00
u32 tagsize=0; //tag<61><67>С
2025-06-27 00:32:57 +08:00
taghead=(ID3V2_TagHead*)buf;
2025-07-05 19:47:28 +08:00
if(strncmp("ID3",(const char*)taghead->id,3)==0)//<2F><><EFBFBD><EFBFBD>ID3?
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
tagsize=((u32)taghead->size[0]<<21)|((u32)taghead->size[1]<<14)|((u16)taghead->size[2]<<7)|taghead->size[3];//<2F>õ<EFBFBD>tag <20><>С
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
//У<><D0A3><EFBFBD><EFBFBD>ʽ<EFBFBD>Ƿ<EFBFBD>֧<EFBFBD><D6A7>
2025-06-27 00:32:57 +08:00
HMP3Decoder decoder={0};
MP3FrameInfo frame_info={0};
int offset=0;
2025-07-05 19:47:28 +08:00
decoder=MP3InitDecoder(); //MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
ft_if_fseek(file,tagsize,SEEK_SET);
ft_if_fread(buf,1,buf_size,file);
2025-07-05 19:47:28 +08:00
offset=MP3FindSyncWord(buf,buf_size); //<2F><><EFBFBD><EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD><EFBFBD>Ϣ
if(offset>=0&&MP3GetNextFrameInfo(decoder,&frame_info,&buf[offset])==0)//<2F>ҵ<EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>,<2C><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{ res=0; }
else res=-1;
2025-07-05 19:47:28 +08:00
MP3FreeDecoder(decoder);//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
//<2F>ر<EFBFBD><D8B1>ļ<EFBFBD>
2025-06-27 00:32:57 +08:00
ft_if_fclose(file);
2025-07-05 19:47:28 +08:00
//<2F>ͷŻ<CDB7><C5BB><EFBFBD>
2025-06-27 00:32:57 +08:00
myfree(buf);
2025-07-05 19:47:28 +08:00
//<2F>ͷ<EFBFBD>mp3<70><EFBFBD><E1B9B9>
2025-06-27 00:32:57 +08:00
myfree(mp3ctrl);
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
2025-06-27 00:32:57 +08:00
return res;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>MP3<50><33><EFBFBD><EFBFBD>
//fname:MP3<50>ļ<EFBFBD>·<EFBFBD><C2B7>.
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//[b7]:0,<2C><><EFBFBD><EFBFBD>״̬;1,<2C><><EFBFBD><EFBFBD>״̬
//[b6:0]:b7=0ʱ,<2C><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// b7=1ʱ,<2C><>ʾ<EFBFBD>д<EFBFBD><D0B4><EFBFBD>(<28><><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,0X80~0XFF,<2C><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD>)
2025-06-27 00:32:57 +08:00
u8 mp3_play_song(u8* data,u32 size)
{
2025-07-05 19:47:28 +08:00
if (mp3ctrl) return AP_ERR;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
HMP3Decoder mp3decoder={0};
MP3FrameInfo mp3frameinfo={0};
u8 res=0;
2025-07-05 19:47:28 +08:00
u8* buffer=0; //<2F><><EFBFBD><EFBFBD>buffer
u8* readptr=0; //MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
2025-06-27 00:32:57 +08:00
u8 *data_ptr=0;
2025-07-05 19:47:28 +08:00
int offset=0; //ƫ<><C6AB><EFBFBD><EFBFBD>
int outofdata=0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD>Χ
int bytesleft=0;//buffer<65><72>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
u32 br=0;
int err=0;
DAC_UserStruct dac={0};
mp3ctrl=mymalloc(sizeof(__mp3ctrl));
2025-07-05 19:47:28 +08:00
buffer=mymalloc(MP3_FILE_BUF_SZ); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>buf<75><66>С
2025-06-27 00:32:57 +08:00
audiodev.i2sbuf1=mymalloc(2304*2);
audiodev.i2sbuf2=mymalloc(2304*2);
audiodev.tbuf=mymalloc(2304*2);
audiodev.file_seek=mp3_file_seek;
2025-07-05 19:47:28 +08:00
if(!mp3ctrl||!buffer||!audiodev.i2sbuf1||!audiodev.i2sbuf2||!audiodev.tbuf)//<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
2025-06-27 00:32:57 +08:00
{
myfree(mp3ctrl);
myfree(buffer);
myfree(audiodev.i2sbuf1);
myfree(audiodev.i2sbuf2);
myfree(audiodev.tbuf);
2025-07-05 19:47:28 +08:00
return AP_ERR; //<2F><><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
mymemset(audiodev.i2sbuf1,0,2304*2); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
mymemset(audiodev.i2sbuf2,0,2304*2); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
mymemset(mp3ctrl,0,sizeof(__mp3ctrl));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
res=mp3_get_info(data,size,mp3ctrl);
if(res==0)
{
2025-07-05 19:47:28 +08:00
//<2F><>ʼ<EFBFBD><CABC>DAC
2025-06-27 00:32:57 +08:00
dac.buff1=(u32 *)audiodev.i2sbuf1;
dac.buff2=(u32 *)audiodev.i2sbuf2;
//dac.buff_size=2304*2;
dac.buff_size=mp3ctrl->outsamples*2;
dac.rate=DAC_GetRate(mp3ctrl->samplerate);
dac.call_back=dma_tx_callback;
DAC_NormalInit (&dac);
2025-07-05 19:47:28 +08:00
mp3decoder=MP3InitDecoder(); //MP3<50><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
audiodev.status|=1<<1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
audiodev.status|=1<<0; //<2F><><EFBFBD><EFBFBD>ͣ״̬
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
if(res==0&&mp3decoder!=0)//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ɹ<EFBFBD>
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
//f_lseek(audiodev.file,mp3ctrl->datastart); //<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷ<EFBFBD><CDB7>tag<61><67>Ϣ
2025-06-27 00:32:57 +08:00
data_ptr=data+mp3ctrl->datastart;
2025-07-05 19:47:28 +08:00
//audio_start(); //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
while(res==0)
{
2025-07-05 19:47:28 +08:00
readptr=buffer; //MP3<50><33>ָ<EFBFBD><D6B8>ָ<EFBFBD><D6B8>buffer
offset=0; //ƫ<><C6AB><EFBFBD><EFBFBD>Ϊ0
outofdata=0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
bytesleft=0;
2025-07-05 19:47:28 +08:00
//res=f_read(audiodev.file,buffer,MP3_FILE_BUF_SZ,&br);//һ<>ζ<EFBFBD>ȡMP3_FILE_BUF_SZ<53>ֽ<EFBFBD>
2025-06-27 00:32:57 +08:00
br=MP3_FILE_BUF_SZ;
if (br>data+size-data_ptr) br=data+size-data_ptr;
mymemcpy (buffer,data_ptr,br);
data_ptr+=br;
2025-07-05 19:47:28 +08:00
if(res)//<2F><><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
res=AP_ERR;
break;
}
2025-07-05 19:47:28 +08:00
if(br==0) //<2F><><EFBFBD><EFBFBD>Ϊ0,˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
res=AP_OK; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
break;
}
2025-07-05 19:47:28 +08:00
bytesleft+=br; //buffer<65><72><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ЧMP3<50><33><EFBFBD><EFBFBD>?
2025-06-27 00:32:57 +08:00
err=0;
2025-07-05 19:47:28 +08:00
while(!outofdata)//û<>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣(<28><><EFBFBD>ɷ<EFBFBD><C9B7>ҵ<EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD>ַ<EFBFBD>)
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
offset=MP3FindSyncWord(readptr,bytesleft);//<2F><>readptrλ<72><CEBB>,<2C><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ַ<EFBFBD>
if(offset<0) //û<><C3BB><EFBFBD>ҵ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ַ<EFBFBD>,<2C><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
outofdata=1;//û<>ҵ<EFBFBD>֡ͬ<D6A1><CDAC><EFBFBD>ַ<EFBFBD>
}else //<2F>ҵ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
readptr+=offset; //MP3<50><33>ָ<EFBFBD><D6B8>ƫ<EFBFBD>Ƶ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>.
bytesleft-=offset; //buffer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥƫ<C8A5><C6AB><EFBFBD><EFBFBD>
err=MP3Decode(mp3decoder,&readptr,&bytesleft,(short*)audiodev.tbuf,0);//<2F><><EFBFBD><EFBFBD>һ֡MP3<50><33><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if(err!=0)
{
//printf("decode error:%d\r\n",err);
break;
}else
{
2025-07-05 19:47:28 +08:00
MP3GetLastFrameInfo(mp3decoder,&mp3frameinfo); //<2F>õ<EFBFBD><C3B5>ոս<D5B8><D5BD><EFBFBD><EFBFBD><EFBFBD>MP3֡<33><D6A1>Ϣ
if(mp3ctrl->bitrate!=mp3frameinfo.bitrate) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
mp3ctrl->bitrate=mp3frameinfo.bitrate;
}
2025-07-05 19:47:28 +08:00
mp3_fill_buffer((u16*)audiodev.tbuf,mp3frameinfo.outputSamps,mp3frameinfo.nChans);//<2F><><EFBFBD><EFBFBD>pcm<63><6D><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
if(bytesleft<MAINBUF_SIZE*2)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>2<EFBFBD><32>MAINBUF_SIZE<5A><45>ʱ<EFBFBD><CAB1>,<2C><><EFBFBD><EFBFBD><EBB2B9><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD>.
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
memmove(buffer,readptr,bytesleft);//<2F>ƶ<EFBFBD>readptr<74><72>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>buffer<65><72><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СΪ:bytesleft
//f_read(audiodev.file,buffer+bytesleft,MP3_FILE_BUF_SZ-bytesleft,&br);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
br=MP3_FILE_BUF_SZ-bytesleft;
if (br>data+size-data_ptr) br=data+size-data_ptr;
mymemcpy (buffer+bytesleft,data_ptr,br);
data_ptr+=br;
if(br<MP3_FILE_BUF_SZ-bytesleft)
{
mymemset(buffer+bytesleft+br,0,MP3_FILE_BUF_SZ-bytesleft-br);
}
bytesleft=MP3_FILE_BUF_SZ;
readptr=buffer;
}
2025-07-05 19:47:28 +08:00
while(audiodev.status&(1<<1))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
rt_thread_delay (5);
//mp3_get_curtime(audiodev.file,mp3ctrl);
u32 fpos=0;
2025-07-05 19:47:28 +08:00
if(data_ptr>data)fpos=data_ptr-data; //<2F>õ<EFBFBD><C3B5><EFBFBD>ǰ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5>ĵط<C4B5>
mp3ctrl->cursec=fpos*mp3ctrl->totsec/(size-mp3ctrl->datastart); //<2F><>ǰ<EFBFBD><C7B0><EFBFBD>ŵ<EFBFBD><C5B5>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
audiodev.totsec=mp3ctrl->totsec; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
audiodev.cursec=mp3ctrl->cursec;
audiodev.bitrate=mp3ctrl->bitrate;
audiodev.samplerate=mp3ctrl->samplerate;
2025-07-05 19:47:28 +08:00
audiodev.bps=16;//MP3<50><33>֧<EFBFBD><D6A7>16λ
if(audiodev.status&0X01)break;//û<>а<EFBFBD><D0B0><EFBFBD><EFBFBD><EFBFBD>ͣ
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
if((audiodev.status&(1<<1))==0)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
{
2025-07-05 19:47:28 +08:00
res=AP_NEXT;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD>ѭ<EFBFBD><D1AD>
outofdata=1;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ѭ<EFBFBD><D1AD>
2025-06-27 00:32:57 +08:00
break;
}
}
}
}
2025-07-05 19:47:28 +08:00
//audio_stop();//<2F>ر<EFBFBD><D8B1><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
}else res=AP_ERR;//<2F><><EFBFBD><EFBFBD>
MP3FreeDecoder(mp3decoder); //<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
if (mp3ctrl->jpeg_data) myfree(mp3ctrl->jpeg_data);
myfree(mp3ctrl);
myfree(buffer);
myfree(audiodev.i2sbuf1);
myfree(audiodev.i2sbuf2);
myfree(audiodev.tbuf);
DAC_NormalDeInit (&dac);
mp3ctrl=0;
audiodev.cursec=0;
audiodev.totsec=0;
return res;
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>0<EFBFBD>ɹ<EFBFBD>
2025-06-27 00:32:57 +08:00
char *mp3_get_name(void)
{
if(mp3ctrl)
return (char *)mp3ctrl->title;
else return 0;
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD>ط<EFBFBD>0<EFBFBD>ɹ<EFBFBD>
2025-06-27 00:32:57 +08:00
char *mp3_get_artist(void)
{
if(mp3ctrl)
return (char *)mp3ctrl->artist;
else return 0;
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD>ŵ<EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>1<EFBFBD>ɹ<EFBFBD>
2025-06-27 00:32:57 +08:00
int mp3_get_time(int *totsec,int *cursec)
{
if(mp3ctrl)
{
if(totsec) *totsec=mp3ctrl->totsec;
if(cursec) *cursec=mp3ctrl->cursec;
return 1;
}
else
{
return 0;
}
}
__audiodev *mp3_getAudiodev (void)
{
return &audiodev;
}
__mp3ctrl *mp3_getMp3Info (void)
{
return mp3ctrl;
}
void mp3_stop (void)
{
mp3_getAudiodev()->status=0;
}
void mp3_play (void)
{
2025-07-05 19:47:28 +08:00
//<2F><>ͣ<EFBFBD><CDA3>
2025-06-27 00:32:57 +08:00
if (mp3_getAudiodev()->status&1)
{
mp3_getAudiodev()->status&=(~1);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
else
{
mp3_getAudiodev()->status|=1;
}
}
void mp3_suspend (void)
{
mp3_getAudiodev()->status|=1;
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int mp3_set_vol(int vol)
{
if(vol>MP3_VOL_MAX) vol=MP3_VOL_MAX;
else if(vol<0) vol=0;
g_vol=vol;
return 0;
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int mp3_add_val(int vol)
{
vol=vol+g_vol;
if(vol>MP3_VOL_MAX) vol=MP3_VOL_MAX;
else if(vol<0) vol=0;
g_vol=vol;
return 0;
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int mp3_sub_val(int vol)
{
vol=g_vol-vol;
if(vol>MP3_VOL_MAX) vol=MP3_VOL_MAX;
else if(vol<0) vol=0;
g_vol=vol;
return 0;
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int mp3_get_vol(void)
{
return g_vol;
}