#include "app_music.h" #include "system/includes.h" #include "server/audio_server.h" #include "app_config.h" #include "action.h" #include "storage_device.h" #include "led_eyes.h" #include "server/led_ui_server.h" #include "reverb_deal.h" #include "fm/fm_manage.h" #include "app_power_manage.h" #include "syscfg/syscfg_id.h" #include "asm/rf_coexistence_config.h" #if (defined CONFIG_DUI_SDK_ENABLE) #ifdef CONFIG_NET_ENABLE #include "network_download/net_download.h" #include "server/ai_server.h" #include "lwip/netdb.h" #include "net/assign_macaddr.h" #include "net/config_network.h" #endif #include "event/key_event.h" #include "event/net_event.h" #include "event/bt_event.h" #include "event/device_event.h" #include "database.h" #include "asm/eq.h" #include "syscfg/syscfg_id.h" #ifdef CONFIG_BT_ENABLE #include "btstack/avctp_user.h" #include "btctrler/btctrler_task.h" extern const struct music_dec_ops *get_bt_music_dec_ops(void); extern void bt_connection_disable(void); extern void bt_connection_enable(void); extern int app_music_bt_event_handler(struct sys_event *event); extern void low_power_hw_unsleep_lock(void); extern void low_power_hw_unsleep_unlock(void); #endif enum { LISTEN_STATE_STOP = 0, LISTEN_STATE_STOPPING, LISTEN_STATE_START, LISTEN_STATE_WAKEUP, }; struct __wechat_url { struct list_head entry; void *url; }; /* #define CONFIG_HOLD_SEND_VOICE */ #define CONFIG_PLAY_PROMPT_DISABLE_KEY 0 //播放提示音时屏蔽按键 /* #define CONFIG_STORE_VOLUME */ #define VOLUME_STEP 5 #define MIN_VOLUME_VALUE 0 #define MAX_VOLUME_VALUE 80 #define INIT_VOLUME_VALUE 15 #if defined CONFIG_NO_SDRAM_ENABLE #define DEC_BUF_LEN 6 * 1024 #else #define DEC_BUF_LEN 12 * 1024 #endif static struct app_music_hdl music_handler; #define __this (&music_handler) static void app_music_play_mode_switch_notify(void); static int app_music_switch_local_device(const char *path); static int app_music_play_voice_prompt(const char *fname, void *dec_end_handler); extern int fs_update_check(const char *path); static const struct music_dec_ops local_music_dec_ops; static const struct { APP_LOCAL_PROMPT_TYPE_E prompt_type; const char *file_name; } local_prompt_table[] = { {APP_LOCAL_PROMPT_POWER_ON, "PowerOn.mp3"}, {APP_LOCAL_PROMPT_POWER_OFF, "PowerOff.mp3"}, {APP_LOCAL_PROMPT_PLAY_DOMAIN_MUSIC, "004.mp3"}, {APP_LOCAL_PROMPT_PLAY_DOMAIN_STORY, "005.mp3"}, {APP_LOCAL_PROMPT_PLAY_DOMAIN_SINOLOGY, "006.mp3"}, {APP_LOCAL_PROMPT_PLAY_DOMAIN_ENGLISH, "007.mp3"}, {APP_LOCAL_PROMPT_BT_OPEN, "BtOpen.mp3"}, {APP_LOCAL_PROMPT_BT_CLOSE, "BtClose.mp3"}, {APP_LOCAL_PROMPT_BT_CONNECTED, "BtSucceed.mp3"}, {APP_LOCAL_PROMPT_BT_DISCONNECT, "BtDisc.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONNECTING, "NetConnting.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONNECT_SUCCESS, "NetCfgSucc.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONNECT_FAIL, "NetCfgFail.mp3"}, {APP_LOCAL_PROMPT_WIFI_DISCONNECT, "NetDisc.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONFIG_START, "NetCfgEnter.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONFIG_INFO_RECV, "SsidRecv.mp3"}, {APP_LOCAL_PROMPT_WIFI_FIRST_CONFIG, "NetEmpty.mp3"}, {APP_LOCAL_PROMPT_WIFI_CONFIG_TIMEOUT, "NetCfgTo.mp3"}, {APP_LOCAL_PROMPT_LIGHT_OPEN, "LightOpen.mp3"}, {APP_LOCAL_PROMPT_LIGHT_CLOSE, "LightClose.mp3"}, {APP_LOCAL_PROMPT_AI_ASR_FAIL, "AiAsrFail.mp3"}, {APP_LOCAL_PROMPT_AI_TRANSLATE_FAIL, "AiTransFail.mp3"}, {APP_LOCAL_PROMPT_AI_PICTURE_FAIL, "AiPicFail.mp3"}, {APP_LOCAL_PROMPT_SEND_MESSAGE_FAIL, "SendMsgFail.mp3"}, {APP_LOCAL_PROMPT_RECV_NEW_MESSAGE, "RecvNewMsg.mp3"}, {APP_LOCAL_PROMPT_MESSAGE_TOO_SHORT, "MsgTooShort.mp3"}, {APP_LOCAL_PROMPT_MESSAGE_EMPTY, "MsgEmpty.mp3"}, {APP_LOCAL_PROMPT_LOW_BATTERY_LEVEL, "LowBatLevel.mp3"}, {APP_LOCAL_PROMPT_LOW_BATTERY_SHUTDOWN, "LowBatOff.mp3"}, {APP_LOCAL_PROMPT_ENTER_AI_TRANSLATE_MODE, "AiTransMode.mp3"}, {APP_LOCAL_PROMPT_ENTER_AI_ASR_MODE, "AiAsrMode.mp3"}, {APP_LOCAL_PROMPT_ENTER_AI_PICTURE_MODE, "PicModeIn.mp3"}, {APP_LOCAL_PROMPT_EXIT_AI_PICTURE_MODE, "PicModeOut.mp3"}, {APP_LOCAL_PROMPT_PICTURE_RECOGNIZE_FAIL, "PicRecgFail.mp3"}, {APP_LOCAL_PROMPT_SERVER_CONNECTED, "SerConnect.mp3"}, {APP_LOCAL_PROMPT_SERVER_DISCONNECT, "SerDiscon.mp3"}, {APP_LOCAL_PROMPT_ASR_EMPTY, "AsrEmpty.mp3"}, {APP_LOCAL_PROMPT_KWS_ENABLE, "KwsEnable.mp3"}, {APP_LOCAL_PROMPT_KWS_DISABLE, "KwsDisable.mp3"}, {APP_LOCAL_PROMPT_REVERB_ENABLE, "ReverbEnter.mp3"}, {APP_LOCAL_PROMPT_REVERB_DISABLE, "ReverbExit.mp3"}, {APP_LOCAL_PROMPT_ENTER_NETWORK_MODE, "NetMusic.mp3"}, {APP_LOCAL_PROMPT_ENTER_FLASH_MUSIC_MODE, "FlashMusic.mp3"}, {APP_LOCAL_PROMPT_ENTER_SDCARD_MUSIC_MODE, "SDcardMusic.mp3"}, {APP_LOCAL_PROMPT_ENTER_UDISK_MUSIC_MODE, "UdiskMusic.mp3"}, {APP_LOCAL_PROMPT_ENTER_FM_MUSIC_MODE, "FMMusic.mp3"}, {APP_LOCAL_PROMPT_PHONE_RING, "ring.mp3"}, {APP_LOCAL_PROMPT_AI_LISTEN_START, "rec.mp3"}, {APP_LOCAL_PROMPT_AI_LISTEN_STOP, "send.mp3"}, {APP_LOCAL_PROMPT_VOLUME_SET, "Volume.mp3"}, {APP_LOCAL_PROMPT_VOLUME_FULL, "VolumeFull.mp3"}, {APP_LOCAL_PROMPT_DEVICE_BIND_SUCCESS, "BindSucc.mp3"}, {APP_LOCAL_PROMPT_DEVICE_BIND_FAIL, "BindFail.mp3"}, {APP_LOCAL_PROMPT_DEVICE_UNBIND_DEFAULT, "UnbindDef.mp3"}, {APP_LOCAL_PROMPT_DEVICE_UNBIND_SUCCESS, "UnbindSucc.mp3"}, {APP_LOCAL_PROMPT_DEVICE_UNBIND_FAIL, "UnbindFail.mp3"}, {APP_LOCAL_PROMPT_DEVICE_INFO_RESTORE, "Restore.mp3"}, {APP_LOCAL_PROMPT_DEVICE_RESTART, "Restart.mp3"}, {APP_LOCAL_PROMPT_OTA_UPGRADE_START, "OtaInUpdate.mp3"}, {APP_LOCAL_PROMPT_OTA_UPGRADE_SUCCESS, "OtaSuccess.mp3"}, {APP_LOCAL_PROMPT_OTA_UPGRADE_FAIL, "OtaFailed.mp3"}, {APP_LOCAL_PROMPT_ALARM, "reminder.mp3"}, {APP_LOCAL_PROMPT_SCHEDULE, "schedule.mp3"}, }; static const u8 dir_name_chars[][8] = { { 0x3F, 0x51, 0x4C, 0x6B, 0x00, 0x00 }, //儿歌 { 0x45, 0x65, 0x8B, 0x4E, 0x00, 0x00 }, //故事 { 0xFD, 0x56, 0x66, 0x5B, 0x00, 0x00 }, //国学 { 0xF1, 0x82, 0xED, 0x8B, 0x00, 0x00 }, //英语 }; static const char *dir_name_chars_english[] = { "CHILD", //儿歌 "STORY", //故事 "CHINESE", //国学 "ENGLISH", //英语 }; static const char *voice_prompt_file[] = { "004.mp3", //儿歌 "005.mp3", //故事 "006.mp3", //国学 "007.mp3", //英语 }; #if TCFG_EQ_ENABLE && !defined EQ_CORE_V1 void *get_eq_hdl(void) { return __this->eq_hdl; } #endif #ifdef CONFIG_ASR_ALGORITHM extern int aisp_open(u16 sample_rate); extern void aisp_suspend(void); extern void aisp_resume(void); #endif static const char *find_local_prompt_filename(APP_LOCAL_PROMPT_TYPE_E prompt_type) { for (int i = 0; i < ARRAY_SIZE(local_prompt_table); ++i) { if (local_prompt_table[i].prompt_type == prompt_type) { return local_prompt_table[i].file_name; } } return NULL; } static int app_music_shutdown(int priv) { sys_power_poweroff(); return 0; } #include "asm/pwm.h" #define LED_GREEN_GPIO IO_PORTC_01 #define LED_RED_GPIO IO_PORTC_02 #define LED_BLUE_GPIO IO_PORTC_06 enum LED_MODE { LED_MUTE = 0, LED_OFF, LED_ON, LED_RED_BREATH, LED_RED_HOLD, LED_GREEN_BREATH, LED_GREEN_HOLD, LED_BLUE_BREATH, LED_BLUE_HOLD, }; static DEFINE_SPINLOCK(led_lock); static void *pwm_led_open(void) { struct pwm_platform_data pwm = {0}; void *pwm_dev_handl = dev_open("pwm0", &pwm); if (!pwm_dev_handl) { printf("open pwm err !!!\n"); return NULL; } pwm.pwm_ch = PWMCH4_L; pwm.freq = 400; pwm.duty = 20; dev_ioctl(pwm_dev_handl, PWM_SET_FREQ, (u32)&pwm); return pwm_dev_handl; } static void pwm_led_close(void *pwm_dev_handl) { struct pwm_platform_data pwm = {0}; pwm.pwm_ch = PWMCH4_L; dev_ioctl(pwm_dev_handl, PWM_REMOV_CHANNEL, (u32)&pwm); dev_close(pwm_dev_handl); } static void set_led_mode(enum LED_MODE led_mode) { static void *pwm_hdl = NULL; spin_lock(&led_lock); __this->led_breath_on = 1; if (led_mode > LED_MUTE) { __this->led_mode = led_mode; } if (__this->mute) { if (led_mode == LED_MUTE) { gpio_direction_output(LED_BLUE_GPIO, 1); gpio_direction_output(LED_GREEN_GPIO, 1); gpio_direction_output(LED_RED_GPIO, 0); pwm_hdl = pwm_led_open(); } spin_unlock(&led_lock); return; } if (pwm_hdl) { pwm_led_close(pwm_hdl); pwm_hdl = NULL; gpio_direction_output(LED_BLUE_GPIO, 1); gpio_direction_output(LED_GREEN_GPIO, 1); gpio_direction_output(LED_RED_GPIO, 1); } switch (__this->led_mode) { case LED_RED_BREATH: case LED_RED_HOLD: gpio_direction_output(LED_GREEN_GPIO, 1); gpio_direction_output(LED_RED_GPIO, 0); gpio_direction_output(LED_BLUE_GPIO, 1); break; case LED_GREEN_BREATH: case LED_GREEN_HOLD: gpio_direction_output(LED_GREEN_GPIO, 0); gpio_direction_output(LED_RED_GPIO, 1); gpio_direction_output(LED_BLUE_GPIO, 1); break; case LED_OFF: gpio_direction_output(LED_GREEN_GPIO, 1); gpio_direction_output(LED_RED_GPIO, 1); gpio_direction_output(LED_BLUE_GPIO, 1); break; default: break; } spin_unlock(&led_lock); } static void led_breath_timer(void *p) { spin_lock(&led_lock); if (__this->mute) { spin_unlock(&led_lock); return; } switch (__this->led_mode) { case LED_RED_BREATH: gpio_direction_output(LED_RED_GPIO, __this->led_breath_on); break; case LED_GREEN_BREATH: gpio_direction_output(LED_GREEN_GPIO, __this->led_breath_on); break; default: break; } __this->led_breath_on = !__this->led_breath_on; spin_unlock(&led_lock); } static void set_dec_end_handler(void *file, void *handler, int arg0, int arg1) { __this->dec_end_file = file; __this->dec_end_args[0] = arg0; __this->dec_end_args[1] = arg1; __this->dec_end_handler = handler; } static void do_dec_end_handler(void *file) { if (file == __this->dec_end_file) { __this->dec_end_file = NULL; if (__this->dec_end_handler) { if (__this->dec_end_args[1] == -1) { ((int (*)(int))__this->dec_end_handler)(__this->dec_end_args[0]); } else { ((int (*)(int, int))__this->dec_end_handler)(__this->dec_end_args[0], __this->dec_end_args[1]); } } } } static const char *__get_dirname_file(const char *name, int len) { for (int i = 0; i < ARRAY_SIZE(dir_name_chars); i++) { if (name[0] == '\\' && name[1] == 'U') { if (!memcmp(dir_name_chars[i], name + 2, len - 2)) { return voice_prompt_file[i]; } } else { if (!memcmp(dir_name_chars[i], name, len)) { return voice_prompt_file[i]; } } } for (int i = 0; i < ARRAY_SIZE(dir_name_chars_english); i++) { if (!strncmp(dir_name_chars_english[i], name, len)) { return voice_prompt_file[i]; } } for (int i = 0; i < ARRAY_SIZE(voice_prompt_file); i++) { if (!memcmp(name, voice_prompt_file[i], 3)) { return voice_prompt_file[i]; } } return NULL; } static void mix_dec_server_event_handler(void *priv, int argc, int *argv) { union audio_req r = {0}; switch (argv[0]) { case AUDIO_SERVER_EVENT_ERR: puts("mix_music: AUDIO_SERVER_EVENT_ERR\n"); case AUDIO_SERVER_EVENT_END: puts("mix_music: AUDIO_SERVER_EVENT_END\n"); r.dec.cmd = AUDIO_DEC_STOP; server_request(priv, AUDIO_REQ_DEC, &r); server_close(priv); fclose((FILE *)argv[1]); break; default: break; } } static int app_music_play_mix_file(const char *path) { int err = 0; union audio_req req = {0}; #if defined CONFIG_NO_SDRAM_ENABLE || !defined CONFIG_AUDIO_MIX_ENABLE return 0; #endif log_d("play_mix_file : %s\n", path); if (__this->dec_ops->dec_status(0) == AUDIO_DEC_START) { return -ENOENT; } FILE *file = fopen(path, "r"); if (!file) { return -ENOENT; } void *dec_server = server_open("audio_server", "dec"); if (!dec_server) { goto __err; } server_register_event_handler(dec_server, dec_server, mix_dec_server_event_handler); req.dec.cmd = AUDIO_DEC_OPEN; req.dec.volume = __this->volume; req.dec.output_buf_len = DEC_BUF_LEN; req.dec.file = file; req.dec.sample_source = "dac"; err = server_request(dec_server, AUDIO_REQ_DEC, &req); if (err) { goto __err; } req.dec.cmd = AUDIO_DEC_START; err = server_request(dec_server, AUDIO_REQ_DEC, &req); if (err) { goto __err; } puts("play_mix_music_file: suss\n"); return 0; __err: if (dec_server) { server_close(dec_server); } if (file) { fclose(file); } printf("play_mix_music_file: fail : %d\n", err); return err; } static int __get_dec_breakpoint(struct audio_dec_breakpoint *bp) { int err; union audio_req r = {0}; bp->len = 0; r.dec.bp = bp; r.dec.cmd = AUDIO_DEC_GET_BREAKPOINT; if (bp->data) { free(bp->data); bp->data = NULL; } err = server_request(__this->dec_server, AUDIO_REQ_DEC, &r); if (err) { return err; } if (r.dec.status == AUDIO_DEC_STOP) { bp->len = 0; free(bp->data); bp->data = NULL; return -EFAULT; } /* put_buf(bp->data, bp->len); */ return 0; } static int __set_dec_volume(int step) { union audio_req req = {0}; extern u8 get_s_is_record(void); int volume = __this->volume + step; if (volume < MIN_VOLUME_VALUE) { volume = MIN_VOLUME_VALUE; } else if (volume > MAX_VOLUME_VALUE) { #ifdef CONFIG_NET_ENABLE if (!get_s_is_record() && (!is_in_config_network_state())) #endif { app_music_play_mix_file(CONFIG_VOICE_PROMPT_FILE_PATH"VolumeFull.mp3"); } volume = MAX_VOLUME_VALUE; } if (volume == __this->volume) { return -EINVAL; } __this->volume = volume; #ifdef CONFIG_NET_ENABLE if (!get_s_is_record() && (!is_in_config_network_state())) #endif { if (volume == MAX_VOLUME_VALUE) { app_music_play_mix_file(CONFIG_VOICE_PROMPT_FILE_PATH"VolumeFull.mp3"); } else { app_music_play_mix_file(CONFIG_VOICE_PROMPT_FILE_PATH"Volume.mp3"); } } log_d("set_dec_volume: %d\n", volume); req.dec.cmd = AUDIO_DEC_SET_VOLUME; req.dec.volume = volume; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); return 0; } static int __get_dec_status(int priv) { union audio_req req = {0}; req.dec.cmd = AUDIO_DEC_GET_STATUS; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); return req.dec.status; } //打断提示音的播放 static void app_music_stop_voice_prompt(void) { if (__this->play_voice_prompt) { local_music_dec_ops.dec_stop(0); __this->play_voice_prompt = 0; if (!__this->key_disable) { key_event_enable(); } } } /* * ****************************本地播放************************************* */ static int local_music_dec_play_pause(u8 notify) { union audio_req r = {0}; #ifdef CONFIG_DEC_ANALOG_VOLUME_ENABLE r.dec.attr = AUDIO_ATTR_FADE_INOUT; #endif r.dec.cmd = AUDIO_DEC_PP; server_request(__this->dec_server, AUDIO_REQ_DEC, &r); return 0; } static int local_music_dec_stop(int save_breakpoint) { int err = 0; union audio_req req; if (!__this->file) { return 0; } puts("local_music_dec_stop\n"); if (save_breakpoint) { err = __get_dec_breakpoint(&__this->local_bp); if (!err) { if (__this->local_bp_file && __this->local_bp_file != __this->file) { fclose(__this->local_bp_file); } __this->local_bp_file = __this->file; } } req.dec.cmd = AUDIO_DEC_STOP; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); int argv[2]; argv[0] = AUDIO_SERVER_EVENT_END; argv[1] = (int)__this->file; server_event_handler_del(__this->dec_server, 2, argv); if (!save_breakpoint || err) { fclose(__this->file); if (__this->local_bp_file == __this->file) { __this->local_bp_file = NULL; } } __this->file = NULL; return 0; } /* * 选择文件并播放, mode为选择方式,如FSEL_NEXT_FILE */ static int local_music_dec_file(void *file, int breakpoint, void *handler, int arg) { int err; union audio_req req = {0}; puts("app_music_dec_local_file\n"); if (__this->file == file && file && __this->local_play_mode == SINGLE_PLAY_MODE && __this->dec_ops == &local_music_dec_ops) { puts("local_music_dec_stop no close file\n"); req.dec.cmd = AUDIO_DEC_STOP; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); if (__this->local_bp_file == __this->file) { __this->local_bp_file = NULL; } } else { __this->dec_ops->dec_stop(0); } if (!file) { return -1; } set_dec_end_handler(file, handler, arg, -1); if (breakpoint) { req.dec.bp = &__this->local_bp; } req.dec.cmd = AUDIO_DEC_OPEN; req.dec.volume = __this->volume; req.dec.output_buf = NULL; req.dec.output_buf_len = DEC_BUF_LEN; req.dec.file = (FILE *)file; req.dec.channel = 0; req.dec.sample_rate = 0; req.dec.priority = 1; req.dec.vfs_ops = NULL; req.dec.sample_source = "dac"; #if 0 //变声变调功能 req.dec.speedV = 80; // >80是变快,<80是变慢,建议范围:30到130 req.dec.pitchV = 32768; // >32768是音调变高,<32768音调变低,建议范围20000到50000 req.dec.attr = AUDIO_ATTR_PS_EN; #endif #if TCFG_EQ_ENABLE #if defined EQ_CORE_V1 req.dec.attr |= AUDIO_ATTR_EQ_EN; #if TCFG_LIMITER_ENABLE req.dec.attr |= AUDIO_ATTR_EQ32BIT_EN; #endif #if TCFG_DRC_ENABLE req.dec.attr |= AUDIO_ATTR_DRC_EN; #endif #else struct eq_s_attr eq_attr = {0}; extern void set_eq_req_attr_parm(struct eq_s_attr * eq_attr); set_eq_req_attr_parm(&eq_attr); if (!__this->play_voice_prompt) { req.dec.eq_attr = &eq_attr; req.dec.eq_hdl = __this->eq_hdl; } #endif #endif #if CONFIG_DEC_DECRYPT_ENABLE if (!__this->play_voice_prompt) { extern const struct audio_vfs_ops *get_decrypt_vfs_ops(void); req.dec.vfs_ops = get_decrypt_vfs_ops(); req.dec.attr |= AUDIO_ATTR_DECRYPT_DEC; } #endif err = server_request(__this->dec_server, AUDIO_REQ_DEC, &req); if (err) { log_e("audio_dec_open: err = %d\n", err); fclose((FILE *)file); return err; } __this->play_time = req.dec.play_time; __this->total_time = req.dec.total_time; if (breakpoint) { __this->local_bp.len = 0; } if (__this->seek_step && !__this->play_voice_prompt) { __this->dec_ops->dec_seek(__this->seek_step); __this->seek_step = 0; } req.dec.cmd = AUDIO_DEC_START; err = server_request(__this->dec_server, AUDIO_REQ_DEC, &req); if (err) { log_e("audio_dec_start: err = %d\n", err); fclose((FILE *)file); return err; } __this->file = (FILE *)file; __this->cmp_file = (void *)file; if (!__this->play_voice_prompt) { __this->dec_ops = &local_music_dec_ops; } puts("play_music_file: suss\n"); return 0; } static int local_music_dec_switch_file(int fsel_mode) { int i = 0; FILE *file = NULL; int len = 0; char name[64] = {0}; char vm_name[64] = {0}; puts("app_music_dec_switch_file\n"); if (!__this->fscan || !__this->fscan->file_number) { return -ENOENT; } app_music_stop_voice_prompt(); if (__this->local_play_mode == SINGLE_PLAY_MODE && fsel_mode == FSEL_NEXT_FILE && __this->file) { return local_music_dec_file(__this->file, 0, local_music_dec_switch_file, FSEL_NEXT_FILE); } if (__this->local_play_mode == RANDOM_PLAY_MODE) { fsel_mode = FSEL_BY_NUMBER; } __retry: do { file = fselect(__this->fscan, fsel_mode, fsel_mode == FSEL_BY_NUMBER ? (CPU_RAND() % __this->fscan->file_number) + 1 : 0); if (file) { memset(name, 0, sizeof(name)); len = fget_name(file, (u8 *)name, sizeof(name)); if (len > 0) { printf("play file name : %s\n", name); } ++i; break; } if (fsel_mode == FSEL_NEXT_FILE) { fsel_mode = FSEL_FIRST_FILE; } else if (fsel_mode == FSEL_PREV_FILE) { fsel_mode = FSEL_LAST_FILE; } else { break; } } while (i++ < __this->fscan->file_number); if (!file) { return -ENOENT; } if (!__this->local_play_all) { return local_music_dec_file(file, 0, local_music_dec_switch_file, FSEL_NEXT_FILE); } if (0 != local_music_dec_file(file, 0, local_music_dec_switch_file, FSEL_NEXT_FILE)) { if (fsel_mode == FSEL_FIRST_FILE) { fsel_mode = FSEL_NEXT_FILE; } else if (fsel_mode == FSEL_LAST_FILE) { fsel_mode = FSEL_PREV_FILE; } if (i < __this->fscan->file_number) { goto __retry; } } return 0; } static void local_music_create_new_dir(void) { if (__this->local_path && strcmp(__this->local_path, CONFIG_MUSIC_PATH_FLASH)) { char path[64] = {0}; char dir[8] = {'\\', 'U', 0, 0, 0, 0, '/'}; for (u8 i = 0; i < 4; ++i) { memcpy(&dir[2], dir_name_chars[i], 4); strcpy(path, __this->local_path); memcpy(path + strlen(path), dir, sizeof(dir)); FILE *fp = fopen(path, "w+"); if (fp) { fclose(fp); } } } } static int local_music_dec_switch_dir(int fsel_mode) { int len = 0; int i = 0; char name[16] = {0}; char path[128] = {0}; FILE *dir = NULL; FILE *file = NULL; puts("app_music_dec_switch_dir\n"); if (!__this->local_path) { return app_music_switch_local_device("unknown"); } if (__this->local_play_all && __this->local_path != CONFIG_MUSIC_PATH_FLASH) { if (__this->fscan) { fscan_release(__this->fscan); } #if CONFIG_DEC_DECRYPT_ENABLE __this->fscan = fscan(__this->local_path, "-r -tMP3WMAWAVM4AAMRAPEFLAAACSPXDTSADPSMP -sn", 2); #else __this->fscan = fscan(__this->local_path, "-r -tMP3WMAWAVM4AAMRAPEFLAAACSPXDTSADP -sn", 2); #endif if (!__this->fscan) { return -ENOENT; } return local_music_dec_switch_file(FSEL_FIRST_FILE); } //搜索文件夹 if (!__this->dir_list) { __this->dir_list = fscan(__this->local_path, "-d -sn", 2); if (!__this->dir_list || __this->dir_list->file_number == 0) { puts("no_music_dir_find\n"); local_music_create_new_dir(); return -ENOENT; } } //选择文件夹 __again: do { dir = fselect(__this->dir_list, fsel_mode, 0); if (dir) { i++; break; } if (fsel_mode == FSEL_NEXT_FILE) { fsel_mode = FSEL_FIRST_FILE; } else if (fsel_mode == FSEL_PREV_FILE) { fsel_mode = FSEL_LAST_FILE; } else { puts("fselect_dir_faild, create dir\n"); return -ENOENT; } } while (i++ < __this->dir_list->file_number); if (!dir) { return -ENOENT; } len = fget_name(dir, (u8 *)name, sizeof(name) - 1); if (0 == len) { fclose(dir); if (fsel_mode == FSEL_FIRST_FILE) { fsel_mode = FSEL_NEXT_FILE; } else if (fsel_mode == FSEL_LAST_FILE) { fsel_mode = FSEL_PREV_FILE; } goto __again; } #if 0 //根据文件夹名打开提示音文件,不需要可屏蔽 int __len = 0; char __name[64] = {0}; __len = fget_name(dir, (u8 *)__name, sizeof(__name) - 1); const char *note = __get_dirname_file(__name, __len); if (note) { fname_to_path(path, CONFIG_VOICE_PROMPT_FILE_PATH, note, strlen(note) + 1, 0, 0); } else { fname_to_path(path, CONFIG_VOICE_PROMPT_FILE_PATH, __name, strlen(__name) + 1, 0, 0); } file = fopen(path, "r"); if (!file) { if (i >= __this->dir_list->file_number) { fclose(dir); puts("fselect_no_purpose_dir, create dir\n"); local_music_create_new_dir(); return -ENOENT; } if (fsel_mode == FSEL_FIRST_FILE) { fsel_mode = FSEL_NEXT_FILE; } else if (fsel_mode == FSEL_LAST_FILE) { fsel_mode = FSEL_PREV_FILE; } fclose(dir); goto __again; } if (note) { fclose(file); app_music_play_voice_prompt(note, local_music_dec_switch_file); } else { __this->play_voice_prompt = 1; #if CONFIG_PLAY_PROMPT_DISABLE_KEY key_event_disable(); #endif local_music_dec_file(file, 0, local_music_dec_switch_file, FSEL_FIRST_FILE); } #endif fclose(dir); if (__this->fscan) { fscan_release(__this->fscan); } /* * 搜索文件夹下的文件,按序号排序 */ fname_to_path(path, __this->local_path, name, len, 1, 0); #if 0 //此处播放指定目录,用户填写的目录路径要注意中文编码问题,具体例子见local_music_create_new_dir函数,看不懂就直接用16进制把路径打印出来 const char *user_dir = ""; if (!file && strcmp(path, user_dir)) { printf("dir name : %s\n", path); if (fsel_mode == FSEL_FIRST_FILE) { fsel_mode = FSEL_NEXT_FILE; } else if (fsel_mode == FSEL_LAST_FILE) { fsel_mode = FSEL_PREV_FILE; } goto __again; } #endif printf("fscan path : %s\n", path); #if CONFIG_DEC_DECRYPT_ENABLE __this->fscan = fscan(path, "-tMP3WMAWAVM4AAMRAPEFLAAACSPXDTSADPSMP -sn", 2); #else __this->fscan = fscan(path, "-tMP3WMAWAVM4AAMRAPEFLAAACSPXDTSADP -sn", 2); #endif if (!file) { if (!__this->fscan || !__this->fscan->file_number) { if (fsel_mode == FSEL_FIRST_FILE) { fsel_mode = FSEL_NEXT_FILE; } else if (fsel_mode == FSEL_LAST_FILE) { fsel_mode = FSEL_PREV_FILE; } goto __again; } local_music_dec_switch_file(FSEL_FIRST_FILE); } return 0; } static int local_music_dec_breakpoint(int priv) { if (!__this->fscan) { return -ENOENT; } if (__this->local_bp.len == 0) { return -ENOENT; } return local_music_dec_file(__this->local_bp_file, 1, local_music_dec_switch_file, FSEL_NEXT_FILE); } static int local_musci_dec_progress(int time) { return 0; } static int local_music_dec_volume(int step) { return 0; } static int local_music_dec_seek(int seek_step) { int err; union audio_req r = {0}; if (0 == seek_step) { return 0; } if (__this->total_time != 0 && __this->total_time != -1) { if (__this->play_time + seek_step <= 0 || __this->play_time + seek_step >= __this->total_time) { log_e("local music seek out of range\n"); return -1; } } if (seek_step > 0) { r.dec.cmd = AUDIO_DEC_FF; r.dec.ff_fr_step = seek_step; } else { r.dec.cmd = AUDIO_DEC_FR; r.dec.ff_fr_step = -seek_step; } log_i("local music seek step : %d\n", seek_step); err = server_request(__this->dec_server, AUDIO_REQ_DEC, &r); return 0; } static const struct music_dec_ops local_music_dec_ops = { .switch_dir = local_music_dec_switch_dir, .switch_file = local_music_dec_switch_file, .dec_file = local_music_dec_file, .dec_breakpoint = local_music_dec_breakpoint, .dec_play_pause = local_music_dec_play_pause, .dec_volume = local_music_dec_volume, .dec_progress = local_musci_dec_progress, .dec_stop = local_music_dec_stop, .dec_seek = local_music_dec_seek, .dec_status = __get_dec_status, }; /* * flash、sd卡和U盘之间的切换 */ static int app_music_switch_local_device(const char *path) { puts("app_music_switch_local_device\n"); if (__this->dir_list) { fscan_release(__this->dir_list); __this->dir_list = NULL; } if (__this->fscan) { fscan_release(__this->fscan); __this->fscan = NULL; } if (__this->local_bp_file && __this->local_bp_file != __this->file) { fclose(__this->local_bp_file); __this->local_bp_file = NULL; __this->local_bp.len = 0; } if ((path && !strcmp(path, "unknown")) || !__this->local_path) { return 0; } else if (path == CONFIG_MUSIC_PATH_SD || __this->local_path == CONFIG_MUSIC_PATH_SD) { if (!storage_device_ready()) { return -1; } __this->wait_sd = 0; __this->media_dev_online |= BIT(0); } else if (path == CONFIG_MUSIC_PATH_UDISK || __this->local_path == CONFIG_MUSIC_PATH_UDISK) { #if TCFG_UDISK_ENABLE if (!udisk_storage_device_ready(0)) { return -1; } __this->wait_udisk = 0; __this->media_dev_online |= BIT(1); #endif } if (path) { __this->local_path = path; } local_music_dec_switch_dir(FSEL_FIRST_FILE); return 0; } /* * ******************************FM电台************************************* */ #if CONFIG_FM_DEV_ENABLE static const struct music_dec_ops fm_music_dec_ops; static int fm_music_dec_switch_dir(int fsel_mode) { return fm_server_msg_post(fsel_mode == FSEL_NEXT_FILE ? FM_SCAN_ALL_DOWN : FM_SCAN_ALL_UP); } static int fm_music_dec_switch_file(int fsel_mode) { return fm_server_msg_post(fsel_mode == FSEL_NEXT_FILE ? FM_NEXT_STATION : FM_PREV_STATION); } static int fm_music_dec_file(void *priv, int breakpoint, void *handler, int arg) { if (0 != fm_server_init()) { return -1; } set_dec_end_handler(priv, handler, arg, -1); __this->dec_ops = &fm_music_dec_ops; return 0; } static int fm_music_dec_play_pause(u8 notify) { return fm_server_msg_post(FM_MUSIC_PP); } static int fm_music_dec_volume(int step) { return fm_server_msg_post(step > 0 ? FM_VOLUME_DOWN : FM_VOLUME_UP); } static int fm_music_dec_stop(int save_breakpoint) { if (1 == save_breakpoint) { return fm_server_msg_post(FM_DEC_OFF); } else { fm_sever_kill(); } return 0; } static int fm_music_dec_breakpoint(int priv) { return fm_server_msg_post(FM_DEC_ON); } static const struct music_dec_ops fm_music_dec_ops = { .switch_dir = fm_music_dec_switch_dir, .switch_file = fm_music_dec_switch_file, .dec_file = fm_music_dec_file, .dec_breakpoint = fm_music_dec_breakpoint, .dec_play_pause = fm_music_dec_play_pause, .dec_volume = fm_music_dec_volume, .dec_stop = fm_music_dec_stop, .dec_status = __get_dec_status, }; #endif /* * ****************************网络播歌************************************* */ #ifdef CONFIG_NET_ENABLE static const struct music_dec_ops net_music_dec_ops; static const struct audio_vfs_ops net_audio_dec_vfs_ops = { .fread = net_download_read, .fseek = net_download_seek, .flen = net_download_get_file_len, }; static int __net_download_ready() { __this->download_ready = net_download_check_ready(__this->net_file); if (__this->download_ready) { return 1; } return 0; } static int net_music_dec_play_pause(u8 notify) { union audio_req r = {0}; union ai_req req = {0}; #ifdef CONFIG_DEC_ANALOG_VOLUME_ENABLE r.dec.attr = AUDIO_ATTR_FADE_INOUT; #endif r.dec.cmd = AUDIO_DEC_PP; server_request(__this->dec_server, AUDIO_REQ_DEC, &r); if (r.dec.status == AUDIO_DEC_START) { /* 播放状态 */ net_download_set_pp(__this->net_file, 0); } else if (r.dec.status == AUDIO_DEC_PAUSE) { if (__this->play_tts) { __this->dec_ops->dec_stop(0); } else { /* 暂停状态 */ net_download_set_pp(__this->net_file, 1); } } else if (r.dec.status == AUDIO_DEC_STOP) { if (0 == __this->dec_ops->dec_breakpoint(0)) { r.dec.status = AUDIO_DEC_START; } } if (notify && __this->ai_server && r.dec.status != AUDIO_DEC_STOP) { req.evt.event = AI_EVENT_PLAY_PAUSE; req.evt.ai_name = __this->ai_name; if (r.dec.status == AUDIO_DEC_PAUSE) { req.evt.arg = 1; } ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } return 0; } static int net_music_dec_stop(int save_breakpoint) { int err; union audio_req r = {0}; union ai_req req = {0}; //如果是语音链接不应该保存断点 if (__this->play_tts) { save_breakpoint = 0; } printf("net_music_dec_stop: %d\n", save_breakpoint); if (!__this->net_file) { return 0; } if (__this->play_tts) { set_led_mode(LED_OFF); } net_download_buf_inactive(__this->net_file); if (__this->wait_download) { /* * 歌曲还未播放,删除wait */ /* sys_timer_del(__this->wait_download); */ wait_completion_del(__this->wait_download); __this->wait_download = 0; __this->wait_download_suspend = 1; } else { if (save_breakpoint) { int url_len = strlen(__this->url) + 1; if (url_len > __this->net_bp.url_len) { if (__this->net_bp.url) { free(__this->net_bp.url); } __this->net_bp.url = malloc(url_len); if (!__this->net_bp.url) { __this->net_bp.url_len = 0; } else { __this->net_bp.url_len = url_len; } } if (__this->net_bp.url) { err = __get_dec_breakpoint(&__this->net_bp.dec_bp); if (!err) { __this->net_bp.ai_name = __this->ai_name; strcpy(__this->net_bp.url, __this->url); __this->net_bp.fptr = __this->net_bp.dec_bp.fptr; if (net_download_check_if_is_m3u8_url(__this->net_file)) { __this->net_bp.fptr = 0; free(__this->net_bp.dec_bp.data); __this->net_bp.dec_bp.data = NULL; } log_d("save_breakpoint: fptr=%x\n", __this->net_bp.fptr); } else if (1 == err && __this->ai_server) { //解决暂停时的断点问题 req.evt.event = AI_EVENT_MEDIA_STOP; req.evt.arg = __this->play_time; req.evt.ai_name = __this->ai_name; ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } } } r.dec.cmd = AUDIO_DEC_STOP; server_request(__this->dec_server, AUDIO_REQ_DEC, &r); int argv[2]; argv[0] = AUDIO_SERVER_EVENT_END; argv[1] = (int)__this->net_file; server_event_handler_del(__this->dec_server, 2, argv); } canceladdrinfo(); net_download_close(__this->net_file); __this->net_file = NULL; __this->seek_step = 0; return 0; } static int net_music_dec_end(int save_bp) { union ai_req req = {0}; puts("net_music_dec_end\n"); net_music_dec_stop(save_bp); if (!__this->ai_server) { return 0; } /* * 歌曲播放完成,发送此命令后ai平台会发送新的URL */ req.evt.event = __this->play_tts ? AI_EVENT_SPEAK_END : AI_EVENT_MEDIA_END; req.evt.ai_name = __this->ai_name; return ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } static int __net_music_dec_file(int breakpoint) { int err; union ai_req r = {0}; union audio_req req = {0}; __this->wait_download = 0; __this->wait_download_suspend = 0; if (__this->download_ready < 0) { /* 网络下载失败 */ goto __err; } if (__this->wait_switch_file) { puts("del_wait_switch_file\n"); sys_timeout_del(__this->wait_switch_file); __this->wait_switch_file = 0; } if (__this->play_voice_prompt) { set_dec_end_handler(__this->file, __net_music_dec_file, breakpoint, -1); return 0; } req.dec.dec_type = net_download_get_media_type(__this->net_file); if (req.dec.dec_type == NULL) { goto __err; } printf("urc_file_type: %s\n", req.dec.dec_type); if (breakpoint == 1) { __this->ai_name = __this->net_bp.ai_name; req.dec.bp = &__this->net_bp.dec_bp; } net_download_set_read_timeout(__this->net_file, 1000); req.dec.cmd = AUDIO_DEC_OPEN; req.dec.volume = __this->volume; req.dec.output_buf = NULL; req.dec.output_buf_len = DEC_BUF_LEN; req.dec.file = (FILE *)__this->net_file; req.dec.channel = 0; req.dec.sample_rate = 0; req.dec.priority = 1; req.dec.vfs_ops = &net_audio_dec_vfs_ops; req.dec.sample_source = "dac"; #if 0 //变声变调功能 req.dec.speedV = 80; // >80是变快,<80是变慢,建议范围:30到130 req.dec.pitchV = 32768; // >32768是音调变高,<32768音调变低,建议范围20000到50000 req.dec.attr = AUDIO_ATTR_PS_EN; #endif #if TCFG_EQ_ENABLE #if defined EQ_CORE_V1 req.dec.attr |= AUDIO_ATTR_EQ_EN; #if TCFG_LIMITER_ENABLE req.dec.attr |= AUDIO_ATTR_EQ32BIT_EN; #endif #if TCFG_DRC_ENABLE req.dec.attr |= AUDIO_ATTR_DRC_EN; #endif #else struct eq_s_attr eq_attr = {0}; extern void set_eq_req_attr_parm(struct eq_s_attr * eq_attr); set_eq_req_attr_parm(&eq_attr); req.dec.eq_attr = &eq_attr; req.dec.eq_hdl = __this->eq_hdl; #endif #endif err = server_request(__this->dec_server, AUDIO_REQ_DEC, &req); if (err) { goto __err; } __this->cmp_file = __this->net_file; __this->play_time = req.dec.play_time; __this->total_time = req.dec.total_time; if (breakpoint == 1) { __this->net_bp.dec_bp.len = 0; } net_download_set_read_timeout(__this->net_file, 0); if (__this->seek_step) { __this->dec_ops->dec_seek(__this->seek_step); __this->seek_step = 0; net_download_set_read_timeout(__this->net_file, 0); } req.dec.cmd = AUDIO_DEC_START; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); net_download_set_pp(__this->net_file, 0); if (__this->ai_server) { r.evt.event = __this->play_tts ? AI_EVENT_SPEAK_START : AI_EVENT_MEDIA_START; r.evt.ai_name = __this->ai_name; ai_server_request(__this->ai_server, AI_REQ_EVENT, &r); } return 0; __err: puts("play_net_music_faild\n"); net_download_buf_inactive(__this->net_file); req.dec.cmd = AUDIO_DEC_STOP; server_request(__this->dec_server, AUDIO_REQ_DEC, &req); net_download_close(__this->net_file); __this->net_file = NULL; if (__this->ai_server) { r.evt.event = __this->play_tts ? AI_EVENT_SPEAK_END : AI_EVENT_MEDIA_END; r.evt.ai_name = __this->ai_name; ai_server_request(__this->ai_server, AI_REQ_EVENT, &r); } return -EFAULT; } static void check_net_download_ready_timer(void *priv) { if (!__this->wait_download || !__this->net_file) { return; } __this->download_ready = net_download_check_ready(__this->net_file); if (__this->download_ready) { sys_timer_del(__this->wait_download); __this->wait_download = 0; __net_music_dec_file((int)priv); } } static int net_music_dec_file(void *_url, int breakpoint, void *handler, int arg) { int err; struct net_download_parm parm; if (__this->dec_ops) { __this->dec_ops->dec_stop(0); } puts("net_download_open\n"); if (!_url) { return -1; } memset(&parm, 0, sizeof(struct net_download_parm)); parm.url = (const char *)_url; parm.prio = 0; #ifdef CONFIG_NO_SDRAM_ENABLE parm.cbuf_size = 40 * 1024; #else parm.cbuf_size = 500 * 1024; #endif parm.timeout_millsec = 16500; parm.seek_high_range = 0; parm.seek_low_range = breakpoint ? __this->net_bp.fptr : 0; #ifdef CONFIG_DOWNLOAD_SAVE_FILE if (!__this->play_tts && storage_device_ready()) { parm.save_file = 1; parm.file_dir = NULL; parm.dir_len = 0; //路径长度 } #endif /* parm.no_wait_close = 1; */ /* parm.start_play_threshold = 1024 * 4; */ parm.seek_threshold = 1024 * 200; //用户可适当调整 err = net_download_open(&__this->net_file, &parm); if (err) { log_e("net_download_open: err = %d\n", err); return err; } __this->url = (const char *)_url; set_dec_end_handler(__this->net_file, handler, arg, -1); /* * 异步等待网络下载ready,防止网络阻塞导致app卡住 */ __this->wait_download_suspend = 0; #if 1 __this->wait_download = wait_completion(__net_download_ready, (int (*)(void *))__net_music_dec_file, (void *)breakpoint, NULL); #else __this->wait_download = sys_timer_add((void *)breakpoint, check_net_download_ready_timer, 20); #endif __this->dec_ops = &net_music_dec_ops; if (__this->play_tts) { set_led_mode(LED_GREEN_BREATH); } return 0; } static int net_music_dec_switch_file(int fsel_mode) { union ai_req req = {0}; puts("net_music_dec_switch_file\n"); if (!strcmp(__this->ai_name, "dlna")) { return 0; } net_music_dec_stop(0); if (fsel_mode == FSEL_NEXT_FILE) { req.evt.event = AI_EVENT_NEXT_SONG; } else if (fsel_mode == FSEL_PREV_FILE) { req.evt.event = AI_EVENT_PREVIOUS_SONG; } else { return 0; } if (!__this->ai_server) { return 0; } req.evt.ai_name = __this->ai_name; return ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } static int net_music_dec_switch_dir(int fsel_mode) { return 0; } static int net_music_dec_breakpoint(int priv) { puts("net_music_dec_breakpoint\n"); if (__this->play_tts) { __this->play_tts = 0; } if (__this->wait_download_suspend) { if (__this->net_bp.dec_bp.len > 0 && !strcmp(__this->url, __this->net_bp.url)) { return net_music_dec_file(__this->net_bp.url, 1, net_music_dec_end, 0); } else { return net_music_dec_file((void *)__this->url, 0, net_music_dec_end, 0); } } if (__this->net_bp.dec_bp.len == 0) { return -ENOENT; } return net_music_dec_file(__this->net_bp.url, 1, net_music_dec_end, 0); } static int net_music_dec_progress(int sec) { union ai_req req = {0}; req.evt.event = AI_EVENT_PLAY_TIME; req.evt.arg = sec; req.evt.ai_name = __this->ai_name; return ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } static int net_music_dec_volume(int step) { union ai_req req = {0}; if (__this->ai_server) { req.evt.event = AI_EVENT_VOLUME_CHANGE; req.evt.arg = __this->volume; req.evt.ai_name = __this->ai_name; return ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } return 0; } static int net_music_dec_seek(int seek_step) { int err; union audio_req r = {0}; if (0 == seek_step) { return 0; } if (__this->total_time != 0 && __this->total_time != -1) { if (__this->play_time + seek_step <= 0 || __this->play_time + seek_step >= __this->total_time) { log_e("local music seek out of range\n"); return -1; } } if (seek_step > 0) { r.dec.cmd = AUDIO_DEC_FF; r.dec.ff_fr_step = seek_step; } else { r.dec.cmd = AUDIO_DEC_FR; r.dec.ff_fr_step = -seek_step; } log_i("net music seek step : %d\n", seek_step); err = server_request(__this->dec_server, AUDIO_REQ_DEC, &r); return 0; } static const struct music_dec_ops net_music_dec_ops = { .switch_dir = net_music_dec_switch_dir, .switch_file = net_music_dec_switch_file, .dec_file = net_music_dec_file, .dec_breakpoint = net_music_dec_breakpoint, .dec_play_pause = net_music_dec_play_pause, .dec_volume = net_music_dec_volume, .dec_progress = net_music_dec_progress, .dec_stop = net_music_dec_stop, .dec_seek = net_music_dec_seek, .dec_status = __get_dec_status, }; static void ai_server_media_stop_notify(void) { union ai_req req = {0}; if (__this->ai_server) { req.evt.event = AI_EVENT_MEDIA_STOP; req.evt.arg = __this->play_time; req.evt.ai_name = __this->ai_name; ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } } static int __play_net_music(const char *url) { return net_music_dec_file((void *)url, 0, net_music_dec_end, 0); } static int app_music_play_net_music(void *url) { if (__this->play_voice_prompt) { if (__this->dec_end_handler != (void *)app_music_shutdown) { set_dec_end_handler(__this->dec_end_file, __play_net_music, (int)url, -1); } return 0; } if (__this->net_bp.url && __this->net_bp.dec_bp.len > 0 && !strcmp((const char *)url, __this->net_bp.url)) { return net_music_dec_file(url, 1, net_music_dec_end, 0); } return net_music_dec_file(url, 0, net_music_dec_end, 0); } static int app_music_ai_listen_start(u8 voice_mode, u8 enable_vad); //第三方平台的事件通知回调 static void ai_server_event_handler(void *priv, int argc, int *argv) { int err = 0; if (!__this->ai_server) { switch (argv[0]) { case AI_SERVER_EVENT_URL: free((void *)argv[1]); break; default: break; } return; } switch (argv[0]) { case AI_SERVER_EVENT_CONNECTED: __this->ai_connected = 1; break; case AI_SERVER_EVENT_DISCONNECTED: __this->ai_connected = 0; break; case AI_SERVER_EVENT_URL: case AI_SERVER_EVENT_URL_TTS: case AI_SERVER_EVENT_URL_MEDIA: if (__this->listening == LISTEN_STATE_START || __this->listening == LISTEN_STATE_WAKEUP || __this->upgrading || __this->call_flag) { free((void *)argv[1]); return; } if (__this->dec_ops && __this->dec_ops == &net_music_dec_ops && AUDIO_DEC_START == __this->dec_ops->dec_status(0)) { __this->last_mode = NET_MUSIC_MODE; __this->last_play_status = __this->dec_ops->dec_status(0); __this->dec_ops->dec_stop(1); } __this->play_tts = argv[0] == AI_SERVER_EVENT_URL_TTS ? 1 : 0; __this->total_time = 0; //清空上一首歌的信息 if (strcmp((const char *)argv[2], __this->ai_name)) { ai_server_media_stop_notify(); } __this->ai_name = (const char *)argv[2]; free(__this->save_url); __this->save_url = (void *)argv[1]; if (__this->mode != NET_MUSIC_MODE) { app_music_play_mode_switch_notify(); __this->mode = NET_MUSIC_MODE; } app_music_play_net_music((void *)argv[1]); break; case AI_SERVER_EVENT_CONTINUE: if (__this->dec_ops == &net_music_dec_ops && !strcmp((const char *)argv[2], __this->ai_name)) { if (__this->play_voice_prompt) { if (__this->net_bp.dec_bp.len > 0) { app_music_stop_voice_prompt(); __this->dec_ops->dec_play_pause(__this->dec_ops != &net_music_dec_ops); } } else if (!__this->play_tts && AUDIO_DEC_START != __this->dec_ops->dec_status(0)) { __this->dec_ops->dec_play_pause(__this->dec_ops != &net_music_dec_ops); } } break; case AI_SERVER_EVENT_PAUSE: if (__this->dec_ops == &net_music_dec_ops && !strcmp((const char *)argv[2], __this->ai_name)) { if (__this->play_voice_prompt) { if (__this->dec_end_handler == net_music_dec_ops.dec_breakpoint) { __this->dec_end_handler = NULL; } } else if (!__this->play_tts && AUDIO_DEC_START == __this->dec_ops->dec_status(0)) { __this->dec_ops->dec_play_pause(__this->dec_ops != &net_music_dec_ops); } } break; case AI_SERVER_EVENT_STOP: if (__this->dec_ops == &net_music_dec_ops && !strcmp((const char *)argv[2], __this->ai_name)) { __this->dec_ops->dec_stop(0); __this->net_bp.dec_bp.len = 0; } break; case AI_SERVER_EVENT_SEEK: if (__this->dec_ops == &net_music_dec_ops || __this->dec_ops == &local_music_dec_ops) { if (AUDIO_DEC_STOP == __this->dec_ops->dec_status(0)) { __this->seek_step = argv[1]; if (0 != __this->dec_ops->dec_breakpoint(0)) { __this->seek_step = 0; } } else { __this->dec_ops->dec_seek(argv[1] - __this->play_time); } } break; case AI_SERVER_EVENT_UPGRADE: sys_power_auto_shutdown_pause(); __this->key_disable |= BIT(1); __this->upgrading = 1; ai_server_media_stop_notify(); app_music_play_voice_prompt("OtaInUpdate.mp3", NULL); #ifdef CONFIG_LOW_POWER_ENABLE low_power_hw_unsleep_lock(); #endif break; case AI_SERVER_EVENT_UPGRADE_SUCC: if (argv[1] && strlen((const char *)argv[1]) < 16) { char version[16]; memset(version, 0, sizeof(version)); version[0] = 0; //升级类型 memcpy(version + 1, (const char *)argv[1], strlen((const char *)argv[1])); syscfg_write(VM_VERSION_INDEX, version, 16); } free((void *)argv[1]); if (!__this->mute) { u8 upg = 1; syscfg_write(VM_UPG_INDEX, &upg, sizeof(upg)); } /* cpu_reset(); */ system_reset(); break; case AI_SERVER_EVENT_UPGRADE_FAIL: __this->key_disable &= ~BIT(1); __this->upgrading = 0; if (!__this->play_voice_prompt && !__this->key_disable) { key_event_enable(); } app_music_play_voice_prompt("OtaFailed.mp3", NULL); sys_power_auto_shutdown_resume(); #ifdef CONFIG_LOW_POWER_ENABLE low_power_hw_unsleep_unlock(); #endif break; case AI_SERVER_EVENT_MIC_OPEN: set_led_mode(LED_GREEN_BREATH); if (__this->listening == LISTEN_STATE_STOP) { __this->listening = LISTEN_STATE_WAKEUP; app_music_play_voice_prompt("rec.mp3", NULL); } if (argv[1]) { os_sem_post((OS_SEM *)argv[1]); } break; case AI_SERVER_EVENT_MIC_CLOSE: if (__this->listening == LISTEN_STATE_WAKEUP) { __this->listening = LISTEN_STATE_STOP; } else if (__this->listening == LISTEN_STATE_START) { __this->listening = LISTEN_STATE_STOPPING; } #ifdef CONFIG_ALL_ADC_CHANNEL_OPEN_ENABLE extern void adc_multiplex_set_gain(const char *source, u8 channel_bit_map, u8 gain); adc_multiplex_set_gain("mic", BIT(CONFIG_ASR_CLOUD_ADC_CHANNEL), CONFIG_AISP_MIC_ADC_GAIN); #endif if (__this->wechat_flag && !__this->rec_again) { /* app_music_play_voice_prompt("send.mp3", __this->dec_ops->dec_breakpoint); */ break; } if (__this->rec_again && 0 == app_music_ai_listen_start(__this->voice_mode, 1)) { __this->listening = LISTEN_STATE_WAKEUP; } else { /* app_music_play_voice_prompt("send.mp3", NULL); */ } set_led_mode(LED_OFF); break; case AI_SERVER_EVENT_PLAY_BEEP: if (__this->listening == LISTEN_STATE_STOP && !__this->upgrading && __this->mode == NET_MUSIC_MODE) { app_music_play_voice_prompt((const char *)argv[1], __this->dec_ops->dec_breakpoint); } break; case AI_SERVER_EVENT_VOLUME_CHANGE: if (0 == __set_dec_volume(argv[1] - __this->volume)) { #ifdef CONFIG_STORE_VOLUME syscfg_write(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)); #endif if (__this->dec_ops == &net_music_dec_ops && __this->ai_server) { __this->dec_ops->dec_volume(0); } } break; case AI_SERVER_EVENT_SET_PLAY_TIME: __this->play_time = argv[1]; break; #ifdef CONFIG_BT_ENABLE case AI_SERVER_EVENT_BT_CLOSE: app_music_play_voice_prompt("BtClose.mp3", __this->dec_ops->dec_breakpoint); //关闭蓝牙 if (__this->bt_music_enable) { __this->bt_music_enable = 0; bt_connection_disable(); } break; case AI_SERVER_EVENT_BT_OPEN: app_music_play_voice_prompt("BtOpen.mp3", __this->dec_ops->dec_breakpoint); //打开蓝牙 if (!__this->bt_music_enable) { __this->bt_music_enable = 1; bt_connection_enable(); } break; #endif case AI_SERVER_EVENT_RESUME_PLAY: printf("\n__this->last_mode = %d\n", __this->last_mode); if (__this->last_mode == NET_MUSIC_MODE) { __this->dec_ops = &net_music_dec_ops; __this->dec_ops->dec_breakpoint(0); } #ifdef CONFIG_BT_ENABLE else if (__this->last_mode == BT_MUSIC_MODE && __this->last_play_status == AUDIO_DEC_START) { __this->dec_ops = get_bt_music_dec_ops(); __this->dec_ops->dec_play_pause(1); } #endif break; case AI_SERVER_EVENT_PREV_PLAY: if (__this->dec_ops) { __this->dec_ops->switch_file(FSEL_PREV_FILE); } break; case AI_SERVER_EVENT_NEXT_PLAY: if (__this->dec_ops) { __this->dec_ops->switch_file(FSEL_NEXT_FILE); } break; default: break; } } static int app_music_ai_listen_start(u8 voice_mode, u8 enable_vad) { int err; union ai_req req = {0}; __this->rec_again = 0; __this->wechat_flag = 0; app_music_stop_voice_prompt(); if (__this->upgrading || __this->listening != LISTEN_STATE_STOP) { return -1; } if (!__this->ai_connected || !__this->net_connected) { set_led_mode(LED_RED_HOLD); if (AI_MODE == voice_mode) { app_music_play_voice_prompt("NetDisc.mp3", __this->dec_ops->dec_breakpoint); } return -1; } __this->last_mode = __this->mode; __this->last_play_status = __this->dec_ops->dec_status(0); if (__this->mode == BT_MUSIC_MODE) { __this->dec_ops->dec_stop(-1); } else { __this->dec_ops->dec_stop(1); } app_music_play_voice_prompt("rec.mp3", NULL); os_time_dly(30); if (enable_vad && voice_mode != WECHAT_MODE) { voice_mode |= VAD_ENABLE; //enable local vad } //voice_mode:(bit0_bit1) 交互模式 0:智能聊天 1:中英翻译 2:微聊 3:口语评测 //voice_mode:(bit3_bit6) 采样源选择 0:AUDIO_ADC不是四路全开时使用0 1-4:AUDIO_ADC四路全开时代表具体使用的ADC通道 //voice_mode:(bit3_bit6) 采样源选择 5:plnk0 6:plnk1 7:iis0 8:iis1 //voice_mode:(bit7) 0:关闭VAD 1:打开VAD #if CONFIG_AUDIO_ENC_SAMPLE_SOURCE != AUDIO_ENC_SAMPLE_SOURCE_MIC req.lis.arg = voice_mode | ((CONFIG_AUDIO_ENC_SAMPLE_SOURCE + 4) << 3); #else #ifdef CONFIG_ALL_ADC_CHANNEL_OPEN_ENABLE req.lis.arg = voice_mode | ((CONFIG_ASR_CLOUD_ADC_CHANNEL + 1) << 3); #else req.lis.arg = voice_mode; #endif #endif req.lis.cmd = AI_LISTEN_START; err = ai_server_request(__this->ai_server, AI_REQ_LISTEN, &req); if (err == 0) { __this->listening = LISTEN_STATE_START; if (voice_mode == WECHAT_MODE) { __this->wechat_flag = 1; } os_time_dly(30); } return 0; } static void app_music_ai_listen_stop(void) { union ai_req req = {0}; if (__this->listening == LISTEN_STATE_STOP) { return; } if (__this->listening != LISTEN_STATE_STOPPING) { if (__this->ai_server) { req.lis.cmd = AI_LISTEN_STOP; ai_server_request(__this->ai_server, AI_REQ_LISTEN, &req); } } __this->listening = LISTEN_STATE_STOP; } static void app_music_ai_listen_break(void) { union ai_req req = {0}; if (__this->listening == LISTEN_STATE_STOP) { return; } if (__this->listening != LISTEN_STATE_STOPPING) { req.evt.event = AI_EVENT_RECORD_BREAK; req.evt.ai_name = "dui"; ai_server_request(__this->ai_server, AI_REQ_EVENT, &req); } __this->listening = LISTEN_STATE_STOP; } static void app_music_event_net_connected() { union ai_req req = {0}; /* * 网络连接成功,开始连接ai服务器 */ if (__this->ai_server) { return; } __this->ai_server = server_open("ai_server", NULL); if (__this->ai_server) { server_register_event_handler(__this->ai_server, NULL, ai_server_event_handler); ai_server_request(__this->ai_server, AI_REQ_CONNECT, &req); } } /***************************************************************/ #ifdef CONFIG_SERVER_ASSIGN_PROFILE extern void dev_profile_init(void); extern void dev_profile_uninit(void); #endif extern void wifi_return_sta_mode(void); extern void cancel_server_assign_macaddr(void); static void switch_rf_coexistence_timer(void *p) { __this->coexistence_timer = 0; switch_rf_coexistence_config_unlock(); if (!is_in_config_network_state()) { switch_rf_coexistence_config_table(0); } } static void cancel_dns_timer(void *p) { canceladdrinfo(); } static void app_music_net_config(void) { __this->mode = NET_MUSIC_MODE; __this->net_bp.dec_bp.len = 0; __this->reconnecting = 0; #ifdef CONFIG_ASSIGN_MACADDR_ENABLE cancel_server_assign_macaddr(); #endif app_music_stop_voice_prompt(); app_music_switch_local_device("unknown"); __this->local_path = NULL; if (!is_in_config_network_state()) { sys_power_auto_shutdown_pause(); if (__this->coexistence_timer) { sys_timeout_del(__this->coexistence_timer); __this->coexistence_timer = 0; switch_rf_coexistence_config_unlock(); } #ifdef CONFIG_BT_ENABLE if (__this->bt_music_enable) { bt_connection_disable(); } #endif __this->net_connected = 0; __this->net_cfg_fail = 0; __this->net_connected_frist = 0; __this->volume = INIT_VOLUME_VALUE; #ifdef CONFIG_STORE_VOLUME syscfg_write(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)); #endif app_music_play_voice_prompt("NetCfgEnter.mp3", NULL); set_led_mode(LED_GREEN_HOLD); if (__this->ai_server) { __this->cancel_dns_timer = sys_timer_add_to_task("sys_timer", NULL, cancel_dns_timer, 1000); } if (__this->ai_server) { server_close(__this->ai_server); __this->ai_server = NULL; __this->ai_connected = 0; sys_timer_del(__this->cancel_dns_timer); __this->cancel_dns_timer = 0; } #ifdef CONFIG_SERVER_ASSIGN_PROFILE dev_profile_uninit(); #endif #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { aisp_suspend(); } #endif config_network_start(); } else { #if 0 app_music_play_voice_prompt("NetConnting.mp3", NULL); config_network_stop(); wifi_return_sta_mode(); #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { aisp_resume(); } #endif #ifdef CONFIG_BT_ENABLE //避免打开蓝牙自动回连设备时挡住wifi连接 switch_rf_coexistence_config_table(3); switch_rf_coexistence_config_lock(); __this->coexistence_timer = sys_timeout_add(NULL, switch_rf_coexistence_timer, 15000); if (__this->bt_music_enable) { bt_connection_enable(); } #endif sys_power_auto_shutdown_resume(); #endif } __this->dec_ops = &net_music_dec_ops; } #endif /* * ****************************提示音************************************* */ static void dec_server_event_handler(void *priv, int argc, int *argv) { switch (argv[0]) { case AUDIO_SERVER_EVENT_ERR: puts("app_music: AUDIO_SERVER_EVENT_ERR\n"); case AUDIO_SERVER_EVENT_END: puts("app_music: AUDIO_SERVER_EVENT_END\n"); if (__this->cmp_file != (void *)argv[1]) { printf("not the same file, may be closed!\n"); break; } /* os_time_dly(3); */ union audio_req r = {0}; r.dec.cmd = AUDIO_DEC_PAUSE; if (__this->dec_server) { server_request(__this->dec_server, AUDIO_REQ_DEC, &r); } if (!__this->key_disable) { key_event_enable(); } if (__this->play_voice_prompt) { local_music_dec_ops.dec_stop(0); __this->play_voice_prompt = 0; } #ifdef CONFIG_NET_ENABLE else if (__this->play_tts && __this->mode == NET_MUSIC_MODE) { set_led_mode(LED_OFF); } #endif #ifdef CONFIG_BT_ENABLE #if BT_SUPPORT_RECEIVER_AUTO_A2DP_START if (__this->bt_connecting == 1) { user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL); } #endif #endif __this->bt_connecting = 0; do_dec_end_handler((void *)argv[1]); __this->play_tts = 0; /* __this->play_time = 0; */ break; case AUDIO_SERVER_EVENT_CURR_TIME: log_d("play_time: %d\n", argv[1]); __this->play_time = argv[1]; sys_power_auto_shutdown_clear(); /* __this->dec_ops->dec_progress(argv[1]); */ break; } } static int __play_voice_prompt(const char *fname, void *dec_end_handler, int save_bp) { int err; char path[64]; if ((u32)fname < APP_LOCAL_PROMPT_NUMM) { fname = find_local_prompt_filename((APP_LOCAL_PROMPT_TYPE_E)fname); if (!fname) { return -1; } } log_d("play_voice_prompt: %s\n", fname); sprintf(path, "%s%s", CONFIG_VOICE_PROMPT_FILE_PATH, fname); FILE *file = fopen(path, "r"); if (!file) { return -ENOENT; } if (__this->play_voice_prompt) { local_music_dec_ops.dec_stop(0); } else { __this->dec_ops->dec_stop(save_bp); } __this->play_voice_prompt = 1; #if CONFIG_PLAY_PROMPT_DISABLE_KEY key_event_disable(); #endif err = local_music_dec_file(file, 0, dec_end_handler, 0); if (err) { __this->play_voice_prompt = 0; if (!__this->key_disable) { key_event_enable(); } } return err; } static int _play_voice_prompt(const char *fname, void *dec_end_handler) { return __play_voice_prompt(fname, dec_end_handler, 0); } /* * 播放提示音 */ static int app_music_play_voice_prompt(const char *fname, void *dec_end_handler) { if (*fname == '0') { return 0; //过滤旧提示音 } if ((__this->call_flag && strcmp(fname, "ring.mp3")) || __this->mute) { return 0; } if (dec_end_handler == (void *)app_music_shutdown) { return _play_voice_prompt(fname, dec_end_handler); } if (__this->play_voice_prompt) { if (__this->dec_end_handler != (void *)app_music_shutdown) { set_dec_end_handler(__this->dec_end_file, _play_voice_prompt, (int)fname, (int)dec_end_handler); } return 0; } #ifdef CONFIG_NET_ENABLE if (AUDIO_DEC_START != __get_dec_status(0) && !__this->wait_download && !__this->reconnecting) { if (dec_end_handler == local_music_dec_ops.dec_breakpoint || dec_end_handler == net_music_dec_ops.dec_breakpoint ) { //如果备份状态为播放状态,那么播完提示音需要回复断点 if (AUDIO_DEC_START != __this->last_play_status) { //避免本来已经暂停了又恢复播放 dec_end_handler = NULL; } } } #endif return __play_voice_prompt(fname, dec_end_handler, 1); } u8 last_audio_dec_is_start(void) { return __this->last_play_status == AUDIO_DEC_START; } int is_net_music_mode(void) { return __this->last_mode == NET_MUSIC_MODE; } int get_app_music_volume(void) { return __this->volume; } void set_app_music_volume(int volume, u8 mode) { if (__this->mode == mode) { //避免蓝牙模式和网络模式音量不同步 __this->volume = volume; } } int get_app_music_playtime(void) { return __this->play_time; } int get_app_music_total_time(void) { return __this->total_time; } int get_app_music_light_intensity(void) { return __this->light_intensity; } int get_app_music_battery_power(void) { return __this->battery_per; } void play_voice_prompt_for_app(char *name) { struct intent it = {0}; it.name = "app_music"; it.action = ACTION_MUSIC_PLAY_VOICE_PROMPT; it.data = name; it.exdata = 1; start_app(&it); } static void app_music_play_mode_switch_notify(void) { if (__this->mode == NET_MUSIC_MODE) { #ifdef CONFIG_NET_ENABLE ai_server_media_stop_notify(); #endif } else if (__this->mode >= LOCAL_MUSIC_MODE && __this->mode <= UDISK_MUSIC_MODE) { app_music_switch_local_device("unknown"); __this->local_path = NULL; } else if (__this->mode == BT_MUSIC_MODE) { __this->dec_ops->dec_stop(-1); } } static int app_music_resume_net_music_mode(int priv) { app_music_switch_local_device(NULL); #ifdef CONFIG_NET_ENABLE //这里是否需要恢复之前的网络播放 net_music_dec_breakpoint(0); __this->dec_ops = &net_music_dec_ops; #endif return 0; } #if CONFIG_FM_DEV_ENABLE static int app_music_start_fm_music_mode(int priv) { app_music_switch_local_device(NULL); __this->dec_ops = &fm_music_dec_ops; return __this->dec_ops->dec_file(NULL, 0, NULL, 0); } #endif static void local_music_play_mode_switch(void) { app_music_stop_voice_prompt(); if (__this->mode == NET_MUSIC_MODE) { __this->dec_ops->dec_stop(1); } else { __this->dec_ops->dec_stop(0); } if (__this->mode < LOCAL_MUSIC_MODE) { app_music_play_mode_switch_notify(); __this->dec_ops = &local_music_dec_ops; __this->mode = LOCAL_MUSIC_MODE; app_music_play_voice_prompt("FlashMusic.mp3", app_music_switch_local_device); __this->local_path = CONFIG_MUSIC_PATH_FLASH; } else if (__this->mode == LOCAL_MUSIC_MODE) { __this->dec_ops = &local_music_dec_ops; __this->mode = SDCARD_MUSIC_MODE; app_music_play_voice_prompt("SDcardMusic.mp3", app_music_switch_local_device); __this->local_path = CONFIG_MUSIC_PATH_SD; } else if (__this->mode == SDCARD_MUSIC_MODE) { __this->dec_ops = &local_music_dec_ops; __this->mode = UDISK_MUSIC_MODE; app_music_play_voice_prompt("UdiskMusic.mp3", app_music_switch_local_device); __this->local_path = CONFIG_MUSIC_PATH_UDISK; } else if (__this->mode == UDISK_MUSIC_MODE) { __this->local_path = NULL; #if CONFIG_FM_DEV_ENABLE __this->mode = FM_MUSIC_MODE; app_music_play_voice_prompt("FMMusic.mp3", app_music_start_fm_music_mode); } else if (__this->mode == FM_MUSIC_MODE) { #endif __this->mode = NET_MUSIC_MODE; app_music_play_voice_prompt("NetMusic.mp3", app_music_resume_net_music_mode); } } static int app_music_main() { int err = 0; puts("action_music_play_main\n"); #ifdef CONFIG_STORE_VOLUME if (syscfg_read(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)) < 0 || __this->volume < MIN_VOLUME_VALUE || __this->volume > MAX_VOLUME_VALUE) { __this->volume = INIT_VOLUME_VALUE; } #else __this->volume = INIT_VOLUME_VALUE; #endif if (__this->volume < 0 || __this->volume > MAX_VOLUME_VALUE) { __this->volume = INIT_VOLUME_VALUE; } __this->dec_server = server_open("audio_server", "dec"); if (!__this->dec_server) { puts("play_music open audio_server fail!\n"); return -EPERM; } server_register_event_handler(__this->dec_server, NULL, dec_server_event_handler); #if TCFG_EQ_ENABLE && !defined EQ_CORE_V1 __this->eq_hdl = eq_open(2); #endif #ifdef CONFIG_ASR_ALGORITHM aisp_open(16000); #endif set_led_mode(LED_RED_BREATH); sys_hi_timer_add(NULL, led_breath_timer, 800); u8 upg = 0; if (syscfg_read(VM_UPG_INDEX, &upg, sizeof(upg)) == sizeof(upg) && upg) { __this->mute = 1; set_led_mode(LED_MUTE); __this->wakeup_support = 0; #if defined CONFIG_ASR_ALGORITHM aisp_suspend(); #endif syscfg_write(VM_UPG_INDEX, &upg, sizeof(upg)); return 0; } /* * 播放开机提示音 */ FILE *file = fopen(CONFIG_VOICE_PROMPT_FILE_PATH"PowerOn.mp3", "r"); if (file) { #if CONFIG_PLAY_PROMPT_DISABLE_KEY key_event_disable(); #endif __this->play_voice_prompt = 1; if (__this->mode == LOCAL_MUSIC_MODE) { err = local_music_dec_file(file, 0, app_music_switch_local_device, (int)CONFIG_MUSIC_PATH_FLASH); __this->local_path = CONFIG_MUSIC_PATH_FLASH; } else { err = local_music_dec_file(file, 0, NULL, 0); } if (err) { key_event_enable(); __this->play_voice_prompt = 0; } #ifdef CONFIG_NET_ENABLE #if 0 //曾经配网,上电后直接连接网络,播放成功失败 if (1 == get_cur_wifi_mode()) { app_music_play_voice_prompt("NetConnting.mp3", NULL); } #endif #endif } return err; } static void app_music_exit(void) { key_event_enable(); sys_power_auto_shutdown_pause(); #ifdef CONFIG_NET_ENABLE if (__this->ai_server) { server_close(__this->ai_server); __this->ai_server = NULL; __this->ai_connected = 0; } #ifdef CONFIG_SERVER_ASSIGN_PROFILE dev_profile_uninit(); #endif free(__this->net_bp.url); free(__this->save_url); __this->net_bp.url = NULL; #endif if (__this->dec_server) { app_music_stop_voice_prompt(); if (__this->dec_ops) { __this->dec_ops->dec_stop(0); } server_close(__this->dec_server); __this->dec_server = NULL; } #if TCFG_EQ_ENABLE && !defined EQ_CORE_V1 if (__this->eq_hdl) { eq_close(__this->eq_hdl); __this->eq_hdl = NULL; } #endif if (__this->wait_switch_file) { sys_timeout_del(__this->wait_switch_file); __this->wait_switch_file = 0; } if (__this->wait_sd) { wait_completion_del(__this->wait_sd); __this->wait_sd = 0; } if (__this->wait_udisk) { wait_completion_del(__this->wait_udisk); __this->wait_udisk = 0; } if (__this->fscan) { fscan_release(__this->fscan); __this->fscan = NULL; } if (__this->dir_list) { fscan_release(__this->dir_list); __this->dir_list = NULL; } if (__this->local_bp_file) { fclose(__this->local_bp_file); __this->local_bp_file = NULL; __this->local_bp.len = 0; } if (__this->local_bp.data) { free(__this->local_bp.data); __this->local_bp.data = NULL; } if (__this->led_ui) { server_close(__this->led_ui); __this->led_ui = NULL; } #ifdef CONFIG_NET_ENABLE while (!list_empty(&__this->wechat_list)) { struct __wechat_url *first = list_first_entry(&__this->wechat_list, struct __wechat_url, entry); list_del(&first->entry); free(first->url); free(first); --__this->wechat_url_num; } if (__this->net_bp.dec_bp.data) { free(__this->net_bp.dec_bp.data); __this->net_bp.dec_bp.data = NULL; } if (__this->coexistence_timer) { sys_timeout_del(__this->coexistence_timer); __this->coexistence_timer = 0; } #endif } /* *按键响应函数 */ static int app_music_key_click(struct key_event *key) { switch (key->value) { case KEY_MUTE: #ifdef CONFIG_NET_ENABLE if (is_in_config_network_state()) { break; } #endif if (__this->wakeup_support) { __this->mute = 1; set_led_mode(LED_MUTE); if (__this->play_voice_prompt) { app_music_stop_voice_prompt(); } else { __this->dec_ops->dec_stop(1); } __this->wakeup_support = 0; #if defined CONFIG_ASR_ALGORITHM if (!is_in_config_network_state()) { app_music_ai_listen_break(); aisp_suspend(); } #endif } else { __this->mute = 0; set_led_mode(LED_MUTE); __this->wakeup_support = 1; __this->dec_ops->dec_breakpoint(0); #if defined CONFIG_ASR_ALGORITHM if (!is_in_config_network_state()) { aisp_resume(); } #endif } break; case KEY_OK: if (__this->play_voice_prompt) { app_music_stop_voice_prompt(); } else { __this->dec_ops->dec_play_pause(1); } break; case KEY_UP: if (0 == __set_dec_volume(-VOLUME_STEP) && 0 == __this->dec_ops->dec_volume(-VOLUME_STEP)) { #ifdef CONFIG_STORE_VOLUME syscfg_write(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)); #endif } break; case KEY_DOWN: if (0 == __set_dec_volume(VOLUME_STEP) && 0 == __this->dec_ops->dec_volume(VOLUME_STEP)) { #ifdef CONFIG_STORE_VOLUME syscfg_write(CFG_MUSIC_VOL, &__this->volume, sizeof(__this->volume)); #endif } break; #ifdef CONFIG_NET_ENABLE #ifdef CONFIG_HOLD_SEND_VOICE #else case KEY_ENC: if (0 == app_music_ai_listen_start(__this->voice_mode, 1)) { __this->listening = LISTEN_STATE_WAKEUP; } break; case KEY_F1: //wechat if (0 == app_music_ai_listen_start(WECHAT_MODE, 0)) { __this->listening = LISTEN_STATE_WAKEUP; } break; #endif #endif case KEY_CANCLE: local_music_play_mode_switch(); break; case KEY_MODE: #ifdef CONFIG_BT_ENABLE if (__this->bt_music_enable) { __this->bt_music_enable = 0; app_music_play_voice_prompt("BtClose.mp3", __this->dec_ops->dec_breakpoint); //关闭蓝牙 bt_connection_disable(); } else { app_music_play_voice_prompt("BtOpen.mp3", __this->dec_ops->dec_breakpoint); //打开蓝牙 __this->bt_music_enable = 1; bt_connection_enable(); } #endif break; case KEY_MENU: #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { __this->wakeup_support = 0; app_music_play_voice_prompt("KwsDisable.mp3", __this->dec_ops->dec_breakpoint); aisp_suspend(); } else { __this->wakeup_support = 1; app_music_play_voice_prompt("KwsEnable.mp3", __this->dec_ops->dec_breakpoint); aisp_resume(); } #endif break; default: break; } return false; } static int app_music_key_hold(struct key_event *key) { switch (key->value) { #ifdef CONFIG_NET_ENABLE #ifdef CONFIG_HOLD_SEND_VOICE case KEY_ENC: app_music_ai_listen_start(__this->voice_mode, 0); break; case KEY_F1: //wechat app_music_ai_listen_start(WECHAT_MODE, 0); break; #endif #endif case KEY_RIGHT: ++__this->seek_step; break; case KEY_LEFT: --__this->seek_step; break; case KEY_LOCAL: if (AUDIO_DEC_START == __this->dec_ops->dec_status(0)) { if (__this->play_voice_prompt) { app_music_stop_voice_prompt(); } else { __this->dec_ops->dec_play_pause(1); } } break; default: break; } return false; } static int app_music_key_up(struct key_event *key) { switch (key->value) { #ifdef CONFIG_NET_ENABLE #ifdef CONFIG_HOLD_SEND_VOICE case KEY_ENC: app_music_ai_listen_stop(); break; case KEY_F1: app_music_ai_listen_stop(); break; #endif #endif case KEY_LEFT: case KEY_RIGHT: if (__this->dec_ops->dec_seek) { __this->dec_ops->dec_seek(__this->seek_step); } __this->seek_step = 0; break; case KEY_LOCAL: if (AUDIO_DEC_PAUSE == __this->dec_ops->dec_status(0)) { if (__this->play_voice_prompt) { app_music_stop_voice_prompt(); } __this->dec_ops->dec_play_pause(1); } break; default: break; } return false; } static int app_music_key_long(struct key_event *key) { switch (key->value) { case KEY_OK: break; case KEY_UP: puts("music key up\n"); __this->dec_ops->switch_file(FSEL_PREV_FILE); break; case KEY_DOWN: puts("music key down\n"); __this->last_local_play_mode = __this->local_play_mode; __this->local_play_mode = __this->local_play_mode == SINGLE_PLAY_MODE ? LOOP_PLAY_MODE : __this->local_play_mode; __this->dec_ops->switch_file(FSEL_NEXT_FILE); __this->local_play_mode = __this->last_local_play_mode; break; case KEY_MODE: #ifdef CONFIG_NET_ENABLE puts("switch_net_config\n"); app_music_net_config(); #endif break; case KEY_MENU: app_music_shutdown(0); break; case KEY_CANCLE: if (__this->mode >= LOCAL_MUSIC_MODE && __this->mode <= UDISK_MUSIC_MODE) { if (!__this->local_play_all || __this->local_path == CONFIG_MUSIC_PATH_FLASH) { puts("switch_next_dir\n"); local_music_dec_switch_dir(FSEL_NEXT_FILE); } break; } if (__this->mode == FM_MUSIC_MODE) { __this->dec_ops->switch_dir(FSEL_NEXT_FILE); } break; default: break; } return false; } static int app_music_key_event_handler(struct key_event *key) { int ret = false; #if defined CONFIG_BOARD_DUI if (key->action == KEY_EVENT_CLICK && key->value == KEY_MODE) { key->value = KEY_MUTE; } #endif if (__this->call_flag && (key->value != KEY_UP && key->value != KEY_DOWN && key->value != KEY_OK)) { return true; //通话模式下只有音量键和暂停键能起作用 } #ifdef CONFIG_NET_ENABLE if (__this->upgrading && (key->value != KEY_MUTE || key->action != KEY_EVENT_CLICK)) { app_music_play_voice_prompt("OtaKey.mp3", NULL); return true; //升级过程中所有按键失效 } if (is_in_config_network_state() && (key->action != KEY_EVENT_LONG || key->value != KEY_MODE) && key->value != KEY_MUTE) { return true; //配网模式下只有配网键能起作用 } #ifndef CONFIG_HOLD_SEND_VOICE if (__this->listening != LISTEN_STATE_STOP) { //云端识别过程中过滤其它按键 #if 0 if (key->action != KEY_EVENT_CLICK || (key->value != KEY_ENC && key->value != KEY_F1)) { return ret; } #endif #ifdef CONFIG_ASR_ALGORITHM if (key->value == KEY_ENC) { __this->rec_again = 1; app_music_ai_listen_break(); return ret; } #endif } #endif #endif switch (key->action) { case KEY_EVENT_CLICK: ret = app_music_key_click(key); break; case KEY_EVENT_LONG: ret = app_music_key_long(key); break; case KEY_EVENT_HOLD: ret = app_music_key_hold(key); break; case KEY_EVENT_UP: ret = app_music_key_up(key); break; default: break; } return ret; } /* *设备响应函数 */ static int app_music_device_event_handler(struct sys_event *sys_eve) { struct device_event *device_eve = (struct device_event *)sys_eve->payload; /* * SD卡插拔处理 */ if (sys_eve->from == DEVICE_EVENT_FROM_SD) { switch (device_eve->event) { case DEVICE_EVENT_IN: if (__this->mode == SDCARD_MUSIC_MODE) { __this->wait_sd = wait_completion(sdcard_storage_device_ready, (int (*)(void *))app_music_switch_local_device, CONFIG_MUSIC_PATH_SD, device_eve->arg); } break; case DEVICE_EVENT_OUT: if (__this->mode == SDCARD_MUSIC_MODE) { if (__this->dec_ops == &local_music_dec_ops && !__this->play_voice_prompt) { __this->dec_ops->dec_stop(0); } else { __this->local_bp.len = 0; } app_music_switch_local_device("unknown"); } if (__this->wait_sd) { wait_completion_del(__this->wait_sd); __this->wait_sd = 0; } break; } } else if (sys_eve->from == DEVICE_EVENT_FROM_POWER) { if (device_eve->event == POWER_EVENT_POWER_CHANGE) { __this->battery_per = sys_power_get_battery_persent(); } else if (device_eve->event == POWER_EVENT_POWER_WARNING) { app_music_play_voice_prompt("LowBatLevel.mp3", __this->dec_ops->dec_breakpoint); } else if (device_eve->event == POWER_EVENT_POWER_LOW) { log_d("low_power_shutdown\n"); app_music_play_voice_prompt("LowBatOff.mp3", app_music_shutdown); } else if (device_eve->event == POWER_EVENT_POWER_AUTOOFF) { app_music_play_voice_prompt("PowerOff.mp3", app_music_shutdown); } else if (device_eve->event == POWER_EVENT_POWER_CHARGE) { } #if TCFG_UDISK_ENABLE } else if (sys_eve->from == DEVICE_EVENT_FROM_USB_HOST && !strncmp((const char *)device_eve->value, "udisk", 5)) { switch (device_eve->event) { case DEVICE_EVENT_IN: if (__this->mode == UDISK_MUSIC_MODE) { __this->wait_udisk = wait_completion(udisk_storage_device_ready, (int (*)(void *))app_music_switch_local_device, CONFIG_MUSIC_PATH_UDISK, ((const char *)device_eve->value)[5] - '0'); } break; case DEVICE_EVENT_OUT: if (__this->mode == UDISK_MUSIC_MODE) { if (__this->dec_ops == &local_music_dec_ops && !__this->play_voice_prompt) { __this->dec_ops->dec_stop(0); } else { __this->local_bp.len = 0; } app_music_switch_local_device("unknown"); } if (__this->wait_udisk) { wait_completion_del(__this->wait_udisk); __this->wait_udisk = 0; } break; } #endif } return false; } #ifdef CONFIG_NET_ENABLE #include extern char get_MassProduction(void); int net_dhcp_ready(void) { #ifdef CONFIG_MASS_PRODUCTION_ENABLE if (get_MassProduction()) { return 0; } #endif return __this->_net_dhcp_ready; } static int app_music_net_event_handler(struct net_event *event) { if (!ASCII_StrCmp(event->arg, "net", 4)) { switch (event->event) { case NET_CONNECT_TIMEOUT_NOT_FOUND_SSID: case NET_CONNECT_ASSOCIAT_FAIL: set_led_mode(LED_RED_HOLD); if (__this->mode == NET_MUSIC_MODE && !__this->net_cfg_fail) { __this->net_cfg_fail = 1; app_music_play_voice_prompt("NetCfgFail.mp3", NULL); } wifi_return_sta_mode(); break; case NET_EVENT_SMP_CFG_FIRST: set_led_mode(LED_RED_HOLD); if (__this->mode == NET_MUSIC_MODE) { app_music_play_voice_prompt("NetEmpty.mp3", NULL); } break; case NET_EVENT_SMP_CFG_FINISH: if (is_in_config_network_state()) { app_music_play_voice_prompt("SsidRecv.mp3", NULL); config_network_stop(); config_network_connect(); #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { aisp_resume(); } #endif #ifdef CONFIG_BT_ENABLE //避免打开蓝牙自动回连设备时挡住wifi连接 switch_rf_coexistence_config_table(3); switch_rf_coexistence_config_lock(); __this->coexistence_timer = sys_timeout_add(NULL, switch_rf_coexistence_timer, 15000); if (__this->bt_music_enable) { bt_connection_enable(); } #endif sys_power_auto_shutdown_resume(); #if TCFG_USER_BLE_ENABLE && (BT_NET_CFG_EN || BT_NET_CFG_DUI_EN) && CONFIG_POWER_ON_ENABLE_BLE } else { app_music_play_voice_prompt("SsidRecv.mp3", NULL); config_network_connect(); __this->reconnecting = 1; #endif } break; case NET_EVENT_CONNECTED: puts("NET_EVENT_CONNECTED\n"); __this->_net_dhcp_ready = 1; #ifdef WIFI_PCM_STREAN_SOCKET_ENABLE extern void wifi_pcm_stream_task_init(void); wifi_pcm_stream_task_init(); #endif set_led_mode(LED_OFF); if (!is_in_config_network_state()) { if (!__this->net_cfg_fail && __this->mode == NET_MUSIC_MODE) { if (!__this->mute) { __this->dec_ops = &net_music_dec_ops; __this->dec_ops->dec_breakpoint(0); } if (!__this->net_connected_frist) { __this->net_connected_frist = 1; app_music_play_voice_prompt("NetCfgSucc.mp3", __this->dec_ops->dec_breakpoint); } } __this->reconnecting = 0; #ifdef CONFIG_SERVER_ASSIGN_PROFILE dev_profile_init(); #endif app_music_event_net_connected(); } __this->net_cfg_fail = 0; __this->net_connected = 1; if (__this->coexistence_timer) { sys_timeout_del(__this->coexistence_timer); __this->coexistence_timer = 0; switch_rf_coexistence_config_unlock(); switch_rf_coexistence_config_table(0); } break; case NET_EVENT_DISCONNECTED: puts("NET_EVENT_DISCONNECTED\n"); if (!__this->_net_dhcp_ready) { break; } canceladdrinfo(); __this->_net_dhcp_ready = 0; if (!__this->net_connected_frist && __this->net_connected && !is_in_config_network_state() && !__this->reconnecting && __this->mode == NET_MUSIC_MODE) { app_music_play_voice_prompt("NetDisc.mp3", NULL); } if (!is_in_config_network_state()) { set_led_mode(LED_RED_HOLD); } __this->last_mode = __this->mode; __this->last_play_status = __this->dec_ops->dec_status(0); __this->net_connected = 0; return false; case NET_EVENT_SMP_CFG_TIMEOUT: if (is_in_config_network_state()) { __this->net_cfg_fail = 1; set_led_mode(LED_RED_HOLD); app_music_play_voice_prompt("NetCfgFail.mp3", NULL); config_network_stop(); wifi_return_sta_mode(); #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { aisp_resume(); } #endif #ifdef CONFIG_BT_ENABLE //避免打开蓝牙自动回连设备时挡住wifi连接 switch_rf_coexistence_config_table(3); switch_rf_coexistence_config_lock(); __this->coexistence_timer = sys_timeout_add(NULL, switch_rf_coexistence_timer, 15000); if (__this->bt_music_enable) { bt_connection_enable(); } #endif sys_power_auto_shutdown_resume(); } break; case NET_SMP_CFG_COMPLETED: break; case NET_EVENT_DISCONNECTED_AND_REQ_CONNECT: wifi_return_sta_mode(); break; case NET_NTP_GET_TIME_SUCC: //NTP获取成功事件返回 break; default: break; } } return false; } #endif #ifdef CONFIG_BT_ENABLE void set_bt_dec_end_handler(void *handler) { __this->dec_end_handler = handler; } u8 get_bt_connecting_flag(void) { return __this->bt_connecting; } void set_app_music_dec_ops(const struct music_dec_ops *ops) { if (!__this->bt_connecting) { app_music_stop_voice_prompt(); } if (__this->mode == NET_MUSIC_MODE) { app_music_play_mode_switch_notify(); __this->dec_ops->dec_stop(1); } else if (__this->mode != BT_MUSIC_MODE) { __this->dec_ops->dec_stop(0); app_music_play_mode_switch_notify(); } __this->mode = BT_MUSIC_MODE; __this->dec_ops = get_bt_music_dec_ops(); } static int app_music_bt_event_handler_pretreatment(struct bt_event *event) { #if CONFIG_POWER_ON_ENABLE_BT && defined CONFIG_NET_ENABLE if (BT_STATUS_INIT_OK == event->event) { //避免打开蓝牙自动回连设备时挡住wifi连接 switch_rf_coexistence_config_table(3); switch_rf_coexistence_config_lock(); __this->coexistence_timer = sys_timeout_add(NULL, switch_rf_coexistence_timer, 15000); } #endif if (event->event == BT_STATUS_A2DP_MEDIA_START) { if (__this->listening == LISTEN_STATE_START || __this->listening == LISTEN_STATE_WAKEUP || __this->upgrading) { app_music_ai_listen_break(); } } if (BT_STATUS_A2DP_MEDIA_START == event->event || BT_STATUS_SCO_STATUS_CHANGE == event->event) { if (__this->listening == LISTEN_STATE_START || __this->listening == LISTEN_STATE_WAKEUP || __this->upgrading) { #if 0 /* get_bt_music_dec_ops()->dec_stop(-1); */ /* return false; */ #endif } set_app_music_dec_ops(NULL); if (BT_STATUS_SCO_STATUS_CHANGE == event->event) { __this->call_flag = event->value == 0xff ? 0 : 1; #ifdef CONFIG_ASR_ALGORITHM if (__this->wakeup_support) { if (__this->call_flag) { aisp_suspend(); } else { aisp_resume(); } } #endif } } return 0; } #endif static int app_music_event_handler(struct application *app, struct sys_event *event) { switch (event->type) { case SYS_KEY_EVENT: return app_music_key_event_handler((struct key_event *)event->payload); case SYS_DEVICE_EVENT: return app_music_device_event_handler(event); #ifdef CONFIG_NET_ENABLE case SYS_NET_EVENT: return app_music_net_event_handler((struct net_event *)event->payload); #endif #ifdef CONFIG_BT_ENABLE case SYS_BT_EVENT: #define SYS_BT_EVENT_TYPE_DECODE_STATUS (('D' << 24) | ('E' << 16) | ('C' << 8) | '\0') #define BT_MUSIC_DEC_EVENT_MUTE_SET 0x02 if (event->from == BT_EVENT_FROM_USER && ((struct bt_event *)event->payload)->event == BT_MUSIC_DEC_EVENT_MUTE_SET) { app_music_ai_listen_break(); } if (event->from == BT_EVENT_FROM_CON) { app_music_bt_event_handler_pretreatment((struct bt_event *)event->payload); } return app_music_bt_event_handler(event); #endif default: return false; } } static int app_music_state_machine(struct application *app, enum app_state state, struct intent *it) { switch (state) { case APP_STA_CREATE: memset(__this, 0, sizeof(struct app_music_hdl)); #ifdef CONFIG_NET_ENABLE __this->ai_name = "unknown"; __this->net_bp.url = malloc(512); __this->net_bp.url_len = 512; INIT_LIST_HEAD(&__this->wechat_list); __this->mode = NET_MUSIC_MODE; //开机默认网络模式 __this->dec_ops = &net_music_dec_ops; #else #ifdef CONFIG_BT_ENABLE __this->mode = BT_MUSIC_MODE; __this->dec_ops = get_bt_music_dec_ops(); #else __this->mode = LOCAL_MUSIC_MODE; __this->dec_ops = &local_music_dec_ops; #endif #endif __this->last_mode = __this->mode; __this->last_play_status = AUDIO_DEC_STOP; /* __this->local_play_all = 1; */ __this->local_play_mode = LOOP_PLAY_MODE; #ifdef CONFIG_ASR_ALGORITHM __this->wakeup_support = 1; #endif #ifdef CONFIG_BT_ENABLE #if CONFIG_POWER_ON_ENABLE_BT __this->bt_music_enable = 1; #else __this->bt_music_enable = 0; #endif #endif __this->battery_per = 100; break; case APP_STA_START: if (!it) { break; } switch (it->action) { case ACTION_MUSIC_PLAY_MAIN: app_music_main(); break; case ACTION_MUSIC_PLAY_VOICE_PROMPT: #ifdef CONFIG_NET_ENABLE if ((!__this->bt_music_enable || is_in_config_network_state()) && !strcmp((const char *)it->data, "BtDisc.mp3")) { break; //蓝牙关闭后不需要蓝牙断开提示音 } if (__this->listening != LISTEN_STATE_STOP || __this->dec_ops->dec_status(0) == AUDIO_DEC_START) { break; } #endif if (!strcmp((const char *)it->data, "BtSucceed.mp3") && __this->dec_end_handler != (void *)app_music_shutdown) { if (__this->play_voice_prompt) { local_music_dec_ops.dec_stop(0); __this->play_voice_prompt = 0; } __this->bt_connecting = 1; } if (it->exdata) { app_music_play_voice_prompt(it->data, __this->dec_ops->dec_breakpoint); } else { app_music_play_voice_prompt(it->data, NULL); } break; } break; case APP_STA_PAUSE: break; case APP_STA_RESUME: break; case APP_STA_STOP: break; case APP_STA_DESTROY: app_music_exit(); break; } return 0; } static const struct application_operation app_music_ops = { .state_machine = app_music_state_machine, .event_handler = app_music_event_handler, }; REGISTER_APPLICATION(app_music) = { .name = "app_music", .ops = &app_music_ops, .state = APP_STA_DESTROY, }; #endif