语音服务

更新时间:2023-01-09 06:44:00

AI 语音给中控带来了更智能的语音控制与娱乐交互体验。本文主要介绍 TuyaOS 中控 SDK 中语音服务的能力集,以及接口的具体使用说明。

背景信息

中控语音能力依赖云端,本地上传音频到云端后,云端经过一系列处理后将结果下发到设备本地。整个能力包括:

  • 语音上传通道
  • TTS 音频下发
  • Music/FM 音频下发
  • ASR 文本下发
  • TTS 文本下发
  • 获取闹钟提醒信息
  • 语音配网
  • 昵称设置
  • 语音系统 DP(音量设置、闹钟/提醒、MIC 开关、播放/暂停、上一首/下一首、蓝牙播放开/关)

本文将从代码接口层面介绍语音服务的具体使用。

开启语音服务

函数原型 OPERATE_RET home_control_user_voice_sevice_start(VOID)
函数描述 这是一个 demo 函数,作用是开启语音服务。
参数说明 -
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

用法示例

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;
    }

    // 注册语音系统 DP 回调
    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 透传接口函数,具体协议内容由云端与客户制定,并提供说明。
参数说明
  • type:接口类型
  • json:JSON 数据
返回值 VOID
详细描述 -

上报当前音量

函数原型 OPERATE_RET tuya_voice_capable_report_vol (UINT8_T vol)
函数描述 上报当前音量值到云端
参数说明 vol:音量值,取值范围 0-100
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

上报当前控制状态

函数原型 OPERATE_RET tuya_voice_capable_report_vol (UINT8_T vol)
函数描述 上报当前控制状态给云端。
参数说明 ctl:命令
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 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;//704
    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)
函数描述 开启上传语音数据到云端。
参数说明
  • info:音频基本参数信息
  • type:编码类型
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 音频基本参数信息:
  • 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:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

停止上传

函数原型 OPERATE_RET tuya_voice_upload_media_stop(VOID)
函数描述 停止上传,并释放资源
参数说明 VOID
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

释放多媒体接收资源

函数原型 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
  • 0:成功
  • 其他:失败,详见错误码
详细描述 __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:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 针对单次唤醒,连续对话的场景,完成 TTS 播放后需要调用该接口告知云端,当前对话完成,才能继续进行下一轮对话。

语音配网

向云端上报配网请求

函数原型 OPERATE_RET tuya_speaker_mqtt_report_thing_config_request (VOID)
函数描述 向云端上报开启配网请求。
参数说明 VOID
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

向云端上报停止配网请求

函数原型 OPERATE_RET tuya_speaker_mqtt_report_thing_config_stop (VOID)
函数描述 向云端上报停止配网请求。
参数说明 VOID
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

向云端上报拒绝配网请求

函数原型 OPERATE_RET tuya_speaker_mqtt_report_thing_config_reject (VOID)
函数描述 向云端上报拒绝配网请求。
参数说明 VOID
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

向云端上报接入设备个数

函数原型 OPERATE_RET tuya_speaker_mqtt_report_thing_config_access_count (IN CONST INT_T count)
函数描述 向云端上报接入设备个数。
参数说明 count:接入子设备个数
返回值 OPERATE_RET:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 -

上报当前昵称设置执行结果

函数原型 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:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 昵称设置命令:
  • 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:
  • 0:成功
  • 其他:失败,详见错误码
详细描述 __voice_rcv_cloud_media_cb 会接收到对应 TTS 音频,用户可以播放。