一、前提条件
1. 你需要先 注册腾讯云 账号,并完成 实名认证。
2. 购买了 腾讯云物联网开发平台 相关实例,开通并激活了 智能语音增值服务。
3. 在 物联网开发平台控制台 拿到了本 Demo 所需要的设备三元组(已经激活过了)。
4. 已按 登录与注册 文档跑通 tc_iot_login 登录。
注意:警告:
注意:AI 对话服务属于增值服务,必须开通此增值服务后激活设备 license 才可以正常使用。
二、步骤 1:初始化 AI 对话模块
请从 下载页面 获取包含 talk 模块的 SDK 包。SDK 包名中 talk 表示 AI 对话功能,例如:tc_iot_sdk_linux_x64_c_av_cs_talk.zip。
登录 成功后,调用 tc_iot_aitalk_init 初始化 AI 对话模块并注册回调。常用回调如下:
| 回调 | 说明 |
| on_receive_bot_audio | 接收机器人回复的音频帧,将数据送入设备扬声器播放。 |
| on_receive_bot_text | 接收机器人回复的文本,可用于屏幕或日志展示。 |
| on_receive_asr_text | 接收用户语音识别结果。 |
| on_bot_state_changed | 机器人状态变化通知,例如监听、思考、播报和结束。 |
| on_launch_call | 机器人触发联系人呼叫时回调,需要先注册联系人。 |
| on_error | AI 对话过程中发生错误时回调。 |
#include <stdio.h>#include <string.h>#include "audio_device.h"#include "tc_iot_aitalk.h"static void on_bot_audio(const tc_iot_audio_frame *frame, void *user_data) { (void)user_data; if (!frame || !frame->data || frame->data_size == 0) { return; } if (audio_device_write(frame->data, frame->data_size, frame->codec) != 0) { printf("play bot audio failed\\n"); }}static void on_aitalk_error(tc_iot_error_e code, const char *message, void *user_data) { (void)user_data; printf("aitalk error: %d, %s\\n", code, message ? message : "");}static tc_iot_error_e init_aitalk(void) { tc_iot_aitalk_observer_s observer = {0}; observer.on_receive_bot_audio = on_bot_audio; observer.on_error = on_aitalk_error; tc_iot_aitalk_init_params_s params = {0}; params.audio_option.codec = TC_IOT_AUDIO_CODEC_OPUS; // 音频编码传输格式,可选 aac/opus/g722 params.audio_option.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000; // 音频采样率默认 16 kHz params.audio_option.frame_duration_ms = 20; // g722/opus 默认填 20 ms,aac 默认填 64 ms /* bot_id 为空时使用平台默认智能体配置; prompt_variables_json 是用户自定义信息 */ return tc_iot_aitalk_init(¶ms, &observer, NULL);}
注意:tc_iot_aitalk_init 必须在 tc_iot_login 登录成功后调用。音频的编码、采样率和帧长应与设备音频采集链路保持一致。
三、步骤 2:注册联系人(可选)
如需让机器人根据语义触发联系人呼叫,请在开始对话前调用 tc_iot_aitalk_register_contacts。最多可注册 10 位联系人。
static void on_register_contacts(tc_iot_error_e code, const char *message) { printf("register contacts: %d, %s\\n", code, message ? message : "");}static tc_iot_contact_s contacts[] = { {.user_id = "USER_ID", .user_name = "联系人名称"},};tc_iot_aitalk_register_contacts(contacts, 1, on_register_contacts);
四、步骤 3:开始对话并发送音频
调用 tc_iot_aitalk_start_speak 开始对话。接口为异步调用,请在回调返回成功后再启动麦克风采集。开始采集前,请先完成平台音频设备初始化(示例中的 audio_device_* 为平台适配接口)。
| 模式 | 说明 |
| TC_IOT_AITALK_MODE_CONTINUOUS | 持续对话模式,适用于免按键交互场景。 |
| TC_IOT_AITALK_MODE_PUSH_TO_TALK | 按键说话模式,适用于按住按键采集语音的场景(暂不支持)。 |
static void on_mic_captured(const uint8_t *data, uint32_t size, tc_iot_audio_codec_e codec, uint64_t pts_ms, void *user_data);static void on_start_speak(tc_iot_error_e code, const char *message) { if (code != TC_IOT_ERR_SUCCESS) { printf("start speak failed: %d, %s\\n", code, message ? message : ""); return; } if (audio_device_start_capture(on_mic_captured, NULL) != 0) { printf("start capture failed\\n"); }}tc_iot_aitalk_start_speak(TC_IOT_AITALK_MODE_CONTINUOUS, on_start_speak);
采集到音频后,组装 tc_iot_audio_frame 并调用 tc_iot_aitalk_send_audio 发送:
static void on_mic_captured(const uint8_t *data, uint32_t size, tc_iot_audio_codec_e codec, uint64_t pts_ms, void *user_data) { (void)user_data; if (!data || size == 0) { return; } tc_iot_audio_frame frame = {0}; frame.codec = codec; // 可直接推送 PCM,由 SDK 内部完成编码与发送 frame.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000; frame.channels = TC_IOT_AUDIO_CHANNEL_MONO; frame.frame_duration_ms = 20; // 根据实际情况填写 frame.data = (uint8_t *)data; frame.data_size = size; frame.pts_ms = pts_ms; tc_iot_error_e rc = tc_iot_aitalk_send_audio(&frame); if (rc != TC_IOT_ERR_SUCCESS) { printf("send audio failed: %d\\n", rc); }}
如需直接发送文本,可调用 tc_iot_aitalk_send_text。
五、步骤 4:中断和停止对话
机器人播报过程中,可调用 tc_iot_aitalk_interrupt 中断当前回复。结束对话时,先停止本地采集,再停止 AI 对话并释放模块资源。
audio_device_stop_capture(); // 停止音频采集tc_iot_aitalk_stop_speak(); // 停止 AI 对话tc_iot_aitalk_deinit(); // 反初始化并释放资源,完全退出 AI 对话服务
随后请按照 登录与注册 的流程退出登录并反初始化 SDK,则 SDK 完全释放资源。
六、完整示例代码
以下示例保留 SDK 的真实 API 和关键参数校验;音频采集、播放、休眠等平台相关逻辑均以注释标出,请替换为芯片或操作系统提供的接口。
#include <stdbool.h>#include <stdint.h>#include <stdio.h>#include "tc_iot.h"#include "tc_iot_aitalk.h"/* 登录和开始对话均为异步操作,回调中记录结果,主流程据此继续或退出。 */static volatile bool s_login_done = false;static volatile bool s_start_done = false;static volatile bool s_aitalk_error = false;static tc_iot_error_e s_login_result = TC_IOT_ERR_SUCCESS;static tc_iot_error_e s_start_result = TC_IOT_ERR_SUCCESS;static void on_login(tc_iot_error_e error_code, const char *error_message) { s_login_result = error_code; s_login_done = true; // 登录失败时,可在这里记录 error_message 并通知上层业务。}static void on_start_speak(tc_iot_error_e error_code, const char *error_message) { s_start_result = error_code; s_start_done = true; // 开始对话失败时,可在这里记录 error_message 并通知上层业务。}static void on_receive_bot_audio(const tc_iot_audio_frame *frame, void *user_data) { (void)user_data; if (!frame || !frame->data || frame->data_size == 0) { return; } // 这里收到的音频是经过解码后的 PCM 音频 // 将 frame->data 推送到具体的音频设备播放。 // 例如:调用芯片平台的扬声器播放、PCM 输出或音频框架接口。}static void on_receive_bot_text(const char *text, void *user_data) { (void)user_data; if (!text) { return; } // 将机器人回复文本显示到屏幕,或上传到你的业务服务。}static void on_receive_asr_text(const char *text, void *user_data) { (void)user_data; if (!text) { return; } // 将用户语音识别结果显示到屏幕,或用于本地业务处理。}static void on_bot_state_changed(tc_iot_aitalk_bot_state_e old_state, tc_iot_aitalk_bot_state_e new_state, void *user_data) { (void)old_state; (void)user_data; // 根据 new_state 更新设备指示灯、屏幕或其他交互状态。}static void on_aitalk_error(tc_iot_error_e error_code, const char *error_message, void *user_data) { (void)user_data; s_aitalk_error = true; // 记录 error_code 和 error_message,并停止或重试业务流程。}/* * 在平台麦克风的数据回调中调用本函数。 * data、size、codec 和 pts_ms 均来自当前平台的音频采集结果。 */static void on_mic_captured(const uint8_t *data, uint32_t size, tc_iot_audio_codec_e codec, uint64_t pts_ms, void *user_data) { (void)user_data; if (!data || size == 0) { return; } tc_iot_audio_frame frame = {0}; frame.codec = codec; frame.sample_rate = TC_IOT_AUDIO_SAMPLE_RATE_16000; frame.channels = TC_IOT_AUDIO_CHANNEL_MONO; frame.frame_duration_ms = 20; frame.data = (uint8_t *)data; frame.data_size = size; frame.pts_ms = pts_ms; tc_iot_error_e rc = tc_iot_aitalk_send_audio(&frame); if (rc != TC_IOT_ERR_SUCCESS) { // 记录发送失败原因;必要时停止采集或触发重连。 }}int main(void) { bool sdk_inited = false; bool aitalk_inited = false; bool speak_started = false; bool conversation_completed = false; tc_iot_error_e rc; // 1. 配置并初始化 SDK。 tc_iot_config_s sdk_config = {0}; sdk_config.storage_path = "./"; sdk_config.log_level = TC_IOT_LOG_LEVEL_INFO; rc = tc_iot_init(&sdk_config); if (rc != TC_IOT_ERR_SUCCESS) { goto cleanup; } sdk_inited = true; // 2. 从安全配置中读取设备三元组并登录平台。 tc_iot_device_info_s device_info = {0}; device_info.product_id = get_product_id(); device_info.device_id = get_device_name(); device_info.device_secret = get_device_secret(); s_login_done = false; rc = tc_iot_login(&device_info, on_login); if (rc != TC_IOT_ERR_SUCCESS) { goto cleanup; } // 等待 on_login 回调或超时;休眠接口请替换为具体平台实现。 wait_until(&s_login_done, 30000); if (!s_login_done || s_login_result != TC_IOT_ERR_SUCCESS) { goto cleanup; } // 3. 注册 AI 对话事件回调并初始化模块。 tc_iot_aitalk_observer_s observer = {0}; observer.on_receive_bot_audio = on_receive_bot_audio; observer.on_receive_bot_text = on_receive_bot_text; observer.on_receive_asr_text = on_receive_asr_text; observer.on_bot_state_changed = on_bot_state_changed; observer.on_error = on_aitalk_error; tc_iot_aitalk_init_params_s init_params = {0}; // 根据实际采集参数设置编码、采样率和单帧时长。 init_params.audio_option = get_platform_audio_option(); rc = tc_iot_aitalk_init(&init_params, &observer, NULL); if (rc != TC_IOT_ERR_SUCCESS) { goto cleanup; } aitalk_inited = true; // 4. 如需机器人触发联系人呼叫,在开始对话前注册联系人。 // tc_iot_aitalk_register_contacts(contacts, contact_count, on_register_contacts); // 5. 初始化具体平台的麦克风和扬声器。 // 麦克风采集到一帧音频后,调用 on_mic_captured() 发送给 AI 对话服务。 // 6. 异步开始持续对话,成功后再启动麦克风采集。 s_start_done = false; rc = tc_iot_aitalk_start_speak(TC_IOT_AITALK_MODE_CONTINUOUS, on_start_speak); if (rc != TC_IOT_ERR_SUCCESS) { goto cleanup; } wait_until(&s_start_done, 30000); if (!s_start_done || s_start_result != TC_IOT_ERR_SUCCESS) { goto cleanup; } speak_started = true; // 启动具体平台的麦克风采集流程。 // 采集线程或回调中不要阻塞过久,按帧调用 on_mic_captured()。 while (!s_aitalk_error && !is_exit_requested()) { // 使用具体平台的休眠、事件循环或任务调度机制。 } conversation_completed = !s_aitalk_error;cleanup: // 先停止具体平台的麦克风采集和扬声器播放。 if (speak_started) { tc_iot_aitalk_stop_speak(); } if (aitalk_inited) { tc_iot_aitalk_deinit(); } if (sdk_inited) { tc_iot_deinit(); } return conversation_completed ? 0 : 1;}
注意:该示例使用持续对话模式。若需联系人呼叫,请在 tc_iot_aitalk_start_speak 前按 步骤 2 的方式注册联系人。
七、常见问题
| 现象 | 排查建议 |
| 启动 AI 对话返回 -204(License 未激活) | 设备的 TWeTalk license 未激活,请确认已开通服务并完成设备 license 激活。 |
| 未收到机器人音频 | 确认 tc_iot_aitalk_start_speak 的回调已成功返回,且麦克风采集后持续调用了 tc_iot_aitalk_send_audio。 |
| 收到音频但没有声音 | 检查 on_receive_bot_audio 是否已将数据送入平台播放接口,并确认播放设备支持回调中的音频编码。 |
| 未触发联系人呼叫 | 确认在 tc_iot_aitalk_start_speak 前调用了 tc_iot_aitalk_register_contacts,且联系人信息有效。 |
八、联系我们
如果你在接入或使用过程中有任何疑问或者建议,欢迎 联系我们 提交反馈。