You need to enable JavaScript to run this app.
导航

C 接口调用流程

最近更新时间2023.06.28 18:18:14

首次发布时间2023.04.12 19:42:58

初始化

环境依赖

创建音色转换 SDK 引擎实例前调用,完成网络环境等相关依赖配置。本方法每个进程生命周期内仅需调用一次。

int ret = SpeechSDK_PrepareEnvironment();
if (ret) {
    std::cout << "Fail to prepare engine environment!" << std::endl;
    return -1;
}

创建引擎实例

调用如下接口获取音色转换 SDK 相关实例。每个实例在同一时刻只能处理一个音色转换任务,如需同时处理多个任务可以创建多个实例。
其中,第三个void*参数会在回调接口中作为实参传递,如果不需要可以设为 nullptr

SpeechSDK_Handle handle;
ret = SpeechSDK_CreateHandle(&handle, OnMessage, nullptr);
if (ret) {
    std::cout << "Fail to create engine!" << std::endl;
    SpeechSDK_DestroyHandle(handle);
    return -1;
}

参数配置

引擎类型

// 设置引擎类型为音色转换
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_ENGINE_NAME_STRING, VOICECONV_ENGINE_NAME);

工作模式

音色转换 SDK 当前支持 2 个工作模式

  • 离线音色转换 kVoiceConvWorkModeOffline
// 设置工作模式为离线音色转换
SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_WORK_MODE_INT, kVoiceConvWorkModeOffline);
  • 在线音色转换 kVoiceConvWorkModeOnline
// 设置工作模式为在线音色转换
SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_WORK_MODE_INT, kVoiceConvWorkModeOnline);
// 建连超时,默认12000ms
SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_CONN_TIMEOUT_INT, 12000);
// 接收超时,默认8000ms
SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_RECV_TIMEOUT_INT, 8000);

日志

为便于开发者集成调试,有如下建议:

  • 日志级别,开发时设置为 DEBUG(最低级别),线上设置WARN
  • 调试路径,开发时设置,线上关闭,设置以后 SDK 会在该路径下生成文件名形如 speech_sdk_*.log 的日志文件;
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_LOG_LEVEL_STRING, LOG_LEVEL_DEBUG);
// 注意 Windows 平台需要使用 SpeechSDK_SetOptionWString 函数
#ifdef _WIN32
SpeechSDK_SetOptionWString(handle, OPTIONS_KEY_DEBUG_PATH_STRING u"{YOUR DEBUG PATH}");
#else
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_DEBUG_PATH_STRING "{YOUR DEBUG PATH}");
#endif

线上问题定位

为了方便定位线上问题,需要开发者配置相关参数,包括:

  • UID, 用于区分不同的用户
  • DEVICE_ID, 用于区分不同的设备

开发者需要保证这两个参数是可靠的,如果出现多个用户使用同一个 UID 或者多台设备使用同一个 DEVICE_ID, 会导致我们无法还原问题发生时的现场状况从而难以定位、解决问题。
配置方法如下:

SpeechSDK_SetOptionString(handle, OPTIONS_KEY_UID_STRING, "USER ID");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_DEVICE_ID_STRING, "DEVICE ID");

为了保证信息上传成功,我们会将采集到的数据先落盘再上传,所以需要配置数据的存储路径:

#ifdef _WIN32
SpeechSDK_SetOptionWString(handle, OPTIONS_KEY_DEBUG_PATH_STRING u"{YOUR DEBUG PATH}");
#else
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_DEBUG_PATH_STRING "{YOUR DEBUG PATH}");
#endif

鉴权

使用在离线流式音色转换能力时,需要完成相关授权验证。

在线鉴权

需要申请 AppidToken,配置时 Token 需要添加固定前缀 Bearer;

// 在线鉴权
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_APP_ID_STRING, "{APPID}");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_APP_TOKEN_STRING, "Bearer;{TOKEN}");

离线鉴权

若要使用离线音色转换,需联系商务人员申请离线功能授权,在获取到相关配置参数之后才能正常使用。
离线授权包括两种授权方式,按使用期限授权按装机量授权,按使用期限授权是指开通了权限的软件在授权期限内可以不限次数、不限装机量的使用离线音色转换功能;按装机量授权限制使用离线音色转换的设备数量,但是不限制使用次数和使用期限。在联系商务人员获取授权相关配置参数时,开发者需要确认选用哪种授权方式。
获取到授权参数business keysecret之后,调用以下函数进行鉴权相关配置:

SpeechSDK_SetOptionString(handle, OPTIONS_KEY_AUTHENTICATE_TYPE_STRING, AUTHENTICATE_TYPE_LATE_BIND);
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_AUTHENTICATE_ADDRESS_STRING, "https://cv-tob.bytedance.com");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_AUTHENTICATE_URI_STRING, "/v1/api/sdk/tob_license/getlicense");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_BUSINESS_KEY_STRING, "{YOUR BUSINESS KEY}}");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_AUTHENTICATE_SECRET_STRING, "{YOUR SECRET}");

上面的配置指定了在触发鉴权时,使用什么参数向什么服务请求证书文件,拿到证书文件之后需要将其保存在设备磁盘上,调用下面的函数配置证书存放路径:

#ifdef _WIN32
SpeechSDK_SetOptionWString(handle, OPTIONS_KEY_LICENSE_DIRECTORY_STRING, u"{YOUR LICENSE PATH}");
#else
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_LICENSE_DIRECTORY_STRING, "{YOUR LICENSE PATH}");
#endif

在线请求资源配置

发起在线音色转换请求,需要配置 域名URI 以及 集群 参数。

// 在线请求资源配置
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_VOICECONV_ADDRESS_STRING, "wss://openspeech.bytedance.com");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_VOICECONV_URI_STRING, "{URI}");
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_VOICECONV_CLUSTER_STRING, "{CLUSTER}");

音频来源

对于 Windows 平台,音色转换 SDK 可以调用系统内置播放器,同时也支持以原始音频流或音频文件作为输入,配置值分别为:

  • RECORDER_TYPE_RECORDER,系统内置录音机,需要硬件支持录音;
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_RECORDER_TYPE_STRING, RECORDER_TYPE_RECORDER);
  • RECORDER_TYPE_FILE,原始音频文件,需要设置音频文件路径,设置后 SDK 会自行读取配置路径下的音频文件;
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_RECORDER_TYPE_STRING, RECORDER_TYPE_FILE);
#ifdef _WIN32
SpeechSDK_SetOptionWString(handle, OPTIONS_KEY_RECORDER_FILE_STRING, u"{AUDIO FILE PATH}");
#else
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_RECORDER_FILE_STRING, "{AUDIO FILE PATH}");
#endif
  • RECORDER_TYPE_STREAM,原始音频流,需要在执行过程中 输入音频数据,并在所有音频数据均输入完成后,发送 音频输入完成 指令。具体调用方式可参考下文的输入音频流小节
SpeechSDK_SetOptionString(handle, OPTIONS_KEY_RECORDER_TYPE_STRING, RECORDER_TYPE_STREAM);

控制音色转换的结果

音色

SDK 支持将语音转换为多种不同的音色,当前支持的音色参考音色列表

设置音色的方法如下:

SpeechSDK_SetOptionString(handle, OPTIONS_KEY_VOICECONV_VOICE_TYPE_STRING, "{YOUR VOICE TYPE}");

音量、音调

SDK 还支持调节转换出的音频的音调和音量,设置方法分别为:

SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_VOLUME_INT, 1);
SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_PITCH_INT, 1);

采样率

音色转换的输出结果支持多种采样率,目前支持 8000, 16000, 24000 三种。设置输出采样率的方法如下:

SpeechSDK_SetOptionInt(handle, OPTIONS_KEY_VOICECONV_RESULT_SAMPLE_RATE_INT, 24000);

初始化引擎实例

参数配置完成后,调用 初始化接口,完成引擎实例的初始化。

ret = SpeechSDK_InitEngine(handle);
if (ret) {
    std::cout << "Fail to initialize engine!" << std::endl;
    SpeechSDK_DestroyHandle(handle);
    return -1;
}
发送指令

音色转换 SDK 通过发送指令接口 SpeechSDK_SendDirectiveToEngine 触发各种操作,需要注意以下两点:

  1. 该接口不要在回调线程中调用;
  2. 该接口所支持的指令中, kStartEngine, kStopEngine 是异步指令,在相应的回调到达后才真正完成了操作。

启动引擎 kStartEngine

// 注意这里先调用同步停止,确保 SDK 内部处于空闲状态
SpeechSDK_SendDirectiveToEngine(handle, DirectiveType::kSyncStopEngine, "");
SpeechSDK_SendDirectiveToEngine(handle, DirectiveType::kStartEngine, "");

音频输入完成 kFinishTalking

//音频输入完成,等待最终转换结果
SpeechSDK_SendDirectiveToEngine(handle, DirectiveType::kFinishTalking, "");

关闭引擎 kStopEngine

// 强制停止本次音色转换
SpeechSDK_SendDirectiveToEngine(handle, DirectiveType::kStopEngine, "");
输入音频数据

当使用系统内置录音机或使用音频文件时,直接按照前文中提到的方法设置即可,不需额外操作。下面说明输入原始音频流时的一般调用过程。

输入音频流

音频来源为 RECORDER_TYPE_STREAM 时,需要主动通过SpeechSDK_FeedAudioToEngine接口输入音频数据,并在结束后发送音频输入完成 kFinishTalking指令。

以下示例是输入并读取音频文件。但实际上可以通过这种方式,输入从任何地方获得的音频数据,比如客户端网络上传或者通过其他 RPC 方式获得的数据:

FILE* fp = fopen("../data/asr_rec_file.pcm", "rb");
char data[2048];
while (!feof(fp)) {
    auto n = fread(data, 1, 2048, fp);
    
    // Feed audio.
    ret = SpeechSDK_FeedAudioToEngine(
        handle, reinterpret_cast<const int16_t*>(data), n / 2);
    if (ret) {
        std::cout << "Fail to feed audio!" << std::endl;
        SpeechSDK_DestroyHandle(handle);
        return -1;
    }
}
fclose(fp);
SpeechSDK_SendDirectiveToEngine(handle, DirectiveType::kFinishTalking, "");
回调接收返回数据

SDK 的回调函数签名为 void (*)(int32_t type, const char* data, const int32_t data_length, void* user_context),其中 user_context 就是前文创建引擎实例时传入的第 3 个类型为 void*的参数。 下面简要介绍各个不同的 type 分别代表的含义及建议处理方法。

引擎启动成功 kEngineStart

收到该回调后表示音色转换已经开始。数据字段为该次任务的 ID。

引擎关闭 kEngineStop

收到该回调后,音色转换任务已经结束,引擎进入空闲状态。

播放开始 kTtsStartPlaying

收到该回调后表示系统内置播放器已经开始播放转换后的音频数据。

播放结束 kTtsFinishPlaying

收到该回调后,表示播放器播完了所有音频。

错误信息 kEngineError

引擎发生错误。数据部分为 JSON 结构,内部包含三个字段:

  • req_id:任务 ID;
  • err_msg:错误描述信息;
  • err_code:错误码,可参考错误码说明
销毁引擎实例

当不再需要音色转换后,建议对引擎实例进行销毁,释放内存资源。

SpeechSDK_DestroyHandle(handle);