天天看点

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

上一章: 智能语音终端开发板适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第五章 >>> 下一章: 基本调试指南 | 《无需从0开发 1天上手智能语音离在线方案》第七章>>>

1. 语音服务适配指南

1.1 概述

语音服务组件提供关键词识别和语音数据的处理控制。输入麦克风的语音数据经过回音消除降噪和关键词识别处理后再输出到应用层使用。YoC在语音服务接口和算法实现之间增加了适配层,方便多种语音算法的接入,保持了应用代码的统一。

下图以SC5654芯片双核架构为例,适配层利用核间通讯,实现应用与DSP算法的数据交互。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

1.2 适配接口

1.2.1 语音服务适配接口

语音服务适配接口注册在mic_ops结构体中,详细信息如下:

组件:mic

头文件:

语音服务的适配接口如下:

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
1.2.2 应用接口映射

应用通过调用应用层API,操作对应语音服务适配接口,语音服务开发者只需实现适配接口定义。用户无需修改代码,即可迁移至对应语音服务上。

应用API与语音服务适配接口映射如下:

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

1.3 接口说明

init

• 函数原型

int (*init) (mic_t *mic, mic_event_t mic_event);
           

• 功能描述

语音服务初始化,在应用调用aui_mic_start时会调用该接口。若有私有数据需要保存,可通过函数mic_set_privdata将其保存在mic->priv私有成员指针中。设置后,其他适配函数就可以通过函数mic_get_privdata获取该指针。语音服务层通过应用注册的mic_event回调函数将语音事件传递给应用层。

• 参数描述

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

• 相关定义

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

deinit

int (*deinit) (mic_t *mic);
           

应用接口aui_mic_stop执行时会调用该适配接口释放资源。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

kws_control

int (*kws_control) (mic_t *mic, int flag);
           

关键词识别使能控制。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

kws_wake

int (*kws_wake) (mic_t *mic, int flag);
           

强制算法发出一个模拟唤醒事件。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

pcm_data_control

int (*pcm_data_control) (mic_t *mic, int flag);
           

控制算法输出的音频流的开关。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

• 返回值

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

pcm_aec_control

int (*pcm_aec_control) (mic_t *mic, int flag);
           

控制算法是否使能回音消除。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

pcm_set_param

int (*pcm_set_param) (mic_t *mic, void *param);
           

初始化语音算法参数。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

mic_set_privdata

int mic_set_privdata(void *priv);
           

设置适配私有数据到mic对象。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

mic_get_privdata

void *mic_get_privdata(void);
           

获取mic对象中的私有数据指针。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

mic_ops_register

int mic_ops_register(mic_ops_t *ops);
           

注册适配层,一般增加一个适配需要实现一个新的函数封装该函数,提供一个简单的注册函数供应用使用。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

1.4 适配示例

适配完成所有接口函数后,定义适配接口结构体,完成函数注册。

示例如下:

/* 适配接口结构体 */
static mic_ops_t mic_adp_ops = {
    .init = mic_adaptor_init,
    .deinit = mic_adaptor_deinit,
    .kws_control = mic_adaptor_kws_control,
    .kws_wake = mic_adaptor_kws_wake,
    .pcm_data_control = mic_adaptor_pcm_data_control,
    .pcm_aec_control = mic_adaptor_pcm_aec_control,
    .pcm_set_param = mic_adaptor_set_param,
    .pcm_get_param = mic_adaptor_get_param,
};

/* 注册函数 */
void mic_thead_v1_register(void)
{
    mic_ops_register(&mic_adp_ops);
}
           

2. 云服务适配指南

2.1 概述

云服务组件提供应用与云端ASR/NLP/TTS服务交互的接口。调用对应服务API后,组件自动完成云端连接、鉴权、启动服务的过程,用户只需通过接口将需识别的音频或需合成的字符串传入,即可获得云端返回结果,设备端只需根据结果完成预定的应用行为。

为了减少用户的开发成本, YoC定义了一套统一的适配接口,应用层可以用同样的代码在不同的云服务之间无缝切换。

2.2 适配接口

已适配的组件:aui_aliyunnls、aui_cloud

云服务组件的主要API如下:

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

2.3 接口说明

aui_cloud_init

int aui_cloud_init(aui_t *aui);
           

该函数用于初始化云服务。参数aui_t结构包含的config成员用来指定语音合成的参数,包括发言人、音量、语速。适配云端请务必参考取值范围并进行转换,保证多平台切换是参数不做调整也能达到预期的效果,还有nlp_cb回调函数,供用户处理云端返回的信息,ASR结果和NLP结果都使用同一个回调。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_start_pcm

int aui_cloud_start_pcm(aui_t *aui);
           

启动语音数据交互,准备上传语音数据。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_push_pcm

int aui_cloud_push_pcm(aui_t *aui, void *data, size_t size);
           

推送语音数据到云端进行识别。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_stop_pcm

int aui_cloud_stop_pcm(aui_t *aui);
           

结束语音数据推送,云端返回的结果通过调用nlp_cb回调函数通知应用进行处理。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_push_text

int aui_cloud_push_text(aui_t *aui, char *text);
           

文本内容推送到云端进行NLP处理。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_start_tts

int aui_cloud_start_tts(aui_t *aui);
           

启动TTS语音合成服务

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_req_tts

int aui_cloud_req_tts(aui_t *aui, const char *player_fifo_name, const char *text, aui_tts_cb stat_cb);
           

向云端发送文本信息,请求TTS音频数据。要求异步实现,云端的语音数据可以直接写入播放器的nsfifo,然后调用aui_player_play来播放语音数据。nsfifo的使用方法可参见组件

components_aliyunnls_mit_tts.c中的实现。

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章
智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

aui_cloud_stop_tts

int aui_cloud_stop_tts(aui_t *aui);
           

停止TTS语音合成服务

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

3. 语音算法适配指南

智能语音SDK将算法实现与接口分离,设计出了一套层次化得调用框架,用户在此框架上可以方便得将自研算法移植进DSP中,利用SDK中原有得数据采集、播放、上云通道,以实现设备端算法得快速落地。

3.1 框架图

智能语音组件适配指南 | 《无需从0开发 1天上手智能语音离在线方案》第六章

• AP(Application Processor)主要负责应用开发,CP(coprocessor)用来通过处理主cpu的一些工作负荷来使操作提速的辅助处理器,如语音算法。

• IPC (Inter-Process Communication,异构多核通信)

• voice data:数据内容格式为麦克风m(m路数据)和参考声 n(n路数据)

3.2 特性

• 适用于多核SoC,AP核负责采集及搬送数据,CP核负责离线语音识别及抛出各类事件

• 提供多种录音数据,方便对接云端语音处理及本地算法问题调试

• 提供LPM接口,方便低功耗管理

• 接入方式简单,最小只需实现数据采集及语音识别部分算法等接口

3.3 接口定义

本地算法初始化

voice_t *voice_ai_init(void *priv, voice_cts_ops_t *ops);
           

• 参数:

– priv: 用户私有数据

– ops: ai算法实现

• 返回值:

– 0: 成功 非0:失败

typedef struct __voice_cts_ops {
    int (*init)(void *priv);
    int (*deinit)(void *priv);
    int (*aec)(void *priv, void *mic, void *ref, int ms, void *out); //aec算法实现
    int (*vad)(void *priv, void *mic, void *ref, int ms, void *out); //vad算法实现
    int (*kws)(void *priv, void *mic, void *ref, int ms, void *out); //kws算法实现
    int (*asr)(void *priv, void *vad_data, int ms); //asr算法实现
} voice_cts_ops_t;           

初始化及去初始化

voice_t *voice_init(voice_evt_t cb, void *priv);
void voice_deinit(voice_t *v);
           

– cb: voice事件

– priv: 用户私有数

– v: voice 句柄

typedef void (*voice_evt_t)(void *priv, voice_evt_id_t evt_id, void *data, int len);
typedef enum {
    VOICE_ASR_EVT,//asr事件
    VOICE_SILENCE_EVT,//断句事件
    VOICE_DATA_EVT//回流数据到达事件
} voice_evt_id_t;           

参数配置

int voice_config(voice_t *v, voice_param_t *p);
           

– p: voice参数

typedef struct {
    int cts_ms;//ai算法每次数据大小,单位(ms)
    int ipc_mode;//与ai算法侧的通信方式,1:ipc
} voice_param_t;           

拾音参数配置

int voice_add_mic(voice_t *v, voice_pcm_param_t *p);
int voice_add_ref(voice_t *v, voice_pcm_param_t *p);           

初始化ai算法模块

– p:pcm参数

typedef struct {
    char            *pcm_name; //pcm设备名
    unsigned int     rate;//采样率
    int              sample_bits;//采样位数
    int              access;//是否为交错模式,0:非交错 1:交错
    int              channles;//通道总数
    int              channles_sum;//通道总数
    int              period_bytes;//pcm周期数据量(用户不必配置)
} voice_pcm_param_t;
           

启动(停止)本地算法

int voice_start(voice_t *v);
int voice_stop(voice_t *v);
           

数据回流控制

int voice_backflow_control(voice_t *v, voice_backflow_id_t id, int flag);
           

– id:数据类型

– flag: 0:关闭回流,1:打开回流

typedef enum {
    VOICE_MIC_DATA,//mic数据
    VOICE_REF_DATA,//ref数据
    VOICE_VAD_DATA,//vad后数据
    VOICE_AEC_DATA,//aec后数据

    VOCIE_BACKFLOW_DATA
} voice_backflow_id_t;
           

继续阅读