📄 main.c
字号:
/*****************************************************/
/* mp3 player V2.3 */
/* Description : A mp3 player support lrc sd & U disk */
/* Platform : SourceInsight + WinARM20060606 7s256 */
/* Author : Michael Zhang - 章其波 */
/* Email : sudazqb@163.com */
/* MSN : zhangqibo_1985@hotmail.com */
/* Date : 2007-12-08 */
/* NOT FOR COMMERCIAL USE, ALL RIGHT RESERVED! */
/*****************************************************/
/********************* old ***************************/
/* MP3/Wma/Midi播放器 */
/* 环境WinAVR 20060421 */
/* 作者:Bozai(章其波) */
/* E-mail:sudazqb@163.com */
/* 2006年12月12日 */
/*************************************************************/
/* 20081002: for LPC2132 mp3 board */
/* 20071222: add CH375 support for s64 mp3 board(from mcuzone) */
/* 20071212: modify code for mcuzone's mp3 player */
/* 20071208: modify codes for ARM platform (AT91SAM7S256) */
/* 20071122: add teminal control code */
/* 20071121: solve glitch problem when playing 320Kbps files */
/* 20071109: add & modify function for any directory music file playing */
/* 20071103: add function for lyric display */
#if 0
#include <stdio.h> /* I/O Functions */
#include "Board.h"
#include "global.h"
#include "serial.h"
#include "time.h"
#include "MMC_SD.h"
#include "VS1003B.h"
#include "LCD.h"
#include "FAT.h"
#include "LCD_APP.h"
#include "LCD_ASCII.h"
#include "LCD_GBK.h"
#include "stdlib.h"
#include "CH375.h"
#include "port.h"
#endif
#include "global.h"
#include "serial.h"
//#include "time.h"
#include "MMC_SD.h"
#include "VS1003B.h"
#include "LCD.h"
#include "FAT.h"
#include "LCD_APP.h"
#include "LCD_ASCII.h"
#include "LCD_GBK.h"
//#include "stdlib.h"
//#include "CH375.h"
//#include "port.h"
#if 0
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef float fp32;
typedef double fp64;
typedef unsigned char INT8U;
typedef signed char INT8;
typedef unsigned short INT16U;
typedef signed short INT16;
typedef unsigned int INT32U;
typedef signed int INT32;
typedef float FP32;
typedef double FP64;
#endif
//AT91S_PIO * pPIO = AT91C_BASE_PIOA; /* Global Pointer to PIO */
#define uint unsigned short
//p0.25
#define KEY_PLAY (0x01 << 25)
#define KEY_PLAY_GPIO() PINSEL1 &= ~(0x03 <<18)
#define KEY_PLAY_IN() IO0DIR &=~KEY_PLAY
#define KEY_PLAY_STATE() (IO0PIN & KEY_PLAY)
//P0.26
#define KEY_UP (0x01 << 26)
#define KEY_UP_GPIO() PINSEL1 &= ~(0x03 <<20)
#define KEY_UP_IN() IO0DIR &=~KEY_UP
#define KEY_UP_STATE() (IO0PIN & KEY_UP)
//P0.27
#define KEY_DOWN (0x01 << 27)
#define KEY_DOWN_GPIO() PINSEL1 &= ~(0x03 <<22)
#define KEY_DOWN_IN() IO0DIR &=~KEY_DOWN
#define KEY_DOWN_STATE() (IO0PIN & KEY_DOWN)
//P0.28
#define KEY_VOLD (0x01 << 28)
#define KEY_VOLD_GPIO() PINSEL1 &= ~(0x03 <<24)
#define KEY_VOLD_IN() IO0DIR &=~KEY_VOLD
#define KEY_VOLD_STATE() (IO0PIN & KEY_VOLD)
//P0.29
#define KEY_VOLU (0x01 << 29)
#define KEY_VOLU_GPIO() PINSEL1 &= ~(0x03 <<26)
#define KEY_VOLU_IN() IO0DIR &=~KEY_VOLU
#define KEY_VOLU_STATE() (IO0PIN & KEY_VOLU)
//P0.30
#define KEY_MODE (0x01 << 30)
#define KEY_MODE_GPIO() PINSEL1 &= ~(0x03 <<28)
#define KEY_MODE_IN() IO0DIR &=~KEY_MODE
#define KEY_MODE_STATE() (IO0PIN & KEY_MODE)
//LCD_BL P0.10
#define LCD_BL (0x01 << 10)
#define LCD_BL_GPIO() PINSEL0 &= ~(0x03 <<20)
#define LCD_BL_OUT() IO0DIR |= LCD_BL
#define LCD_BL_SET() IO0SET |= LCD_BL
#define LCD_BL_CLR() IO0CLR |= LCD_BL
//LED P1.21
#define LED (0x01 << 21)
#define LED_GPIO() PINSEL2 &= ~(0x02 <<2)
#define LED_OUT() IO1DIR |= LED
#define LED_SET() IO1SET |= LED
#define LED_CLR() IO1CLR |= LED
#define ENTER_KEY 0x0d
#define BACK_KEY 0x08
#define ESC_KEY 0x1b
#define MAX 64
#define MODE (1<<17)
#define STOP
#define NEXT (1<<18)
#define UP (1<<23)
#define DOWN (1<<24)
#define PREV (1<<19)
#define MP3 1
#define WMA 2
#define MID 3
#define WAV 4
//mode
#define REPET_ALL 0
#define REPET_ONE 1
#define RANDOM 2
#if 1
/* enum for ICON */
enum IconTag
{
Playing,Pause,RepetAll,RepetOne,Shuffle,Time,Music,Speaker
};
/* Long name buffer and flag */
extern unsigned char LongNameBuffer[MAX_LONG_NAME_SIZE];
extern unsigned char LongNameFlag;
/* indicate if the file system is FAT32 , ortherwise it is FAT16, note FAT12 is not supported */
extern BYTE FAT32_Enable;
extern WORD SectorsPerClust;//每簇扇区数
extern WORD FirstDataSector;//第一个数据扇区数
//struct FileInfoStruct FileInfo;//文件信息
struct direntryBytes MusicInfo; /* Music file information, 32Bytes short directory record, contain the short name and others */
struct direntryBytes LrcInfo; /* lyric file information, 32Bytes short directory record, the short name and others */
/* The path of the music file & lyric file , caution: each driectory should long longer than 8, that is not support long name*/
#if FIX_DIRECTORY
#define MUSIC_PATH "\\music"
#endif
#define LRC_PATH "\\lrc"
//void (*BootLoaderEntry)(void) = 0xf800; /* boot loader entry, bootloader size: 2048Bytes */
uint16 totalsongs; /* total number of songs*/
uint8 type; /* current song's file type, mp3 wma mid or wav */
uint8 lrc =0; /* Gloable variable to indicate wether the songs has a lyric file, 1 means have */
uint8 HanziEnable = 0; /* Gloable variable to indicate wether the firmware are exist, and 1 means exist */
/* Time tag structure */
struct LrcStruct_s {
struct LrcStruct_s * next; /* the next node */
uint32 time; /* Time */
uint16 eeaddr; /* Address, start with 0, value greater than MAXLRCDATSIZE is the eeprom address*/
};
struct LrcStructHead_s {
struct LrcStruct_s *header; /* Pointer to the first node of time tag struct */
#define TI_LEN 32
uint8 title[TI_LEN]; /* Title */
#define AR_LEN 16
uint8 artist[AR_LEN]; /* Artist */
uint16 offset; /* Offset */
uint8 sign; /* "1" means "+", and "0" means "-" */
};
#define DEBUG 0 /* Macro for DEBUG, if 1 DEBUG message will show throw the UART */
struct LrcStructHead_s LrcStructHead; /* Gloable struct variable to record the lyric info */
/* Use to record the time tag info */
#define MAXITEM 120
uint8 lrcbuffer[sizeof(struct LrcStruct_s) * MAXITEM];
/* Use to record the lyric data */
#define MAXLRCDATSIZE 4096 /* Max data size in SRAM, other will be store in EEPROM of ATmega64 */
uint8 lrcdatbuf[MAXLRCDATSIZE];
uint8 track[128]; /* stroe the information of songs (bit set indicate songs has been played) */
void ClearTrackInfo() /* cleare the array track[128] */
{
uint8 i;
for(i=0;i<128;i++)track[i] = 0;
}
uint8 SetTrack(uint16 songs)/* set the track bit, return 1 means the song has been played */
{
uint8 byte_offset;
uint8 bit_offset;
songs--;
byte_offset = songs/8;
bit_offset = songs%8;
if(track[byte_offset] & (1<<bit_offset))return 1;
else
{
track[byte_offset] |= 1<<bit_offset;
return 0;
}
}
/*void nextline()
{
uart0_putc(0x0d);
uart0_putc(0x0a);
}*/
void Delay(uint16 n)//延时
{
//soft_delay_ms(n);
while(n--);
}
#if 1
uint8 FLGG=0;
void __irq Timer0_Exception(void)
{
if(FLGG==0 ) { IO0SET=LED; FLGG=1;}
else {IO0CLR=LED; FLGG=0; }
T0IR = 0x01;
VICVectAddr = 0;
}
#endif
#if 1
void Time0Init(void)
{
T0PR=0;
T0MCR = 0x03;
T0MR0 = 0xffffffff;
T0TCR = 0x03;
T0TCR = 0x01;
//VICIntEnClr = 0xffffffff;
VICIntSelect = 0x00;
VICVectCntl0 = (0x20 | 0x04);
//VICVectAddr0 = (uint32) Timer0_Exception;
//VICIntEnable =( 0x0ff <<1); //04
}
#endif
//Timer initialization offer seed of the srandom()
uint8 strcomp(uint8 * src, uint8 * dst) /* String compare */
{
while(*src)
{
if(*src++ != *dst++)return 0;
}
return 1;
}
uint8 strcomp_noncase(uint8 * src, uint8 * dst)/*we should make sure the src is upcase*/
{
uint8 * p1 = src, * p2 = dst;
while(*p1)
{
if((*p1 == *p2) || ((*p1<*p2)&&((*p2-*p1) == 0x20 )) )
{
p1 ++;
p2 ++;
}
else return 0;
}
return 1;
}
/* Lyric proccess fuction */
#if FIX_DIRECTORY
uint8 LrcProc(uint8 *LongNameBuffer) /* Parameter is the song's long name or short name, note: do not contain the extention*/
#else
uint8 LrcProc(uint8 *LongNameBuffer,WORD music_record_addr) /* Parameter is the song's long name or short name, note: do not contain the extention*/
#endif
{
#if 1
/* lyric time tag struct pointer for process*/
struct LrcStruct_s * LrcStruct_p;
struct LrcStruct_s * LrcStruct_p_up, * LrcStruct_p_temp,* LrcStruct_p_down;
struct LrcStruct_s * LrcStruct_p_header;
uint16 lrcaddr; /* The address to store each lyric */
uint8 part; /* the sector number of one cluster */
uint16 i; /* loop variable for gerneral perpus */
uint16 j;
uint8 temp; /* temp variable */
uint8 * buffer; /* buffer pointer, later will use malloc to get the data area for it*/
uint16 min,sec,ms; /* temp variable for time tag process, minter, second, and milisecond */
uint8 sector; /* sector number to record current sector, with variable j to determine wether the file is ended*/
uint8 totalsect; /* total sectors the file contains */
uint16 leftbytes; /* how many data contained in the last sector */
uint32 p; /* cluster number of file, next ,etc */
uint8 mscnt; /* counter for ms, you konw 2.3 means 2300ms not 2003ms, so need this variable to determin this*/
LrcStructHead.header = (struct LrcStruct_s *)lrcbuffer; /* set lrc info struct 's header to the buffer */
#if FIX_DIRECTORY
if(SearchLrc(LRC_PATH,LongNameBuffer,&LrcInfo)==0) /* search the path specified, and if found lyric file it will return 0*/
#else
if(SearchLrc(LRC_PATH,LongNameBuffer,&LrcInfo,music_record_addr)==0) /* search the path specified, and if found lyric file it will return 0*/
#endif
{
printf_P(("\r\n*****************************************************\r\n"));
printf_P(("Found LRC file!\r\n"));
printf_P(("\r\nAnalyzing LRC file ...........\r\n"));
lrc = 1; /* Set the flag */
lrcaddr = 0; /* Clear the address */
LrcStruct_p = LrcStructHead.header; /* intialize the sigle direction node */
for(i=0;i<MAXITEM-1;i++)
{
LrcStruct_p->next = LrcStruct_p + 1;
LrcStruct_p = LrcStruct_p->next;
}
LrcStruct_p->next = 0;
LrcStruct_p = LrcStructHead.header;
LrcStructHead.offset = 0; /* clear the lyc info struct */
LrcStructHead.title[0] = '\0';
LrcStructHead.artist[0] = '\0';
buffer = malloc(520); /* allocate memory for read the lyric file */
if(buffer==0)
{
#if DEBUG
printf_P(("ERROR: No enough memory!\r\n"));
#endif
return 1;
}
p = get16_little(LrcInfo.deStartCluster)+(((DWORD)get16_little(LrcInfo.deHighClust))<<16); /* Calculate the first cluster of the lyric file */
totalsect = get32_little(LrcInfo.deFileSize)/512; /*计算扇区数 //calculate the total sectors */
leftbytes = get32_little(LrcInfo.deFileSize)%512; /*计算剩余的字节数 //calculate the left bytes */
sector=0; /* clear the sector counter */
/* here to start analyze the lyric file */
while(1)
{
for(part=0;part<SectorsPerClust;part++) /* first loop for read a sector of a culster */
{
if(FAT_LoadPartCluster(p,part,buffer))
{
#if DEBUG
printf_P(("ERROR: Failed to read one sector\r\n"));
#endif
free(buffer);
return 1;
}
for(j=0;j<512;) /* second loop for analyze each byte of the sector */
{
if(sector == totalsect && j == leftbytes) /* see if it is the end of file */
{
part = SectorsPerClust; /* next loop it will get out */
break;
}
if(buffer[j] == '[') /* if it is the "[" : the tag start */
{
#if DEBUG
printf_P(("found tag start ["));
#endif
/**********************************************************************************************************/
i = 0;
if(strcomp_noncase("TI:",&buffer[j+1])) /* string compare to check if this is a title tag */
{
j+=4; /* count add 4 */
while(1) /* store the title */
{
temp = buffer[j++];
if(temp == 0x0d || temp == 0x0a || temp == ']' || i> (TI_LEN - 2)) /* title ended */
break;
LrcStructHead.title[i++] = temp;
}
LrcStructHead.title[i] = 0; /* need a 0 to end the string */
#if DEBUG
printf_P((" found title tag: %s ]\r\n"),LrcStructHead.title);
#else
printf_P(("Title : %s \r\n"),LrcStructHead.title);
#endif
}
/**********************************************************************************************************/
else if(strcomp_noncase("AR:",&buffer[j+1])) /* string compare to check if this is a artist tag */
{
j+=4; /* count += 4 */
while(1) /* store the content */
{
temp = buffer[j++];
if(temp == 0x0d || temp == 0x0a || temp == ']' || i>(AR_LEN - 2)) /* tag ended */
break;
LrcStructHead.artist[i++] = temp;
}
LrcStructHead.artist[i] = 0; /* need a 0 to end the string */
#if DEBUG
printf_P((" found artist tag: %s ]\r\n"),LrcStructHead.artist);
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -