📄 lrc.c
字号:
/******************************************************************/
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*******************************************************************
File : lrc.c
Desc : 歌词处理
Author :
Date : 2007-08-24
Notes :
$Log :
*********************************************************************/
/**********************include**********************/
#include "include.h"
#include "lrc.h"
#include "../../../system/gui/guictrl/list.h"
#include "system.h"
#include "../../browser/BrowserStruct.h"
#include "../../browser/browsermacro.h"
/**********************define**********************/
#define a2i(a) (a-'0')
/**********************extern**********************/
UILISTENTRY *LrcCurrLine = NULL;
extern SYS_FILE_INFO AudioFileInfo;
/**********************global Variable**********************/
UILIST* LrcTimeLable = NULL;
UILIST* LrcContentTable = NULL;
UILISTFTABLE LrcTimeListFunc;
UILISTFTABLE LrcContentListFunc;
MY_FILE *hLrcFile;
void LrcDeInit(void);
/**********************Lrc Function**********************/
UILISTENTRY* LrcFindCurrLine(UINT32 TimeLable1)
{
UILISTENTRY *node;
LRCLISTITEM *LrcData = NULL;
if (LrcTimeLable)node = LrcTimeLable->last;
else return NULL;
while (node)
{
if (node->data)
{
LrcData = (LRCLISTITEM*)node->data;
if ((LrcData->TimeLable <= TimeLable1) || (NULL == node->prev))
return node;
else
node = node->prev;
}
}
return NULL;
}
INT32 LrcTimeCmpFunc(const void* TimeLable1, const void* TimeLable2)
{
LRCLISTITEM* ItemAdd = (LRCLISTITEM*)TimeLable1;
LRCLISTITEM* ItemCurr = (LRCLISTITEM*)TimeLable2;
return (INT32)(ItemAdd->TimeLable - ItemCurr->TimeLable);
}
void LrcFreeFunc(void* buf)
{
RKfree(buf);
}
/*******************************************************************************
*0:非有效时间标签
*1:型如[mm:ss]的时间标签
*2:型如[mm:ss.msms]的时间标签
*******************************************************************************/
INT16U GetTimeLable(char* start)
{
if (start[0] == 0x005b && start[3] == 0x003a &&
(start[1] >= '0' && start[1] <= '9') && (start[2] >= '0' && start[2] <= '9')
&& (start[4] >= '0' && start[4] <= '9') && (start[5] >= '0' && start[5] <= '9')
)
{
if (start[6] == 0x005d)
{
return 2;
}
else if (start[9] == 0x005d && (start[6] == 0x003a || start[6] == 0x002e))
{
return 1;
}
}
return 0;
}
/*******************************************************************************
*找出第一个有效的时间标签
*******************************************************************************/
char* LrcCheckStart(char* pBuf, char* pBufend)
{
while (pBuf <= pBufend)
{
if (!GetTimeLable((char*)pBuf))
pBuf++;
else
break;
}
return pBuf;
}
UINT16 LrcTrans(char* pbuf)
{
return (a2i(pbuf[1])*600 + a2i(pbuf[2])*60 + a2i(pbuf[4])*10 + a2i(pbuf[5]));
}
UINT16 LrcGetContent(char* pbuf, char* pbufend)
{
UINT16 ContentLen = 0;
while (pbuf < pbufend)
{
ContentLen++;
pbuf++;
if ((('[' == *pbuf) && (0x80 > *(pbuf - 1))) || ('\n' == *pbuf))//hj2008.3.7 gbk中ascii码ItemAdd->TimeLable
break;
}
return ContentLen;
}
#ifdef LRC_DEBUG
void lrcdebug(void)
{
UILISTENTRY* pListEntry = LrcTimeLable->first;
LRCLISTITEM *pCurrTimeItem;
do
{
pCurrTimeItem = (LRCLISTITEM*)pListEntry->data;
TR("[%d]: %s", pCurrTimeItem->TimeLable, (char*)pCurrTimeItem->pLrcContent);
pListEntry = pListEntry->next;
}
while (pListEntry);
}
#endif
BOOLEAN LrcSetup(char* FileBuf, size_t size)
{
char* pBuf;
INT16 LrcType;
UINT16 ContentLen;
UINT16 LableCnt = 0;
LRCLISTITEM* ItemAdd;
pBuf = LrcCheckStart(FileBuf, &FileBuf[size-1]);
if (&FileBuf[size-1] == pBuf)
return FALSE;
do
{
LrcType = GetTimeLable(pBuf);
if (LrcType)
{
ItemAdd = (LRCLISTITEM*)RKmalloc(sizeof(LRCLISTITEM));
ItemAdd->TimeLable = LrcTrans(pBuf);
ItemAdd->pLrcContent = NULL;
ListAddItem(LrcTimeLable, ItemAdd);
pBuf += (LrcType - 1) ? 7 : 10;
LableCnt++;
}
else
{
ContentLen = LrcGetContent(pBuf, &FileBuf[size-1]);
if (ContentLen)
{
UINT16 cnt;
char *LrcContent = (char*)RKmalloc(2 * (ContentLen + 1));
LRCLISTITEM *pCurrTimeItem;
UILISTENTRY *CurItem = LrcTimeLable->first;
RKmemcpy(&LrcContent[ContentLen], pBuf, ContentLen);
LrcContent[ContentLen*2] = 0;
Gbk2Unicode((WCHAR*)LrcContent, (INT8U*)&LrcContent[ContentLen]);
ListAddItem(LrcContentTable, LrcContent);
while (CurItem)
{
pCurrTimeItem = (LRCLISTITEM*)CurItem->data;
if (NULL == pCurrTimeItem->pLrcContent)
pCurrTimeItem->pLrcContent = LrcContent;
CurItem = CurItem->next;
}
}
pBuf += ContentLen;
}
}
while (LrcType || ContentLen);
return TRUE;
}
void LFNameUpward(UINT16* LName, UINT16 len)
{
UINT16 cnt = 0;
UINT16 diff = (INT16)('a' -'A');
while (cnt < len)
{
if ((LName[cnt] >= 0x0041) && (LName[cnt] <= 0x005a))//4A到Z 转到a到z
LName[cnt] += diff;
cnt++;
}
}
UINT16 LrcLFnameCmp(UINT16* Lname1, UINT16* Lname2, UINT16 len)
{
UINT16 cnt = 0;
LFNameUpward(Lname1, len);
LFNameUpward(Lname2, len);
while (cnt < len)
{
if (Lname1[cnt] != Lname2[cnt])
return 1;
if ((!Lname1[cnt]) || (!Lname2[cnt]))
break;
cnt++;
}
return 0;
}
MY_FILE* LrcGetFile(void)
{
char FileName[12];
UINT16 pLname[FS_MAX_FILENAME_LEN];
UINT16 LRCUnicode[] = {0X004C, 0X0052, 0X0043};
char PathName[FS_MAX_PATH_LEN];
UINT16 cnt = 0;
FS_FDT Rt;
FS_FIND_DATA FindData;
MY_FILE* hLrc = NULL;
FileName[11] = 0;
while (AudioFileInfo.LongFileName[cnt])
cnt++;
while (cnt && (0x002e != AudioFileInfo.LongFileName[--cnt]));
if (!cnt)return 0;
FS_FindFirst(&Rt, &FindData, AudioFileInfo.Path, "LRC");
while (1)
{
RKmemcpy(PathName, AudioFileInfo.Path, FS_MAX_PATH_LEN);
RKmemcpy(FileName, (char*)Rt.Name, 11);
RKstrcat(PathName, FileName);
hLrc = FS_fopen(PathName, "rb");
if (hLrc)
{
RKmemset(pLname, 0, sizeof(UINT16)*FS_MAX_FILENAME_LEN);
FS_GetLongFileName(hLrc, (char*)pLname);
if (0 == pLname[0])
{
if (0 == LrcLFnameCmp((UINT16*)Rt.Name, (UINT16*)AudioFileInfo.Name, 4))
return hLrc;
}
else if (0 == LrcLFnameCmp(pLname, AudioFileInfo.LongFileName, cnt))
{
return hLrc;
}
FS_fclose(hLrc);
}
if (FS_RETURN_OK != FS_FindNext(&Rt, &FindData, "LRC"))
break;
}
return FALSE;
}
BOOLEAN LrcInit(void)
{
//071106,huangsl,修改堆栈意外改写的BUG.
//char pathname[FS_MAX_PATH_LEN+12];
size_t size;
char* FileBuf;
LrcDeInit();
hLrcFile = LrcGetFile();
if (NULL == hLrcFile)
return FALSE;
#ifdef BOARD
size = hLrcFile->FileSize;
#else
size = RKFSFileGetSize(hLrcFile);
#endif
FileBuf = (char*)RKmalloc(size);
if (NULL == FileBuf)
goto InvalideLrc;
#ifdef BOARD
if (size != RKFSFileRead(FileBuf, size, hLrcFile))
goto InvalideLrc;
#else
size = RKFSFileRead(FileBuf, size, hLrcFile);
#endif
RKFSFileClose(hLrcFile);
LrcTimeListFunc.CompareItem = LrcTimeCmpFunc;
LrcTimeListFunc.FreeItem = LrcFreeFunc;
LrcContentListFunc.CompareItem = NULL;
LrcContentListFunc.FreeItem = LrcFreeFunc;
LrcTimeLable = ListCreate(LS_OWNSITEMS | LS_SORTED, &LrcTimeListFunc);
LrcContentTable = ListCreate(LS_OWNSITEMS, NULL);
if ((NULL == LrcTimeLable) || (NULL == LrcContentTable))
goto InvalideLrc;
if (FALSE == LrcSetup(FileBuf, size))
goto InvalideLrc;
#ifdef LRC_DEBUG
lrcdebug();
#endif
RKfree(FileBuf);
LrcCurrLine = NULL;//LrcTimeLable->first;
return TRUE;
InvalideLrc:
RKfree(FileBuf);
return FALSE;
}
void LrcDeInit(void)
{
ListDestroy(LrcTimeLable);
ListDestroy(LrcContentTable);
LrcCurrLine = NULL;
LrcTimeLable = NULL;
LrcContentTable = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -