单项功能概述(Windows)

1、SDK云端功能

1.1 产品介绍 

云端SDK 提供在线语音识别,在线语音合成,长语音实时识别,以及录音文件长语音转写功能等单项语音服务。

目前SDK提供的单项语音服务如下:

1) 在线语音识别(Automatic Speech Recognition,ASR):识别语音内容,转化为相应的文字。

2) 在线语音合成(Text to Speech,TTS):将文字信息转变为可以听得懂的、流利的汉语。

3) 长语音实时识别:将很长的一段语音内容,实时转化为相应的文字。

4) 录音文件长语音转写:将很长的一段录音文件,转化为相应的文字。

1.2 预备工作

1) 账号:DUI平台的账号,进行SDK集成的必备前提之一。
2) 产品:在控制台上创建产品后,会自动生成一个产品ID。创建流程见:单项基础技术接入
3) SDK:前往SDK下载页下载Windows平台的压缩包,支持x86和x86_64的windows10平台,并且含有集成手册、开发手册、FAQ,example。
4)   网络:SDK仅支持纯云端功能,因此必须连接网络才能正常使用,用来和dui平台进行交互,完成识别、合成等功能。

1.3 接口描述

       SDK包含两个功能接口和一系列消息接口

              功能接口为dds_start和dds_send,其中dds_start用于启动SDK服务,dds_send用于发送消息

              消息接口为以dds_msg_xxx开头的函数,它们用于组合不同的消息类型,通过dds_send接口发送出去

 

       注意:dds_send接口是线程安全的,可以在不同的线程中调用,但是不要在dds的回调函数中调用,头文件介绍如下:

#ifndef __DDS_H__

#define __DDS_H__

 

#ifdef __cplusplus

extern "C" {

#endif

 

#if (!(defined DDS_CALL) || !(defined DDS_IMPORT_OR_EXPORT))

#if defined _WIN32

#if defined _WIN64

#define DDS_CALL __stdcall//windos系统和linux 系统,函数参数压栈方向不一样

#else

#define DDS_CALL

#endif

 

#ifdef DDS_IMPLEMENTION

#define DDS_IMPORT_OR_EXPORT __declspec(dllexport)//类似标准ANSI c的 export方法,供被调用

#else

#define DDS_IMPORT_OR_EXPORT __declspec(dllimport)

#endif

#if 0

#elif defined __ANDROID__

#define DDS_CALL

#define DDS_IMPORT_OR_EXPORT

#undef  JNIEXPORT

#define JNIEXPORT __attribute ((visibility("default")))

#endif

#elif defined __APPLE__

#define DDS_CALL

#define DDS_IMPORT_OR_EXPORT

#elif defined __unix__

#define DDS_CALL

#define DDS_IMPORT_OR_EXPORT __attribute ((visibility("default")))

#else

#define DDS_CALL

#define DDS_IMPORT_OR_EXPORT

#endif

#endif

 

#define DDS_VERSION     "DDS 0.2.26"

#define DDS_VERSION_NUM 226

 

/* callback event */

#define DDS_EV_OUT_RECORD_AUDIO                                1 //dds主动索要音频数据,一般100ms一次,

#define DDS_EV_OUT_NATIVE_CALL                                    2 //dds 查询本地数据,通过DDS_EV_IN_NATIVE_RESPONSE 消息返回给dds server

#define DDS_EV_OUT_COMMAND                                        3 //向客户端发送控制命令,一般为json格式字符串,比如打开台灯

#define DDS_EV_OUT_MEDIA                                              4 //云端返回的json格式的播放列表

#define DDS_EV_OUT_STATUS                                            5 //云端返回dds状态,idle,listening,understanding

#define DDS_EV_OUT_TTS                                                  6 //语音合成,返回合成的音频的url,nlg文本可选

#define DDS_EV_OUT_ERROR                                             7 //dds 异常

#define DDS_EV_OUT_ASR_RESULT                                    8 //语音识别,返回识别后的文本和拼音

#define DDS_EV_OUT_DUI_RESPONSE                                9 //dui 服务返回完整结果,json格式

#define DDS_EV_OUT_DUI_LOGIN                                     10 //返回login注册结果,设备名

#define DDS_EV_OUT_CINFO_RESULT                                11 //获得get的操作结果,成功失败,tts或词库的返回结果

#define DDS_EV_OUT_OAUTH_RESULT                               12 //第三方授权结果返回

#define DDS_EV_OUT_PRODUCT_CONFIG_RESULT              13 //获取产品配置信息

#define DDS_EV_OUT_WEB_CONNECT                                14 //返回和dui平台端tcp连接成功与否的消息

#define DDS_EV_OUT_DUI_DEVICENAME                            15 //返回当前设备名

#define DDS_EV_OUT_REFRESH_TOKEN                              23 //refresh token更新结果

#define DDS_EV_OUT_LASR_RT_RESULT                             24 //长语音实时结果返回

#define DDS_EV_OUT_LASR_RT_RAW                                 25 //长语音实时结果(服务端返回结果)

#define DDS_EV_OUT_LASR_RAW                                       26 //长语音文件转写结果返回

#define DDS_EV_OUT_REQUEST_ID                                    27 //request id生成通知

#define DDS_EV_OUT_VAD_RESULT                                    28 //全链路云端vad结果

#define DDS_EV_OUT_TTS_MULTIPLE                                 29 //tts多路复刻结果

 

/* external event */

#define DDS_EV_IN_SPEECH                                             101 //语音输入开始事件,start,end

#define DDS_EV_IN_WAKEUP                                            102 //唤醒事件,触发读取音频

#define DDS_EV_IN_NATIVE_RESPONSE                            103

#define DDS_EV_IN_RESET                                               104 //重置对话,该接口阻塞实现

#define DDS_EV_IN_EXIT                                                 105 // 退出SDK

#define DDS_EV_IN_CUSTOM_TTS_TEXT                           106 // 需要合成的中文文本

#define DDS_EV_IN_AUDIO_STREAM                                 107 //发送音频流到dds server

#define DDS_EV_IN_PLAYER_STATUS                                108 //当前播放状态,播放结束后 dds server进入listening

#define DDS_EV_IN_NLU_TEXT                                         109 //语义请求

#define DDS_EV_IN_WAKEUP_WORD                                 110 //配置单个唤醒词

#define DDS_EV_IN_CINFO_OPERATE                                111 //删除终端自定义配置

#define DDS_EV_IN_OAUTH_OPERATE                               112

#define DDS_EV_IN_DM_INTENT                                       113

#define DDS_EV_IN_COMMON_WAKEUP_WORD                  114

#define DDS_EV_IN_PHRASE_HINTS                                  115

#define DDS_EV_IN_PRODUCT_CONFIG                             116  //获取DUI控制台产品配置

#define DDS_EV_IN_TTS_STOP                                         128  //停止tts多路复刻

#define DDS_EV_IN_LASR_RT_START                                129  //长语音实时识别开始接口

#define DDS_EV_IN_LASR_RT_STOP                                  130  //长语音实时识别结束接口

#define DDS_EV_IN_LASR_FILE_UPLOAD                           131  //长语音文件转写文件分片上传接口

#define DDS_EV_IN_LASR_TASK_CREATE                          132  //长语音文件转写创建识别任务接口

#define DDS_EV_IN_LASR_TASK_QUERY                           133  //长语音文件转写结果查询接口

 

/* error id */

#define DDS_ERROR_BASE 1000

#define DDS_ERROR_FATAL     (DDS_ERROR_BASE + 1)

#define DDS_ERROR_TIMEOUT   (DDS_ERROR_BASE + 2)

#define DDS_ERROR_NETWORK   (DDS_ERROR_BASE + 3)

#define DDS_ERROR_SERVER    (DDS_ERROR_BASE + 4)  

#define DDS_ERROR_LOGIC (DDS_ERROR_BASE + 5)

#define DDS_ERROR_INPUT (DDS_ERROR_BASE + 6)

 

struct dds_msg;

typedef int (*dds_ev_callback)(void *userdata, struct dds_msg *msg);//dds 回调函数,所有out 事件在此接口处理

 

struct dds_opt {

dds_ev_callback _handler;

void *userdata;

};

 

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_start(struct dds_msg *conf, struct dds_opt *opt);

//dds 服务启动接口,阻塞运行,需要传送产品配置参数,pID,aliaskey,profile必选和opt操作句柄,dds服务启动后会一直阻塞等待消息

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_send(struct dds_msg *msg);

//发送消息给dds 服务,dds回调函数收到回复消息并处理

 

/* message pack or unpack */

DDS_IMPORT_OR_EXPORT struct dds_msg * DDS_CALL dds_msg_new(); //新建一个消息,并分配保存消息的内存

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_delete(struct dds_msg *msg); //删除一个消息,并回收内存

DDS_IMPORT_OR_EXPORT void DDS_CALL dds_msg_print(struct dds_msg *msg); //打印出start消息的地址和当前消息之间的长度

 

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_type(struct dds_msg *msg, int value); //设置消息type 类型,DDS_EV_IN_SPEECH

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_integer(struct dds_msg *msg, const char *key, int value); //key 变量赋值为整形value

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_double(struct dds_msg *msg, const char *key, double value); //key 变量赋值为double 型value

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_boolean(struct dds_msg *msg, const char *key, int value); //key 变量赋值为boolean value

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_string(struct dds_msg *msg, const char *key, const char *value); //key 变量赋值为字符串

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_bin(struct dds_msg *msg, const char *key, const char *value, int value_len); //设置 audio stream 数据流给key

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_set_bin_p(struct dds_msg *msg, const char *key, const char *value, int value_len); //设置 value 指向的数据流文件给key

 

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_type(struct dds_msg *msg, int *value);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_integer(struct dds_msg *msg, const char *key, int *value);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_double(struct dds_msg *msg, const char *key, double *value);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_boolean(struct dds_msg *msg, const char *key, int *value);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_string(struct dds_msg *msg, const char *key, char **value);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_bin(struct dds_msg *msg, const char *key, char **value, int *value_len);

DDS_IMPORT_OR_EXPORT int DDS_CALL dds_msg_get_bin_p(struct dds_msg *msg, const char *key, char **value, int *value_len);

 

#ifdef __cplusplus

}

#endif

#endif

1.4 输入和输出

       在调用dds_start的时候会注册一个回调函数,在回调中返回各种消息,消息的类型定义是以DDS_EV_OUT_开头的宏

       通过dds_send发送各种消息,驱动SDK工作,支持的输入消息类型是以DDS_EV_IN_开头的宏

1.5 启动与授权

        dds_start用于启动服务,它是一个阻塞接口,实现为一个死循环,用于接收dds_send发送的消息,并进行处理,所以该接口运行于一个独立的线程。

        示例代码如下

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include "dds.h"

 

static int dds_ev_ccb(void *userdata, struct dds_msg *msg) {//事件回调函数,dds云端返回的响应都会回调此函数

    int type;

    if (!dds_msg_get_type(msg, &type)) {//获得消息对应的事件类型

        switch (type) {

            case DDS_EV_OUT_DUI_LOGIN: {

                printf("\n");

                char *value;

                if (!dds_msg_get_string(msg, "error", &value)) {//如果云端login失败,打印出错误码

                    printf("ERROR: %s\n", value);

                } else if (!dds_msg_get_string(msg, "deviceName", &value)) {//如果无法获得错误码,打印设备名字,表示授权成功

                    printf("deviceName: %s\n", value);

                }

                break;

            }

            default:

               break;

        }

    }

    return 0;

}

 

void *_run(void *arg) {//一般在main函数中创建线程回调函数

    struct dds_msg *msg = dds_msg_new();

    dds_msg_set_string(msg, "productId", "产品ID");

    dds_msg_set_string(msg, "asrRes", "aihome");

    dds_msg_set_string(msg, "savedProfile", "./xxx.profile");

 

    dds_msg_set_string(msg, "productKey", "产品Key");

    dds_msg_set_string(msg, "productSecret", "产品Secret");

    dds_msg_set_string(msg, "devInfo", "{\"deviceName\": \"设备唯一标识\", \"platform\": \"linux\"}");

 

    struct dds_opt opt;

    opt._handler = dds_ev_ccb;

    opt.userdata = arg;

    dds_start(msg, &opt);

    dds_msg_delete(msg);

    return NULL;

}

 

int main(int argc, char **argv) {

    struct dds_msg *msg = NULL;

 

    pthread_t tid;//创建一个线程的 id

    pthread_create(&tid, NULL, _run, NULL);//创建一个线程,创建完毕后立即执行回调_run

 

    /*do something*/

    sleep(5);

 

    msg = dds_msg_new();

    dds_msg_set_type(msg, DDS_EV_IN_EXIT);

    dds_send(msg);

    dds_msg_delete(msg);

 

    pthread_join(tid, NULL);//阻塞方式等待子线程执行结束,回收线程资源

 

    return 0;

}


正如上面的示例,dds_start的时候需要传入两个参数:

  • struct dds_msg

      该参数用于设置SDK的一些配置信息,主要包含产品配置和授权配置

      产品配置:

参数名称 是否必选 描述
productId 
必选 产品id,是在dui平台上新建的产品
asrRes 语音识别产品必选 识别模型,取值可为“aihome”、"aicomm"、"aicar"、"airobot"

 

      授权配置:针对不同的使用场景,dds支持两种授权方式,两种授权方式的比较如下表

 授权方式

离线预烧录授权

在线productKey授权

使用场景

没有唯一id的设备,比如MCU

有唯一id的设备,比如mac地址

使用方法

产线给每台设备烧录一个profile文件

设备启动时,上传唯一id,获取profile

获取profile

DUI平台上申请

设备运行时在线下载

配置项

savedProfile:profile文件的路径

productKey:DUI平台上生成的产品Key

productSecret:DUI平台上生成的产品Secret

savedProfile:下载的profile文件的保存路径和文件名

devInfo:JSON格式,其中deviceName为设备唯一id

 

  • struct dds_opt

       该参数用于注册回调,传递需要透传的用户指针,dds的所有输出都通过该回调返回,并透传userdata

1.6 日志调试

dds_msg_set_boolean(msg, "logEnable", 1);

dds_msg_set_string(msg, "logFile", "./dds.log");

2、SDK离线功能

2.1 产品介绍 

        离线SDK支持前端信号处理(线性麦克风阵列,环麦麦克风阵列,线性双麦)、离线语音识别、离线语音合成、单麦语音唤醒、语音断点检测、以及语法编译等单项语音服务。

目前SDK提供的单项语音服务如下:

       1) 线性麦克风阵列(fespl):支持线性四麦和线性六麦,包含回声消除(echo),声源定位(doa),波速成形(beamforming)和语音唤醒(wakeup)

       2) 环形麦克风阵列(fespa):支持环形六麦,包含回声消除(echo),声源定位(doa),波速成形(beamforming)和语音唤醒(wakeup)

       3) 线性双麦(fespd):包含回声消除(echo),声源定位(doa),波速成形(beamforming)和语音唤醒(wakeup)

       4) 离线线语音识别(Automatic Speech Recognition,ASR):识别语音内容,转化为相应的文字。

       5) 离线语音合成(Text to Speech,TTS):将文字信息转变为可以听得懂的、流利的汉语,输出16K 16bit 单通道的PCM。

       6) 单麦语音唤醒(wakeup):又称关键词检测(keyword spooting),一般输入经过信号处理后的单通道音频数据。若有关键词音频,则输出唤醒结果。

       7) 语音端点检测(Voice Activity Detection, VAD):检测语音的开始和结束时间点,过滤静音,提取有效人声,一般配合语音识别使用。

       8) 语法编译(gram):基于ebnf的语法格式,对输入的文本内容进行解析,生成可用于离线语音识别的语法网络资源。

2.2 预备工作

1) 账号:DUI平台的账号,进行SDK集成的必备前提之一。
2) 产品:在控制台上创建产品后,会自动生成一个产品ID。创建流程见:单项基础技术接入
3) SDK:前往SDK下载页下载Windows平台的压缩包,支持x86和x86_64的windows10平台,并且含有集成手册、开发手册、FAQ,example。

2.3 注意事项

 

  • 不包含业务逻辑与云端功能
  • 默认只支持单线程使用,不保证多线程接口调用安全
  • 支持多实例使用
  • 回调中禁用接口

2.4 典型调用流程

各个模块接口典型调用顺序如下:

 

2.5 回调函数定义

2.5.1 通用回到函数

typedef int (*duilite_callback)(void * userdata, int type, char *msg, int len);

 接口能力

负责输出结果,通用回调函数吗,若无特殊说明所有模块均使用此回调函数。

 输入参数

userdata - 用户数据,注册回调时传入,回调时透传;

type - 回调数据类型

DUILITE_MSG_TYPE_JSON表示JSON字符串;

DUILITE_MSG_TYPE_BINARY表示二进制数据;

DUILITE_MSG_TYPE_TLV表示TLV数据包;

msg - 回调数据,在各个模块中详细说明;

len - 回调数据的长度;

  返回值

一般为0,语音合成模块例外,详见语音合成模块。

2.5.2 模型数据回调函数(暂时不支持)

typedef int (*duilite_model_callback)(void *userdata, int type, char *id, char**data, int *data_size, int *data_nmemb);

 接口能力

负责输出模型数据,用于支持模型数据外部存储功能,具体使用方式参见各个模块,目前仅支持声纹模块。

 输入参数

userdata - 用户数据,注册回调时传入,回调时透传;

type – 模型数据操作类型,详见各模块中说明;

 id – 该条模型数据的标识符;

 data – 模型数据,数组;

 data_size – 每条模型数据的大小,数组;

 data_nmemb – 模型数据的数量;

  返回值

成功  0;

失败 – 非0;

2.6 授权接口

2.6.1 duilite_library_load

int duilite_library_load(char *cfg)

接口能力

加载库函数,完成初始化与授权,接口阻塞,调用一次即可。

输入参数

cfg – 初始化参数,省略部分为授权相关,授权配置详见附录。

{

......

"prof": {

"enable": 1,

"output": "",

        "level": 1

},

    

"deviceId": "abcd",

"userId": "user",

    "productVersion": "0.1.2",

"upload": {

"enable": 1,

"logId": 141,

"tmpdir":"upload_dir",

"tmpdirMaxSize": 104857600,

"netType": "wifi",

"mno": "office",

"clientIP": "20.13.21.24"

}

}

 

字段

释义

类型

prof

enable

日志开关,1为开,0为关,可选,默认为关

int

output

日志输出路径,可选,默认为标准输出

string

level

日志等级,默认为1

int

deviceId

设备唯一标识,用于数据上传

string

userId

用户标识,可选,用于数据上传

string

productVersion

dui发布产品版本,使用数据上传时必选

string

upload

enable

数据上传开关,1为开,0为关,可选,默认为关

int

logId

云端日志id,必选,统一使用141

int

tmpdir

存储目录,需要有可写权限,必选

string

tmpdirMaxSize

存储目录最大空间,单位为byte,可选,默认为100m

int

netType

客户端网络类型,可选

string

mno

网络运营商类型,可选

string

clientIP

客户端ip,可选

string

 

日志等级取值如下:

Level

Value

Type

VERBOSE

1

Int

DEBUG

2

Int

INFO

3

Int

WARNING

4

Int

ERROR

5

Int

   返回值

成功  0;

失败 – 非0;

2.6.2 duilite_library_release

void duilite_library_release()

接口能力

释放库资源。

输入参数

返回值

2.6.3 duilite_library_opt

int duilite_library_opt(int opt, char *data, int size)

接口能力

实现一些辅助功能,如获取版本号和检查授权结果等。

输入参数

     opt – 功能类型:

opt

功能说明

DUILITE_OPT_VERSION_STR_GET

获取版本信息

DUILITE_OPT_AUTH_CHECK

duilite_library_load时授权失败后,获取服务端授权错误码

DUILITE_OPT_AUTH_TRY

执行授权操作

DUILITE_OPT_UPLOAD_MODE_GET

重新从服务端更新数据上传的权限

data – 调用者外部申请的内存与该块内存大小,作用如下:

opt

data

DUILITE_OPT_VERSION_STR_GET

用于存放输出的版本信息

DUILITE_OPT_AUTH_CHECK

NULL

DUILITE_OPT_AUTH_TRY

输入授权参数,同duilite_library_load授权相关参数

DUILITE_OPT_UPLOAD_MODE_GET

NULL

size – data大小;

  返回值

opt

返回值

DUILITE_OPT_VERSION_STR_GET

成功 - 输入参数data中版本信息的实际大小

失败 - 非0

DUILITE_OPT_AUTH_CHECK

成功  服务端授权错误码

失败 - 非0,若为-1,则为授权库返回,一般为本地校验失败

DUILITE_OPT_AUTH_TRY

成功 - 0

失败 - 非0

DUILITE_OPT_UPLOAD_MODE_GET

成功 - 0

失败 - 非0

2.7 附录

DUILite SDK必须通过授权方可使用,目前支持如下三种授权方式,配置参数在初始化时输入,具体的申请方式与收费模式,请咨询相关人员。

预烧录

预烧录方式,涉及到产线支持,一般只应用于特殊的嵌入式硬件产品。需要在DUI平台产品授权页面下载已生成好的profile文件,烧录到设备中去,一台设备对应一个profile文件,不需要联网,sdk配置如下:

{

"productId": "xxx",

"savedProfile": "xxx",

"deviceProfile": "xxx"

}

 

参数

释义

productId

DUI平台产品ID

deviceProfile

deviceProfile文件内容

savedProfile

deviceProfile文件路径

deviceProfilesavedProfile二选一即可,若都填写,则使用deviceProfile

预登记

预登记方式不涉及到产线支持,推荐嵌入式产品使用此种方式,需要开发者在控制台上传所有设备的DeviceName列表的文本文件,即白名单,并要求设备在一次运行时进行了联网注册,只有在白名单内的设备才会注册成功, sdk配置如下:

{

"productId": "xxx",

"savedProfile": "xxx",

"productKey": "xxx",

"productSecret": "xxx",

"devInfo": {

"deviceName": "xxx",

"platform": "xxx",

"productId": "xxx",

"deviceId": "xxx",

"clientName": "xxx",

"instructionSet": "xxx",

"chipModel": "xxx"

}

}

 

参数

释义

productId

DUI平台产品ID

savedProfile

保存deviceProfile文件路径

productKey

productSecret一起作为产品密钥

productSecret

productKey一起作为产品密钥

devInfo

 

设备详细信息,部分可选

deviceName

设备标识,一台设备对应一个设备标识,必选

platform

设备平台类型,如Linux,必选

productId

DUI平台产品ID,可选

deviceId

设备ID,可选

clientName

客户端名字,可选

instructionSet

指令集,可选

chipModel

芯片型号,可选

devInfo中的deviceName,用于标识唯一的一台设备,可以使用设备MAC ID等信息。若两台设备使用相同的deviceName,则前一台设备会下线,只允许最近使用该deviceName的设备访问服务。

动态注册

         动态注册方式与预登记配置的参数是相同的,不同之处在于动态注册使用的deviceName不需要进行预登记,在设备运行时进行动态的注册即可。同一个产品动态注册和预登记方式的productKeyproductSecret是不相同的。