杰理 SDK 文档中心
首页
首页
  • 概述与快速开始

    • SDK 总览与芯片能力
    • 环境搭建与编译构建
    • 烧录与固件升级
    • 文档与版本资源
  • 应用与示例方案

    • demo 示例工程
    • WiFi 摄像头方案 (wifi_camera)
    • WiFi 音箱方案 (wifi_soundbox)
    • WiFi 婴儿监护方案 (wifi_bbm)
    • 公共应用模块库
    • 示例代码库 (example)
  • 系统架构与平台

    • 总体架构与工程分层
    • 系统启动与运行框架
    • 芯片驱动与板级适配
    • 设备管理与文件系统
    • 系统工具库与算法
  • 音频子系统

    • 音频框架与处理节点
    • 音频编解码与音效
    • 播放器与录音器
    • 语音交互与 AI 唤醒
    • LE Audio 与蓝牙音频
    • 音频调试与歌词
  • 视频与显示子系统

    • 摄像头驱动与 ISP
    • 视频编码与图像处理
    • 显示与 GPU 加速
    • 屏幕镜像 (screen_mirror)
  • 无线连接与网络

    • 蓝牙协议栈 (双模蓝牙)
    • WiFi 协议栈与配网
    • 网络协议栈
    • 云平台与 IoT 协议
  • UI 子系统

    • LVGL 集成与应用
    • UI 工程与工具链
  • 配置系统

    • 功能配置
    • 板级配置
    • 网络与蓝牙配置
    • 音频配置与提示音
  • 工具与测试

    • 产测与射频测试工具
    • 固件升级与更新机制
    • 调试与日志工具
  • 硬件参考设计

    • 原理图参考设计
    • 芯片数据手册

音频配置与提示音

本文档详细介绍 AC792N SDK(fw-AC792_SDK,分支 release/AC792N_SDK_V3)中音频配置与提示音相关的实现:数字音量通道体系(audio_dvol.h)、提示音播放接口(tone_player / bt_tone_player)、正弦波提示音合成(sine_make)、提示音数据在 Bank 中的存储管理,以及 TWS 提示音同步、空间音效模式切换提示音等配置项。

Purpose and Scope

本页覆盖"音频配置与提示音"这一完整能力的端到端实现,包括:

  • 数字音量(Digital Volume)的多通道配置与淡入淡出机制(sdk/audio/common/audio_dvol.h)
  • 提示音播放 API(tone_play / tone_play_index / tone_stop)及其与蓝牙状态机的联动(BT_STATUS_TONE_BY_FILE_NAME)
  • 正弦波提示音合成器(sdk/include_lib/media/sine_make.h)
  • 提示音数据在 Flash Bank 中的存放(CONFIG_BANK_NUM_TONE)
  • 与提示音相关的应用层配置项(TWS 开机提示音同步、空间音效切换提示音开关)

以下主题属于相邻页面,不在本页展开:音频编解码器(AAC/SBC 等)细节、蓝牙协议栈 HFP 的 DTMF 信令(仅在 avctp_user.h 中引用)、麦克风/录音链路、音效 DSP 算法本身(变调变速 audio_pitch_speed_api.h 仅作为提示音处理的扩展点提及)。

Overview

在蓝牙音频设备(如本 SDK 中的 wifi_bbm、wifi_camera 等应用)中,"提示音"是用户与设备交互的重要反馈渠道:开机提示音、按键音、来电铃声、连接/断开提示音、TWS 同步提示音等。这些提示音通常是一段短小的 PCM 数据(可预先烧录在 Flash 的 Tone Bank 中,也可由正弦波合成器实时生成),通过数字音量(DVOL)通道混入主音频通路输出。

SDK 的设计将"音量控制"与"声音内容"解耦:

  • 音量控制由 dvol_handle(数字音量句柄)统一管理,支持多路声音叠加时按通道独立设置音量、淡入淡出(fade)、静音与音量上限;
  • 声音内容由提示音播放器(tone_player)或正弦波合成器(sine_make)产生,前者播放预置的音频文件,后者按参数(频率、点数、窗函数、衰减、增益)实时合成提示音。

两者通过公共音频通路(audio_dvol_run 处理 PCM 数据)衔接,形成一条从"事件触发 → 提示音数据源 → 数字音量 → 输出"的完整链路。

Architecture

flowchart TD
    subgraph sg_Event["事件触发层"]
        BT["蓝牙状态机<br/>BT_STATUS_TONE_BY_FILE_NAME"]
        KEY["按键事件"]
        TWS["TWS 同步事件"]
        SPATIAL["空间音效模式切换<br/>audio_spatial_effects_mode_switch_tone_play"]
    end

    subgraph sg_TonePlayer["提示音播放层"]
        TP["tone_player / bt_tone_player<br/>tone_play / tone_play_index / tone_stop"]
        RING["ring_player<br/>来电铃声"]
    end

    subgraph sg_Source["提示音数据源"]
        SINE["sine_make 正弦波合成器<br/>sin_tone_open / sin_tone_make"]
        BANK["Tone Bank 存储<br/>CONFIG_BANK_NUM_TONE / __BANK_TONE_ENTRY"]
    end

    subgraph sg_DVOL["数字音量层"]
        DVOL["dvol_handle 多通道音量<br/>MUSIC / CALL / TONE / RING / KEY_TONE / TTS / TWS / FLOW"]
        FADE["淡入淡出控制<br/>fade_step / vol_target / vol_fade"]
        MUTE["静音与音量上限<br/>mute_en / vol_limit / vol_max"]
    end

    subgraph sg_Out["输出层"]
        DAC["DAC / 音频通路输出"]
    end

    BT -->|"按文件名播放"| TP
    KEY --> TP
    TWS --> TP
    SPATIAL --> TP
    TP --> SINE
    TP --> BANK
    SINE -->|"PCM 数据"| DVOL
    BANK -->|"PCM 数据"| DVOL
    DVOL --> FADE
    DVOL --> MUTE
    DVOL -->|"audio_dvol_run"| DAC

架构说明:

  • 事件触发层是提示音的入口:蓝牙协议栈上报 BT_STATUS_TONE_BY_FILE_NAME(直接使用文件名播放提示音,见 avctp_user.h),应用层按键、TWS 同步、空间音效模式切换等事件也会触发播放。
  • 提示音播放层封装了播放逻辑:tone_play(const char *name) 按文件名播放、tone_play_index(u8 index) 按下标播放、tone_stop() 停止播放;铃声播放由 ring_player 单独管理(两者在 app_tone.h 中一并引入)。
  • 数据源层决定声音内容来自何处:实时合成(sine_make)或预置存储(Tone Bank)。Tone Bank 通过 bank_switch.h 中的 __BANK_TONE_ENTRY 宏挂接到 Flash 分区,只有定义了 CONFIG_BANK_NUM_TONE 才启用独立 Tone Bank。
  • 数字音量层是多路音频叠加时的关键仲裁点:8 个通道(MUSIC/CALL/TONE/RING/KEY_TONE/TTS/TWS/FLOW)各自拥有音量、淡入淡出步进和最大等级,audio_dvol_run 逐样本处理 PCM 数据。
  • 输出层将混音结果送 DAC。整条链路中提示音只是"声音内容"的一种,与音乐、通话、TTS 共用同一数字音量框架,这正是本设计的核心意图:音量策略统一、声音内容可插拔。

数字音量通道体系(audio_dvol.h)

audio_dvol.h 是整个音频配置体系的基石,它定义了数字音量(Digital Volume)的分辨率、通道掩码、淡入淡出步进与最大音量等级,以及两个核心数据结构 audio_vol_params 与 dvol_handle。

全局音量参数

#define DVOL_RESOLUTION		14
#define DVOL_MAX			16384
#define DVOL_MAX_FLOAT		16384.0f

#define BG_DVOL_FADE_ENABLE		0	/*多路声音叠加,背景声音自动淡出小声*/

#define DIGITAL_VOLUME_LEVEL_MAX  200  //默认的音量等级限制设成200

来源:audio_dvol.h

  • DVOL_RESOLUTION 为 14 位,DVOL_MAX 为 16384,即数字音量的满刻度对应 2^14 个量化等级;DVOL_MAX_FLOAT 是供浮点计算使用的同值常量。
  • BG_DVOL_FADE_ENABLE 默认为 0:多路声音叠加时,背景声音不会自动淡出。若置 1,dvol_handle 中会额外维护 vol_bk(后台自动淡出前音量值)与 entry(链表节点),用于实现"提示音/通话声打断时背景音自动让位"的效果。
  • DIGITAL_VOLUME_LEVEL_MAX 为 200,是默认的音量等级上限,应用层可据此映射 0~200 的 UI 音量刻度。

通道掩码:声音类型的仲裁基础

/*Digital Volume Channel*/
#define MUSIC_DVOL          0b00001
#define CALL_DVOL           0b00010
#define TONE_DVOL           0b00100
#define RING_DVOL           0b01000
#define KEY_TONE_DVOL       0b10000
#define TTS_DVOL            0b100000
#define TWS_TONE_DVOL       0b1000000
#define FLOW_DVOL           0b10000000

/*Digital Volume Fade Step*/
#define MUSIC_DVOL_FS		2
#define CALL_DVOL_FS		4
#define TONE_DVOL_FS		30

/*Digital Volume Max Level*/
#define MUSIC_DVOL_MAX		16
#define CALL_DVOL_MAX		15
#define TONE_DVOL_MAX		16

来源:audio_dvol.h

设计意图解读:

  • 每个通道使用独立的 bit 位(0b00001 ~ 0b10000000),意味着这些掩码可以按位组合,用于表示"这路声音属于哪些类型"或在多路混音时按类型仲裁优先级。
  • 通道划分体现了声音的业务语义:音乐(MUSIC)、通话(CALL)、系统提示音(TONE)、来电铃声(RING)、按键音(KEY_TONE)、语音合成(TTS)、TWS 对耳提示音(TWS_TONE)、流水/渐变提示音(FLOW)。不同业务的声音可以同时存在(如音乐 + 提示音),各自独立控制音量。
  • 淡入淡出步进(Fade Step)是各通道音量的"变化速度":MUSIC 为 2(缓慢渐入渐出,避免音乐突兀)、CALL 为 4、TONE 为 30(提示音短促,需要快速完成淡入淡出,否则听感拖沓)。这是典型的"按业务特性调参"的设计。
  • 最大等级(Max Level)限制每类声音能达到的最大音量:TONE 为 16,比 MUSIC(16)相同、比 CALL(15)高,保证提示音在混音中可被清晰听见。

数据结构:audio_vol_params 与 dvol_handle

struct audio_vol_params {
    u16 vol;
    u16 vol_max;
    u16 fade_step;
    s16 vol_limit;
    u8 bit_wide;
};

typedef struct {
    u8 toggle;				/*数字音量开关*/
    u8 fade;				/*淡入淡出标志*/
    u16 vol;				/*淡入淡出当前音量(level)*/
    u16 vol_max;				/*淡入淡出最大音量(level)*/
    s16 vol_limit;			/*最大数字音量限制*/
    s16 vol_fade;			/*淡入淡出对应的起始音量*/
#if BG_DVOL_FADE_ENABLE
    s16 vol_bk;				/*后台自动淡出前音量值*/
    struct list_head entry;
#endif/*BG_DVOL_FADE_ENABLE*/
    volatile s16 vol_target;	/*淡入淡出对应的目标音量*/
    volatile u16 fade_step;		/*淡入淡出的步进*/
    float  cfg_vol_min;         /*最小音量的分贝数*/
    float  cfg_vol_max;         /*最小音量的分贝数*/
    u16    cfg_level_max;       /*最大音量等级*/
    u8     vol_table_custom;    /*是否使用外部工具读取的音量表*/
    u8     vol_table_default;   /*是否使用默认的音量表*/
    u8     mute_en;             /*是否将数据设成0*/
    u8     bit_wide;            /*数据位宽*/
    float   *vol_table;         /*自定义音量表*/
} dvol_handle;

来源:audio_dvol.h

  • audio_vol_params 是打开数字音量通道时的入参:初始音量、最大音量、淡入淡出步进、音量上限与数据位宽。
  • dvol_handle 是运行期句柄:vol/vol_target/vol_fade 构成淡入淡出状态机(起始音量 → 逐 tick 步进 → 目标音量),fade_step 与 vol_target 用 volatile 修饰,说明它们会在中断/多任务上下文中被并发读写。
  • 音量表机制:vol_table_custom 与 vol_table_default 两个标志配合 vol_table 指针,支持"使用外部工具读取的音量表"或"默认音量表"两种曲线,用于把线性音量等级映射为符合人耳感知的对数分贝曲线。
  • mute_en 为 1 时 audio_dvol_run 直接输出 0,实现瞬时静音;bit_wide 决定数据处理时的位宽(16/24/32 bit)。

数字音量 API 一览

int audio_digital_vol_init(u16 *vol_table, u16 vol_max);
void audio_digital_vol_bg_fade(u8 fade_out);
dvol_handle *audio_digital_vol_open(struct audio_vol_params *params);
void audio_digital_vol_close(dvol_handle *dvol);
void audio_digital_vol_set(dvol_handle *dvol, u16 vol);
void audio_digital_vol_mute_set(dvol_handle *dvol, u8 mute_en);
int audio_digital_vol_run(dvol_handle *dvol, void *data, u32 len);
void audio_digital_vol_reset_fade(dvol_handle *dvol);

来源:audio_dvol.h

典型生命周期:audio_digital_vol_init(全局初始化音量表)→ audio_digital_vol_open(为某路声音打开通道,返回句柄)→ 循环调用 audio_digital_vol_run(对 PCM 数据逐样本应用音量)→ 需要变音时 audio_digital_vol_set / audio_digital_vol_reset_fade → 结束后 audio_digital_vol_close。audio_digital_vol_bg_fade 在 BG_DVOL_FADE_ENABLE=1 时用于让背景声音整体淡出。

提示音播放接口与触发流程

提示音的播放入口位于应用层:app_tone.h 统一引入 tone_player.h 与 ring_player.h(见 wifi_bbm/include/app_tone.h 与 wifi_camera/include/app_tone.h),而 bt_tone_player.h 给出了播放器的核心接口:

void tone_stop();
int tone_play(const char *name);
int tone_play_index(u8 index);

来源:bt_tone_player.h

  • tone_play(const char *name):按文件名播放提示音,例如 tone_play("power_on.mp3")。这一接口与蓝牙状态机上报的 BT_STATUS_TONE_BY_FILE_NAME 事件一一对应——协议栈侧直接给出文件名,播放器按名查找并播放,省去"事件→编号→文件"的映射表。
  • tone_play_index(u8 index):按下标播放,适用于预置提示音表(tone table)的场景,播放器内部按下标查表得到文件。
  • tone_stop():停止当前提示音。由于提示音通常有严格时序(如开机音播完才初始化 TWS),停止接口必须可被抢占式调用。

蓝牙状态事件与提示音的联动

在蓝牙协议栈的用户事件定义中:

BT_STATUS_TONE_BY_FILE_NAME, /*直接使用文件名播放提示音*/

来源:avctp_user.h

该事件与 BT_STATUS_INBAND_RINGTONE(来电铃声内录)、BT_STATUS_VOICE_RECOGNITION 等事件并列,说明提示音播放已经内建到蓝牙状态机的事件分发机制中:协议栈在连接成功、断开、来电等状态跳转时主动上报文件名,应用层只需在事件回调中调用 tone_play 即可,无需自行判断状态。

TWS 提示音同步

#define TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END 1 //tws播完开机提示音再初始化,处理提示音不同步问题

来源:wifi_bbm/include/app_config.h

当 TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END 置 1 时,TWS(真无线对耳)的初始化被推迟到开机提示音播放完毕之后。设计意图:左右耳若在开机音播放中途各自初始化 TWS 链路,会造成两耳提示音不同步;先播完提示音再初始化,可保证双耳提示音节奏一致。这是提示音时序与系统初始化顺序耦合的典型配置。

正弦波提示音合成(sine_make)

对于不需要预置音频文件的场景(如按键音、低电提示音),SDK 提供实时正弦波合成器,接口定义在 sine_make.h:

#define DEFAULT_SINE_SAMPLE_RATE 16000
#define SINE_TOTAL_VOLUME        26843546//16106128//20132660 //26843546

struct sin_param {
    //int idx_increment;
    int freq;
    int points;
    int win;
    int decay;
    float gain; // 0到-90dB
};

int sin_tone_make(void *_maker, void *data, int len);
void *sin_tone_open(const struct sin_param *param, int num, u8 channel, u8 repeat);
int sin_tone_points(void *_maker);
void sin_tone_close(void *_maker);
void sin_pcm_fill(void *buf, u32 len, u32 fs);
void sweepsin_pcm_fill(void *buf, u32 len);

来源:sine_make.h

  • sin_param 定义单音参数:freq 频率(Hz)、points 采样点数、win 窗函数类型(用于平滑首尾、抑制频谱泄漏)、decay 衰减(使音色自然收尾)、gain 增益(0 ~ -90 dB)。
  • sin_tone_open(param, num, channel, repeat):创建合成器实例。num 为音调个数(可连续合成多个频率构成旋律/和弦),channel 为声道数,repeat 是否循环播放。
  • sin_tone_make:每次调用填充 len 字节的 PCM 数据到 data 缓冲区,供数字音量层处理。
  • sin_tone_points:返回当前合成的总点数,用于上层判断播放进度;sin_tone_close 释放句柄。
  • 默认采样率为 16000 Hz;SINE_TOTAL_VOLUME 为 28 位满幅量化值(注释中保留了多次调参痕迹:16106128 → 20132660 → 26843546),说明该常量经历过响度校准。

与数字音量的衔接:sin_tone_make 产出的 PCM 数据与 Tone Bank 播出的 PCM 数据走同一条通路——先进入对应通道的 dvol_handle,经 audio_dvol_run 应用音量与淡入淡出后再输出。因此合成提示音同样受 TONE_DVOL 通道的步进(30)与最大等级(16)约束,保证与预置提示音听感一致。

提示音数据存储(Tone Bank)

预置提示音(开机音、配对音等音频文件)通过 Bank 机制存放在 Flash 中,由 bank_switch.h 统一管理:

#ifdef CONFIG_BANK_NUM_TONE
#define __BANK_TONE_ENTRY   __BANK_ENTRY(CONFIG_BANK_NUM_TONE)
#define __BANK_TONE         __BANK_NUM(CONFIG_BANK_NUM_TONE)
#else
#define __BANK_TONE_ENTRY
#define __BANK_TONE
#endif

来源:bank_switch.h

  • 当定义了 CONFIG_BANK_NUM_TONE 时,编译器为提示音分配独立的 Flash Bank 编号,__BANK_TONE_ENTRY 声明该 Bank 的入口(entry),__BANK_TONE 提供 Bank 号访问宏;未定义时两者为空,提示音资源回退到普通代码段/资源段。
  • 设计意图:把提示音数据独立成 Bank 可以在运行时按需切换/加载(Bank Switch 机制),减少常驻内存占用;同时便于通过工具单独烧录/升级提示音资源,无需重刷整个固件。

空间音效模式切换提示音

在空间音效(Spatial Effect)处理模块中,模式切换是否播放打断提示音由宏控制:

#define SPATIAL_AUDIO_EFFECT_SW_TONE_PLAY     0

来源:spatial_effects_process.h

配套接口为 audio_spatial_effects_mode_switch_tone_play(enum SPATIAL_EFX_MODE mode)。当宏置 1 时,切换空间音效模式(如标准 → 音乐厅 → 影院)会先播放一段打断提示音,同时重开数据流;置 0(默认)则静默切换。该配置体现了提示音策略的"可裁剪"特性——不同产品对提示音数量的要求差异很大,宏开关让开发者按需取舍。

核心流程:一次提示音播放的完整链路

sequenceDiagram
    participant App as 应用/协议栈事件
    participant TP as tone_player<br/>(tone_play / tone_play_index)
    participant SRC as 数据源<br/>(Tone Bank / sine_make)
    participant DVOL as dvol_handle<br/>(TONE_DVOL 通道)
    participant DAC as 音频输出

    App->>TP: 事件触发(BT_STATUS_TONE_BY_FILE_NAME / 按键 / TWS)
    TP->>TP: 解析文件名或下标,查找提示音资源
    TP->>SRC: 打开数据源(读 Bank 文件或 sin_tone_open)
    SRC-->>TP: 返回数据句柄 / 合成器句柄
    loop 每帧数据
        TP->>SRC: 请求 PCM 数据(sin_tone_make / 文件读取)
        SRC-->>DVOL: PCM buffer
        DVOL->>DVOL: audio_dvol_run 应用音量/淡入淡出/mute
        DVOL->>DAC: 混音后输出
    end
    App->>TP: 播放结束或被抢占(tone_stop)
    TP->>SRC: 关闭数据源(sin_tone_close)
    TP-->>App: 返回(tone_play 返回值 0/负错误码)

流程要点:

  1. 触发源多样化但入口统一:蓝牙状态事件(按文件名)、应用按键、TWS 同步、空间音效模式切换都收敛到 tone_play / tone_play_index。
  2. 数据源二选一:预置文件从 Tone Bank 读取,合成音由 sine_make 实时生成;两者最终都产出标准 PCM。
  3. 数字音量层逐帧处理:audio_dvol_run 是每帧必经路径,TONE_DVOL 通道的 fade_step=30 使提示音快速到位,vol_limit 限制其峰值。
  4. 生命周期管理:tone_stop 可随时抢占;TWS 场景下播放结束事件还参与系统初始化时序(TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END)。

Usage Examples

示例一:配置并打开一路提示音数字音量通道

以下代码展示了如何用 audio_vol_params 配置 TONE 通道并打开 dvol_handle(流程:设置初始音量/最大音量/步进/上限 → open → 逐帧 run → close):

struct audio_vol_params params = {
    .vol       = 0,            /*初始音量,从 0 开始便于淡入*/
    .vol_max   = TONE_DVOL_MAX,/*最大等级 16*/
    .fade_step = TONE_DVOL_FS, /*淡入淡出步进 30,提示音快速到位*/
    .vol_limit = TONE_DVOL_MAX,/*音量上限*/
    .bit_wide  = 16,           /*16bit PCM*/
};
dvol_handle *tone_dvol = audio_digital_vol_open(&params);
/* ... 每帧对提示音 PCM 调用 audio_dvol_run(tone_dvol, pcm, len) ... */
audio_digital_vol_close(tone_dvol);

来源:audio_dvol.h(audio_vol_params 定义)与 audio_dvol.h(API 声明)

说明:TONE_DVOL_FS/TONE_DVOL_MAX 分别对应淡入淡出步进 30 与最大等级 16,见 audio_dvol.h。

示例二:按文件名播放提示音(蓝牙事件场景)

蓝牙状态机上报 BT_STATUS_TONE_BY_FILE_NAME 后,应用直接以文件名播放:

int tone_play(const char *name);     /*按文件名播放,如 "power_on.mp3"*/
int tone_play_index(u8 index);       /*按下标播放预置提示音表*/
void tone_stop();                    /*停止当前提示音*/

来源:bt_tone_player.h

调用示例(示意,按协议栈回调事件驱动):

case BT_STATUS_TONE_BY_FILE_NAME: {
    /*参数携带文件名,直接播放*/
    tone_play(file_name);
    break;
}

来源:avctp_user.h(事件定义)

示例三:实时合成正弦提示音

无需预置文件时,用 sine_make 按参数合成(如 880 Hz、带衰减、单声道、不循环的按键提示音):

struct sin_param param = {
    .freq   = 880,      /*频率 Hz*/
    .points = 3200,     /*200ms @ 16kHz*/
    .win    = 1,        /*加窗平滑*/
    .decay  = 8,        /*衰减,自然收尾*/
    .gain   = -6.0f,    /*增益 -6dB,0 到 -90dB*/
};
void *maker = sin_tone_open(&param, 1, 1, 0); /*1 个音调、单声道、不循环*/
int pts = sin_tone_points(maker);
/* 循环填充 PCM:sin_tone_make(maker, buf, len) 后送入 TONE 通道 dvol */
sin_tone_close(maker);

来源:sine_make.h

Configuration Options

配置项类型默认值说明
DVOL_RESOLUTION宏 (int)14数字音量分辨率(位),满刻度 DVOL_MAX=16384
BG_DVOL_FADE_ENABLE宏 (int)0多路声音叠加时背景音是否自动淡出(1 启用,启用后 dvol_handle 增加 vol_bk/链表字段)
DIGITAL_VOLUME_LEVEL_MAX宏 (int)200默认音量等级上限,UI 音量刻度基准
MUSIC_DVOL_FS / CALL_DVOL_FS / TONE_DVOL_FS宏 (int)2 / 4 / 30音乐/通话/提示音通道淡入淡出步进
MUSIC_DVOL_MAX / CALL_DVOL_MAX / TONE_DVOL_MAX宏 (int)16 / 15 / 16音乐/通话/提示音通道最大音量等级
DEFAULT_SINE_SAMPLE_RATE宏 (int)16000正弦波合成默认采样率
SINE_TOTAL_VOLUME宏 (int)26843546正弦波合成满幅音量(响度校准值)
CONFIG_BANK_NUM_TONE宏 (int)未定义定义后启用独立 Tone Bank(__BANK_TONE_ENTRY / __BANK_TONE)
TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END宏 (int)1TWS 播完开机提示音后再初始化,避免双耳提示音不同步
SPATIAL_AUDIO_EFFECT_SW_TONE_PLAY宏 (int)0空间音效模式切换时是否播放打断提示音

API Reference

int audio_digital_vol_init(u16 *vol_table, u16 vol_max)

初始化数字音量模块(设置全局音量表与最大等级)。

参数:

  • vol_table (u16*):音量查找表(可为自定义曲线),NULL 时使用默认表
  • vol_max (u16):全局最大音量

返回: 0 成功;负值失败。

来源:audio_dvol.h

dvol_handle *audio_digital_vol_open(struct audio_vol_params *params)

打开一路数字音量通道,返回句柄。

参数:

  • params (audio_vol_params*):初始音量、最大音量、淡入淡出步进、音量上限、位宽

返回: dvol_handle*;失败返回 NULL。

来源:audio_dvol.h

void audio_digital_vol_set(dvol_handle *dvol, u16 vol)

设置目标音量,触发淡入淡出(从当前音量向 vol 以 fade_step 步进)。

参数:

  • dvol (dvol_handle*):通道句柄
  • vol (u16):目标音量等级

int audio_digital_vol_run(dvol_handle *dvol, void *data, u32 len)

对 PCM 数据逐样本应用音量/淡入淡出/静音。

参数:

  • dvol (dvol_handle*):通道句柄
  • data (void*):PCM 缓冲区(就地处理)
  • len (u32):数据字节数

返回: 0 成功;负值失败(如句柄非法)。

来源:audio_dvol.h

void audio_digital_vol_mute_set(dvol_handle *dvol, u8 mute_en)

设置静音标志,mute_en=1 时输出全 0。

void audio_digital_vol_reset_fade(dvol_handle *dvol)

重置淡入淡出状态(重新从当前音量开始)。

void audio_digital_vol_bg_fade(u8 fade_out)

背景音整体淡出/淡入(需 BG_DVOL_FADE_ENABLE=1)。

来源:audio_dvol.h

int tone_play(const char *name) / int tone_play_index(u8 index) / void tone_stop()

提示音播放器接口:按文件名播放、按下标播放、停止播放。

返回: tone_play/tone_play_index 返回 0 成功、负值失败(资源未找到、播放器忙等)。

来源:bt_tone_player.h

void *sin_tone_open(const struct sin_param *param, int num, u8 channel, u8 repeat) / int sin_tone_make(void *_maker, void *data, int len) / int sin_tone_points(void *_maker) / void sin_tone_close(void *_maker)

正弦波提示音合成器:创建(参数:音调参数数组、音调个数、声道数、是否循环)、填充 PCM、查询总点数、释放。

来源:sine_make.h

void audio_spatial_effects_mode_switch_tone_play(enum SPATIAL_EFX_MODE mode)

空间音效模式切换时播放提示音(由 SPATIAL_AUDIO_EFFECT_SW_TONE_PLAY 宏控制是否生效)。

来源:spatial_effects_process.h

失败模式、边界情况与并发

提示音资源缺失

  • tone_play / tone_play_index 在文件名或下标对应的资源不存在时返回负值。由于提示音属于"尽力而为"的反馈机制,调用方通常忽略返回值,但不应当阻塞主流程——例如蓝牙状态事件回调中播放失败不应影响连接状态机推进。
  • 若 CONFIG_BANK_NUM_TONE 未定义,__BANK_TONE_ENTRY 与 __BANK_TONE 展开为空,依赖 Tone Bank 的提示音将回退到默认资源路径。症状:某些提示音无声但系统正常,需检查 Bank 配置与资源烧录是否匹配。

播放抢占与打断

  • 提示音可被新的提示音抢占(tone_stop + 新 tone_play)。设计上提示音是短促的反馈信号,不允许排队阻塞——新事件直接打断旧音。对时序敏感的场景(如 TWS 双耳开机音),通过 TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END=1 把初始化推迟到播放结束后,从根源上避免"播放中途被初始化流程打断"造成的不同步。
  • 来电铃声走独立的 ring_player(app_tone.h 中与 tone_player 并列引入),避免铃声与系统提示音互相抢占导致的听感冲突。

并发读写

  • dvol_handle 中的 vol_target 与 fade_step 使用 volatile 修饰,说明音量设置(可能来自按键任务/UI 线程)与 audio_dvol_run(音频中断/音频任务)存在跨上下文并发访问。音频通路中不应直接加锁(会引入延迟),volatile + 单次写入/读取是此处采用的轻量同步策略。
  • BG_DVOL_FADE_ENABLE=1 时 dvol_handle 挂入链表(entry),多路背景音淡出由统一流程遍历处理;此时需保证链表操作与音频回调互斥。

音量边界

  • 各通道有独立的 vol_limit 与 vol_max(如 TONE 上限 16、CALL 上限 15),audio_digital_vol_set 传入超限值时会被钳制。淡入淡出状态机以 vol_fade(起始)→ vol_target(目标)为界,fade_step 决定每 tick 变化量,vol 越界会造成音量跳变,因此上层应始终通过 API 设置而非直接改结构体字段。

合成器参数边界

  • sin_param.gain 取值范围 0 ~ -90 dB,超出范围的增益可能导致削波或听不见;freq 过高(接近采样率 16 kHz 的奈奎斯特上限)会产生混叠失真。SINE_TOTAL_VOLUME 是满幅量化常量,响度已校准,业务层不宜再放大。

性能与运维考量

  • 逐样本处理的开销:audio_dvol_run 对每帧 PCM 逐样本应用音量/淡入淡出,是音频热路径。TONE_DVOL_FS=30 意味着提示音在极短时间(约几十个 tick)内完成淡入淡出,减少处理时长;音乐通道步进 2 则保证平滑。修改这些宏会直接影响 CPU 占用与听感,需在性能与体验间权衡。
  • 正弦波合成的开销:sine_make 实时合成比播放预置文件更省 Flash 但占 CPU。对低功耗场景,优先使用 Tone Bank 预置文件;对必须动态生成的声音(频率可变),使用合成器并注意 sin_tone_close 释放句柄,避免泄漏。
  • Bank 切换:独立 Tone Bank(CONFIG_BANK_NUM_TONE)允许按需加载提示音资源,减小常驻内存,但 Bank 切换本身有 Flash 访问延迟,不要在音频中断里触发 Bank 加载。
  • TWS 时序:TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END 增加开机流程时延(等待提示音播完),但换取双耳同步;若产品对开机速度敏感,可评估关闭该配置并改用短提示音。

扩展点

  • 新增提示音类型:在 audio_dvol.h 的通道掩码中按 bit 递增扩展(当前已用 8 位),并在 dvol_handle 打开时使用新通道掩码;同时补充对应的 *_DVOL_FS 与 *_DVOL_MAX 宏以独立控制其淡入淡出速度与上限。
  • 自定义音量表:通过 audio_digital_vol_init(vol_table, vol_max) 传入对数曲线表,或设置 dvol_handle.vol_table_custom/vol_table_default 切换"外部工具读取的音量表"与"默认表",可适配不同喇叭/耳机的响度特性。
  • 变调变速提示音:audio_pitch_speed_api.h 提供的 audio_pitch_speed_set(char *node_name, float semi_tones, float speed)(半音符 -12~12、变速 >0.5)可作为提示音的后处理扩展,在同一节点链路上实现变调变速效果。
  • 提示音开关裁剪:SPATIAL_AUDIO_EFFECT_SW_TONE_PLAY 等宏开关使不同产品线可以按需裁剪提示音数量;新增提示音时建议同样以宏开关控制,保持资源可裁剪。

测试与验证建议

仓库中的音效/音频模块头文件(如 audio_pitch_speed_api.h、spatial_effects_process.h)提供了可注入的接口,验证提示音链路时可关注:

  • 播放回调完整性:tone_play 后数据源正确打开、audio_dvol_run 每帧被调用、tone_stop 后句柄释放;
  • 音量边界:对 TONE_DVOL 通道反复 set 0 / 16 / 超限值,确认无越界与跳变;
  • 抢占行为:连续快速触发多个提示音,确认无崩溃、无内存泄漏;
  • TWS 时序:验证 TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END=1 时双耳提示音播放结束才进入 TWS 初始化;
  • 合成器参数:用 sin_tone_open 全参数遍历(freq/points/win/decay/gain)跑稳定性测试,确认 sin_tone_points 与 sin_tone_make 输出一致。

Related Links

  • 音频数字音量配置(audio_dvol.h)
  • 正弦波提示音合成(sine_make.h)
  • 提示音播放器接口(bt_tone_player.h)
  • 蓝牙状态事件定义(avctp_user.h)
  • Tone Bank 存储管理(bank_switch.h)
  • 空间音效切换提示音开关(spatial_effects_process.h)
  • 相关能力页:蓝牙音频链路、音频编解码器、变调变速音效(audio_pitch_speed_api.h)等主题请参见对应目录页面。
Prev
网络与蓝牙配置