LeventureTecTips

Welcome to Leventure’s Tech Blog.

[旧日谈] 再考 IIR 与 FIR 滤波器对相位影响的定量分析

IIR 与 FIR 濾波器对音频相位的影响 先前我有写过一个简单的文章分析过两种滤波器对音频相位的影响,但是我只是知其然不知其所以然。对于音频,我虽然知道相位是一个很重要的概念,但是我始终不知道相位对实际音频的印象是什么水平的。这个问题在这些年的开发过程中始终萦绕在心头。虽然不做音频了,但是我仍然对这个问题保持好奇,综上,这也是为什么有了这个文章。 一、从一个问题开始 假设我们有一个 1kHz 的正弦信号,经过一个低通滤波器之后,输出还是 1kHz 的正弦信号,幅度变小了——这很好理解,滤波器嘛,该衰减的衰减。 但仔细看输出波形,会发现它相对于输入信号产生了一个时间上的延迟。这个延迟不是简单的"整体往后挪了 N 个采样点",而是不同频率的信号延迟不一样。 1kHz 的信号延迟了 0.5ms,500Hz 的信号延迟了 0.8ms,2kHz 的信号延迟了 0.3ms——每个频率成分的延迟都不一样。 这就是相位失真。 对于音频处理来说,这个问题比听起来严重得多。人耳对相位差的感知不如幅度那么直接,但当不同频率成分的延迟差异大到一定程度时,会导致: 瞬态信号(比如鼓点、齿音)的波形被"模糊化" 立体声声像偏移 某些频段的"堆叠"或"空洞" 所以,理解滤波器的相位特性,是做音频处理的基本功。 先说结论,IIR 的相位响应受幅度响应约束(最小相位特性),无法独立控制;FIR 可以独立控制幅度和相位,因此能实现线性相位或任意指定相位。 但是至于为什么音频行业常用IIR滤波器,这个问题我将在补充后说明。 二、先回顾一下:FIR 和 IIR 是什么 FIR(有限脉冲响应) FIR 滤波器的差分方程: $$ y[n] = \sum_{k=0}^{M} b_k \, x[n-k] $$输出只依赖于当前和过去的输入,没有反馈。脉冲响应是有限长的(长度 M+1)。 IIR(无限脉冲响应) IIR 滤波器的差分方程: $$ y[n] = \sum_{k=0}^{M} b_k \, x[n-k] - \sum_{k=1}^{N} a_k \, y[n-k] $$输出同时依赖于输入和过去的输出(反馈)。脉冲响应理论上是无限长的。 两者的核心区别在于有没有反馈。这个结构上的差异,直接决定了它们的相位特性。 三、相位响应的推导 从频率响应说起 一个 LTI(线性时不变)系统的频率响应可以写成: ...

June 18, 2026 · 17 min · Leventure

3D 曲面力场重建架构与点云显示算法研究

3D 曲面力场重建与点云显示算法研究 背景 三维曲面力场重建要解决的,是如何根据少量离散传感器的空间位置、表面方向和测量值,估计模型表面上没有传感器位置的力值,并把结果显示成连续、稳定且符合物体形状的分布。 这件事看起来像普通插值,实际包含两个性质不同的问题。第一个问题是力值应该传播到哪里。它由距离定义、曲面连通关系和传感器朝向决定。第二个问题是重建结果应该怎样显示。它由表面采样密度、颜色映射和几何位移决定。早期方案多次调整,根本原因就是把传播算法和显示载体混在一起:传播关系不正确时,仅改变颜色无法消除串色;传播关系正确时,直接在粗三角面上着色又可能产生大片色块。 最终采用的思路是先把三角模型整理成可传播的曲面图,再把每个传感器附着到模型表面,沿曲面执行有限半径的最短路径搜索,用 Wendland C² 核计算距离权重。多个传感器按连续场采样点进行归一化插值,再通过 coverage 控制支撑区域边缘的衰减。显示层不再改变模型本身,而是在灰色模型表面覆盖彩色点云,用颜色和沿法线的隆起共同表达力值。 图 Fig001:力场算法的主要演进。距离定义、边缘衰减和显示载体分别经历调整,最终形成曲面传播与点云显示的组合。 本文以左手手套三维模型作为演示对象,使用确定性的 Wave 合成力值观察动态效果。由于没有与该模型对应的真实加载实验数据,文中的结果只能说明算法行为和显示效果,不能被解释为真实设备精度验证。 从欧氏插值到曲面传播 最直接的重建方法,是计算传感器与模型顶点之间的三维直线距离,然后让距离近的传感器具有更大权重。这种方法实现简单,在平面或结构单一的缓曲面上也可能得到合理结果,但它隐含了一个不适用于复杂模型的假设:空间上接近的位置,也可以沿物体表面直接传播。 手套模型能清楚暴露这个问题。两根手指之间的空气间隙很小,手掌正反面之间也可能只有很薄的模型厚度。欧氏距离会把这些位置视为近邻,使一个传感器的影响直接到达另一根手指或模型背面。折角附近也有同样的问题。两个点的直线距离可能很短,但真实的表面路径需要绕过较长距离,甚至根本不存在连续路径。 早期的视觉修正曾把低值区域改成灰色,重新定义平滑显示与离散点显示的切换,并调整颜色过渡。这些改动提高了画面可读性,却没有改变传播距离,因此不能从根本上修复薄壁、折角和相邻部件之间的串色。 像素化重建是另一条尝试路线。它先把模型投影到高分辨率平面,在规则像素网格上插值和后处理。规则像素能够减轻原始三角面大小不均造成的色块,Gaussian 平滑也能让边缘更柔和,但单一投影难以表达任意方向、多层和自遮挡曲面。模型前后两层还可能落到相同像素位置。高分辨率重建带来的计算量也比较大。因此,这条路线适合作为视觉实验,却不适合作为一般三维模型的传播基础。 曲面传播的核心变化,是把"距离"从三维空间中的直线长度,改成模型表面的路径长度。模型顶点作为图节点,共享三角形边作为图边,边权是相邻顶点之间的几何长度。传感器先找到附近且朝向兼容的表面点,再从该点沿曲面图执行截断 Dijkstra。一个位置只有在曲面上存在合法路径,并且路径总长不超过传播半径时,才会受到该传感器影响。 这并不意味着算法完全不再使用欧氏距离。传感器的导出位置可能略微离开模型表面,因此仍要用直线距离找到附近表面作为附着点。区别在于,这个距离只用于完成传感器到表面的初始附着。附着之后的扩散范围由曲面路径决定,不能继续穿过模型内部走捷径。 曲面如何变成可计算的传播域 三角网格不能直接拿来做曲面搜索。STL 模型通常以彼此独立的三角形保存,同一个几何点可能在相邻三角形中重复出现。如果不先合并这些重复顶点,算法看到的会是大量互不连接的小三角形,最短路径也无法跨越三角形边界。 因此,曲面准备的第一步是顶点焊接。算法按照一个较小的位置容差,将坐标相同或足够接近的顶点合并为共享顶点,同时删除顶点重复或面积接近零的退化三角形。焊接容差需要与模型单位和导出精度匹配。容差过小会留下不应存在的裂缝,容差过大则可能把距离很近但实际分离的两层表面错误连接起来。 焊接之后可以根据三角形共享边建立邻接图。图边的长度取两个顶点之间的几何距离。为了避免传播穿过尖锐折角,还要比较相邻顶点法线。设相邻顶点为 $u$ 和 $v$,只有满足 $$ \mathbf{n}_u\cdot\mathbf{n}_v\ge\tau_e $$时,二者之间的边才允许参与传播。本文采用的邻接法线阈值为 $\tau_e=0.25$。这是一种硬门控:达到阈值的边可以通过,低于阈值的边完全禁止通过。它的优点是折角隔离清楚,缺点是高曲率但连续的表面也可能被切断。更平滑的替代方案是根据夹角增加路径代价,但这会引入新的衰减参数,必须通过真实数据才能判断是否更合理。 网格密度同样会影响曲面距离和点云连续性。如果最大三角形边长远大于传播半径,支撑区域内可能只有少量顶点,最短路径会变得粗糙,显示点也会过于稀疏。可以把目标边长定义为 $$ E_{target}=\max\left(\frac{R}{4},1\text{ mm}\right) $$当最大边长明显超过目标边长时,将一个三角形沿三条边的中点拆成四个子三角形。共享边的中点必须复用,避免细分后重新产生裂缝。细分还要设置顶点数上限,否则高面数模型可能快速膨胀。 细分后需要重新计算顶点法线。顶点法线既控制传播能否经过某条边,也决定点云隆起方向,因此不能把它当成单纯的光照数据。通常将相邻三角形的面积加权法线累加到顶点,再进行归一化。无条件执行 Laplacian 平滑并不稳妥,因为平滑会收缩几何并改变传感器到表面的物理距离。视觉上更圆润不代表几何关系更准确。 传感器附着也使用法线约束。设曲面点法线为 $\mathbf{n}_v$,传感器法线为 $\mathbf{n}_i$,只有满足 $$ \mathbf{n}_v\cdot\mathbf{n}_i\ge\tau_c $$的顶点才参与附着点选择。本文采用 $\tau_c=0.1$。在所有兼容顶点中选择与传感器中心最近的点作为种子。如果传感器到种子的初始距离已经大于传播半径,该传感器不产生曲面影响。 从种子开始执行 Dijkstra 搜索,路径距离由曲面边长累计: $$ d_i(v)=\min_{\pi:i\rightarrow v}\sum_{(u,w)\in\pi}\|\mathbf{x}_u-\mathbf{x}_w\| $$路径只能经过法线兼容的邻接边,并在距离超过半径 $R$ 时停止。这样得到的 $d_i(v)$ 是离散网格上的测地距离近似。它不完美依赖模型质量,但比直接使用穿过空间的直线距离更符合复杂表面的传播关系。 图 Fig004:传感器附着、曲面路径和紧支撑权重。欧氏距离只用于选择附近表面,实际传播距离由曲面路径决定。 离散测量如何形成连续场 得到曲面距离之后,仍然需要决定距离如何转化为权重。本文采用 Wendland C² 紧支撑核。对曲面距离 $d$ 和传播半径 $R$,令 $r=d/R$,权重定义为 ...

July 28, 2026 · 2 min · Leventure

频域维纳滤波降噪算法——设计思路与工程手记

频域维纳滤波降噪算法——设计思路与工程手记 写在前头 这份笔记记录的是一个面向实时语音通信的频域降噪算法。它的设计目标很明确:在 48kHz 采样率下,以 10ms 帧长实时处理单通道语音,把稳态和准稳态背景噪声压下去,同时尽量不伤语音。算法脱胎于 WebRTC 的 Noise Suppression 模块,但经过了面向嵌入式的重构——所有动态分配被消除,所有 C++ 模板和虚函数被拍平成纯 C 结构体。 我按照信号流经的顺序来谈。先说为什么要这么做,再说具体怎么做。 1. 信号模型 一切降噪算法的出发点都是同一个假设:麦克风采集到的信号 $x(n)$ 是干净语音 $s(n)$ 和加性噪声 $d(n)$ 的叠加: $$ x(n) = s(n) + d(n) $$这个模型简单到近乎天真,但它成立的前提条件其实很苛刻:噪声和语音不相关,噪声在短时间尺度上是准平稳的。实际工程中,空调嗡嗡声、风扇声、马路上的低频轰鸣,在几十毫秒内确实变化不大——这就够了。 我们的目标是从 $x(n)$ 中恢复 $\hat{s}(n)$。在频域里,这意味着对每个频率 bin 施加一个增益 $G(k)$: $$ \hat{S}(k) = G(k) \cdot X(k) $$问题归结为:怎么求这个 $G(k)$? 2. 为什么选频域 时域降噪(比如 LMS 自适应滤波)需要参考信号,这在单麦克风场景下不现实。频域方法的好处是: 频率分辨率。噪声和语音在不同频段的能量分布差异很大。白噪声全频段平坦,语音能量集中在 300Hz–4kHz。频域处理可以逐 bin 调节衰减深度。 短时平稳假设更容易满足。一帧 10ms 内,噪声功率谱几乎不变,这给估计器提供了稳定的观测窗口。 计算量可控。256 点 FFT 在嵌入式平台上是成熟操作,远比时域长 FIR 滤波器经济。 代价是引入了帧延迟和频谱泄漏,这些后面会谈。 3. 总体处理流程 一帧 480 个采样点(48kHz × 10ms)进来后,经过以下环节: ...

July 28, 2026 · 6 min · Leventure

琴谱 - Duvet

Duvet ← Previous Page 0 / 0 Next → 下载 PDF 正在加载 PDF 预览...

July 19, 2026 · 1 min · Leventure

琴谱 - 蓬莱伝説 (Forest306)

蓬莱伝説 Forest306 编曲。 ← Previous Page 0 / 0 Next → 下载 PDF 正在加载 PDF 预览...

July 19, 2026 · 1 min · Leventure

线性代数不难

线性代数不难 《线性代数不难》是生姜 DrGinger 编写的线性代数入门读物。本页面收录带书签的 PDF 版本,方便在线阅读与章节跳转。 ← Previous Page 0 / 0 Next → 下载 PDF 正在加载 PDF 预览...

July 16, 2026 · 1 min · Leventure

散点到 3D 曲面:力场重建工程算法

散点到 3D 曲面:力场重建工程算法 一、目标与边界 本文说明如何将三角网格表面的离散 Cell 采样值重建为连续、稳定且可实时渲染的 3D 曲面力场,覆盖算法输入、几何预处理、曲面距离、插值、颜色映射、缓存、渲染和验证。 算法解决以下工程问题: STL 三角面重复顶点导致表面拓扑断裂。 三维欧氏距离会穿过薄壁、折角或独立零件传播数值。 离散 Cell 数值需要连续插值,但不能因邻近 Cell 数量增加而产生虚假峰值。 覆盖边缘需要自然回落到模型基底颜色,不能出现硬截断。 几何计算与实时帧更新必须分离,以满足连续数据刷新需求。 算法输入包括三角网格、Cell 位置与法线、当前帧采样值、显示范围和重建参数;输出为与渲染顶点一一对应的颜色数组。 1.1 算法全景流程 二、曲面采样模型 2.1 曲面距离问题 目标曲面具有曲率、折角、正反面和多个独立零件,不能把它视为平面或无拓扑关系的三维点集。 核心问题是:两个点在三维空间里看起来很近,是否意味着它们沿模型表面也很近? 2.2 Cell 语义:离散采样,不是独立力源 Cell 表示连续真实力场的离散采样点。 重建值表达附近采样值的加权平均,不把多个 Cell 的数值简单相加。 若四个相邻 Cell 都是 0.6,中间位置也应接近 0.6,不能仅因为附近有四个点就变成 2.4。 以下 12 个采样点用于说明算法在圆柱曲面上的输入形式: 点 z / mm θ / ° x / mm y / mm 归一化压力 S1 -6 -70 -5.638 37.948 0.18 S2 0 -70 -5.638 37.948 0.32 S3 6 -70 -5.638 37.948 0.46 S4 -6 -25 -2.536 34.562 0.42 S5 0 -25 -2.536 34.562 0.82 S6 6 -25 -2.536 34.562 0.68 S7 -6 25 2.536 34.562 0.55 S8 0 25 2.536 34.562 1.00 S9 6 25 2.536 34.562 0.76 S10 -6 70 5.638 37.948 0.28 S11 0 70 5.638 37.948 0.48 S12 6 70 5.638 37.948 0.36 三、Wendland C2 与归一化插值 3.1 紧支撑核 算法使用 Wendland C2 作为紧支撑权重函数: ...

July 15, 2026 · 3 min · Leventure

Wendland Functions

Wendland Functions Wendland 函数是一类具有紧支集的径向基函数(Compactly Supported Radial Basis Functions),由 Holger Wendland 在其 1995 年的论文 Piecewise Polynomial, Positive Definite and Compactly Supported Radial Functions of Minimal Degree 中提出。 这类函数广泛应用于散乱数据插值(scattered data interpolation)、无网格方法(meshfree methods)等领域,其紧支撑特性使得插值矩阵具有稀疏性,显著降低了大规模问题的计算复杂度。 ← Previous Page 0 / 0 Next → 下载 PDF 正在加载 PDF 预览...

July 7, 2026 · 1 min · Leventure

Wendland 紧支撑核的散点场重建方法

Wendland 紧支撑核的散点场重建方法 Wendland Functions(这篇笔记对 Wendland 核函数的数学构造有更完整的推导) 从散点到连续场 Wendland 并不是“力场重建”专用算法。它更像是一种通用工具:当你手里有一批离散采样点,想把它们变成一个连续场时,Wendland C2 紧支撑核可以作为一个很好的重建核。 问题可以抽象成这样:平面上有一组采样点 $$ (x_i, y_i, v_i), \quad i = 1,2,\dots,N $$其中 $(x_i,y_i)$ 是采样位置,$v_i$ 是这个位置的观测值。我们想得到一个连续函数 $f(x,y)$,让它在没有传感器的位置也能给出合理估计。压力传感器数据只是这个问题的一个例子。换成温度站点、高程采样点、点云属性,甚至仿真里的 collocation points,本质都是“散点样本 → 连续场”。 这里有一个容易混淆的点:这件事到底是“重建”,还是只是“平滑”?我的理解是,平滑更像后期修图,它不关心背后有没有真实函数,只是让数据看起来更顺;重建则先假设背后确实存在一个连续函数,而采样点只是对它的离散观测。对于压力传感器来说,我们认为背后存在一个连续压力分布 $P(x,y)$,传感器只是采到了若干个 $P(x_i,y_i)$,所以目标是从这些离散值恢复连续压力分布的近似,而不只是让图变得柔和。 这也是为什么我更愿意把这个问题叫“散点场重建”。它不是某个物理量专属的问题,而是一类数据重建问题。 为什么会选到 Wendland 从散点构造连续场的方法很多。最朴素的是最近邻:每个位置直接拿最近采样点的值。这很诚实,但画出来会像马赛克。线性插值或三角插值更自然一些,不过它往往需要明确的拓扑结构,边界处理也麻烦。点高斯叠加看起来很直觉:每个采样点盖一个光斑,所有光斑相加。但它有一个致命问题——如果不归一化,采样点密集的地方会天然更亮。亮度来自采样密度,而不是来自真实场值。 KNN-IDW 往前走了一步:找附近 K 个点,按距离倒数加权平均。它已经是“插值”的思路了,但邻居集合会随着像素位置切换,梯度大的地方容易出现细小斑点。局部平面拟合能表达局部趋势,不过不同邻域拟合出的平面一切换,就容易出现片状接缝。全局 RBF 插值理论上更完整,但需要解线性方程组,计算成本会比较高。 所以这个场景真正需要的不是“最花哨”的方法,而是同时满足几个工程约束的方法。第一,它要归一化,否则采样点密度会污染颜色。第二,它要局部计算,否则输出图像一大,每个像素都遍历所有采样点就不现实。第三,它要视觉连续,不能有块状边界、凸包、片状拼缝。Wendland C2 恰好把这几件事放在一起:它是归一化加权平均;它是紧支撑核,超出半径就严格为零;它在支撑边界处 C² 连续,不容易产生拼缝;同时它还是正定 RBF,作为插值或近似核有数学基础。 也就是说,Wendland 不是因为“它专门适合压力场”才被选中,而是因为当前任务具备这些条件:散点采样、需要连续场、采样密度可能不均匀、要求实时、要求视觉上没有明显伪影。 从旧的高斯光斑到 Wendland 核 旧的点高斯方案很容易理解:在每个采样点位置盖一个高斯光斑,然后把所有光斑相加。 $$ \text{field}{[x][y]} = \sum_i \text{value}_i \times \exp\!\left(-\frac{d_i^2}{2\sigma^2}\right) $$这里 $\text{value}_i$ 是第 $i$ 个采样点的值,$d_i$ 是像素到这个采样点的距离,$\sigma$ 控制光斑扩散范围。这个公式最大的问题就在求和符号上。两个采样点靠得近,光斑重叠区域就会叠得更亮。结果是:采样点密度越高的地方越亮,即便真实场值并没有更高。 ...

July 7, 2026 · 2 min · Leventure

GTCRN:一个 23.7K 参数语音降噪网络的设计思路完整解读

GTCRN:一个 23.7K 参数语音降噪网络的设计思路完整解读 作者从零讲起:背景、骨架、模块、训练、部署、设计哲学,一篇看完。 配套材料:GTCRN 论文与公开实现都可以作为辅助阅读材料,但本文尽量按原理本身展开,不依赖具体工程代码跳转。 目录 前言:这篇文章写给谁看 第一章 设计思路与背景:作者到底要解决什么问题? 第二章 整体架构:一张图看懂 GTCRN 是怎么搭起来的 第三章 输入处理与 ERB:怎么把 257 个频点压成 129 个还不丢信息? 第四章 GT-Conv 详解:ShuffleNetV2 + 时间空洞,省到极致的卷积块 第五章 DPGRNN 详解:双路径 + 分组,RNN 的极致瘦身 第六章 SFE 与 TRA:两个"点睛"模块 第七章 输出与损失函数:复数掩码 CRM 和"混合损失"的玄学 第八章 流式推理:从离线训练到逐帧实时 第九章 设计哲学总结:从 GTCRN 学到的可迁移工程思维 前言 如果你和我一样,是一名有信号处理(STFT、滤波器组、感知声学)和经典机器学习基础的工程师,能看懂代码,知道"卷积"、“RNN”、“注意力"大概是什么,但是看到 GTCRN 这样的网络结构图时会想: “作者为什么这么搭?这些模块之间凭什么能拼成一个能降噪的东西?” “23.7K 参数怎么做到打过 RNNoise(60K参数),并且打平甚至超过几百万参数的大模型的?” “如果让我从零设计,我能想到这些 trick 吗?我和作者之间差的是什么?” 那这篇文章可能对你有用。 我不打算把它写成论文复读机,那样毫无价值——论文你自己就能看。我想做的是 还原作者的思考路径:当他坐在工位上想"我要做一个能放在耳机里跑的降噪模型”,他第一步会想什么,第二步又怎么走到 ERB、ShuffleNet、DPRNN 这些组件上,每一个看起来很骚的设计背后到底解决的是什么实际问题。 读完这一系列,你应该能: 理解 GTCRN 每个模块解决的具体问题,而不是只记住名字; 看到一个新的 SE 模型时,能识别其中哪些是骨架、哪些是 trick; 在自己的项目里能做出取舍:什么时候上 attention、什么时候用 grouped conv、什么时候 CRM 不如 mag-mask。 阅读建议: ...

June 30, 2026 · 25 min · Leventure