KT24-1110_65E-HA-651B/apps/common/music/general_player.c

273 lines
7.9 KiB
C
Raw Permalink Normal View History

2024-11-10 10:44:17 +00:00
#include "app_config.h"
#include "key_event_deal.h"
#include "audio_enc.h"
#include "general_player.h"
#include "dev_manager.h"
#include "bt/bt.h"
#include "common/dev_status.h"
#include "app_task.h"
#include "app_msg.h"
#include "media/audio_decoder.h"
#include "file_operate/file_manager.h"
#include "audio_dec/audio_dec_file.h"
///播放参数,文件扫描时用,文件后缀等
static const char scan_parm[] = "-t"
#if (TCFG_DEC_MP3_ENABLE)
"MP1MP2MP3"
#endif
#if (TCFG_DEC_WMA_ENABLE)
"WMA"
#endif
#if ( TCFG_DEC_WAV_ENABLE || TCFG_DEC_DTS_ENABLE)
"WAVDTS"
#endif
#if (TCFG_DEC_FLAC_ENABLE)
"FLA"
#endif
#if (TCFG_DEC_APE_ENABLE)
"APE"
#endif
#if (TCFG_DEC_M4A_ENABLE)
"M4AAAC"
#endif
#if (TCFG_DEC_M4A_ENABLE || TCFG_DEC_ALAC_ENABLE)
"MP4"
#endif
#if (TCFG_DEC_AMR_ENABLE)
"AMR"
#endif
#if (TCFG_DEC_DECRYPT_ENABLE)
"SMP"
#endif
#if (TCFG_DEC_MIDI_ENABLE)
"MID"
#endif
" -sn -r"
;
struct __general_player {
struct __dev *dev;
struct vfscan *fsn;
FILE *file;
struct __scan_callback *scan_cb;
u8 scandisk_break;
};
static struct __general_player *general_player = NULL;
#define __this general_player
int general_player_init(struct __scan_callback *scan_cb)
{
printf("the general_player init\n");
__this = zalloc(sizeof(struct __general_player));
if (__this == NULL) {
return -1;
} else {
__this->scan_cb = scan_cb;
return 0;
}
}
void general_player_exit()
{
if (__this) {
general_player_stop(1);
free(__this);
__this = NULL;
}
}
void general_player_stop(u8 fsn_release)
{
if (__this == NULL) {
return ;
}
///停止解码
file_dec_close();
if (__this->file) {
fclose(__this->file);
__this->file = NULL;
}
if (fsn_release && __this->fsn) {
///根据播放情景, 通过设定flag决定是否需要释放fscan 释放后需要重新扫盘!!!
dev_manager_scan_disk_release(__this->fsn);
__this->fsn = NULL;
}
}
//可以添加播放回调函数
static int general_player_decode_start(FILE *file)
{
int ret = 0;
if (file) {
///get file short name
u8 file_name[12 + 1] = {0}; //8.3+\0
fget_name(file, file_name, sizeof(file_name));
log_i("\n");
log_i("file name: %s\n", file_name);
log_i("\n");
}
ret = file_dec_create(NULL, NULL);
if (ret) {
return GENERAL_PLAYER_ERR_NO_RAM;
}
ret = file_dec_open(file, NULL);
if (ret) {
return GENERAL_PLAYER_ERR_DECODE_FAIL;
}
return GENERAL_PLAYER_SUCC;
}
static const char *general_player_get_phy_dev(int *len)
{
if (__this) {
char *logo = dev_manager_get_logo(__this->dev);
if (logo) {
char *str = strstr(logo, "_rec");
if (str) {
///录音设备,切换到音乐设备播放
if (len) {
*len = strlen(logo) - strlen(str);
}
} else {
if (len) {
*len = strlen(logo);
}
}
return logo;
}
}
if (len) {
*len = 0;
}
return NULL;
}
int general_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 = general_player_get_phy_dev(&str_len);
//logo = dev_manager_get_logo(__this->dev);
///响应设备插拔打断
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;
}
break;
}
break;
}
if (__this->scandisk_break) {
///查询到需要打断的事件, 返回1 并且重新推送一次该事件,跑主循环处理流程
printf("\n--func=%s, line=%d\n", __FUNCTION__, __LINE__);
sys_event_notify(event);
printf("scandisk_break!!!!!!\n");
return 1;
} else {
return 0;
}
}
int general_play_by_sculst(char *logo, u32 sclust)
{
int ret = 0;
if (logo == NULL) {
return GENERAL_PLAYER_ERR_PARM;
}
char *cur_logo = dev_manager_get_logo(__this->dev);
if (cur_logo == NULL || strcmp(cur_logo, logo) != 0) {
if (cur_logo != NULL) {
general_player_stop(1);
}
__this->dev = dev_manager_find_spec(logo, 1);
if (!__this->dev) {
return GENERAL_PLAYER_ERR_DEV_NOFOUND;
}
__this->fsn = dev_manager_scan_disk(__this->dev, NULL, scan_parm, 0, __this->scan_cb);
if (!__this->fsn) {
return GENERAL_PLAYER_ERR_FSCAN;
}
__this->file = file_manager_select(__this->dev, __this->fsn, FSEL_BY_SCLUST, sclust, __this->scan_cb);
if (!__this->file) {
return GENERAL_PLAYER_ERR_FILE_NOFOUND;
}
ret = general_player_decode_start(__this->file);
if (ret != GENERAL_PLAYER_SUCC) {
return ret;
}
} else {
general_player_stop(0);
__this->file = file_manager_select(__this->dev, __this->fsn, FSEL_BY_SCLUST, sclust, __this->scan_cb);
if (!__this->file) {
return GENERAL_PLAYER_ERR_FILE_NOFOUND;
}
ret = general_player_decode_start(__this->file);
if (ret != GENERAL_PLAYER_SUCC) {
return ret;
}
}
return GENERAL_PLAYER_ERR_NULL;
}
void general_player_test()
{
int tmp = general_player_init(NULL);
if (!tmp) {
printf("the init succ\n");
general_play_by_sculst((char *)"sd0", 6);
} else {
printf("the init fail\n");
}
}