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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|