529 lines
15 KiB
C
529 lines
15 KiB
C
#include "lyrics_api.h"
|
||
#include "ui/lyrics.h"
|
||
#include "system/fs/fs.h"
|
||
#include "app_config.h"
|
||
#include "ui/ui_style.h"
|
||
|
||
#if (TCFG_LRC_LYRICS_ENABLE)
|
||
|
||
|
||
static u8 *lrc_info_buf = NULL; //[2324] __attribute__((aligned(4)));
|
||
static volatile u8 lrc_analysis_flag = 0;
|
||
|
||
static LRC_FILE_IO lrc_file_io = {
|
||
.seek = fseek,
|
||
.read = fread,
|
||
};
|
||
|
||
|
||
static OS_MUTEX mutex;
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 配置翻屏的速度
|
||
@param lrc_len--当前歌词长度,time_gap-与下一条歌词的间隔,
|
||
@param *roll_speed - 翻屏的速度 500ms unit
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void lrc_roll_speed_ctrl(u8 lrc_len, u32 time_gap, u8 *roll_speed)
|
||
{
|
||
///翻页滚动速度控制
|
||
///printf("speed = %d,%d",lrc_len,time_gap);
|
||
///DVcTxt1_11 显示长度为32 bytes
|
||
if (lrc_len > (LRC_DISPLAY_TEXT_LEN * 2)) {
|
||
*roll_speed = ((time_gap + 2) / 3) << 1;
|
||
} else if (lrc_len > LRC_DISPLAY_TEXT_LEN) {
|
||
*roll_speed = time_gap;
|
||
} else {
|
||
*roll_speed = 250; ///never load new page
|
||
}
|
||
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 清空显示区域
|
||
@param
|
||
@return
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void clr_lrc_disp_buff(void)
|
||
{
|
||
/* lcd_clear_area_rect(4, 8, 0, 128); */
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 歌词模块初始化
|
||
@param
|
||
@return 0--成功,非0 失败
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int lrc_init(void)
|
||
{
|
||
LRC_CFG t_lrc_cfg;
|
||
t_lrc_cfg.once_read_len = ONCE_READ_LENGTH;
|
||
t_lrc_cfg.once_disp_len = ONCE_DIS_LENGTH;
|
||
t_lrc_cfg.label_temp_buf_len = LABEL_TEMP_BUF_LEN;
|
||
t_lrc_cfg.roll_speed_ctrl_cb = lrc_roll_speed_ctrl;
|
||
t_lrc_cfg.clr_lrc_disp_cb = NULL;//clr_lrc_disp_buff;
|
||
/* t_lrc_cfg.lrc_text_id = LRC_DISPLAY_TEXT_ID; */
|
||
t_lrc_cfg.read_next_lrc_flag = 0;
|
||
t_lrc_cfg.enable_save_lable_to_flash = LRC_ENABLE_SAVE_LABEL_TO_FLASH;
|
||
|
||
u32 need_buf_size = LRC_SIZEOF_ALIN(sizeof(LRC_INFO), 4)
|
||
+ LRC_SIZEOF_ALIN(sizeof(LABEL_INFO), 4)
|
||
+ LRC_SIZEOF_ALIN(sizeof(SORTING_INFO), 4)
|
||
+ LRC_SIZEOF_ALIN(t_lrc_cfg.once_disp_len, 4)
|
||
+ LRC_SIZEOF_ALIN(t_lrc_cfg.label_temp_buf_len, 4)
|
||
+ LRC_SIZEOF_ALIN(t_lrc_cfg.once_read_len, 4);
|
||
printf("---lrc need_buf_size=%d---\n", need_buf_size);
|
||
/* ASSERT(sizeof(lrc_info_buf) >= need_buf_size); */
|
||
if (!lrc_info_buf) {
|
||
lrc_info_buf = zalloc(need_buf_size);
|
||
}
|
||
|
||
/* memset(lrc_info_buf, 0, sizeof(lrc_info_buf)); */
|
||
|
||
os_mutex_create(&mutex);
|
||
|
||
return lrc_param_init(&t_lrc_cfg, lrc_info_buf);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 歌词模块退出
|
||
@param
|
||
@return
|
||
@note
|
||
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void lrc_exit(void)
|
||
{
|
||
os_mutex_pend(&mutex, 0);
|
||
lrc_destroy();
|
||
if (lrc_info_buf) {
|
||
free(lrc_info_buf);
|
||
lrc_info_buf = NULL;
|
||
}
|
||
os_mutex_post(&mutex);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 搜索歌词,解析
|
||
@param
|
||
@return 0--成功,非0 失败
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
int lrc_find(FILE *file, FILE **newFile, void *ext_name)
|
||
{
|
||
u32 find_lrc_flag;
|
||
|
||
find_lrc_flag = fget_file_byname_indir(file, newFile, ext_name);
|
||
|
||
if (find_lrc_flag) {
|
||
puts("\ncan't find lrc------\n");
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void lrc_set_analysis_flag(u8 flag)
|
||
{
|
||
if (!lrc_info_buf) {
|
||
return;
|
||
}
|
||
os_mutex_pend(&mutex, 0);
|
||
lrc_analysis_flag = flag;
|
||
os_mutex_post(&mutex);
|
||
}
|
||
|
||
bool lrc_show_api(int text_id, u16 dbtime_s, u8 btime_100ms)
|
||
{
|
||
bool ret = 0;
|
||
if (!lrc_info_buf) {
|
||
return false;
|
||
}
|
||
os_mutex_pend(&mutex, 0);
|
||
if (lrc_analysis_flag == 1) {
|
||
ret = lrc_show(text_id, dbtime_s, btime_100ms);
|
||
os_mutex_post(&mutex);
|
||
return ret ;
|
||
} else {
|
||
os_mutex_post(&mutex);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
static FILE *tabfp = NULL;
|
||
int read_tab(int i, char *buf, u8 read_len)
|
||
{
|
||
if (tabfp == NULL) {
|
||
tabfp = fopen("mnt/sdfile/res/gbk2utf8.tab", "r");
|
||
}
|
||
if (!tabfp) {
|
||
r_printf("gbk2utf8.tab open fail");
|
||
return 1;
|
||
}
|
||
fseek(tabfp, (u32)(3 * i), SEEK_SET);
|
||
fread(tabfp, buf, read_len);
|
||
fseek(tabfp, 0, SEEK_SET);
|
||
return 0;
|
||
}
|
||
|
||
u8 read_tab_check(int i, int offser)
|
||
{
|
||
u8 read_buf[3];
|
||
if (tabfp == NULL) {
|
||
tabfp = fopen("mnt/sdfile/res/gbk2utf8.tab", "r");
|
||
}
|
||
if (!tabfp) {
|
||
r_printf("gbk2utf8.tab open fail");
|
||
return 1;
|
||
}
|
||
fseek(tabfp, i * 3 + offser, SEEK_SET);
|
||
fread(tabfp, read_buf, 1);
|
||
|
||
return read_buf[0];
|
||
}
|
||
|
||
int gbk_2_utf8(const char *str, int str_len, char *buf, int buf_len)
|
||
{
|
||
// printf(">>>gbk_2_utf8%s",str);
|
||
int i;
|
||
int count = 0;
|
||
|
||
if (!str || !buf) {
|
||
return 0;
|
||
}
|
||
|
||
if (str_len == -1) {
|
||
str_len = 0x7FFFFFFF;
|
||
}
|
||
|
||
while ((str_len > 0) && (buf_len > 0)) {
|
||
unsigned char lead = *str++;
|
||
unsigned char trail;
|
||
|
||
if (!lead) { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>βNULL<4C>ַ<EFBFBD><D6B7><EFBFBD>*/
|
||
break;
|
||
}
|
||
|
||
if ((lead >= 0x81) && (lead <= 0xFE)) {
|
||
if (str_len < 2) {
|
||
break; /* <20><><EFBFBD><EFBFBD><F3A3ACB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
}
|
||
|
||
str_len -= 2;
|
||
|
||
trail = *str++;
|
||
|
||
/* <20><>λ<EFBFBD><CEBB>ʽ<EFBFBD><CABD>*/
|
||
i = ((lead - 0x81) * 191) + (trail - 0x40);
|
||
if (i >= (24066)) { //24066sizeof(gbk_2_utf8_table) / sizeof(gbk_2_utf8_table[0])
|
||
break; /* <20><><EFBFBD>Ƿ<F3A3ACB7><C7B7><EFBFBD>λ */
|
||
}
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD>ֽڵ<D6BD>UTF8<46><38><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||
if (read_tab_check(i, 2)) { //gbk_2_utf8_table[i][2] read_one_num_check(i*3+2)||
|
||
if (buf_len < 3) {
|
||
break; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
}
|
||
read_tab(i, buf, 3);
|
||
// *buf++ = (char)gbk_2_utf8_table[i][0];
|
||
// *buf++ = (char)gbk_2_utf8_table[i][1];
|
||
// *buf++ = (char)gbk_2_utf8_table[i][2];
|
||
buf += 3;
|
||
// g_printf("bin:");
|
||
// put_buf(read_buf,3);
|
||
// g_printf("buf:");
|
||
// put_buf(buf-3,3);
|
||
|
||
|
||
buf_len -= 3;
|
||
|
||
count += 3;
|
||
}
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD>ֽڵ<D6BD>UTF8<46><38>*/
|
||
else if (read_tab_check(i, 1)) {
|
||
if (buf_len < 2) {
|
||
break; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
}
|
||
|
||
read_tab(i, buf, 2);
|
||
buf += 2;
|
||
|
||
buf_len -= 2;
|
||
count += 2;
|
||
}
|
||
/* һ<><D2BB><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵĿǰ<C4BF><C7B0><EFBFBD>ǷǷ<C7B7><C7B7>ģ<EFBFBD><C4A3><EFBFBD>trail=0x7F<37>Ŀ<EFBFBD><C4BF><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> */
|
||
else {
|
||
*buf++ = (char)read_tab_check(i, 0);
|
||
|
||
buf_len--;
|
||
count++;
|
||
}
|
||
} else {
|
||
str_len--;
|
||
|
||
if (lead < 0x80) {
|
||
*buf++ = (char)lead;
|
||
|
||
buf_len--;
|
||
count++;
|
||
} else if (lead == 0x80) {
|
||
if (buf_len < 3) {
|
||
break;
|
||
}
|
||
|
||
*buf++ = (char)0xE2;
|
||
*buf++ = (char)0x82;
|
||
*buf++ = (char)0xAC;
|
||
|
||
buf_len -= 3;
|
||
count += 3;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (buf_len > 0) {
|
||
*buf = '\0';
|
||
}
|
||
|
||
return count;
|
||
}
|
||
|
||
u16 big5_to_utf8(u8 *big5, u16 big5_len, u8 *utf8, u16 utf8_len)
|
||
{
|
||
static FILE *ft = NULL;
|
||
if (ft == NULL) {
|
||
ft = fopen("mnt/sdfile/res/big5_utf8.tab", "r");
|
||
}
|
||
if (ft == NULL) {
|
||
printf("file open failed");
|
||
return 0;
|
||
}
|
||
u16 offset;
|
||
u16 i, j = 0;
|
||
u8 tmp[3];
|
||
for (i = 0; i < big5_len; i++) {
|
||
if (big5[i] == 0) {
|
||
break;
|
||
}
|
||
if (j >= utf8_len) {
|
||
j = utf8_len;
|
||
break;
|
||
}
|
||
if (big5[i] <= 0x7f) {
|
||
utf8[j] = big5[i];
|
||
j++;
|
||
} else {
|
||
if (i + 1 >= big5_len) {
|
||
break;
|
||
}
|
||
if (big5[i] < 0xa1 || big5[i] > 0xf9 || big5[i + 1] < 0x40 || \
|
||
big5[i + 1] > 0xfe || (big5[i + 1] > 0x7e && big5[i + 1] < 0xa1)) {
|
||
printf("curr code not big5 format, i: %d %d %d\n", i, big5[i], big5[i + 1]);
|
||
i++;
|
||
continue;
|
||
}
|
||
offset = (big5[i] - 0xa1) * (0x7e - 0x40 + 0xfe - 0xa1 + 2);
|
||
if (big5[i + 1] >= 0x40 && big5[i + 1] <= 0x7e) {
|
||
offset += (big5[i + 1] - 0x40);
|
||
} else if (big5[i] >= 0xa1 && big5[i] <= 0xfe) {
|
||
offset += (big5[i + 1] - 0xa1 + (0x7e - 0x40 + 1));
|
||
}
|
||
offset *= 3;
|
||
fseek(ft, offset, SEEK_SET);
|
||
fread(ft, tmp, 3);
|
||
if (j + 3 >= utf8_len) {
|
||
break;
|
||
}
|
||
memcpy(&utf8[j], tmp, 3);
|
||
i++;
|
||
j += 3;
|
||
}
|
||
}
|
||
|
||
return j; //转换后utf8编码长度
|
||
}
|
||
|
||
static int ui_text_utf8_check(u8 *buf, u16 len)
|
||
{
|
||
int i, j;
|
||
u8 code, nbytes;
|
||
for (i = 0; i < len; i++) {
|
||
nbytes = 0;
|
||
code = buf[i];
|
||
while (code & 0x80) {
|
||
code <<= 1;
|
||
nbytes++;
|
||
}
|
||
if (nbytes == 0) {
|
||
continue;
|
||
}
|
||
if (nbytes == 1 || nbytes > 6) {
|
||
return false;
|
||
}
|
||
if (i + nbytes > len) {
|
||
return true;
|
||
}
|
||
for (j = 1; j < nbytes; j++) {
|
||
code = buf[i + j];
|
||
if ((code & 0xc0) != 0x80) {
|
||
return false;
|
||
}
|
||
}
|
||
i += (nbytes - 1);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
u8 ui_check_ansi_type(u8 *str, u16 len)
|
||
{
|
||
u8 ret = ANSI_GB2312;
|
||
for (u16 i = 0; i < len; i++) {
|
||
if (str[i] < 0x7f) {
|
||
continue;
|
||
} else {
|
||
if ((str[i] >= 0xf8 && str[i] <= 0xf9) || \
|
||
(str[i + 1] >= 0x40 && str[i + 1] <= 0x7e)) {
|
||
ret = ANSI_BIG5;
|
||
break;
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
bool user_lyric_info_get(LYRIC_INFO *info, u16 dbtime_s, u8 btime_100ms)
|
||
{
|
||
bool ret = 0;
|
||
static u8 *utf8 = NULL;
|
||
os_mutex_pend(&mutex, 0);
|
||
if (lrc_analysis_flag == 1) {
|
||
ret = lyric_info_get(info, dbtime_s, btime_100ms);
|
||
if (info->update) {
|
||
if (ui_text_utf8_check(info->buf, info->len) == 0) {
|
||
if (utf8) {
|
||
free(utf8);
|
||
utf8 = NULL;
|
||
}
|
||
if (utf8 == NULL) {
|
||
utf8 = zalloc(info->len * 2);
|
||
}
|
||
u8 ansi_type = ui_check_ansi_type(info->buf, info->len);
|
||
if (ansi_type == ANSI_GB2312) {
|
||
info->len = gbk_2_utf8(info->buf, info->len, utf8, info->len * 2);
|
||
} else if (ansi_type == ANSI_BIG5) {
|
||
info->len = big5_to_utf8(info->buf, info->len, utf8, info->len * 2);
|
||
}
|
||
info->buf = utf8;
|
||
}
|
||
}
|
||
os_mutex_post(&mutex);
|
||
return ret ;
|
||
} else {
|
||
os_mutex_post(&mutex);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
bool lrc_get_api(u16 dbtime_s, u8 btime_100ms)
|
||
{
|
||
bool ret = 0;
|
||
os_mutex_pend(&mutex, 0);
|
||
if (lrc_analysis_flag == 1) {
|
||
ret = lrc_get(dbtime_s, btime_100ms);
|
||
return ret ;
|
||
os_mutex_post(&mutex);
|
||
return ret;
|
||
} else {
|
||
os_mutex_post(&mutex);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
bool lrc_analysis_api(FILE *file, FILE **newFile)
|
||
{
|
||
void *ext_name = "LRC";
|
||
LRC_FILE_IO *p_lrc_file_io = &lrc_file_io;
|
||
if (!lrc_info_buf) {
|
||
return false;
|
||
}
|
||
os_mutex_pend(&mutex, 0);
|
||
if (*newFile) {
|
||
fclose(*newFile);
|
||
*newFile = NULL;
|
||
}
|
||
|
||
if (0 == lrc_find(file, newFile, ext_name)) {
|
||
if (false == lrc_analysis(*newFile, p_lrc_file_io)) {
|
||
printf("lrc analazy err \n");
|
||
os_mutex_post(&mutex);
|
||
return false;
|
||
} else {
|
||
printf("lrc analazy succ \n");
|
||
os_mutex_post(&mutex);
|
||
return true;
|
||
}
|
||
} else {
|
||
printf("lrc_find err\n");
|
||
os_mutex_post(&mutex);
|
||
return false;
|
||
}
|
||
}
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 歌词显示,默认显示两行
|
||
@param lrc_show_flag:滚动显示标志 lrc_update:显示下一条歌词内容标志
|
||
@return true--成功
|
||
@note 可以根据xi需要修改该函数的实现方法
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
bool lrc_ui_show(int text_id, u8 encode_type, u8 *buf, int len, u8 lrc_show_flag, u8 lrc_update)
|
||
{
|
||
#if(CONFIG_UI_STYLE == STYLE_JL_SOUNDBOX)
|
||
static int disp_len = 0;
|
||
static u8 lrc_showbytes = 0;
|
||
static u8 offset = 0;
|
||
if (lrc_update) {
|
||
disp_len = len;
|
||
lrc_showbytes = 0;
|
||
offset = 0;
|
||
ui_text_set_text_by_id(LRC_TEXT_ID_SEC, "", 16, FONT_DEFAULT);
|
||
}
|
||
if (lrc_show_flag == 1) {
|
||
if (LRC_UTF16_S == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_FIR, buf + offset, disp_len, FONT_ENDIAN_SMALL, FONT_DEFAULT);
|
||
} else if (LRC_UTF16_B == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_FIR, buf + offset, disp_len, FONT_ENDIAN_BIG, FONT_DEFAULT);
|
||
} else if (LRC_UTF8 == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_FIR, buf + offset, disp_len, FONT_ENDIAN_SMALL, FONT_DEFAULT | FONT_SHOW_MULTI_LINE);
|
||
} else {
|
||
lrc_showbytes = ui_text_set_text_by_id(LRC_TEXT_ID_FIR, buf + offset, disp_len, FONT_DEFAULT);
|
||
}
|
||
offset += lrc_showbytes;
|
||
if (LRC_UTF16_S == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_SEC, buf + offset, disp_len, FONT_ENDIAN_SMALL, FONT_DEFAULT);
|
||
} else if (LRC_UTF16_B == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_SEC, buf + offset, disp_len, FONT_ENDIAN_BIG, FONT_DEFAULT);
|
||
} else if (LRC_UTF8 == encode_type) {
|
||
lrc_showbytes = ui_text_set_textw_by_id(LRC_TEXT_ID_SEC, buf + offset, disp_len, FONT_ENDIAN_SMALL, FONT_DEFAULT | FONT_SHOW_MULTI_LINE);
|
||
} else {
|
||
lrc_showbytes = ui_text_set_text_by_id(LRC_TEXT_ID_SEC, buf + offset, disp_len, FONT_DEFAULT);
|
||
}
|
||
}
|
||
#endif
|
||
return true;
|
||
}
|
||
|
||
#endif //TCFG_LRC_LYRICS_ENABLE
|
||
|