音效、变速变调与降噪
本页介绍 fw-AD15N SDK 中音频处理子系统:音效框架(sound effect)、回声/混响(echo/reverb)、变速变调(pitch shift / formant shift,即"变声")以及 ANS 降噪(noise suppression)的接口设计、数据流与控制流程。
Purpose and Scope
本文档覆盖以下能力的端到端实现说明:
- 音效框架:
sound_effect_api.h定义的EFFECT_OBJ、sound_in_obj/sound_out_obj结构,以及解码器侧音效使能标志位(B_DEC_EFFECT等)。 - 回声/混响:
echo_api.h封装的多段回声参数与固定参数结构。 - 变速变调(变声):
howling_pitchshifter_api.h的 pitch shift(音调)与 formant shift(共振峰)算法 API。 - ANS 降噪:
ans_api.h与NoiseSuppressLib.h提供的实时降噪算法(仅支持 8k/16k 采样率)。
与音效无关的主题(如解码器本身、DAC 输出链路、蓝牙协议栈)不在此页展开,请参见对应目录页。SDK 中的 energe_api.h、howling_api.h、dac.h 等头文件通过 #include 引用本页所述接口,属于音效链路的周边封装,本页会在相关章节说明其关系。
Overview
在 AD15N 这类 MCU 音频方案中,音频链路通常是 解码/录音 → 音效处理 → DAC 播放 的单向流水线。音效子系统在这一链路上提供三类可插拔的处理:
- 常规音效(effect):以
EFFECT_OBJ为统一抽象,回调式run接口把处理模块串进sound_out_obj的effect槽位,解码器通过标志位控制开关。 - 变速变调:
HOWLING_PITCHSHIFT_FUNC_API以need_buf / open / run三函数范式提供变声能力,link_pitchshift_howling_sound()负责把变声模块链接到已有的 sound-out 链路上,可在运行中通过update_howling_parm_fs_api()动态改参。 - 降噪:ANS 算法面向通话/录音场景,
ans_init()挂接环形缓冲区(cbuffer),算法以"踢一脚"(kick)的方式被驱动,且对系统主频和采样率有硬性约束(≥96M 主频、仅 8k/16k)。
设计意图:SDK 将"效果处理"抽象为 统一对象 + 函数指针表,使不同算法(变声、回声、混响、降噪)能以相同范式接入音频流水线,且参数可以在运行时热更新,无需重建整条链路。这是嵌入式音频 SDK 中典型的"以空间换灵活性"设计——每个效果对象占用一段由 need_buf() 查询、open() 初始化的内存。
Architecture
flowchart TD
subgraph sg_Source["音频源"]
Dec["解码器 Decoder"]
Rec["录音 Recorder"]
end
subgraph sg_Effect["音效层"]
EObj["EFFECT_OBJ<br/>(p_si / run / sound)"]
SIn["sound_in_obj<br/>(p_dbuf / ops)"]
SOut["sound_out_obj<br/>(p_obuf / effect / mio / enable / para)"]
PS["Howling PitchShifter<br/>(need_buf / open / run)"]
Echo["Echo / Reverb<br/>(echo_parm_obj + EF_REVERB_FIX_PARM)"]
end
subgraph sg_Noise["降噪层"]
ANS["ANS 降噪<br/>ans_init / ans_check_kick_start"]
NSLib["NoiseSuppressLib<br/>(Freeze / NoiseFloor / LowCutThr)"]
end
subgraph sg_Out["输出层"]
DAC["DAC 播放"]
CBuf["环形缓冲区 cbuffer"]
end
Dec -->|"B_DEC_EFFECT 使能"| EObj
Rec -->|"8k/16k 数据"| ANS
EObj --> SIn
EObj --> SOut
SOut -->|"effect 槽位"| PS
SOut -->|"effect 槽位"| Echo
PS -->|"output 回调"| DAC
Echo -->|"output 回调"| DAC
ANS -->|"kick 驱动"| NSLib
ANS --> CBuf
CBuf --> DAC
架构说明:
EFFECT_OBJ(sound_effect_api.h)是音效的统一外壳:p_si指向输入对象,run是处理回调,内嵌sound_out_obj sound作为输出端。解码器通过B_DEC_EFFECT(BIT(2))等标志位控制其运行状态。sound_out_obj(sound_effect_api.h)携带effect(效果对象指针)、mio、enable(volatile 状态)、para(参数),是效果链的挂载点。- 变速变调与回声混响都挂在
sound_out_obj.effect槽位上,通过各自的output回调(HOWL_PS_IO_CONTEXT.output)把处理结果送回 DAC 链路。 - ANS 降噪独立于常规音效链:它直接操作 cbuffer,以
ans_check_kick_start()的 kick 信号驱动NoiseSuppressLib处理,适合放在录音/通话路径上。
音效框架:EFFECT_OBJ 与解码器标志位
sound_effect_api.h 位于解码器公共头文件目录(sdk/include_lib/decoder/),说明音效框架与解码器强耦合:解码器在运行时通过一组位标志管理音效的执行状态。核心标志定义如下:
#define B_DEC_RUN_EN BIT(0)
#define B_DEC_OBUF_EN BIT(1)
#define B_DEC_ENABLE (B_DEC_OBUF_EN | B_DEC_RUN_EN)
#define B_DEC_EFFECT BIT(2) //#define B_DEC_PAUSE BIT(8)
#define B_DEC_ERR BIT(3)
#define B_DEC_MIO BIT(4) //#define B_DEC_PAUSE BIT(8)
#define B_DEC_PAUSE BIT(7)
#define B_DEC_KICK BIT(8)
#define B_REC_RUN BIT(9)
#define B_DEC_FIRST BIT(10)
Source: sound_effect_api.h
设计意图:这些标志位构成解码器的状态机。B_DEC_RUN_EN | B_DEC_OBUF_EN 组合成 B_DEC_ENABLE 作为"解码在跑且输出缓冲就绪"的默认使能态;B_DEC_EFFECT 单独控制音效开关,使音效可以在解码过程中随时切入/切出而不打断解码主流程;B_DEC_KICK 与 ANS 降噪的 kick 机制呼应(见下文降噪章节)。被注释掉的 B_DEC_PAUSE/B_LOUDSPEAKER/B_HALFWAY_EFFECT 表明该框架曾为暂停、扬声器模式、半程音效预留过扩展位——新功能应优先复用这些位定义而非新增枚举。
对象模型:
typedef struct _sound_in_obj {
void *p_dbuf;
void *ops;
} sound_in_obj;
typedef struct _sound_out_obj {
void *p_obuf;
void *effect;
void *mio;
volatile u32 enable;
u32 para;
} sound_out_obj;
typedef struct _EFFECT_OBJ__ {
void *p_si; /*point to sound in*/
int (*run)(void *hld, short *inbuf, int len);
sound_out_obj sound;
} EFFECT_OBJ;
Source: sound_effect_api.h
关键点:
sound_out_obj.enable声明为volatile u32,因为解码器 ISR(中断服务例程)与应用线程会并发读写该字段;B_DEC_EFFECT等标志即写入此处。EFFECT_OBJ.run的签名int (*run)(void *hld, short *inbuf, int len)与变声 API 的run(void *ptr, short *indata, int len)完全一致——这不是巧合,而是 SDK 刻意统一的效果回调约定:输入 short PCM、按字节计 len、返回处理结果。因此变声/回声模块可以直接被包装进EFFECT_OBJ。sound_output(void *priv, void *data, int len)是链路末端的统一输出口,所有效果模块的output回调最终都会落到它(或等价的 DAC 写接口)上。
变速变调:HOWLING_PITCHSHIFT 变声引擎
变声(音效)能力由 howling_pitchshifter_api.h 提供,它同时支持**音调搬移(pitch shift)与共振峰搬移(formant shift)**两种处理,对应枚举:
enum {
EFFECT_HOWLING_PS = 0x01, //1.5《=》12 ms
EFFECT_HOWLING_FS = 0x02
};
Source: howling_pitchshifter_api.h
注释 1.5《=》12 ms 表明该算法的处理延迟约 1.5–12 ms,具体取决于参数(ps_parm/fs_parm)。EFFECT_HOWLING_FS 即"变速不变调/变调不变速"类效果(如小黄人/大叔音),是短视频与录音类产品的核心卖点。
参数与 IO 上下文
typedef struct HOWLING_PITCHSHIFT_PARM_ {
s16 ps_parm;
s16 fs_parm;
u32 effect_v;
} HOWLING_PITCHSHIFT_PARM;
typedef struct _HOWL_PS_IO_CONTEXT_ {
void *priv;
int(*output)(void *priv, void *data, int len);
} HOWL_PS_IO_CONTEXT;
Source: howling_pitchshifter_api.h
ps_parm:音调(pitch)参数,控制音高低;fs_parm:共振峰(formant)参数,控制"喉型"特征;两者独立可调,配合使用可实现音高与音色解耦的变声。effect_v:效果使能/模式值(对应EFFECT_HOWLING_PS/EFFECT_HOWLING_FS位)。HOWL_PS_IO_CONTEXT是变声模块与外界的数据通道:output回调把处理完的 PCM 送出(通常指向 DAC 或下一级 effect),priv是回调上下文。这种回调式输出让变声模块可以插入任意位置而无需知道下游细节。
函数指针表:need_buf / open / run
typedef struct _HOWLING_PITCHSHIFT_FUNC_API_ {
u32(*need_buf)(int flag);
void (*open)(void *ptr, int sr, HOWLING_PITCHSHIFT_PARM *pitchshift_obj, HOWL_PS_IO_CONTEXT *how_ps_io); //中途改变参数,可以调init
int (*run)(void *ptr, short *indata, int len); //len是多少个byte
} HOWLING_PITCHSHIFT_FUNC_API;
extern HOWLING_PITCHSHIFT_FUNC_API *get_howling_ps_func_api();
void *link_pitchshift_howling_sound(void *p_sound_out, void *p_dac_cbuf, void **pp_effect, u32 sr);
void update_howling_parm_fs_api(u32 sr, s16 new_fs);
Source: howling_pitchshifter_api.h
这是 SDK 中典型的算法函数指针表模式,get_howling_ps_func_api() 返回表的实例:
need_buf(flag):查询算法所需工作内存大小(flag区分 PS/FS 模式),调用方据此分配内存——嵌入式环境必须显式管理内存,不允许算法内部 malloc。open(ptr, sr, parm, io):用采样率sr和参数初始化工作区ptr;头注释特别说明"中途改变参数,可以调 init",即运行中改变ps_parm/fs_parm后重新调用open即可热更新。run(ptr, indata, len):处理一帧 PCM;len单位是字节(不是采样点数),与EFFECT_OBJ.run约定一致。
链路集成函数 link_pitchshift_howling_sound() 把变声模块挂到已有的 sound-out 对象上:输入 p_sound_out(来自 sound_out_obj)与 p_dac_cbuf(DAC 环形缓冲),通过 pp_effect 回传出 effect 对象指针,sr 为当前采样率。update_howling_parm_fs_api(sr, new_fs) 则提供独立的"只改共振峰"运行期接口,避免为单个参数重建整条链路。
回声/混响:echo_api 封装
回声模块 echo_api.h 是混响(reverb)算法之上的薄封装,直接复用 reverb_api.h 的固定参数结构:
#include "reverb_api.h"
typedef struct {
ECHO_PARM_SET echo_parm_obj; //参数
EF_REVERB_FIX_PARM echo_fix_parm;
void *ptr;
} ECHO_OBJ;
Source: echo_api.h
设计意图:把"用户可调参数"(echo_parm_obj)与"算法固定参数"(echo_fix_parm,如滤波器系数、延迟表)分离,ptr 指向运行时工作区。这种"参数/固定系数/工作区"三分离结构与变声模块的 PITCHSHIFT_PARM + FUNC_API + 私有 ptr 异曲同工,是 SDK 音效模块的共同风格,便于移植到不同 DSP 内核。在完整链路中,回声模块同样挂在 sound_out_obj.effect 槽位,与变声模块可以串联(先变声后回声,或反之,由链接顺序决定)。
ANS 降噪:ans_api 与 NoiseSuppressLib
降噪子系统分两层:驱动层 ans_api.h 负责 cbuffer 管理、kick 调度与生命周期;算法层 NoiseSuppressLib.h 是厂商提供的噪声抑制库。
驱动层(ans_api.h)
// ANS降噪算法最低系统时钟需要跑96M以上
// 只支持16k 和 8k采样率
//
int ans_check_kick_start(void *priv);
s32 ans_init(cbuffer_t *in_cbuf, cbuffer_t *out_cbuf, void *kick);
s32 ans_deinit(void);
Source: ans_api.h
- 头文件注释是硬性约束:系统主频必须 ≥96MHz,采样率仅支持 8k/16k。这是算法实时性(每帧处理需在采样间隔内完成)与算法设计(窄带/宽带模型)共同决定的。
ans_init(in_cbuf, out_cbuf, kick):绑定输入/输出环形缓冲,kick是驱动信号(可指向解码器的 kick 标志,对应上文B_DEC_KICK)。ans_check_kick_start(priv):查询是否该启动一帧处理(由缓冲水位/中断触发)。ans_deinit():释放资源,无返回值。
降噪采用 kick 驱动(拉模型):数据先进入 in_cbuf,当 kick 条件满足时算法从输入缓冲取一帧、处理、写入 out_cbuf,再由 DAC 消费。与变声模块的**回调驱动(推模型)**互补——前者适合与录音/通话中断同步的路径,后者适合解码播放路径。
算法层(NoiseSuppressLib.h)
#define NOISESP_CONFIG_FREEZE 0
#define NOISESP_CONFIG_NOISEFLOOR 1
#define NOISESP_CONFIG_LOWCUTTHR 2
int NoiseSuppress_GetMiniFrame(int is_wideband);
int NoiseSuppress_QueryProcessDelay(int mode, int is_wideband);
int NoiseSuppress_QueryBufSize(int mode, int is_wideband);
int NoiseSuppress_QueryTempBufSize(int mode, int is_wideband);
void NoiseSuppress_Init(void *NoiseSpRunBuffer,
int AggressFactor, // Q16
...
Source: NoiseSuppressLib.h
- 配置项为整数索引:
NOISESP_CONFIG_FREEZE(冻结噪声估计)、NOISESP_CONFIG_NOISEFLOOR(噪声底限,防止过度抑制导致音乐感损失)、NOISESP_CONFIG_LOWCUTTHR(低频切除阈值,抑制隆隆声/风噪)。 Query*系列在 init 前查询:最小帧长、处理延迟、运行缓冲与临时缓冲大小——与变声的need_buf()同为"先查询、再分配、后初始化"的嵌入式内存契约。NoiseSuppress_Init的AggressFactor以 Q16 定点数表示抑制强度,值越大抑制越激进但语音损伤风险越高,需按产品场景(通话 vs 录音)权衡。
Core Flow:变声链路与降噪链路的运行流程
两条链路的驱动模型不同,下面分别用时序图说明。
变声(推模型):解码 → 变声 → DAC
sequenceDiagram
participant Dec as 解码器 Decoder
participant EObj as EFFECT_OBJ
participant PS as Howling PitchShifter
participant DAC as DAC/CBuf
Dec->>Dec: 设置 B_DEC_EFFECT | B_DEC_ENABLE
Dec->>EObj: run(hld, inbuf, len)
EObj->>EObj: 检查 sound.enable 标志
EObj->>PS: run(ptr, inbuf, len) 字节长度
PS->>PS: 内部 PS/FS 算法处理<br/>(延迟 1.5~12ms)
PS->>DAC: output(priv, data, len)
DAC-->>EObj: 返回写入结果
EObj-->>Dec: 返回处理状态
要点:解码器每解码出一帧就调用 EFFECT_OBJ.run;run 内部先检查 sound_out_obj.enable(volatile 标志),只有 B_DEC_EFFECT 置位才把数据送入变声模块,否则直通。变声模块处理完通过 HOWL_PS_IO_CONTEXT.output 写回 DAC。运行中若需调整音调/共振峰,应用线程调用 update_howling_parm_fs_api() 或重新 open(),下一帧即生效——这是"中途改参可调 init"的设计红利。
降噪(拉模型):录音 → 环形缓冲 → ANS → 消费
sequenceDiagram
participant Rec as 录音源 (8k/16k)
participant In as in_cbuf
participant ANS as ans_api 驱动
participant NS as NoiseSuppressLib
participant Out as out_cbuf
participant DAC as 下游消费
Rec->>In: 写入 PCM
ANS->>ANS: ans_check_kick_start(priv)
ANS->>NS: 取一帧处理<br/>(AggressFactor 等配置)
NS-->>Out: 抑制后 PCM
ANS->>Out: 写入输出缓冲
Out->>DAC: 消费/播放
要点:与变声不同,降噪不依赖解码器的逐帧回调,而是由 kick 信号(如中断/缓冲水位)触发。ans_check_kick_start() 决定"现在是否够一帧",从而把算法负载与采样节奏解耦,避免在中断里做重计算。NoiseSuppress_QueryProcessDelay 查询出的延迟是固定的(帧长+算法内部延迟),上层可用它做 AEC/同步补偿。
使用示例(源自 SDK 头文件契约)
示例 1:变声模块的标准接入范式
HOWLING_PITCHSHIFT_FUNC_API *api = get_howling_ps_func_api();
u32 buf_size = api->need_buf(EFFECT_HOWLING_PS); // 1. 查询工作内存
void *work = malloc(buf_size); // 2. 分配
HOWLING_PITCHSHIFT_PARM parm = { .ps_parm = 0, .fs_parm = 0, .effect_v = EFFECT_HOWLING_PS };
HOWL_PS_IO_CONTEXT io = { .priv = dac_ctx, .output = sound_output };
api->open(work, sr, &parm, &io); // 3. 初始化(中途改参可重调)
// 每帧调用:
api->run(work, pcm_in, len); // 4. 处理,len 单位:字节
Source: howling_pitchshifter_api.h
该示例忠实反映 SDK 契约:任何音效模块必须支持"查询内存 → 分配 → open → run"四步生命周期;run 的 len 是字节数,调用方需按 采样点数 × 2(16bit PCM)换算。
示例 2:降噪模块的查询-初始化流程
int is_wideband = (sr == 16000) ? 1 : 0; // 仅 8k/16k
int frame = NoiseSuppress_GetMiniFrame(is_wideband);
int delay = NoiseSuppress_QueryProcessDelay(mode, is_wideband);
int size = NoiseSuppress_QueryBufSize(mode, is_wideband);
int temp = NoiseSuppress_QueryTempBufSize(mode, is_wideband);
void *run_buf = malloc(size + temp);
NoiseSuppress_Init(run_buf, 0x10000 /* Q16: 1.0 强度 */, /* 其余参数 */);
// 链路侧:
ans_init(in_cbuf, out_cbuf, kick); // 绑定缓冲与 kick
Source: NoiseSuppressLib.h
先 Query* 后 Init 的顺序是强制的:算法不会在 init 内部隐式分配内存,所有缓冲必须由调用方按查询结果提供,这是 MCU 平台"零隐藏 malloc"的工程约定。
Configuration Options
| 配置项 | 位置/类型 | 默认/典型值 | 说明 |
|---|---|---|---|
B_DEC_EFFECT (BIT(2)) | 解码器标志位,写入 sound_out_obj.enable | 0(关) | 音效总开关,置位后 EFFECT_OBJ.run 才把数据送入 effect 槽位 |
B_DEC_ENABLE (BIT(0)|BIT(1)) | 解码器标志位 | 开 | 解码运行+输出缓冲就绪的组合使能态 |
B_DEC_KICK (BIT(8)) | 解码器标志位 | 0 | kick 信号,可与 ANS 降噪驱动联动 |
ps_parm | HOWLING_PITCHSHIFT_PARM (s16) | 0 | 音调参数,正值升调、负值降调;运行中可改(重调 open) |
fs_parm | HOWLING_PITCHSHIFT_PARM (s16) | 0 | 共振峰参数,独立于音调控制音色(如小黄人/大叔音) |
effect_v | HOWLING_PITCHSHIFT_PARM (u32) | EFFECT_HOWLING_PS | 模式选择:0x01=音调搬移,0x02=共振峰搬移 |
NOISESP_CONFIG_FREEZE | NoiseSuppressLib 配置索引 0 | 0 | 冻结噪声估计(环境突变时手动冻结底噪学习) |
NOISESP_CONFIG_NOISEFLOOR | NoiseSuppressLib 配置索引 1 | 视场景 | 噪声底限,防止过度抑制造成语音断续/音乐感损失 |
NOISESP_CONFIG_LOWCUTTHR | NoiseSuppressLib 配置索引 2 | 视场景 | 低频切除阈值,抑制风噪与隆隆声 |
AggressFactor | NoiseSuppress_Init 参数 (Q16) | 0x10000 (1.0) | 抑制强度,Q16 定点数;越大抑制越强、语音损伤风险越高 |
| ANS 采样率/主频约束 | 系统级 | 8k/16k;≥96MHz | 违反则算法实时性无法保证(头文件注释明确) |
API Reference
int sound_output(void *priv, void *data, int len)
统一输出口,所有 effect 的 output 回调最终落地于此(或等价 DAC 写接口)。
- 参数:
priv输出上下文;dataPCM 数据指针;len字节长度。 - 返回:写入结果(0 或字节数,取决于实现)。
Source: sound_effect_api.h
HOWLING_PITCHSHIFT_FUNC_API *get_howling_ps_func_api(void)
获取变声算法函数指针表实例(need_buf/open/run)。
- 返回:
HOWLING_PITCHSHIFT_FUNC_API*,含三个函数指针。
Source: howling_pitchshifter_api.h
void *link_pitchshift_howling_sound(void *p_sound_out, void *p_dac_cbuf, void **pp_effect, u32 sr)
把变声模块链接到 sound-out 链路上。
- 参数:
p_sound_out上游 sound-out 对象;p_dac_cbufDAC 环形缓冲;pp_effect回传 effect 对象指针;sr采样率。 - 返回:链接后的对象指针(NULL 表示失败)。
Source: howling_pitchshifter_api.h
void update_howling_parm_fs_api(u32 sr, s16 new_fs)
运行期单独更新共振峰参数(无需重建链路)。
- 参数:
sr当前采样率;new_fs新的共振峰参数。
Source: howling_pitchshifter_api.h
s32 ans_init(cbuffer_t *in_cbuf, cbuffer_t *out_cbuf, void *kick)
初始化 ANS 降噪并绑定环形缓冲。
- 参数:
in_cbuf输入缓冲;out_cbuf输出缓冲;kick驱动信号指针。 - 返回:
s32,0 成功,负值失败。 - Throws/约束:主频 <96MHz 或采样率非 8k/16k 时行为未定义(头文件注释)。
Source: ans_api.h
int ans_check_kick_start(void *priv)
查询是否满足启动一帧降噪处理的条件。
- 参数:
priv初始化时传入的上下文。 - 返回:非 0 表示可以启动一帧处理。
Source: ans_api.h
s32 ans_deinit(void)
释放 ANS 资源。
- 返回:
s32状态码。
Source: ans_api.h
故障模式、边界情况与并发
故障模式
| 故障 | 触发条件 | 后果/处理 |
|---|---|---|
| 工作内存不足 | need_buf() 返回值未正确用于分配 | 算法写越界,破坏相邻内存;必须严格按 Query*/need_buf 结果分配 |
| 主频不足 | 系统时钟 <96MHz 运行 ANS | 实时性无法保证,产生爆音/卡顿;头文件注释明示该约束 |
| 采样率不支持 | ANS 输入非 8k/16k | 行为未定义,需在 ans_init 前用 NoiseSuppress_GetMiniFrame(is_wideband) 校验 |
| 参数越界 | ps_parm/fs_parm 超范围 | 变声失真或延迟超预期(1.5–12ms 范围外);建议限定在产品可用区间 |
| 过度抑制 | AggressFactor 过大 + NOISESP_CONFIG_NOISEFLOOR 未设置 | 语音断续、音乐感丢失;用 noise floor 兜底 |
| 缓冲水位错位 | run 的 len 按采样点而非字节传入 | 处理帧长错误,产生咔哒声;SDK 统一约定 len 为字节数 |
边界情况与并发
- volatile 共享状态:
sound_out_obj.enable是volatile u32,解码器 ISR 与应用线程并发读写。置位/清位应使用原子位操作(BIT()掩码 + 读改写),且避免在中断中执行run全流程(只置标志,主循环消费)。 - 运行中热改参:变声支持中途改参(重新
open或update_howling_parm_fs_api),但改参瞬间会清空算法内部状态(延迟线/历史帧),可能产生一帧瞬态噪声。对延迟线敏感的混响/回声模块同理,建议在静音间隙改参。 - 推/拉模型并存:变声(推)由解码器节拍驱动,降噪(拉)由 kick 驱动。若两者在同一链路串联(如"录音降噪 → 变声 → 播放"),必须用 cbuffer 做速率解耦,否则推拉节拍失配会导致数据丢失或重复。
- kick 信号复用:
B_DEC_KICK与ans_check_kick_start的 kick 可共享,但需注意 kick 是"边沿敏感"还是"电平敏感"——ans_check_kick_start的查询语义暗示驱动方应负责去抖/清零。
性能与运维注意事项
- 内存契约:所有算法模块(变声、降噪)遵循"先查询后分配、零隐藏 malloc"约定。工作区 + 临时区(
QueryBufSize+QueryTempBufSize)应一次性分配,避免碎片。 - 延迟预算:变声算法延迟 1.5–12ms(随参数),降噪延迟可用
NoiseSuppress_QueryProcessDelay查询。做"实时耳返"或"通话+播放"场景时,需在系统级把该延迟计入总链路预算。 - 定点数约定:
AggressFactor为 Q16(1.0 = 0x10000),配置时注意定标,避免浮点转定点溢出。 - 采样率一致性:变声
open的sr、update_howling_parm_fs_api的sr必须与链路实际采样率一致;采样率切换(如 44.1k→16k 重采样)后必须重新open,否则音高偏移。
扩展点
SDK 为音效扩展预留了清晰的接入点:
- 新效果模块:实现
need_buf / open / run三函数并注册到函数指针表(参照get_howling_ps_func_api模式),即可挂入sound_out_obj.effect槽位。 - 标志位扩展:
sound_effect_api.h中注释掉的B_DEC_PAUSE/B_LOUDSPEAKER/B_HALFWAY_EFFECT(BIT(9)/BIT(10) 附近)是预留位,新开关应复用这些位而非扩张结构体。 - 链路排序:
link_pitchshift_howling_sound(p_sound_out, p_dac_cbuf, ...)的链接顺序决定效果串联次序(变声→回声 或 回声→变声),可在不改算法的前提下通过链接顺序实现不同的声音风格。 - 降噪配置:
NOISESP_CONFIG_*索引式配置接口支持运行时调整 freeze/noisefloor/lowcut 三个旋钮,适合做"场景模式"(安静/嘈杂/风噪)切换。
相关文件与链接
- sound_effect_api.h — 音效框架与解码器标志
- howling_pitchshifter_api.h — 变速变调/变声引擎
- echo_api.h — 回声/混响封装
- ans_api.h — ANS 降噪驱动层
- NoiseSuppressLib.h — 噪声抑制算法库
- 周边引用:
sdk/include_lib/audio/energe_api.h(包含 sound_effect_api.h)、sdk/include_lib/audio/howling_api.h(组合 pitch shifter 与 notch 啸叫抑制)、sdk/include_lib/audio/dac.h(DAC 输出侧)
说明:本页聚焦音效/变速变调/降噪的接口契约与数据流。解码器状态机、DAC 硬件驱动、录音 AEC 等相邻能力请查阅对应目录页。