MP3歌词lrc文件读取算法 C语言源程序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
■ 时间标签(Time-tag)
形式为"[mm:ss]"或"[mm:ss.fff]"(分钟数:秒数)。数字须为非负整数, 比如 "[12:34.5]"是有效的,而"[0x0C:-34.5]"无效。
它可以位于某行歌词中的任意位置。一行歌词可以包含多个时间标签(比如歌词中的迭 句部分)。根据这些时间标签,用户端程序会按顺序依次高亮显示歌词,从而实现卡拉 OK 功能。另外,标签无须排序。
Lrc 歌词文本中含有两类标签:
一是标识标签,其格式为“[标识名:值]”主要包含以下预定义的标签: [ar:歌手名]、[ti:歌曲名]、[al:专辑名]、[by:编辑者(指 lrc 歌词的制作人)]、[offset: 时间补偿值] (其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢 的,但多数的 MP3 可能不会支持这种标签)。
凡是标签,且被冒号分隔的两部分都为非负数,则应认为是时间标签。因此,对于非标 准形式(非“[mm:ss]”)的时间标签也应能识别(如“[0:0]”)。凡是标签,且非时间标 签的,应认为是标识标签。标识名中大小写等价。
·为了向后兼容,应对未定义的新标签作忽略处理。另应对注释标签([:])后的同一行内 容作忽略处理。 应允许一行中存在多个标签,并能正确处理。应能正确处理未排序的标签。
m_csArtist; m_csTitle; m_csAlbum; m_csBy; m_lOffset; m_csKey;
// Lead time of the lyric
public: BOOL Load(LPCWSTR szFileName, LONG lUserOffset = 0);
ahead; if < 0: put off void UnLoad();
// If lUserOffset > 0:
2
BOOL GetItemByID(DWORD dwItemID, LineLyric &lyric);
// Get the lyric data
by dwItemID
DWORD GetTimeByID(DWORD dwItemID);
// Get the lyric's start
5
源自文库
m_csKey.Empty(); m_LyricList.RemoveAll(); m_dwLineNum = 0; m_bAnalyseTag = TRUE; m_lUserOffset = 0; }
BOOL CLyric::GetItemByID(DWORD dwItemID, LineLyric &lyric) {
{
DWORD dwStartTime; // The unit is millisecond
CString
csLyric;
} LineLyric, *PLineLyric;
class CLyric { public:
CLyric(); ~CLyric();
CString CString CString CString LONG CString
■ 标识标签(ID-tags)
其格式为"[标识名:值]"。大小写等价。以下是预定义的标签。 [ar:艺人名] [ti:曲名] [al:专辑名] [by:编者(指编辑 LRC 歌词的人)] [offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显 示快慢的。分钟:秒.毫秒]歌词 用记事本按照上述格式写好后,将拓展名改为 lrc 即可做出该文件.LRC 歌词是一种通过编辑
time by dwItemID
LONG GetItemIDByTime(DWORD dwTime, DWORD dwStartLineID = 0);// Search
the line index by time(in milliseconds) begin at nStartLineID
DWORD GetTotalNum() { return m_dwLineNum; }
#define MAX_LYRIC_LINE_LEN #define MAX_LYRIC_LEN #define MAX_LYRIC_LINE_NUM #define MAX_LYRIC_TIME_LEN
512 128
5000 30
CLyric::CLyric() {
m_bValid = FALSE; m_lUserOffset = 0; }
BOOL IsValid() { return m_bValid; }
private:
BOOL
m_bValid;
CArray<LineLyric> m_LyricList;
DWORD m_dwLineNum;
BOOL
m_bAnalyseTag;
LONG
m_lUserOffset;
__forceinline BOOL ReadALine(FILE *fp, CHAR *buff, INT bufflen, INT &readlen); __forceinline void AnalyseLine(CHAR *szLine, INT nLength); __forceinline BOOL CheckTag(CHAR *szText); __forceinline LONG GetStartTime(CHAR *szTime);
if (readlen <= 0) continue;
AnalyseLineW(wstr, readlen); } while (m_dwLineNum < MAX_LYRIC_LINE_NUM); } else { fseek(fp, 0L, SEEK_SET); CHAR str[MAX_LYRIC_LINE_LEN]; do {
return FALSE;
4
}
fseek(fp, sizeof(WCHAR), SEEK_SET); WCHAR wstr[MAX_LYRIC_LINE_LEN]; do {
if (!ReadALineW(fp, wstr, MAX_LYRIC_LINE_LEN, readlen)) break;
以下附上C++实现代码,支持ANSI和Unicode格式,超强纠错。
-----------------------------------------------------Lyric.h-----------------------------------------------------
typedef struct
__forceinline DWORD Find(DWORD dwTime); matched the time };
// return the line ID
-----------------------------------------------------Lyric.cpp----------------------------------------------------#include "Lyric.h"
return m_LyricList[dwTotalItem-1].dwStartTime; } }
3
CLyric::~CLyric() { }
BOOL CLyric::Load(LPCWSTR szFileName, LONG lUserOffset) {
UnLoad();
FILE INT
*fp; readlen;
m_lUserOffset = lUserOffset; fp = _tfopen(szFileName, _T("r")); if (fp == NULL) {
二是时间标签,形式为“[mm:ss]”或“[mm:ss.fff]”(分钟数:秒数:毫秒数),时间标 签需位于某行歌词中的句首部分,一行歌词可以包含多个时间标签(比如歌词中的迭句部 分)。当歌曲播放到达某一时间点时,MP3 就会寻找对应的时间标签并显示标签后面的歌词 文本,这样就完成了“歌词同步”的功能。
__forceinline BOOL ReadALineW(FILE *fp, WCHAR *buff, INT bufflen, INT &readlen);
__forceinline void AnalyseLineW(WCHAR *szLine, INT nLength); __forceinline BOOL CheckTagW(WCHAR *szText); __forceinline LONG GetStartTimeW(WCHAR *szTime);
fclose(fp);
m_bValid = TRUE;
return TRUE; }
void CLyric::UnLoad() {
m_bValid = FALSE; m_csArtist.Empty(); m_csTitle.Empty(); m_csAlbum.Empty(); m_csBy.Empty(); m_lOffset = 0;
return FALSE; }
WORD wUnicode_tag = 0; DWORD dwReadLen = 0; try {
dwReadLen = fread((void *)&wUnicode_tag, sizeof(WCHAR), 1, fp); } catch (...) {
printf("CLyric::Load: fread Exception: %s!\r\n", szFileName); fclose(fp); return FALSE; } if (dwReadLen != 1) { printf("CLyric::Load: read file %s failed!\r\n", szFileName); fclose(fp); return FALSE; } if (wUnicode_tag == 0xfeff) // unicode file { fclose(fp); fp = _tfopen(szFileName, _T("rb")); if (fp == NULL) {
if (dwItemID < (DWORD)m_LyricList.GetSize()) {
lyric = m_LyricList[dwItemID]; return TRUE; } else { return FALSE; } }
DWORD CLyric::GetTimeByID(DWORD dwItemID) {
if (!ReadALine(fp, str, MAX_LYRIC_LINE_LEN, readlen)) break;
if (readlen <= 0) continue;
AnalyseLine(str, readlen); } while (m_dwLineNum < MAX_LYRIC_LINE_NUM); }
1
器把歌词按歌曲歌词出现的时间编辑成一个文件,在播放歌曲时同步依次显示出来的一种歌 词文件。把歌曲和 LRC 歌词命为相同的文件名放在同一目录下,用带显示歌词功能的播放器 播放歌曲时歌词就可以同步显示显示,方便查看和学歌。
(供程序员阅读参考)
以下列出了开发支持 LRC 格式的软件时应遵守的一些标准。无论是否在行首,行内凡具 有“[*:*]”形式的都应认为是标签。(注意:其中的冒号并非全角字符“:”) 凡是标签都不应显示。
DWORD dwTotalItem = (DWORD)m_LyricList.GetSize(); if (dwTotalItem == 0)
return 0;
if (dwItemID < dwTotalItem) {
return m_LyricList[dwItemID].dwStartTime; } else {
Lrc 歌词文件格式说明
扩展名为 Lrc 格式的文件,是 MP3 播放器唯一能够识别的歌词文件,在 MP3 数码播放器 或千千静听中可以区同步显示歌词。
它是一种包含着“[*:*]”形式的“标签(tag)”的、基于纯文本的歌词专用格式。最早 由郭祥祥先生(Djohan)提出并在其程序中得到应用。这种歌词文件既可以用来实现卡拉 OK 功能(需要专门程序),又能以普通的文字处理软件查看、编辑。当然,实际操作时通常是 用专门的 LRC 歌词编辑软件进行高效编辑的。
形式为"[mm:ss]"或"[mm:ss.fff]"(分钟数:秒数)。数字须为非负整数, 比如 "[12:34.5]"是有效的,而"[0x0C:-34.5]"无效。
它可以位于某行歌词中的任意位置。一行歌词可以包含多个时间标签(比如歌词中的迭 句部分)。根据这些时间标签,用户端程序会按顺序依次高亮显示歌词,从而实现卡拉 OK 功能。另外,标签无须排序。
Lrc 歌词文本中含有两类标签:
一是标识标签,其格式为“[标识名:值]”主要包含以下预定义的标签: [ar:歌手名]、[ti:歌曲名]、[al:专辑名]、[by:编辑者(指 lrc 歌词的制作人)]、[offset: 时间补偿值] (其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢 的,但多数的 MP3 可能不会支持这种标签)。
凡是标签,且被冒号分隔的两部分都为非负数,则应认为是时间标签。因此,对于非标 准形式(非“[mm:ss]”)的时间标签也应能识别(如“[0:0]”)。凡是标签,且非时间标 签的,应认为是标识标签。标识名中大小写等价。
·为了向后兼容,应对未定义的新标签作忽略处理。另应对注释标签([:])后的同一行内 容作忽略处理。 应允许一行中存在多个标签,并能正确处理。应能正确处理未排序的标签。
m_csArtist; m_csTitle; m_csAlbum; m_csBy; m_lOffset; m_csKey;
// Lead time of the lyric
public: BOOL Load(LPCWSTR szFileName, LONG lUserOffset = 0);
ahead; if < 0: put off void UnLoad();
// If lUserOffset > 0:
2
BOOL GetItemByID(DWORD dwItemID, LineLyric &lyric);
// Get the lyric data
by dwItemID
DWORD GetTimeByID(DWORD dwItemID);
// Get the lyric's start
5
源自文库
m_csKey.Empty(); m_LyricList.RemoveAll(); m_dwLineNum = 0; m_bAnalyseTag = TRUE; m_lUserOffset = 0; }
BOOL CLyric::GetItemByID(DWORD dwItemID, LineLyric &lyric) {
{
DWORD dwStartTime; // The unit is millisecond
CString
csLyric;
} LineLyric, *PLineLyric;
class CLyric { public:
CLyric(); ~CLyric();
CString CString CString CString LONG CString
■ 标识标签(ID-tags)
其格式为"[标识名:值]"。大小写等价。以下是预定义的标签。 [ar:艺人名] [ti:曲名] [al:专辑名] [by:编者(指编辑 LRC 歌词的人)] [offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显 示快慢的。分钟:秒.毫秒]歌词 用记事本按照上述格式写好后,将拓展名改为 lrc 即可做出该文件.LRC 歌词是一种通过编辑
time by dwItemID
LONG GetItemIDByTime(DWORD dwTime, DWORD dwStartLineID = 0);// Search
the line index by time(in milliseconds) begin at nStartLineID
DWORD GetTotalNum() { return m_dwLineNum; }
#define MAX_LYRIC_LINE_LEN #define MAX_LYRIC_LEN #define MAX_LYRIC_LINE_NUM #define MAX_LYRIC_TIME_LEN
512 128
5000 30
CLyric::CLyric() {
m_bValid = FALSE; m_lUserOffset = 0; }
BOOL IsValid() { return m_bValid; }
private:
BOOL
m_bValid;
CArray<LineLyric> m_LyricList;
DWORD m_dwLineNum;
BOOL
m_bAnalyseTag;
LONG
m_lUserOffset;
__forceinline BOOL ReadALine(FILE *fp, CHAR *buff, INT bufflen, INT &readlen); __forceinline void AnalyseLine(CHAR *szLine, INT nLength); __forceinline BOOL CheckTag(CHAR *szText); __forceinline LONG GetStartTime(CHAR *szTime);
if (readlen <= 0) continue;
AnalyseLineW(wstr, readlen); } while (m_dwLineNum < MAX_LYRIC_LINE_NUM); } else { fseek(fp, 0L, SEEK_SET); CHAR str[MAX_LYRIC_LINE_LEN]; do {
return FALSE;
4
}
fseek(fp, sizeof(WCHAR), SEEK_SET); WCHAR wstr[MAX_LYRIC_LINE_LEN]; do {
if (!ReadALineW(fp, wstr, MAX_LYRIC_LINE_LEN, readlen)) break;
以下附上C++实现代码,支持ANSI和Unicode格式,超强纠错。
-----------------------------------------------------Lyric.h-----------------------------------------------------
typedef struct
__forceinline DWORD Find(DWORD dwTime); matched the time };
// return the line ID
-----------------------------------------------------Lyric.cpp----------------------------------------------------#include "Lyric.h"
return m_LyricList[dwTotalItem-1].dwStartTime; } }
3
CLyric::~CLyric() { }
BOOL CLyric::Load(LPCWSTR szFileName, LONG lUserOffset) {
UnLoad();
FILE INT
*fp; readlen;
m_lUserOffset = lUserOffset; fp = _tfopen(szFileName, _T("r")); if (fp == NULL) {
二是时间标签,形式为“[mm:ss]”或“[mm:ss.fff]”(分钟数:秒数:毫秒数),时间标 签需位于某行歌词中的句首部分,一行歌词可以包含多个时间标签(比如歌词中的迭句部 分)。当歌曲播放到达某一时间点时,MP3 就会寻找对应的时间标签并显示标签后面的歌词 文本,这样就完成了“歌词同步”的功能。
__forceinline BOOL ReadALineW(FILE *fp, WCHAR *buff, INT bufflen, INT &readlen);
__forceinline void AnalyseLineW(WCHAR *szLine, INT nLength); __forceinline BOOL CheckTagW(WCHAR *szText); __forceinline LONG GetStartTimeW(WCHAR *szTime);
fclose(fp);
m_bValid = TRUE;
return TRUE; }
void CLyric::UnLoad() {
m_bValid = FALSE; m_csArtist.Empty(); m_csTitle.Empty(); m_csAlbum.Empty(); m_csBy.Empty(); m_lOffset = 0;
return FALSE; }
WORD wUnicode_tag = 0; DWORD dwReadLen = 0; try {
dwReadLen = fread((void *)&wUnicode_tag, sizeof(WCHAR), 1, fp); } catch (...) {
printf("CLyric::Load: fread Exception: %s!\r\n", szFileName); fclose(fp); return FALSE; } if (dwReadLen != 1) { printf("CLyric::Load: read file %s failed!\r\n", szFileName); fclose(fp); return FALSE; } if (wUnicode_tag == 0xfeff) // unicode file { fclose(fp); fp = _tfopen(szFileName, _T("rb")); if (fp == NULL) {
if (dwItemID < (DWORD)m_LyricList.GetSize()) {
lyric = m_LyricList[dwItemID]; return TRUE; } else { return FALSE; } }
DWORD CLyric::GetTimeByID(DWORD dwItemID) {
if (!ReadALine(fp, str, MAX_LYRIC_LINE_LEN, readlen)) break;
if (readlen <= 0) continue;
AnalyseLine(str, readlen); } while (m_dwLineNum < MAX_LYRIC_LINE_NUM); }
1
器把歌词按歌曲歌词出现的时间编辑成一个文件,在播放歌曲时同步依次显示出来的一种歌 词文件。把歌曲和 LRC 歌词命为相同的文件名放在同一目录下,用带显示歌词功能的播放器 播放歌曲时歌词就可以同步显示显示,方便查看和学歌。
(供程序员阅读参考)
以下列出了开发支持 LRC 格式的软件时应遵守的一些标准。无论是否在行首,行内凡具 有“[*:*]”形式的都应认为是标签。(注意:其中的冒号并非全角字符“:”) 凡是标签都不应显示。
DWORD dwTotalItem = (DWORD)m_LyricList.GetSize(); if (dwTotalItem == 0)
return 0;
if (dwItemID < dwTotalItem) {
return m_LyricList[dwItemID].dwStartTime; } else {
Lrc 歌词文件格式说明
扩展名为 Lrc 格式的文件,是 MP3 播放器唯一能够识别的歌词文件,在 MP3 数码播放器 或千千静听中可以区同步显示歌词。
它是一种包含着“[*:*]”形式的“标签(tag)”的、基于纯文本的歌词专用格式。最早 由郭祥祥先生(Djohan)提出并在其程序中得到应用。这种歌词文件既可以用来实现卡拉 OK 功能(需要专门程序),又能以普通的文字处理软件查看、编辑。当然,实际操作时通常是 用专门的 LRC 歌词编辑软件进行高效编辑的。