说明¶
卷积 — 信号处理的基础运算
核翻转后滑过信号,逐位置乘加。FIR 滤波的本质就是卷积。
算法原理¶
完整卷积¶
\[ y[n] = \sum_{k=0}^{M-1} h[k] \cdot x[n - k], \quad n = 0, \dots, L+M-2 \]
\(L\) = 信号长,\(M\) = 核长。输出长度因模式而异。
输出模式¶
| 模式 | 输出长度 | 说明 |
|---|---|---|
CONV_FULL | \(L + M - 1\) | 完整卷积,含瞬态 |
CONV_CENTER | \(L\) | 取中间,与输入等长 |
CONV_HEAD | \(L\) | 取前 \(L\) 点(实时) |
CONV_TAIL | \(L\) | 取后 \(L\) 点(尾随瞬态) |
边界填充¶
| 模式 | 行为 | 场景 |
|---|---|---|
PAD_ZERO | 信号外补零 | 默认 |
PAD_SYMMETRIC | 对称延拓 | DWT、减少边界伪影 |
PAD_PERIODIC | 周期延拓 | 周期信号 |
卷积 vs 相关
卷积翻转核,相关不翻转。正是这个翻转使卷积实现 FIR 滤波的系统响应,而相关衡量的是相似度。
FFT 加速
直接卷积 \(O(LM)\)。长信号可用 FFT 加速到 \(O(N \log N)\):\(\text{conv}(x, h) = \text{IFFT}(\text{FFT}(x) \cdot \text{FFT}(h))\)。
API 参考¶
// 基础卷积(默认完整模式 + 零填充)
tiny_error_t tiny_conv_f32(const float *Signal, int siglen,
const float *Kernel, int kernlen,
float *convout);
// 扩展卷积(可选填充/输出模式)
tiny_error_t tiny_conv_ex_f32(const float *Signal, int siglen,
const float *Kernel, int kernlen,
float *convout,
tiny_padding_mode_t padding_mode,
tiny_conv_mode_t conv_mode);
注意事项¶
输出缓冲区大小
完整模式至少 \(L+M-1\),否则溢出。
ESP32 上信号/核长度顺序影响性能
内部实现假设 Signal 较长、Kernel 较短。若反了仍然正确但性能下降。