AI 语音给中控带来了更智能的语音控制与娱乐交互体验。本文主要介绍 TuyaOS 中控 SDK 中语音服务的能力集,以及接口的具体使用说明。
背景信息
中控语音能力依赖云端,本地上传音频到云端后,云端经过一系列处理后将结果下发到设备本地。整个能力包括:
- 语音上传通道
- TTS 音频下发
- Music/FM 音频下发
- ASR 文本下发
- TTS 文本下发
- 获取闹钟提醒信息
- 语音配网
- 昵称设置
- 语音系统 DP(音量设置、闹钟/提醒、MIC 开关、播放/暂停、上一首/下一首、蓝牙播放开/关)
本文将从代码接口层面介绍语音服务的具体使用。
开启语音服务
函数原型 |
OPERATE_RET home_control_user_voice_sevice_start(VOID) |
函数描述 |
这是一个 demo 函数,作用是开启语音服务。 |
参数说明 |
- |
返回值 |
OPERATE_RET: |
详细描述 |
- |
用法示例
OPERATE_RET home_control_user_voice_sevice_start(VOID)
{
OPERATE_RET rt = OPRT_OK;
TY_SPEAKER_CLOUD_CBS_S speaker_cloud_cbs;
TY_VOICE_CAPABLE_CBS_S voice_cap = {0};
memset(&speaker_cloud_cbs, 0x0, sizeof(TY_SPEAKER_CLOUD_CBS_S));
speaker_cloud_cbs.rev_media_cb = __voice_rcv_cloud_media_cb;
speaker_cloud_cbs.sync_audio_cb = __voice_rcv_sync_audio_cb;
speaker_cloud_cbs.thing_config_cb = __voice_rev_cloud_thing_config_cb;
speaker_cloud_cbs.nick_name_cb = __voice_rev_cloud_set_nick_name_cb;
speaker_cloud_cbs.rev_ext_custom_cb = __voice_rcv_cloud_ext_custom_cb;
rt = tuya_speaker_cloud_register(&speaker_cloud_cbs);
if (OPRT_OK != rt) {
PR_ERR("tuya_speaker_cloud_register error, rt: %d", rt);
return rt;
}
SPEAKER_UPLOAD_CONFIG_S upload_config = SPEAKER_UPLOAD_CONFIG_FOR_SPEEX();
upload_config.report_stat_cb = __voice_upload_media_status_cb;
rt = speaker_intf_upload_init(&upload_config);
if (OPRT_OK != rt) {
PR_ERR("speaker_upload_init error:%d", rt);
return rt;
}
user_voice_system_dp_register();
return OPRT_OK;
}
语音初始化回调注册
设置音量回调
函数原型 |
VOID (*TY_VOICE_VOL_CTL_CB)(UINT8_T vol) |
函数描述 |
云端通过语音系统 DP 点 203,设置音量。 |
参数说明 |
vol:音量值,取值范围 0-100 |
返回值 |
VOID |
详细描述 |
设置完后,通过 tuya_voice_capable_report_vol 接口同步当前音量值给云端。 |
语音系统 DP 控制命令回调
函数原型 |
VOID (*TY_VOICE_CTL_CB)(TY_VOICE_CTL_E ctl) |
函数描述 |
云端下发语音系统 DP 控制命令,来控制设备。 |
参数说明 |
ctl:控制命令 |
返回值 |
VOID |
详细描述 |
cmd 范围参考 TY_VOICE_CTRL_E 结构体:- TY_VOICE_MIC_OPEN:麦克风开启
- TY_VOICE_MIC_CLOSE:麦克风关闭
- TY_VOICE_BT_PLAY_OPEN:蓝牙播歌开启
- TY_VOICE_BT_PLAY_CLOSE:蓝牙播歌关闭
- TY_VOICE_PLAY_START:开始播放
- TY_VOICE_PLAY_PAUSE:暂停播放
- TY_VOICE_PLAY_PREV:上一首
- TY_VOICE_PLAY_NEXT:下一首
设置完后,通过 tuya_voice_capable_report_ctl 接口同步当前控制状态给云端。 |
设置本地闹钟
函数原型 |
VOID (*TY_VOICE_ALARM_CLOCK_CB)(CHAR_T *alarm) |
函数描述 |
云端通过语音系统 DP 点 207,下发本地闹钟。 |
参数说明 |
alarm:闹钟信息 |
返回值 |
VOID |
详细描述 |
|
语音上传状态
函数原型 |
VOID(*SPEAKER_UPLOAD_REPORT_STAT_CB)(SPEAKER_UPLOAD_STAT_E stat) |
函数描述 |
语音上传云端,出现异常将触发该回调。 |
参数说明 |
status:状态 |
返回值 |
VOID |
详细描述 |
status:SPEAKER_UP_STAT_NET_ERR ,网络状态异常 |
云端下发多媒体数据
函数原型 |
VOID (*TY_SPEAKER_REV_CLOUD_MEDIA_CB)(IN TY_CLOUD_MEDIA_S **pp_media_arr, IN CONST UINT_T arr_size) |
函数描述 |
接收云端下发多媒体数据回调,获取音频需要通过地址和参数请求音频数据流。 |
参数说明 |
- pp_media_arr:多媒体数据
- arr_size:结构体数组个数
|
返回值 |
VOID |
详细描述 |
多媒体数据关注下面三个参数:- comm:音频参数。
- p_url:HTTP 请求 URL。
- p_req_body:HTTP 请求 body。
|
子设备配网请求
函数原型 |
VOID (*TY_SPEAKER_THING_CONFIG_CB)(IN TY_THING_CONFIG_MODE_T mode, IN CONST CHAR_T *token, IN CONST UINT_T timeout) |
函数描述 |
接收云端下发开启/关闭给子设备配网请求。 |
参数说明 |
- mode:配网命令
- token:给 Wi-Fi 设备配网时需要 Token
- timeout: 配网持续时长
|
返回值 |
VOID |
详细描述 |
配网命令:- TY_THING_CONFIG_START:开启配网。
- TY_THING_CONFIG_STOP:停止配网。
|
云端下发昵称设置
函数原型 |
VOID (*TY_SPEAKER_NICK_NAME_CB)(IN CONST TY_NICK_NAME_MODE_T mode, IN CONST CHAR_T *nickname, IN CONST CHAR_T *pinyin) |
函数描述 |
接收云端下发昵称设置。 |
参数说明 |
- mode:昵称设置命令
- nickname:昵称中文名称
- pinyin:昵称的汉语拼音
|
返回值 |
VOID |
详细描述 |
昵称设置命令:- TY_NICK_NAME_SET:添加昵称。
- TY_NICK_NAME_DEL:删除昵称。
|
定制透传接口
函数原型 |
VOID (*TY_SPEAKER_REV_CUSTOM_CB)(IN CONST CHAR_T *type, IN CONST ty_cJSON *json) |
函数描述 |
客户定制 501 透传接口函数,具体协议内容由云端与客户制定,并提供说明。 |
参数说明 |
|
返回值 |
VOID |
详细描述 |
- |
上报当前音量
函数原型 |
OPERATE_RET tuya_voice_capable_report_vol (UINT8_T vol) |
函数描述 |
上报当前音量值到云端 |
参数说明 |
vol:音量值,取值范围 0-100 |
返回值 |
OPERATE_RET: |
详细描述 |
- |
上报当前控制状态
函数原型 |
OPERATE_RET tuya_voice_capable_report_vol (UINT8_T vol) |
函数描述 |
上报当前控制状态给云端。 |
参数说明 |
ctl:命令 |
返回值 |
OPERATE_RET: |
详细描述 |
cmd 范围参考 TY_VOICE_CTRL_E 结构体:- TY_VOICE_MIC_OPEN:麦克风开启
- TY_VOICE_MIC_CLOSE:麦克风关闭
- TY_VOICE_BT_PLAY_OPEN:蓝牙播歌开启
- TY_VOICE_BT_PLAY_CLOSE:蓝牙播歌关闭
- TY_VOICE_PLAY_START:开始播放
- TY_VOICE_PLAY_PAUSE:暂停播放
- TY_VOICE_PLAY_PREV:上一首
- TY_VOICE_PLAY_NEXT:下一首
|
语音上传
下面是上传 PCM 音频的示例代码,将 WAV 音频文件打开后,读取 PCM 音频数据上传到云端。音频参考文件可从 audio_resource
目录中获取。
OPERATE_RET home_control_user_voice_upload_cloud(CONST CHAR_T *pcm_file)
{
OPERATE_RET ret = OPRT_OK;
CONST INT_T send_len = 640;
INT_T remain_len = 0;
INT_T sended_len = 0;
CONST INT_T wav_head_len = 44;
PR_DEBUG("start upload test pcm");
if (pcm_file == NULL) {
PR_ERR("Param is invalid");
return OPRT_INVALID_PARM;
}
FILE *p_file = fopen(pcm_file, "r");
if (p_file == NULL) {
PR_ERR("Unable to open file %s", pcm_file);
return OPRT_INVALID_PARM;
}
struct stat statbuf;
stat(pcm_file, &statbuf);
INT_T total_len = statbuf.st_size - wav_head_len;
CHAR_T *buf = (char *)malloc(total_len);
if (buf == NULL) {
PR_ERR("Malloc error");
return OPRT_MALLOC_FAILED;
}
memset(buf, 0, sizeof(total_len));
fseek(p_file, wav_head_len, SEEK_SET);
ret = fread(buf, 1, total_len, p_file);
if (ret != total_len) {
PR_ERR("Read error\n", ret);
ret = OPRT_COM_ERROR;
goto exit;
}
TY_AUDIO_INFO_S audio_info = {
.channels = 1,
.rate = 16000,
.bits_per_sample = 16,
};
tuya_voice_upload_media_start(TY_SPEEX, &audio_info);
do {
ret = tuya_voice_upload_media_send((BYTE_T *)buf + sended_len, send_len);
if (ret < 0) {
PR_ERR("speaker_intf_upload_media_send faild:%d", ret);
ret = OPRT_COM_ERROR;
goto exit;
}
sended_len += send_len;
remain_len = total_len - sended_len;
} while (remain_len >= send_len);
PR_DEBUG("remain_len:%d\n", remain_len);
if (remain_len > 0) {
tuya_voice_upload_media_send((BYTE_T *)buf + sended_len, remain_len);
}
ret = OPRT_OK;
exit:
if (p_file)
fclose(p_file);
if (buf)
free(buf);
tuya_voice_upload_media_stop();
return ret;
}
上传语音数据到云端有三个步骤,仅支持单线程操作:开启 > 上传 > 停止。
初始化上传
函数原型 |
OPERATE_RET tuya_voice_upload_media_start (IN CONST TY_MEDIA_ENCODE_T type, IN CONST TY_AUDIO_INFO_S *info) |
函数描述 |
开启上传语音数据到云端。 |
参数说明 |
|
返回值 |
OPERATE_RET: |
详细描述 |
音频基本参数信息: - channels:声道,设置成单声道,1。
- sample_freq:采样频率,设置成 16000 。
- bit_depth:采样精度,设置成 16bit。
|
上传音频数据
函数原型 |
OPERATE_RET tuya_voice_upload_media_send(IN CONST BYTE_T *p_buf, IN CONST UINT_T buf_len) |
函数描述 |
上传语音数据到云端,buffer 中写入 PCM 音频裸流。 |
参数说明 |
- p_buf:PCM 裸流缓冲区地址
- buf_len:PCM 裸流数据长度
|
返回值 |
OPERATE_RET: |
详细描述 |
- |
停止上传
函数原型 |
OPERATE_RET tuya_voice_upload_media_stop(VOID) |
函数描述 |
停止上传,并释放资源 |
参数说明 |
VOID |
返回值 |
OPERATE_RET: |
详细描述 |
- |
释放多媒体接收资源
函数原型 |
OPERATE_RET tuya_speaker_free_cloud_media_arr (IN TY_CLOUD_MEDIA_S **pp_media_arr, IN CONST UINT_T arr_size) |
函数描述 |
释放多媒体接收资源 |
参数说明 |
- pp_media_arr:同 __voice_rcv_cloud_media_cb 参数
- arr_size:同 __voice_rcv_cloud_media_cb 参数
|
返回值 |
OPERATE_RET |
详细描述 |
__voice_rcv_cloud_media_cb 回调触发后,用户下载对应的 TTS 或者音乐等音频文件,完成播放后,释放资源。 |
告知云端当前对话完成
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_complete_tts(IN CONST CHAR_T *p_callback_val) |
函数描述 |
告知云端当前对话完成。 |
参数说明 |
p_callback_val:对话类型 |
返回值 |
OPERATE_RET: |
详细描述 |
针对单次唤醒,连续对话的场景,完成 TTS 播放后需要调用该接口告知云端,当前对话完成,才能继续进行下一轮对话。 |
语音配网
向云端上报配网请求
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_thing_config_request (VOID) |
函数描述 |
向云端上报开启配网请求。 |
参数说明 |
VOID |
返回值 |
OPERATE_RET: |
详细描述 |
- |
向云端上报停止配网请求
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_thing_config_stop (VOID) |
函数描述 |
向云端上报停止配网请求。 |
参数说明 |
VOID |
返回值 |
OPERATE_RET: |
详细描述 |
- |
向云端上报拒绝配网请求
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_thing_config_reject (VOID) |
函数描述 |
向云端上报拒绝配网请求。 |
参数说明 |
VOID |
返回值 |
OPERATE_RET: |
详细描述 |
- |
向云端上报接入设备个数
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_thing_config_access_count (IN CONST INT_T count) |
函数描述 |
向云端上报接入设备个数。 |
参数说明 |
count:接入子设备个数 |
返回值 |
OPERATE_RET: |
详细描述 |
- |
上报当前昵称设置执行结果
函数原型 |
OPERATE_RET tuya_speaker_mqtt_report_nick_name (IN CONST TY_NICK_NAME_MODE_T mode, IN CONST CHAR_T *nickname, IN CONST CHAR_T *pinyin, IN CONST BOOL_T set_result) |
函数描述 |
上报当前昵称设置(添加/删除)执行结果。 |
参数说明 |
- mode:昵称设置命令
- nickname:昵称中文名称
- pinyin:昵称的汉语拼音
- set_result TRUE:设置成功。FALSE:设置失败
|
返回值 |
OPERATE_RET: |
详细描述 |
昵称设置命令: - TY_NICK_NAME_SET: 添加昵称。
- TY_NICK_NAME_DEL:删除昵称。
|
上传字符文本内容到云端
函数原型 |
OPERATE_RET tuya_speaker_mqtt_get_tts(IN CONST CHAR_T *p_tts_content) |
函数描述 |
上传字符文本内容到云端 |
参数说明 |
p_tts_content:字符文本内容 |
返回值 |
OPERATE_RET: |
详细描述 |
__voice_rcv_cloud_media_cb 会接收到对应 TTS 音频,用户可以播放。 |