doubao_chat/apps/wifi_story_machine/app_music_dui.c

3269 lines
94 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 <time.h>
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