【技术干货】自定义语音对接demo
1. 功能接入
1.1 代码导入
include/tuya_ipc_voice_demo.h
include/tuya_ipc_speaker_demo.h
include/tuya_ipc_media_wave_parse.h
include/tuya_ipc_alsa_play_demo.h
src/tuya_ipc_voice_demo.c
src/tuya_ipc_speaker_demo.c
src/tuya_ipc_media_wave_parse.c
src/tuya_ipc_alsa_play_demo.c
1.2 dp点功能
1.2.1 tuya_ipc_dp_utils.h
Code: Select all
#if defined(DEMO_IPC_VOICE_ENABLE) && (DEMO_IPC_VOICE_ENABLE == 1)
/*自定义语音dp点*/
#define TUYA_DP_VOICE_PLAY 235 /* play cmd */
#define TUYA_DP_VOICE_PLAY_CONTROL 236 /* play control cmd */
#define TUYA_DP_VOICE_PLAY_STATE 237 /* play state */
#define TUYA_DP_VOICE_PLAY_CURRENT 238 /* current playing file */
#define TUYA_DP_VOICE_PLAY_MODE 239 /* play mode */
#define TUYA_DP_VOICE_PLAY_VOLUME 240 /* play volume */
#define TUYA_DP_VOICE_UPGRADE 241 /* voice list update cmd */
#endif
1.2.2 tuya_ipc_dp_utils.c
IPC_APP_upload_all_status函数新增以下dp点的上报
Code: Select all
#ifdef TUYA_DP_VOICE_PLAY_STATE
respone_dp_enum(TUYA_DP_VOICE_PLAY_STATE, IPC_APP_get_voice_play_state());
#endif
#ifdef TUYA_DP_VOICE_PLAY_MODE
respone_dp_enum(TUYA_DP_VOICE_PLAY_MODE, IPC_APP_get_voice_play_mode());
#endif
#ifdef TUYA_DP_VOICE_PLAY_VOLUME
respone_dp_value(TUYA_DP_VOICE_PLAY_VOLUME, IPC_APP_get_voice_play_volume());
#endif
s_dp_table[]变量中添加自定义语音相关的dp点处理函数入口
Code: Select all
#ifdef TUYA_DP_VOICE_PLAY
{TUYA_DP_VOICE_PLAY, handle_DP_VOICE_PLAY},
#endif
#ifdef TUYA_DP_VOICE_PLAY_CONTROL
{TUYA_DP_VOICE_PLAY_CONTROL, handle_DP_VOICE_PLAY_CONTROL},
#endif
#ifdef TUYA_DP_VOICE_PLAY_MODE
{TUYA_DP_VOICE_PLAY_MODE, handle_DP_VOICE_PLAY_MODE},
#endif
#ifdef TUYA_DP_VOICE_PLAY_VOLUME
{TUYA_DP_VOICE_PLAY_VOLUME, handle_DP_VOICE_PLAY_VOLUME},
#endif
#ifdef TUYA_DP_VOICE_UPGRADE
{TUYA_DP_VOICE_UPGRADE, handle_DP_VOICE_UPGRADE},
#endif
定义dp点处理函数
Code: Select all
#ifdef TUYA_DP_VOICE_PLAY
STATIC VOID handle_DP_VOICE_PLAY(IN TY_OBJ_DP_S *p_obj_dp)
{
if ( (p_obj_dp == NULL) || (p_obj_dp->type != PROP_STR) )
{
PR_ERR("Error!! type invalid %d \r\n", p_obj_dp->type);
return;
}
IPC_APP_set_voice_play((cJSON *)p_obj_dp->value.dp_str);
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_CONTROL
STATIC VOID handle_DP_VOICE_PLAY_CONTROL(IN TY_OBJ_DP_S *p_obj_dp)
{
if ( (p_obj_dp == NULL) || (p_obj_dp->type != PROP_ENUM) )
{
PR_ERR("Error!! type invalid %d \r\n", p_obj_dp->type);
return;
}
IPC_APP_set_voice_play_control(p_obj_dp->value.dp_enum);
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_MODE
STATIC VOID handle_DP_VOICE_PLAY_MODE(IN TY_OBJ_DP_S *p_obj_dp)
{
if ( (p_obj_dp == NULL) || (p_obj_dp->type != PROP_ENUM) )
{
PR_ERR("Error!! type invalid %d \r\n", p_obj_dp->type);
return;
}
CHAR_T tmp_str[4] = {0};
snprintf(tmp_str, 4, "%d", p_obj_dp->value.dp_enum);
IPC_APP_set_voice_play_mode(tmp_str);
respone_dp_enum(TUYA_DP_VOICE_PLAY_MODE, IPC_APP_get_voice_play_mode());
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_VOLUME
STATIC VOID handle_DP_VOICE_PLAY_VOLUME(IN TY_OBJ_DP_S *p_obj_dp)
{
if ( (p_obj_dp == NULL) || (p_obj_dp->type != PROP_VALUE) )
{
PR_ERR("Error!! type invalid %d \r\n", p_obj_dp->type);
return;
}
IPC_APP_set_voice_play_volume(p_obj_dp->value.dp_value);
respone_dp_value(TUYA_DP_VOICE_PLAY_VOLUME, IPC_APP_get_voice_play_volume());
}
#endif
#ifdef TUYA_DP_VOICE_UPGRADE
STATIC VOID handle_DP_VOICE_UPGRADE(IN TY_OBJ_DP_S *p_obj_dp)
{
IPC_APP_set_voice_upgrade();
}
#endif
1.2.2 tuya_ipc_dp_handler.h
Code: Select all
#ifdef TUYA_DP_VOICE_PLAY
VOID IPC_APP_set_voice_play(IN cJSON *p_play_info);
#endif
#ifdef TUYA_DP_VOICE_PLAY_CONTROL
VOID IPC_APP_set_voice_play_control(INT_T play_control);
#endif
#ifdef TUYA_DP_VOICE_PLAY_STATE
CHAR_T *IPC_APP_get_voice_play_state(VOID);
#endif
#ifdef TUYA_DP_VOICE_PLAY_MODE
VOID IPC_APP_set_voice_play_mode(CHAR_T *p_play_mode);
CHAR_T *IPC_APP_get_voice_play_mode(VOID);
#endif
#ifdef TUYA_DP_VOICE_PLAY_VOLUME
VOID IPC_APP_set_voice_play_volume(INT_T play_volume);
INT_T IPC_APP_get_voice_play_volume(VOID);
#endif
#ifdef TUYA_DP_VOICE_UPGRADE
VOID IPC_APP_set_voice_upgrade(VOID);
#endif
1.2.3 tuya_ipc_dp_handler.c
Code: Select all
#ifdef TUYA_DP_VOICE_PLAY
VOID IPC_APP_set_voice_play(IN cJSON *p_play_info)
{
if (NULL == p_play_info)
{
return;
}
PR_INFO("%s %d handle_DP_VOICE_PLAY:%s \r\n", __FUNCTION__, __LINE__, (char *)p_play_info);
cJSON *pJson = cJSON_Parse((CHAR_T *)p_play_info);
if (NULL == pJson)
{
PR_ERR("%s %d step error\n", __FUNCTION__, __LINE__);
return;
}
cJSON *pCode = cJSON_GetObjectItem(pJson, "bizcode");
if (NULL == pCode)
{
PR_ERR("%s %d step error\n", __FUNCTION__, __LINE__);
cJSON_Delete(pJson);
return;
}
cJSON *pId = cJSON_GetObjectItem(pJson, "id");
if (NULL == pId)
{
PR_ERR("%s %d step error\n", __FUNCTION__, __LINE__);
cJSON_Delete(pId);
return;
}
if (OPRT_OK == ty_voice_set_play(pCode->valuestring, pId->valueint))
{
__tuya_app_write_STR("tuya_play_code", pCode->valuestring);
__tuya_app_write_INT("tuya_play_id", pId->valueint);
}
cJSON_Delete(pJson);
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_CONTROL
VOID IPC_APP_set_voice_play_control(INT_T play_control)
{
PR_INFO("set voice play control:%d \r\n", play_control);
ty_voice_set_play_control(play_control);
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_STATE
STATIC CHAR_T s_play_state[2] = {0};//for demo
CHAR_T *IPC_APP_get_voice_play_state(VOID)
{
INT_T play_state = ty_voice_get_play_state();
PR_INFO("get voice play state:%d \r\n", play_state);
snprintf(s_play_state, 2, "%d", play_state);
return s_play_state;
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_MODE
STATIC CHAR_T s_play_mode[4] = {0};//for demo
VOID IPC_APP_set_voice_play_mode(CHAR_T *p_play_mode)
{
PR_INFO("set voice play mode:%s \r\n", p_play_mode);
ty_voice_set_play_mode(atoi(p_play_mode));
}
CHAR_T *IPC_APP_get_voice_play_mode(VOID)
{
INT_T play_mode = ty_voice_get_play_mode();
PR_INFO("get voice play mode:%d \r\n", play_mode);
snprintf(s_play_mode, 4, "%d", play_mode);
return s_play_mode;
}
#endif
#ifdef TUYA_DP_VOICE_PLAY_VOLUME
VOID IPC_APP_set_voice_play_volume(INT_T play_volume)
{
PR_INFO("set voice play volume:%d \r\n", play_volume);
ty_voice_set_play_volume(play_volume);
}
INT_T IPC_APP_get_voice_play_volume(VOID)
{
INT_T play_volume = ty_voice_get_play_volume();
PR_INFO("get voice play volume:%d \r\n", play_volume);
return play_volume;
}
#endif
#ifdef TUYA_DP_VOICE_UPGRADE
VOID IPC_APP_set_voice_upgrade(VOID)
{
ty_voice_set_update_voice_list();
}
#endif
1.3 初始化
user_main.c中添加头文件包含
Code: Select all
#if defined(DEMO_IPC_VOICE_ENABLE) && (DEMO_IPC_VOICE_ENABLE == 1)
#include "tuya_ipc_voice_demo.h"
#endif
在tuya_ipc_sdk_mqtt_online_proc中添加自定义语音初始化
Code: Select all
#if defined(DEMO_IPC_VOICE_ENABLE) && (DEMO_IPC_VOICE_ENABLE == 1)
TUYA_APP_Enable_Voice();
#endif
1.4 编译宏
在tuya_ipc_demo_default_cfg.h头文件中添加编译宏定义DEMO_IPC_VOICE_ENABLE
Code: Select all
#define DEMO_IPC_VOICE_ENABLE 1
2. 环境搭建
2.1 工具安装
为了能够在Ubuntu系统中演示自定义语音的播放功能,需要安装alsa-lib库,安装命令:
Code: Select all
sudo apt-get install libasound2-dev
2.2 创建音频缓存文件夹
为了能够缓存下载的音频文件,demo中将下载完的音频文件默认缓存在/tmp/voice文件夹下,用户需手动创建/tmp/voice文件夹。
用户如需更改缓存文件夹,可自行更改tuya_ipc_voice_demo.c中的VOICE_FILE_PATH宏定义。