KT24-1110_65E-HA-651B/apps/soundbox/task_manager/music/music.c

1058 lines
36 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#include "music/music.h"
#include "music_player.h"
#include "system/includes.h"
#include "app_config.h"
#include "app_task.h"
#include "app_main.h"
#include "clock_cfg.h"
#include "app_action.h"
#include "breakpoint.h"
#include "key_event_deal.h"
#include "tone_player.h"
#include "dev_multiplex_api.h"
#include "ui/ui_api.h"
#include "bt/bt.h"
#include "smartbox/smartbox.h"
#include "ui_manage.h"
#include "audio_dec.h"
#include "common/dev_status.h"
#include "clock_cfg.h"
#include "system/fs/fs.h"
#include "user_api/app_status_api.h"
/*************************************************************
music模式按键处理和事件处理
void app_music_task()
music模式主函数
static int music_sys_event_handler(struct sys_event *event)
music模式系统事件所有处理入口
static void music_task_close(void)
music模式退出
**************************************************************/
#define LOG_TAG_CONST APP_MUSIC
#define LOG_TAG "[APP_MUSIC]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_APP_MUSIC_EN
static u8 music_idle_flag = 1;
///模式参数结构体
struct __music_task_parm {
u8 type;
int val;
};
///music模式控制结构体
struct __music {
struct __music_task_parm task_parm;
u16 file_err_counter;//错误文件统计
u8 file_play_direct;//0:下一曲, 1上一曲
u8 scandisk_break;//扫描设备打断标志
char device_tone_dev[16];
#if SD_BAUD_RATE_CHANGE_WHEN_SCAN
u32 old_speed;
#endif
};
struct __music music_hdl;
#define __this (&music_hdl)
static struct __breakpoint *breakpoint = NULL;
static void music_player_play_start(void);
///设备提示音使能
#define MUSIC_DEVICE_TONE_EN 0
#if (MUSIC_DEVICE_TONE_EN)
struct __dev_tone {
char *logo;
char *phy_logo;
char *tone_path;
u16 index;
};
enum {
///0x1000起始为了不要跟提示音的IDEX_TONE_重叠了
DEVICE_INDEX_UDISK = 0x1000,
DEVICE_INDEX_UDISK_REC,
DEVICE_INDEX_SD0,
DEVICE_INDEX_SD0_REC,
DEVICE_INDEX_SD1,
DEVICE_INDEX_SD1_REC,
};
const struct __dev_tone device_tone[] = {
{"udisk0", "udisk0", TONE_RES_ROOT_PATH"tone/udisk.*", DEVICE_INDEX_UDISK} ,
{"udisk0_rec", "udisk0", TONE_RES_ROOT_PATH"tone/udisk.*", DEVICE_INDEX_UDISK_REC} ,
{"sd0", "sd0", TONE_RES_ROOT_PATH"tone/sd.*", DEVICE_INDEX_SD0} ,
{"sd0_rec", "sd0", TONE_RES_ROOT_PATH"tone/sd.*", DEVICE_INDEX_SD0_REC} ,
{"sd1", "sd1", TONE_RES_ROOT_PATH"tone/sd.*", DEVICE_INDEX_SD1} ,
{"sd1_rec", "sd1", TONE_RES_ROOT_PATH"tone/sd.*", DEVICE_INDEX_SD1_REC} ,
};
static void music_tone_play_end_callback(void *priv, int flag);
int music_device_tone_play(char *logo)
{
if (logo == NULL) {
return false;
}
printf("__this->device_tone_dev = %s, logo =%s\n", __this->device_tone_dev, logo);
char *phy_logo = dev_manager_get_phy_logo(dev_manager_find_spec(logo, 0));
if (phy_logo && (strcmp(__this->device_tone_dev, phy_logo) == 0)) {
log_i("[%s, %d]the same phy dev, no need device tone!!\n", logo, __LINE__);
return false;
}
for (int i = 0; i < ARRAY_SIZE(device_tone); i++) {
if (strcmp(device_tone[i].logo, logo) == 0) {
log_i("[%s, %d]device_tone play \n", logo, __LINE__);
memset(__this->device_tone_dev, 0, sizeof(__this->device_tone_dev));
memcpy(__this->device_tone_dev, device_tone[i].phy_logo, strlen(device_tone[i].phy_logo));
tone_play_with_callback_by_name(device_tone[i].tone_path, 1, music_tone_play_end_callback, (void *)device_tone[i].index);
return true;
}
}
log_i("[%s, %d]device_tone play \n", logo, __LINE__);
return false;
}
#endif
#if TCFG_LFN_EN
static u8 music_file_name[128] = {0}; //长文件名
u16 music_file_name_len = 0;
#else
static u8 music_file_name[12 + 1] = {0}; //8.3+\0
u16 music_file_name_len = 0;
#endif
const char *music_file_get_cur_name(int *len, int *is_unicode)
{
if (music_file_name[0] == '\\' && music_file_name[1] == 'U') {
*is_unicode = 1 ;
*len = music_file_name_len - 2;
return (const char *)(music_file_name + 2);
}
*is_unicode = 0 ;
*len = music_file_name_len;
return (const char *)music_file_name;
}
static void music_set_dev_sync_mode(char *logo, u8 mode)
{
if (logo) {
struct imount *mount_hdl = NULL;
u8 async_mode = mode;
if ((!memcmp(logo, "udisk0", strlen("udisk0")))
|| (!memcmp(logo, "udisk0_rec", strlen("udisk0_rec")))) {
struct file_dec_hdl *dec = get_file_dec_hdl();
if (dec) {
mount_hdl = dev_manager_get_mount_hdl(dev_manager_find_spec(logo, 0));
if (mount_hdl) {
if (dec->file_dec.decoder.dec_ops->coding_type == AUDIO_CODING_APE
|| dec->file_dec.decoder.dec_ops->coding_type == AUDIO_CODING_FLAC
|| dec->file_dec.decoder.dec_ops->coding_type == AUDIO_CODING_DTS
|| dec->file_dec.decoder.dec_ops->coding_type == AUDIO_CODING_WAV) {
///指定解码格式开启该功能
dev_ioctl(mount_hdl->dev.fd, IOCTL_SET_ASYNC_MODE, (u32)async_mode);
} else {
///不指定的解码格式不开启
async_mode = 0;
dev_ioctl(mount_hdl->dev.fd, IOCTL_SET_ASYNC_MODE, (u32)async_mode);
}
printf("udisk, set usb ASYNC = %d\n", async_mode);
}
}
} else {
//不是udisk, 如果udisk在线 将udisk设置成非AYSNC_MODE
mount_hdl = dev_manager_get_mount_hdl(dev_manager_find_spec("udisk0", 0));
if (mount_hdl) {
async_mode = 0;
printf("not udisk, set usb ASYNC = 0\n");
dev_ioctl(mount_hdl->dev.fd, IOCTL_SET_ASYNC_MODE, (u32)async_mode);
}
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief music 解码成功回调
@param priv: parm:
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void music_player_play_success(void *priv, int parm)
{
char *logo = music_player_get_dev_cur();
//使能usb预读功能
music_set_dev_sync_mode(logo, 1);
log_i("\n\n----------------music_player_play_success----------------------\n");
log_i("cur dev = %s\n", logo);
log_i("total dev = %d\n", dev_manager_get_total(1));
log_i("cur filenum = %d\n", music_player_get_file_cur());
log_i("totol filenum = %d\n", music_player_get_file_total());
log_i("totol time = %d\n", music_player_get_dec_total_time());
log_i("sclust = %d\n", music_player_get_file_sclust());
log_i("dir_cur = %d\n", music_player_get_dir_cur());
log_i("dir_total = %d\n", music_player_get_dir_total());
log_i("file indir = %d\n", music_player_get_fileindir_number());
music_file_name_len = fget_name(music_player_get_file_hdl(), music_file_name, sizeof(music_file_name));
int unicode = 0;
if ((music_file_name[0] == '\\') && (music_file_name[1] == 'U')) {
unicode = 1;
music_file_name_len -= 2;
log_i("cur file = %s, len = %d, unicode = %d\n", music_file_name + 2, music_file_name_len, unicode);
} else {
log_i("cur file = %s, len = %d, unicode = %d\n", music_file_name, music_file_name_len, unicode);
}
log_i("\n");
///save breakpoint, 只保存文件信息
if (music_player_get_playing_breakpoint(breakpoint, 0) == true) {
breakpoint_vm_write(breakpoint, logo);
}
int analaz = music_player_lrc_analy_start();
///show ui
UI_SHOW_MENU(MENU_FILENUM, 1000, music_player_get_file_cur(), NULL);
UI_MSG_POST("music_start:show_lyric=%4:dev=%4:filenum=%4:total_filenum=%4", !analaz, logo, music_player_get_file_cur(), music_player_get_file_total());
///smartbox info update
SMARTBOX_UPDATE(MUSIC_FUNCTION_MASK,
BIT(MUSIC_INFO_ATTR_STATUS) | BIT(MUSIC_INFO_ATTR_FILE_NAME) | BIT(MUSIC_INFO_ATTR_FILE_PLAY_MODE));
}
//*----------------------------------------------------------------------------*/
/**@brief music 解码结束回调处理
@param
@return
@note key msg中统一响应
*/
/*----------------------------------------------------------------------------*/
static void music_player_play_end(void *priv, int parm)
{
log_i("music_player_play_end\n");
///这里推出消息, 目的是在music主流程switch case统一入口
app_task_put_key_msg(KEY_MUSIC_PLAYER_END, parm);
}
//*----------------------------------------------------------------------------*/
/**@brief music 解码错误回调
@param
@return
@note key msg中统一响应
*/
/*----------------------------------------------------------------------------*/
static void music_player_decode_err(void *priv, int parm)
{
log_i("music_player_decode_err\n");
///这里推出消息, 目的是在music主流程switch case统一入口
app_task_put_key_msg(KEY_MUSIC_PLAYER_DEC_ERR, parm);
}
//*----------------------------------------------------------------------------*/
/**@brief music 播放器扫盘打断接口
@param
@return 1:0:
@note
*/
/*----------------------------------------------------------------------------*/
static int music_player_scandisk_break(void)
{
///注意:
///需要break fsn的事件 请在这里拦截,
///需要结合MUSIC_PLAYER_ERR_FSCAN错误做相应的处理
int msg[32] = {0};
struct sys_event *event = NULL;
char *logo = NULL;
char *evt_logo = NULL;
app_task_get_msg(msg, ARRAY_SIZE(msg), 0);
switch (msg[0]) {
case APP_MSG_SYS_EVENT:
event = (struct sys_event *)(&msg[1]);
switch (event->type) {
case SYS_DEVICE_EVENT:
switch ((u32)event->arg) {
case DRIVER_EVENT_FROM_SD0:
case DRIVER_EVENT_FROM_SD1:
case DRIVER_EVENT_FROM_SD2:
evt_logo = (char *)event->u.dev.value;
case DEVICE_EVENT_FROM_OTG:
if ((u32)event->arg == DEVICE_EVENT_FROM_OTG) {
evt_logo = (char *)"udisk0";
}
///设备上下线底层推出的设备逻辑盘符是跟跟音乐设备一致的(音乐/录音设备, 详细看接口注释)
int str_len = 0;
logo = music_player_get_phy_dev(&str_len);
///响应设备插拔打断
if (event->u.dev.event == DEVICE_EVENT_OUT) {
log_i("__func__ = %s logo=%s evt_logo=%s %d\n", __FUNCTION__, logo, evt_logo, str_len);
if (logo && (0 == memcmp(logo, evt_logo, str_len))) {
///相同的设备才响应
__this->scandisk_break = 1;
}
} else {
///响应新设备上线
__this->scandisk_break = 1;
}
if (__this->scandisk_break == 0) {
log_i("__func__ = %s DEVICE_EVENT_OUT TODO\n", __FUNCTION__);
dev_status_event_filter(event);
log_i("__func__ = %s DEVICE_EVENT_OUT OK\n", __FUNCTION__);
}
break;
}
break;
case SYS_BT_EVENT:
if (bt_background_event_handler_filter(event)) {
__this->scandisk_break = 1;
}
break;
case SYS_KEY_EVENT:
switch (event->u.key.event) {
case KEY_CHANGE_MODE:
///响应切换模式事件
__this->scandisk_break = 1;
break;
//其他按键case 在这里增加
}
///因为TWS转发sys_event_notify需要用原始的按键序号 未经过按键表处理, 所以这里要特殊处理
if (__this->scandisk_break) {
app_task_put_key_msg(event->u.key.event, (int)event->u.key.value);
printf("key break scan!!");
return 1;
}
break;
}
break;
}
if (__this->scandisk_break) {
///查询到需要打断的事件, 返回1 并且重新推送一次该事件,跑主循环处理流程
sys_event_notify(event);
printf("scandisk_break!!!!!!\n");
return 1;
} else {
return 0;
}
}
static const struct __player_cb music_player_callback = {
.start = music_player_play_success,
.end = music_player_play_end,
.err = music_player_decode_err,
// .fsn_break = music_player_scandisk_break,
};
static void scan_enter(struct __dev *dev)
{
#if SD_BAUD_RATE_CHANGE_WHEN_SCAN
struct imount *mount_hdl = dev_manager_get_mount_hdl(dev);
if (mount_hdl) {
if ((!memcmp(dev_manager_get_logo(dev), "sd0", strlen("sd0")))
|| (!memcmp(dev_manager_get_logo(dev), "sd1", strlen("sd1")))) {
dev_ioctl(mount_hdl->dev.fd, IOCTL_GET_SPEED, (u32)&__this->old_speed); //获取sd速度
if (SD_BAUD_RATE_CHANGE_WHEN_SCAN > __this->old_speed) { //设定速度大于获取的才加速
dev_ioctl(mount_hdl->dev.fd, IOCTL_SET_SPEED, SD_BAUD_RATE_CHANGE_WHEN_SCAN);
}
}
}
#endif
clock_add_set(SCAN_DISK_CLK);
}
static void scan_exit(struct __dev *dev)
{
#ifdef SD_BAUD_RATE_CHANGE_WHEN_SCAN
struct imount *mount_hdl = dev_manager_get_mount_hdl(dev);
if (mount_hdl) {
if ((!memcmp(dev_manager_get_logo(dev), "sd0", strlen("sd0")))
|| (!memcmp(dev_manager_get_logo(dev), "sd1", strlen("sd1")))) {
if (SD_BAUD_RATE_CHANGE_WHEN_SCAN > __this->old_speed) {
dev_ioctl(mount_hdl->dev.fd, IOCTL_SET_SPEED, __this->old_speed);//恢复原速
}
}
}
#endif
clock_remove_set(SCAN_DISK_CLK);
}
static const struct __scan_callback scan_cb = {
.enter = scan_enter,
.exit = scan_exit,
.scan_break = music_player_scandisk_break,
};
//*----------------------------------------------------------------------------*/
/**@brief music 模式提示音播放结束处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void music_tone_play_end_callback(void *priv, int flag)
{
u32 index = (u32)priv;
char *logo = NULL;
if (APP_MUSIC_TASK != app_get_curr_task()) {
log_error("tone callback task out \n");
return;
}
switch (index) {
case IDEX_TONE_MUSIC:
///提示音播放结束, 启动播放器播放
music_player_play_start();
break;
#if (MUSIC_DEVICE_TONE_EN)
case DEVICE_INDEX_UDISK:
case DEVICE_INDEX_UDISK_REC:
case DEVICE_INDEX_SD0:
case DEVICE_INDEX_SD0_REC:
case DEVICE_INDEX_SD1:
case DEVICE_INDEX_SD1_REC:
for (int i = 0; i < ARRAY_SIZE(device_tone); i++) {
if (index == device_tone[i].index) {
logo = device_tone[i].logo;
break;
}
}
app_task_put_key_msg(KEY_MUSIC_DEVICE_TONE_END, (int)logo);
break;
#endif
default:
break;
}
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式解码错误处理
@param err:MUSIC_PLAYER错误码表枚举
@return
@note
*/
/*----------------------------------------------------------------------------*/
void music_player_err_deal(int err)
{
u16 msg = KEY_NULL;
char *logo = NULL;
if (err != MUSIC_PLAYER_ERR_NULL && err != MUSIC_PLAYER_ERR_DECODE_FAIL) {
__this->file_err_counter = 0;///清除错误文件累计
}
if (err != MUSIC_PLAYER_ERR_NULL && err != MUSIC_PLAYER_SUCC) {
log_e("music player err = %d\n", err);
}
switch (err) {
case MUSIC_PLAYER_SUCC:
__this->file_err_counter = 0;
break;
case MUSIC_PLAYER_ERR_NULL:
break;
case MUSIC_PLAYER_ERR_POINT:
case MUSIC_PLAYER_ERR_NO_RAM:
msg = KEY_MUSIC_PLAYER_QUIT;//退出音乐模式
break;
case MUSIC_PLAYER_ERR_DECODE_FAIL:
if (__this->file_err_counter >= music_player_get_file_total()) {
__this->file_err_counter = 0;
dev_manager_set_valid_by_logo(music_player_get_dev_cur(), 0);///将设备设置为无效设备
if (dev_manager_get_total(1) == 0) {//参数为1 :获取所有有效设备 参数0获取所有设备
msg = KEY_MUSIC_PLAYER_QUIT;//没有设备了,退出音乐模式
} else {
msg = KEY_MUSIC_AUTO_NEXT_DEV;///所有文件都是错误的, 切换到下一个设备
}
} else {
__this->file_err_counter ++;
if (__this->file_play_direct == 0) {
msg = KEY_MUSIC_NEXT;//播放下一曲
} else {
msg = KEY_MUSIC_PREV;//播放上一曲
}
}
break;
case MUSIC_PLAYER_ERR_DEV_NOFOUND:
log_e("MUSIC_PLAYER_ERR_DEV_NOFOUND \n");
if (dev_manager_get_total(1) == 0) {//参数为1 :获取所有有效设备 参数0获取所有设备
msg = KEY_MUSIC_PLAYER_QUIT;///没有设备在线, 退出音乐模式
} else {
msg = KEY_MUSIC_PLAYER_START;///没有找到指定设备, 播放之前的活动设备
}
break;
case MUSIC_PLAYER_ERR_FSCAN:
///需要结合music_player_scandisk_break中处理的标志位处理
if (__this->scandisk_break) {
__this->scandisk_break = 0;
///此处不做任何处理, 打断的事件已经重发, 由重发事件执行后续处理
break;
}
case MUSIC_PLAYER_ERR_DEV_READ:
case MUSIC_PLAYER_ERR_DEV_OFFLINE:
log_e("MUSIC_PLAYER_ERR_DEV_OFFLINE \n");
logo = music_player_get_dev_cur();
if (dev_manager_online_check_by_logo(logo, 1)) {
///如果错误失败在线, 并且是播放过程中产生的,先记录下断点
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
music_player_stop(0);//先停止防止下一步操作VM卡顿
breakpoint_vm_write(breakpoint, logo);
}
if (err == MUSIC_PLAYER_ERR_FSCAN) {
dev_manager_set_valid_by_logo(logo, 0);///将设备设置为无效设备
} else {
//针对读错误, 因为时间推到应用层有延时导致下一个模式判断不正常, 此处需要将设备卸载
dev_manager_unmount(logo);
}
}
if (dev_manager_get_total(1) == 0) {
app_status_handler(APP_STATUS_MUSIC_QUIT);
msg = KEY_MUSIC_PLAYER_QUIT;///没有设备在线, 退出音乐模式
} else {
msg = KEY_MUSIC_AUTO_NEXT_DEV;///切换设备
}
break;
case MUSIC_PLAYER_ERR_FILE_NOFOUND:
///查找文件有扫盘的可能也需要结合music_player_scandisk_break中处理的标志位处理
if (__this->scandisk_break) {
__this->scandisk_break = 0;
///此处不做任何处理, 打断的事件已经重发, 由重发事件执行后续处理
break;
}
case MUSIC_PLAYER_ERR_PARM:
logo = music_player_get_dev_cur();
if (dev_manager_online_check_by_logo(logo, 1)) {
if (music_player_get_file_total()) {
msg = KEY_MUSIC_PLAYER_PLAY_FIRST;///有文件,播放第一个文件
break;
}
}
if (dev_manager_get_total(1) == 0) {
msg = KEY_MUSIC_PLAYER_QUIT;//没有设备了,退出音乐模式
} else {
msg = KEY_MUSIC_AUTO_NEXT_DEV;
}
break;
case MUSIC_PLAYER_ERR_FILE_READ://文件读错误
msg = KEY_MUSIC_NEXT;//播放下一曲
break;
}
if (msg != KEY_NULL) {
app_task_put_key_msg(msg, 0);
}
}
//*----------------------------------------------------------------------------*/
/**@brief music 按键消息入口
@param
@return 1common不再处理 0common处理
@note
*/
/*----------------------------------------------------------------------------*/
static int music_key_event_opr(struct sys_event *event)
{
int ret = true;
int err = MUSIC_PLAYER_ERR_NULL;
u8 vol, auto_next_dev;
int mode ;
char *logo = NULL;
int msg[2];
msg[0] = event->u.key.event;
msg[1] = event->u.key.value;//
static int msg_demo = 0;
log_i("music task msg = %d\n", msg[0]);
switch (msg[0]) {
case KEY_MUSIC_DEVICE_TONE_END:
#if (MUSIC_DEVICE_TONE_EN)
logo = (char *)msg[1];
log_i("KEY_MUSIC_DEVICE_TONE_END %s\n", logo);
if (logo) {
if (true == breakpoint_vm_read(breakpoint, logo)) {
err = music_player_play_by_breakpoint(logo, breakpoint);
} else {
err = music_player_play_first_file(logo);
}
}
break;
#endif
case KEY_MUSIC_PLAYER_START:
log_i("KEY_MUSIC_PLAYER_START !!\n");
app_status_handler(APP_STATUS_MUSIC_PLAY);
///断点播放活动设备
logo = dev_manager_get_logo(dev_manager_find_active(1));
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
if (music_player_get_dev_cur() && logo) {
///播放的设备跟当前活动的设备是同一个设备,不处理
if (0 == strcmp(logo, music_player_get_dev_cur())) {
log_w("the same dev!!\n");
break;
}
}
}
#if (MUSIC_DEVICE_TONE_EN)
if (music_device_tone_play(logo) == true) {
break;
}
#endif
if (true == breakpoint_vm_read(breakpoint, logo)) {
err = music_player_play_by_breakpoint(logo, breakpoint);
} else {
err = music_player_play_first_file(logo);
}
break;
///播放器退出处理
case KEY_MUSIC_PLAYER_QUIT:
log_i("KEY_MUSIC_PLAYER_QUIT !!\n");
app_task_switch_next();
break;
///结束消息处理
case KEY_MUSIC_PLAYER_END:
log_i("KEY_MUSIC_PLAYER_END\n");
err = music_player_end_deal(msg[1]);
break;
//播放器解码错误处理
case KEY_MUSIC_PLAYER_DEC_ERR:
err = music_player_decode_err_deal(msg[1]);
break;
///播放执行类消息
case KEY_MUSIC_PP:
log_i("KEY_MUSIC_PP\n");
err = music_player_pp();
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
app_status_handler(APP_STATUS_MUSIC_PLAY);
ui_update_status(STATUS_MUSIC_PLAY);
} else {
app_status_handler(APP_STATUS_MUSIC_PP);
ui_update_status(STATUS_MUSIC_PAUSE);
}
printf("=============================================%d\n", music_player_get_play_status());
break;
case KEY_MUSIC_PLAYER_AUTO_NEXT:
log_i("KEY_MUSIC_PLAYER_AUTO_NEXT\n");
err = music_player_play_auto_next();
break;
case KEY_MUSIC_PLAYER_PLAY_FIRST:
log_i("KEY_MUSIC_PLAYER_PLAY_FIRST\n");
err = music_player_play_first_file(NULL);
break;
case KEY_MUSIC_PREV:
log_i("KEY_MUSIC_PREV\n");
app_status_handler(APP_STATUS_MUSIC_FFR);
__this->file_play_direct = 1;
err = music_player_play_prev();
break;
case KEY_MUSIC_NEXT:
log_i("KEY_MUSIC_NEXT\n");
app_status_handler(APP_STATUS_MUSIC_FFR);
__this->file_play_direct = 0;
err = music_player_play_next();
break;
case KEY_MUSIC_PLAYE_PREV_FOLDER:
log_i("KEY_MUSIC_PLAYE_PREV_FOLDER\n");
err = music_player_play_folder_prev();
break;
case KEY_MUSIC_PLAYE_NEXT_FOLDER:
log_i("KEY_MUSIC_PLAYE_NEXT_FOLDER\n");
err = music_player_play_folder_next();
break;
case KEY_MUSIC_AUTO_NEXT_DEV:
case KEY_MUSIC_CHANGE_DEV:
log_i("KEY_MUSIC_CHANGE_DEV\n");
auto_next_dev = ((msg[0] == KEY_MUSIC_AUTO_NEXT_DEV) ? 1 : 0);
logo = music_player_get_dev_next(auto_next_dev);
printf("next dev = %s\n", logo);
if (logo == NULL) { ///找不到下一个设备,不响应设备切换
break;
}
///切换设备前先保存一下上一个设备的断点信息,包括文件和解码信息
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
music_player_stop(0);//先停止防止下一步操作VM卡顿
breakpoint_vm_write(breakpoint, music_player_get_dev_cur());
}
#if (MUSIC_DEVICE_TONE_EN)
if (music_device_tone_play(logo) == true) {
break;
}
#endif
if (true == breakpoint_vm_read(breakpoint, logo)) {
err = music_player_play_by_breakpoint(logo, breakpoint);
} else {
err = music_player_play_first_file(logo);
}
break;
case KEY_MUSIC_PLAYE_REC_FOLDER_SWITCH:
log_i("KEY_MUSIC_PLAYE_REC_FOLDER_SWITCH\n");
#if (TCFG_RECORD_FOLDER_DEV_ENABLE)
///尝试保存断点
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
breakpoint_vm_write(breakpoint, music_player_get_dev_cur());
}
if (true == breakpoint_vm_read(breakpoint, music_player_get_cur_music_dev())) {
err = music_player_play_record_folder(NULL, breakpoint);
} else {
err = music_player_play_record_folder(NULL, NULL);
}
#endif//TCFG_RECORD_FOLDER_DEV_ENABLE
break;
case KEY_MUSIC_PLAYE_BY_DEV_FILENUM:
log_i("KEY_MUSIC_PLAYE_BY_DEV_FILENUM, file_number = %d\n", msg[1]);
logo = dev_manager_get_logo(dev_manager_find_active(1));
err = music_player_play_by_number(logo, msg[1]);
break;
case KEY_MUSIC_PLAYE_BY_DEV_SCLUST:
log_i("KEY_MUSIC_PLAYE_BY_DEV_SCLUST\n");
logo = dev_manager_get_logo(dev_manager_find_active(1));
err = music_player_play_by_sclust(logo, msg[1]);
break;
case KEY_MUSIC_PLAYE_BY_DEV_PATH:
log_i("KEY_MUSIC_PLAYE_BY_DEV_PATH\n");
err = music_player_play_by_path((char *)"udisk0", "/sin.wav");///this is a demo
break;
///非播放执行类消息
case KEY_MUSIC_FF:
log_i("KEY_MUSIC_FF\n");
app_status_handler(APP_STATUS_MUSIC_FFR);
music_player_ff(3);
break;
case KEY_MUSIC_FR:
log_i("KEY_MUSIC_FR\n");
app_status_handler(APP_STATUS_MUSIC_FFR);
music_player_fr(3);
break;
case KEY_MUSIC_CHANGE_REPEAT:
log_i("KEY_MUSIC_CHANGE_REPEAT\n");
mode = music_player_change_repeat_mode();
if (mode > 0) {
UI_SHOW_MENU(MENU_MUSIC_REPEATMODE, 1000, mode, NULL);
}
break;
case KEY_MUSIC_DELETE_FILE:
log_i("KEY_MUSIC_DELETE_FILE\n");
err = music_player_delete_playing_file();
break;
case KEY_MUSIC_PLAYER_AB_REPEAT_SWITCH:
file_dec_ab_repeat_switch();
break;
default:
ret = false;
break;
}
///错误处理
music_player_err_deal(err);
///smartbox info update
SMARTBOX_UPDATE(MUSIC_FUNCTION_MASK,
BIT(MUSIC_INFO_ATTR_STATUS) | BIT(MUSIC_INFO_ATTR_FILE_PLAY_MODE));
return ret;
}
//*----------------------------------------------------------------------------*/
/**@brief music 设备事件响应接口
@param
@return 1comomon不再做处理 0common统一处理
@note
*/
/*----------------------------------------------------------------------------*/
static int music_sys_event_handler(struct sys_event *event)
{
int err = 0;
char *logo = NULL;
char *evt_logo = NULL;
switch (event->type) {
case SYS_KEY_EVENT:
return music_key_event_opr(event);
case SYS_DEVICE_EVENT:
switch ((u32)event->arg) {
case DRIVER_EVENT_FROM_SD0:
case DRIVER_EVENT_FROM_SD1:
case DRIVER_EVENT_FROM_SD2:
evt_logo = (char *)event->u.dev.value;
case DEVICE_EVENT_FROM_OTG:
if ((u32)event->arg == DEVICE_EVENT_FROM_OTG) {
evt_logo = (char *)"udisk0";
}
int str_len = 0;
logo = music_player_get_phy_dev(&str_len);
log_i("evt_logo =%s, logo = %s len =%d\n", evt_logo, logo, str_len);
if (event->u.dev.event == DEVICE_EVENT_OUT) {
if (logo == NULL) {
break;
}
if (logo && (0 == memcmp(logo, evt_logo, str_len))) {
///相同的设备才响应
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
breakpoint_vm_write(breakpoint, logo);
}
memset(__this->device_tone_dev, 0, sizeof(__this->device_tone_dev));
///停止解码,防止设备掉线后还继续使用
music_player_stop(1);
///重新选择活动设备播放
app_task_put_key_msg(KEY_MUSIC_PLAYER_START, 0);//卸载了设备再执行
log_i("KEY_MUSIC_PLAYER_START AFTER UMOUNT\n");
}
} else {
#if (MUSIC_DEV_ONLINE_START_AFTER_MOUNT_EN == 0)
music_task_dev_online_start();
#endif
}
break;
default://switch((u32)event->arg)
break;
}
break;//SYS_DEVICE_EVENT
default://switch (event->type)
break;
}
return false;
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式切换前参数设置
@param type:,
MUSIC_TASK_START_BY_NORMAL
MUSIC_TASK_START_BY_SCLUST
val:
@return
@note music_player_play_start接口
*/
/*----------------------------------------------------------------------------*/
void music_task_set_parm(u8 type, int val)
{
__this->task_parm.type = type;
__this->task_parm.val = val;
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式首次播放
@param
@return
@note music_task_set_parm设置参数,
*/
/*----------------------------------------------------------------------------*/
static void music_player_play_start(void)
{
switch (__this->task_parm.type) {
case MUSIC_TASK_START_BY_NORMAL:
log_i("MUSIC_TASK_START_BY_NORMAL\n");
app_task_put_key_msg(KEY_MUSIC_PLAYER_START, 0);
break;
case MUSIC_TASK_START_BY_SCLUST:
log_i("MUSIC_TASK_START_BY_SCLUST\n");
app_task_put_key_msg(KEY_MUSIC_PLAYE_BY_DEV_SCLUST, __this->task_parm.val);
break;
default:
log_i("other MUSIC_TASK_START!!!\n");
break;
}
///提示音播放失败直接推送KEY_MUSIC_PLAYER_START启动播放
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式新设备上线处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void music_task_dev_online_start(void)
{
u8 save = 0;
char *logo = music_player_get_dev_cur();
if (logo && breakpoint) {
///新设备上线, 先记录当前设备断点, 然后播放活动设备
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
save = 1;
//这里不要直接记忆断点, 解码停了之后再记忆
//breakpoint_vm_write(breakpoint, logo);
}
}
///停止解码,播放新活动设备
music_player_stop(1);
if (save && breakpoint) {
breakpoint_vm_write(breakpoint, logo);
}
app_task_put_key_msg(KEY_MUSIC_PLAYER_START, 0);
log_i("KEY_MUSIC_PLAYER_START AFTER MOUNT\n");
//先挂载了设备再执行
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式初始化处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void music_task_start()
{
printf("music task start!!!!!\n");
music_idle_flag = 0;
ui_update_status(STATUS_MUSIC_MODE);
#if (TCFG_LRC_LYRICS_ENABLE)
extern int lrc_init(void);
lrc_init();
#endif
///显示初始化
UI_SHOW_WINDOW(ID_WINDOW_MUSIC);
UI_SHOW_MENU(MENU_WAIT, 0, 0, NULL);
///时钟初始化
clock_idle(MUSIC_IDLE_CLOCK);
///按键使能
sys_key_event_enable();
///播放器初始化
struct __player_parm parm = {0};
parm.cb = &music_player_callback;
parm.scan_cb = &scan_cb;
music_player_creat(NULL, &parm);
///获取断点句柄, 后面所有断点读/写都需要用到
breakpoint = breakpoint_handle_creat();
///初始化一些参数
__this->file_err_counter = 0;
__this->file_play_direct = 0;
__this->scandisk_break = 0;
memset(__this->device_tone_dev, 0, sizeof(__this->device_tone_dev));
}
//*----------------------------------------------------------------------------*/
/**@brief music 模式退出处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void music_task_close()
{
UI_HIDE_CURR_WINDOW();
tone_play_stop_by_path(tone_table[IDEX_TONE_MUSIC]);//停止播放提示音
char *logo = music_player_get_dev_cur();
if (music_player_get_playing_breakpoint(breakpoint, 1) == true) {
breakpoint_vm_write(breakpoint, logo);
}
music_set_dev_sync_mode(logo, 0);
breakpoint_handle_destroy(&breakpoint);
music_player_destroy();
#if (TCFG_LRC_LYRICS_ENABLE)
extern void lrc_exit(void);
lrc_exit();
#endif
memset(__this, 0, sizeof(struct __music));
music_idle_flag = 1;
}
//*----------------------------------------------------------------------------*/
/**@brief music 在线检测 切换模式判断使用
@param
@return 1 线 0 线
@note
*/
/*----------------------------------------------------------------------------*/
int music_app_check(void)
{
if (dev_manager_get_total(1)) {
return true;
}
return false;
}
//*----------------------------------------------------------------------------*/
/**@brief music 主任务
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void app_music_task()
{
int res;
int msg[32];
music_task_start();
#if (MUSIC_DEVICE_TONE_EN)
music_player_play_start();
#else
#if TCFG_DEC2TWS_ENABLE
extern void set_tws_background_connected_flag(u8 flag);
extern u8 get_tws_background_connected_flag();
if (get_tws_background_connected_flag()) { //不播放提示音
music_player_play_start();
set_tws_background_connected_flag(0);
} else
#endif
{
tone_play_with_callback_by_name(tone_table[IDEX_TONE_MUSIC], 1, music_tone_play_end_callback, (void *)IDEX_TONE_MUSIC);
}
#endif
while (1) {
app_task_get_msg(msg, ARRAY_SIZE(msg), 1);
switch (msg[0]) {
case APP_MSG_SYS_EVENT:
if (music_sys_event_handler((struct sys_event *)(&msg[1])) == false) {
app_default_event_deal((struct sys_event *)(&msg[1]));
}
break;
default:
break;
}
if (app_task_exitting()) {
music_task_close();
return;
}
}
}
static u8 music_idle_query(void)
{
return music_idle_flag;
}
REGISTER_LP_TARGET(music_lp_target) = {
.name = "music",
.is_idle = music_idle_query,
};
#else
void app_music_task()
{
}
#endif