前言

随着 AI 应用的普及,语音交互已成为终端设备的核心能力之一。语音采集与音频数据传输,是这条交互链路上的核心环节。

对实际的产品来说,需求是多样的:有的走 USB 有线,有的要蓝牙,有的用私有 2.4G,而常见做法是——一颗主 MCU,外挂一颗专用音频芯片;如果需要无线传输,还得再加一颗负责无线的芯片。传输通路每多一种,BOM 上就多一颗料,成本、PCB 面积和功耗都得往上抬。

有没有办法用一颗芯片把这几条路都走通?

本文给出的思路是:基于沁恒青稞 RISC-V 无线系列 MCU(CH58x/CH59x),提供一套低成本的语音采样方案设计。单芯片即可实现 USB UAC 音频、蓝牙音频、2.4G 无线音频 三大传输通路,覆盖有线与无线全场景的语音交互需求,适配语音遥控器、无线麦克风、会议拾音棒、USB 语音声卡、便携语音采集终端等各类产品。

一、语音采样基础

1.1 语音采样流程

完整的语音链路步骤如下:

收音 → 偏置/放大 → ADC 采样 → 数字音频流 → 编码(可选) → 传输 → 解码(可选)

收音

由麦克风把声波转换为电信号。目前主流是两种:

类型 输出 特点
ECM(驻极体电容麦克风) 模拟信号 成本极低、使用广泛;需要外部偏置电路,相对来说一致性与抗干扰能力一般
MEMS 麦克风 模拟或数字 体积小、一致性好、抗 RF 干扰强,适合小型化和量产;
数字输出成本相对较高,本文不考虑

偏置/放大

MIC 头子输出信号幅度只有毫伏级,必须先放大到 ADC 的有效输入范围。

对于 驻极体 MIC 语音采集电路,我们需要加个偏置电路进入到运放 ,如果是硅麦的话,可以省偏置电阻,直接进入到放大电路。

这一步的增益设计很关键:增益过小,信号淹没在量化噪声里,底噪明显;增益过大,大音量时波形削顶失真 。

一款通用的 MIC 采样放大电路如下:

在这里插入图片描述

这个通用的方案是可靠并且可以实际使用的,只需要根据自己需求调节好增益,但是本文我们最求的是低成本,所以我们会采用一套三极管搭建的方案,下文硬件实现会有说明。

ADC 采样

ADC 采样使用芯片自带 ADC 即可。

把连续的模拟信号离散成数字量,连续的声音能够采集播放的原理就像:高速连拍照片,连起来就是视频。快速播放一串按时间排列的电压数字。

比如 每 1/16000 秒(16K采样率 )采样一次电压,把电压通过 ADC 转成数字,这些数字排成一串就是 PCM 数据,PCM 就是原始的数字音频编码方式。

编解码(可选)

PCM 直传的数据量偏大,很一些场景在传输前需要压缩。

嵌入式领域常见的编解码如下表格:

在这里插入图片描述

1.2 几个关键参数

对于做语音采样设计,有几个关键的参数。

本节内容和上面表格参考来自博文:嵌入式语音开发应用基础说明

1.2.1 采样率

人声的主要能量集中在 300 Hz – 3.4 kHz,按奈奎斯特采样定理,采样率需不低于信号最高频率的 2 倍。

所以传统传统通话标准 (G.711 标准)使用的 8KHz 的采样率。

现在 主流 AI 语音的标准采样率 16KHz ,更高的采样率保留的声音听起来更加自然。

采样率直接关系到芯片 ADC 的采样周期配置。

1.2.2 位深/声道

位深 = 每个采样点用多少位(bit)来存储幅度值,一般就是 8bit 和 16bit 。

16 位深的数据量相比 8 位直接翻倍。

单声道 / 双声道:

对于语音来说,单声道完全够用,双声道几乎不提升效果,只会徒增数据量(也是翻倍)、带宽、功耗;只有音乐 / 立体音效场景,双声道才有意义。

1.2.3 码率

码率(也叫比特率),是指音频在播放或传输时,一秒钟要消耗/产生多少个“比特(bit)”的数据。

是决定 传输带宽够不的那个量:

码率 = 采样率 × 位深 × 声道数

它同时是后面选择传输通路、判断要不要编码的依据。

现在的主流 AI 语音标准:

参数:采样率 16kHz、位深 16bit、单声道
码率=16000×16×1=256000 bps=256 Kbps

语音应用中,可以使用编码压缩的方式减少码率,以获得更小的资源需求 。

二、方案说明

上面讲解了一下基础知识,接下来介绍一下本文说要讲解的方案: 基于沁恒 CH58x/CH59x 低功耗蓝牙MCU, 应用框图如下:

在这里插入图片描述

采样芯片可使用 CH59x/CH58x,集成12位ADC采集外部模拟MIC信号,支持16 kHz 采样率。芯片兼容BLE5.4规范,支持最高2Mbps速率,-95dBm 灵敏度和最高 +9dBm 发射功率可有效满足室内通讯要求,保障数据传输稳定性,提升识别准确率 。

2.1 硬件实现

得益于沁恒蓝牙芯片,自带 USB ,蓝牙,所以我们只需要芯片的最小系统,加上音频采样电路,就可以实现我们的功能。

2.1.1 芯片最小系统

对于不同系列的芯片,沁恒都会在 EVT 里面提供 开发板的原理图和 PCB,最小系统没有什么难度 。

比如我们想用 CH585 ,可以直接在官网搜索CH585 :

在这里插入图片描述

然后解压出来 PCB 原理图在 PUB 目录下,里面会提供 PCB 设计注意事项文档说明以及 开发板的原理图 :

在这里插入图片描述

我们可以看到官方给出的 EVT 板子,然后参照官方给的原理图自己画最小系统(下图因为 CH585功能比较多, 具有 NFC 和 高速 USB,实际使用不需要的就不用画):

在这里插入图片描述

2.1.2 语音采样电路

本方案提供一个低成本的采样电路,只需要一个三极管加上几个阻容便可实现:

在这里插入图片描述

对于此电路的分析,可参考博文:语音采样电路说明测试

2.2 软件实现

对于使用示例,本文实现了一个方便测试的 USB UAC 设备,即插即用 。软件部分我们只看几个典型的关键部分。

ADC 采样配置:

void mic_start_record(uint16_t *buffer_start, uint16_t *buffer_end)
{
    MIC_POWER_ON();
    mic_data_fifo_reset();
    ADC_ExtSingleChSampInit(SampleFreq_4_or_2, ADC_PGA_1_2);
    ADC_ChannelCfg(2);
    ADC_AutoConverCycle(12);    //  (256-22)*16 16025.6 HZuint8_t8K  (256-139)*16 32.051Kuint16_t
    ADC_DMACfg(ENABLE, (uint32_t)buffer_start, (uint32_t)buffer_end, ADC_Mode_LOOP);
    tmos_start_task(halTaskID, HAL_MICS_EVENT, 8);
}

数据搬运至缓冲区:

//定时器没1ms 执行一次搬运
__INTERRUPT
__HIGH_CODE
void TMR2_IRQHandler(void) // TMR0 
{
    if(TMR2_GetITFlag(TMR0_3_IT_CYC_END))
    {
        TMR2_ClearITFlag(TMR0_3_IT_CYC_END); // 
        extern void mic_produce(void);
        mic_produce();
    }
}
/*
mic_produce()
  ├─ 从 record_buffer 取 ADC 原始值
  ├─ 数据处理
  ├─ 存入局部 pcm_buf[16]
  └─ 调用 usb_mic_push_samples(pcm_buf, cnt)  ──→  mic_ring[]  写入
*/
__HIGH_CODE
void mic_produce(void)
{
    uint16_t dma_idx = (R32_ADC_DMA_NOW - R32_ADC_DMA_BEG) / 4;
    uint16_t avail   = (dma_idx - g_mic_prod_idx) & (RB_SIZE - 1);
    uint16_t pcm_buf[16];
    uint16_t cnt = 0;

    /* One sample per record_buffer entry (ADC ~8kHz matches the 8kHz USB consumer).
       Each entry holds a differential pair [0]/[1]; average them. No 2:1 decimation
       (ADC is already ~8kHz, not 16kHz; decimating caused ring underrun -> zero fill -> noise). */
    while (avail >= 1)
    {
        uint32_t avg = ((uint32_t)record_buffer[g_mic_prod_idx][0] + record_buffer[g_mic_prod_idx][1]) / 2;
        int16_t  pcm = (int16_t)(avg - 2048) << 4;          /* center -> 16-bit signed */
        pcm_buf[cnt++] = (uint16_t)pcm;
        g_mic_prod_idx = (g_mic_prod_idx + 1) & (RB_SIZE - 1);
        avail -= 1;
        if (cnt >= (sizeof(pcm_buf) / sizeof(pcm_buf[0])))  /* flush if local buffer full */
        {
            usb_mic_push_samples(pcm_buf, cnt);
            cnt = 0;
        }
    }
    if (cnt)
    {
        usb_mic_push_samples(pcm_buf, cnt);
    }

    /* Drive EP1 ISO IN re-arm every 1ms: UIS_TOKEN_IN does not reliably fire for ISO,
       so pump a fresh frame into EP1 from this TMR2 1ms tick. */
    if (usb_mic_streaming)
    {
        usb_mic_load_frame();
    }
}
//上面处理 ADC 数据调用下面搬运函数
__HIGH_CODE
void usb_mic_push_samples(const uint16_t *samples, uint16_t n)
{
    uint16_t next;
    while (n--)
    {
        next = (mic_ring_head + 1) & MIC_RING_MASK;
        if (next == mic_ring_tail)
        {
            return;                          /* full: drop remaining samples */
        }
        mic_ring[mic_ring_head] = *samples++;
        mic_ring_head = next;
    }
}

USB 传输部分:

__HIGH_CODE
void usb_mic_load_frame(void)
{
    uint8_t  i;
    uint16_t *p = (uint16_t *)pEP1_IN_DataBuf;
    int16_t  s;

    for (i = 0; i < MIC_FRAME_SAMPLES; i++)
    {
        s = 0;                               /* silence on underrun */
        if (mic_ring_head != mic_ring_tail)
        {
            s = (int16_t)mic_ring[mic_ring_tail];
            mic_ring_tail = (mic_ring_tail + 1) & MIC_RING_MASK;
        }
        p[i] = (uint16_t)s;                  /* RISC-V is little-endian: store directly = LE PCM */
    }
    DevEP1_IN_Deal(MIC_FRAME_BYTES);         /* R8_UEP1_T_LEN=16 + TX ACK */
}


void DevEP1_IN_Deal(uint8_t l)
{
    R8_UEP1_T_LEN = l;           // 告诉硬件:要发 16 字节
    R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;// 告诉硬件:主机来问就回 ACK(给数据)
}

三、效果展示

3.1 测试步骤

1、 通过 USB 连接 PC 后,电脑端会自动识别到 USB 麦克风输入设备,无需额外安装驱动。在系统音频设置中,将默认输入设备切换为识别到的 USB MIC 设备(如果没有其他的 MIC 设备,系统会默认选择)。

2、 打开录音软件、音频测试工具或 AI 模型,直接对 MIC 说话即可。

3.2 实测效果

实测效果大家直接看视频即可:

语音采样测试效果

结语

本文展示了基于 CH58x 芯片的一种低成本语音识别方案,大家可以通过视频很直观的看到测试效果,完全能够满足目前各大 AI 语音识别的应用 。

对于实际应用中,需要使用无线的场合,要合理的根据应用场景,进行必要的编解码,以减小数据的码率。对于目前的沁恒的蓝牙芯片来说,传输速率是完全没有问题的。那这实际上就是软件层面的问题,这个后期我们可以进一步的探讨。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐