跳转至

概述*

请阅读 GX8006大模型开发包下载 国芯微离线语音协议_v*.pdf。

1.串口协议解析流程*

  • 串口驱动层需要用户根据控制端MCU的开发环境进行移植实现,主要完成以下功能:

    • 串口硬件初始化:配置串口基本参数,包括波特率、数据位、停止位、校验位等
    • 数据收发管理:实现串口数据的发送和接收功能,确保数据传输的可靠性
    • DMA配置:配置DMA通道、传输模式、缓冲区等参数,优化数据传输效率
    • 中断处理:实现串口和DMA相关中断的处理,确保数据及时处理
  • 协议解析层可参考开发包中的wifi_uart_demo_example_v*.zip进行开发,主要完成以下功能:

    • 数据帧解析:解析接收到的数据帧,提取命令类型、数据长度、数据内容等信息
    • 响应组装:根据处理结果或用户层相应结果,组装响应数据帧
    • 状态管理:维护帧解析状态机,处理异常情况
    • 数据校验:实现数据帧的校验功能,确保数据完整性
  • 用户控制层处理解析层递交上来的帧结构数据

1.1.通信架构*

  • 串口通信的双方分别是:
    • 语音芯片(GX8006):作为协议的服务端
    • 用户控制MCU:作为协议的客户端

GX8006大模型方案-串口协议框架示意图

GX8006大模型方案-串口协议框架示意图

1.2.DMA传输建议*

  • 由于通信数据中包含较大的音频数据,强烈建议使用DMA进行串口数据传输,原因如下:
    • 减少CPU负载:DMA可以直接在内存和外设之间传输数据,无需CPU干预
    • 提高传输效率:DMA传输速度更快,且不会因为CPU处理其他任务而延迟
    • 避免数据丢失:DMA可以持续接收数据,不会因为CPU处理不及时导致数据丢失

1.3.不定长数据处理*

由于串口数据包长度不固定,建议采用以下方式处理:

GX8006大模型方案-串口协议解析流程

GX8006大模型方案-串口协议解析流程
  • 帧结构设计

    • 帧头:用于标识数据包的开始
    • 长度字段:指示后续数据的长度
    • 数据负载:实际传输的数据
    • 校验字段:用于验证数据完整性
  • 数据接收流程

    • 使用DMA接收数据到缓冲区
    • 通过状态机解析数据帧
    • 根据帧头识别数据包开始
    • 根据长度字段确定数据包结束位置
    • 进行数据校验确保完整性
  • 缓冲区管理

    • 建议使用环形缓冲区
    • 设置合适的缓冲区大小,建议至少能容纳最大数据包的两倍
    • 实现缓冲区满/空状态的处理机制

2.串口交互流程*

GX8006大模型方案-串口协议交互

GX8006大模型方案-串口协议交互
  • 串口通信采用一问一答的交互方式,具体流程如下:

    • 发送数据帧后,需要等待语音芯片的回复才能继续发送新的数据帧
    • 在等待回复期间,可能会收到语音芯片主动上报的数据帧,包括:
      • 音频数据帧:需要及时处理并上报给云端
      • 唤醒事件帧:需要及时处理并发送确认帧
      • 其他事件帧:根据具体事件类型进行相应处理
  • 帧处理机制:

    • 通过帧结构中的子命令字段判断当前帧的类型
    • 若是对之前下发帧的回复,则:
      • 处理回复内容
      • 解除发送阻塞,允许发送新的数据帧
    • 若是主动上报的数据帧,则:
      • 立即处理该帧数据
      • 根据帧类型发送相应的确认帧
      • 继续等待之前下发帧的回复
  • 注意事项:

    • 需要维护发送队列,确保数据帧按序发送
    • 需要实现超时处理机制,避免永久等待
    • 需要正确处理并发情况,确保数据处理的实时性
    • 建议使用状态机管理整个交互流程
    • 语音芯片端采用前后台系统,使用DMA+Ringbuffer的方式管理接收数据
    • 若未等到回复就发送新的数据将导致语音芯片的接收数据被覆盖

3.麦克风增益配置示例:*

麦克风增益配置是语音交互的重要参数,直接影响语音识别的效果。配置时需要注意以下几点:

  • 配置参数说明:

    • 采样率(sample_rate):仅支持16000Hz,适合语音编码,能完整覆盖人声频率范围
    • 采样位深(bit):仅支持16bit,是语音和音乐编码的标准位深
    • 通道数(channels):仅支持使用单声道,适合语音通信场景
    • 增益值(dB):范围0-32dB,建议使用26dB
    • 数据格式(format):仅支持OPUS格式
    • 最大接收长度(max_recv_len):根据实际应用场景设置,建议不小于1024字节;语音芯片将连续发送多个80字节的语音帧,直到模组最大可接收数据长度
  • 配置流程:

    • 发送配置命令帧
    • 等待语音芯片返回确认帧
    • 验证返回的命令号和返回值,若配置不支持,语音芯片将返回错误
    • 释放应答帧内存
static int smartbot_set_mic(void)
{
    int status = 0;
    /* 存放 GX8006 的应答帧 */
    sbot_frame_t *rsp = NULL;
    /* 配置麦克风功能的子命令帧结构 */
    struct smartbot_mic_config
    {
        uint8_t     cmd;            /* 子命令号:SBOT_CMD_SET_MIC_CONFIG */
        uint32_t    sample_rate;    /* 采样率(大端格式传输) */
        uint8_t     bit;            /* 采样位深 */
        uint8_t     channels;       /* 音频通道数量 */
        uint8_t     dB;             /* 麦克风增益,范围 0-32dB */
        uint8_t     format;         /* 传输数据格式 */
        uint32_t    max_recv_len;   /* 单次可以接收的最大数据,单位字节 */
    }
    __PACKED__ req_data =
    {
        .cmd            = SBOT_CMD_SET_MIC_CONFIG,
        .sample_rate    = smartbot_le2be_u32(16000),
        .bit            = 16,
        .channels       = 1,
        .dB             = 26,
        .format         = 2,
        .max_recv_len   = smartbot_le2be_u32(1024),
    };

    /* 此处调用会阻塞当前线程,直到收到 GX8006 的应答帧,并将应答帧的地址返回给 rsp */
    rsp = smartbot_talk((uint8_t *)&req_data, sizeof(req_data));
    if (NULL == rsp)
    {
        return -1;
    }

    /* 应答帧结构,对 rsp 的 data 部分进行解析 */
    struct smartbot_mic_config_resp
    {
        uint8_t cmd;
        uint8_t retcode;
    }
    __PACKED__ *rsp_data = (struct smartbot_mic_config_resp *)(rsp->data);

    /* 验证是否是正确的应答,验证返回值是否正确 */
    status = ((rsp_data->cmd == req_data.cmd) && (rsp_data->retcode == 0x00)) ? 0 : -1;
    LOG(LOG_LVL_INFO, "[SBOT] subcmd: %02X retcode: %d\r\n", rsp_data->cmd, rsp_data->retcode);

    /* 底层返回的应答帧数据为动态分配,需要释放 */
    OS_Free(rsp);

    return status;
}

4.交互模式配置说明:*

4.1 功能控制说明*

  • 语音上报功能由三级控制组成:

    • Mic总开关(0x01):控制麦克风开关
      • 0:关闭MIC
      • 1:开启MIC
    • 唤醒功能(0x03):控制唤醒检测
      • 0:关闭唤醒功能
      • 1:开启唤醒功能
    • Vad功能(0x04):控制语音活动检测
      • 0:关闭Vad
      • 1:开启Vad,超时时间=1000ms
      • 大于1:开启vad,超时时间=配置值*40ms
  • 控制优先级(从高到低):

    • Mic开关 > 唤醒标志 > Vad标志
  • 超时配置:

    • Vad超时配置命令(0x07):控制Vad检测的灵敏度
    • 唤醒超时配置命令(0x05):控制唤醒状态的持续时间

4.2 典型应用场景*

4.2.1 唤醒持续对话模式*

  • 功能描述:唤醒后直接上报音频,持续上报60秒
  • 配置步骤:
    • 设置最大拾音时间:60秒
    • 设置唤醒超时时间:60秒
    • 打开Mic总开关
    • 关闭Vad功能
    • 打开唤醒功能
  • 注意事项:唤醒时间应小于拾音时间,否则无法达到最大拾音时间
  • 配置命令:
    55aa0092000307083cdf  # 最大拾音时间60s
    55aa0092000307073cde  # 唤醒超时时间60s
    55aa009200030701019d  # 打开Mic总开关
    55aa009200030704009f  # 关闭Vad功能
    55aa009200030703019f  # 打开唤醒功能
    

4.2.2 按键长按对话模式*

  • 功能描述:按键长按时上报数据,最长持续60秒
  • 配置步骤:
    • 设置最大拾音时间:60秒
    • 默认关闭所有功能
    • 按键按下时打开mic
    • 按键松开时关闭mic
  • 配置命令:
    55aa0092000307083cdf  # 设置最大拾音时间60秒
    55aa009200030701009c  # 关闭mic
    55aa009200030703009e  # 关闭唤醒
    55aa009200030704009f  # 关闭vad
    55aa009200030701019d  # 长按按键时打开mic
    55aa009200030701009c  # 松开时关闭mic
    

4.2.3 按键触发对话模式*

  • 功能描述:按键触发后,Vad拉起时上报数据,1秒无语音Vad结束,5秒无语音退出唤醒
  • 配置步骤:
    • 设置唤醒超时:5秒
    • 设置Vad间隔:1秒
    • 打开所有功能
    • 配置按键触发和超时处理
  • 配置命令:
    55aa00920003070705a7  # 设置唤醒超时5s
    55aa00920003070419b8  # 设置Vad间隔1s
    55aa009200030701019d  # 打开mic
    55aa009200030703019f  # 打开唤醒
    55aa00920003070401a0  # 打开vad
    55aa00920003070501a1  # 配置按键触发
    55aa00920003070601a2  # 配置超时处理
    

4.2.4 唤醒触发对话模式*

  • 功能描述:每次对话需要唤醒,Vad拉起时上报数据,1秒无语音Vad结束,5秒无语音退出唤醒
  • 配置步骤:
    • 设置唤醒超时:5秒
    • 设置Vad间隔:1秒
    • 打开所有功能
    • 配置超时处理
  • 配置命令:
    55aa00920003070705a7  # 设置唤醒超时5s
    55aa00920003070419b8  # 设置Vad间隔1s
    55aa009200030701019d  # 打开mic
    55aa009200030703019f  # 打开唤醒
    55aa00920003070401a0  # 打开vad
    55aa00920003070601a2  # 配置超时处理
    

4.2.5 自由对话模式*

  • 功能描述:首次需要唤醒,之后通过Vad控制,1秒无语音Vad结束,30秒无语音退出唤醒
  • 配置步骤:
    • 设置唤醒超时:30秒
    • 设置Vad间隔:1秒
    • 打开所有功能
  • 配置命令:
    55aa0092000307071ec0  # 设置唤醒超时30s
    55aa00920003070419b8  # 设置Vad间隔1s
    55aa009200030701019d  # 打开mic
    55aa009200030703019f  # 打开唤醒
    55aa00920003070401a0  # 打开vad
    

4.3 Vad灵敏度控制*

  • 功能描述:调整Vad检测的灵敏度,默认灵敏度45
  • 参数范围:
    • 0-100: 默认45,数值越大,灵敏度越低
  • 配置命令:
    55aa0092000307092dd1  # 设置vad阈值为45
    

4.4 降噪设置*

  • 功能描述:调整降噪等级,默认等级0
  • 参数范围:
    • 0x00-0x03: 代表降噪等级
    • 0xFF: 关闭降噪
  • 配置命令:
    55aa00920003070A01a6  # 设置降噪等级1
    

4.4 参考示例*

  • 在开发包中的wifi_uart_demo_example_v*.zip包含以下4种模式的切换
    • 自由对话模式
    • 唤醒对话模式
    • 按键对话模式
    • 长按对话模式
  • 各个模式抽象为如下结构
    struct smartbot_mode
    {
        /* config */
        uint16_t vad;                               /* VAD(语音活性检测)配置 */
        bool     mic;                               /* 麦克开关配置 */
        bool     awk;                               /* 唤醒开关配置 */
        sbot_audio_res_t res;                       /* 本地模式播报资源 */
    
        /* function */
        void (*on_ui_event)(sbot_mode_event_t);     /* 注册到用户接口的事件回调函数,用于处理不同模式下的用户动作,单击长按按键等 */
        void (*on_selected)(sbot_mode_t *);         /* 当前模式被选中时触发回调 */
        void (*on_conv_start)(sbot_mode_t *);       /* 语音对话开始时触发回调 */
        void (*on_conv_stop)(sbot_mode_t *);        /* 语音对话结束时触发回调 */
        void (*on_mic_stop)(sbot_mode_t *);         /* 麦克上报停止时触发回调 */
    };
    
  • 任一模式被选中时,均会进行如下配置
    • 配置当前模式默认的麦克开关、唤醒和 VAD 的配置
    • 注册当前模式的事件处理函数给按键处理模块
    • 固化当前模式
      static void on_mode_conv_selected(sbot_mode_t *mode_inst)
      {
          smartbot_set_offline_config(SBOT_OFFLINE_SUBCMD_MIC, mode_inst->mic);
          smartbot_set_offline_config(SBOT_OFFLINE_SUBCMD_WAKEUP, mode_inst->awk);
          smartbot_set_offline_config(SBOT_OFFLINE_SUBCMD_VAD, mode_inst->vad);
      
          ui_button_awk_register_callback(mode_inst->on_ui_event);
          sysparam_store(SBOT_MODE_KEY, (const void *)&_this_mode_index, sizeof(_this_mode_index));
      }
      
  • 长按对话模式的示例
    /* 用户接口的事件处理 */
    static void on_longpress_conv_ui_event(sbot_mode_event_t event)
    {
        switch (event)
        {
            case SBOT_MEVT_BTN_DOUBLE_CLICK:
            {
                SBOT_MODE_EVT_CALL(SBOT_MEVT_CONV_MODE_SWITCH);     /* 双击上报模式切换事件 */
                break;
            }
    
            case SBOT_MEVT_BTN_LONGPRESS:
            {
                SBOT_MODE_EVT_CALL(SBOT_MEVT_CONV_START);           /* 长按上报对话开始事件 */
                break;
            }
    
            case SBOT_MEVT_BTN_RELEASE:
            {
                SBOT_MODE_EVT_CALL(SBOT_MEVT_CONV_STOP);            /* 松开触发对话结束事件 */
                break;
            }
    
            default:
                break;
        }
    }
    
    /* 对话开始的回调,在 on_longpress_conv_ui_event 上报 SBOT_MEVT_CONV_START 后,上层执行相关处理后调用该回调 */
    static void on_longpress_conv_start(sbot_mode_t *mode_inst)
    {
        (void)mode_inst;
        smartbot_set_offline_config(SBOT_OFFLINE_SUBCMD_MIC, 1);    /* 开启麦克 */
    }
    
    /* 对话结束的回调,在 on_longpress_conv_ui_event 上报 SBOT_MEVT_CONV_STOP 后,上层执行相关处理后调用该回调 */
    static void on_longpress_conv_stop(sbot_mode_t *mode_inst)
    {
        (void)mode_inst;
        smartbot_set_offline_config(SBOT_OFFLINE_SUBCMD_MIC, 0);    /* 开启麦克 */
    }
    
    /* 长按对话模式实例 */
    static sbot_mode_t sbot_mode_longprss_conv =
    {
        .vad = 0,                                       /* 默认VAD配置:关闭 */
        .awk = 0,                                       /* 默认唤醒配置:关闭 */
        .mic = 0,                                       /* 默认麦克配置:关闭 */
        .on_ui_event = on_longpress_conv_ui_event,      /* 注册当前对话模式的用户事件处理函数 */
        .res = SBOT_AUDIO_RES_MODE_LONGPRSS_CONV,       /* 注册当前对话模式的本地播报资源 */
        .on_selected = on_mode_conv_selected,           /* 注册当前对话模式激活的回调函数 */
        .on_conv_start = on_longpress_conv_start,       /* 注册当前对话模式开始的回调函数 */
        .on_conv_stop = on_longpress_conv_stop,         /* 注册当前对话模式结束的回调函数 */
    };
    

5.FAQ*

5.1.客户的模组负责播放,如何开启语音芯片的AEC功能?*

  • 一般 AEC(声学回声消除)功能需要播报和录音都在语音芯片端,芯片可通过内部回采消除自身喇叭播放的声音
  • 如果客户的模组负责播放音频,仅需要语音芯片负责唤醒和录音,但又需要开启 AEC,则需要:
    • 硬件上,客户的模组需要将音频播放信号接入语音芯片的回采通道
    • 软件上,客户的模组在播放开始和结束时,需要使用【命令:通知 MCU 模组播放状态(0xF6)】告诉语音芯片当前的播放状态

5.2.云端下发的音频是否有格式限制?*

  • 语音芯片播报的数据有格式限制
  • 语音芯片播报的配置命令格式定义如下:
    struct smartbot_spk_config
    {
        uint8_t     cmd;            /* 子命令号:SBOT_CMD_SET_SPK_CONFIG */
        uint32_t    sample_rate;    /* 采样率(大端格式传输) */
        uint8_t     bit;            /* 采样位深 */
        uint8_t     volume;         /* 音量,范围 0-100 */
        uint8_t     format;         /* 传输数据格式 */
        uint32_t    max_send_len;   /* 单次可以接收的最大数据,单位字节 */
    }
    
  • 配置参数说明:
    • 采样率(sample_rate):仅支持16000Hz,适合语音编码,能完整覆盖人声频率范围
    • 采样位深(bit):仅支持16bit,是语音和音乐编码的标准位深
    • 音量(volume):仅支持使用单声道,适合语音通信场景
    • 数据格式(format):仅支持PCM和OPUS格式
    • 最大发送长度(max_send_len):根据实际应用场景设置;若长度超出语音芯片能处理的最大长度,将返回错误及可接受的长度