Audio-Triangulation 用三麦克风做低成本声学相机
原始项目仓库:https://github.com/Sam-Belliveau/Audio-Triangulation
Audio-Triangulation 是一个基于 Raspberry Pi Pico 的声音定位项目。项目介绍页把它称为 20 美元级声学相机:三个麦克风监听声音,Pico 在片上计算声音到达时间差,再把声源可能位置画成 VGA 热图。

这篇项目最值得学习的地方,是它把“声音从哪里来”这个问题拆成了三个层次:先用 TDOA 得到距离差,再用互相关估计时间差,最后用网格评分避开难解的非线性方程。
被动声源定位拿不到绝对距离
声音定位容易让人先想到“画几个圆相交”。如果知道声音从什么时候发出,就可以用到达时间乘以声速,得到声源到每个麦克风的绝对距离。二维里是圆,三维里是球面,几个圆或球面的交点就是声源位置。
被动监听场景没有这个条件。人说话、物体敲击、环境里突然响了一声,系统通常不知道发声时刻。麦克风只能比较同一段声音先到谁、后到谁。
这时能得到的是相对信息:
- 声音到 A 和 B 的时间差。
- 时间差乘以声速得到距离差。
- 距离差只能说明声源到两个麦克风的距离相差多少。
距离差不能直接变成两个确定半径的圆。假设声源到 A 的距离是 10cm,B 的距离可能是 15cm;假设 A 是 50cm,B 就可能是 55cm。距离差相同,绝对距离可以有很多组。
所以被动声音定位不能按“已知半径的圆相交”来理解。它的核心约束是“到两个麦克风的距离差固定”。
TDOA 对应的是双曲线
平面上到两个定点距离差固定的点,会形成双曲线。两个麦克风就是双曲线的两个焦点。声音到达 A、B 的时间差越大,说明声源越偏向其中一侧;时间差接近 0,说明声源大致在两者的垂直平分线附近。
三个麦克风可以形成三对约束:
- A-B 约束一条双曲线。
- A-C 约束一条双曲线。
- B-C 约束一条双曲线。
理想情况下,三组双曲线共同指向同一个声源位置。Audio-Triangulation 的数学核心就是这个:它使用 TDOA,把未知发声时刻的问题转化为相对时间差问题。
另一个现实限制是:时间差是离散采样得到的。项目采样率为 50kHz,一个采样点是 20 微秒。声速按 343m/s 计算,一个采样点对应约 6.86mm 的传播距离。延迟估计只能落在整数采样点上,因此声源位置也会被量化成有限的可区分区域。
远处声源会让双曲线变密
麦克风阵列越小,远处声源越难定位。原因是远处声源移动一小段距离时,到三个麦克风的距离差变化很小,几组双曲线会挤在一起。
这张图的价值在于提醒:定位精度同时受算法、采样率、麦克风间距、声源距离和空间几何限制。
提升分辨率有两条常见路径:
- 提高采样率,让时间差量化更细。
- 增大麦克风间距,让同一方向变化产生更大的时间差。
两条路都有代价。提高采样率会增加数据处理压力;增大间距会让设备变大,也会放大布线、同步和环境误差。这个项目选择 50kHz 和三麦克风面包板阵列,是一个低成本实时演示的平衡点。
互相关从波形里找时间差
有了 TDOA 思路,还需要从三路麦克风波形里估计“到底差了几个采样点”。Audio-Triangulation 用互相关完成这一步。
互相关的直觉是滑动对齐。拿 A、B 两段波形,把 B 向前或向后移动若干采样点,每移动一次就逐点相乘并求和。某个偏移下得分最高,说明两段波形在这个偏移下最相似,这个偏移就是时间差估计。
项目源码会遍历 -MAX_SHIFT_SAMPLES 到 +MAX_SHIFT_SAMPLES 的整数偏移,分别计算 A-B、A-C、B-C 三对互相关。每一对都会得到一条“偏移量到相似度”的曲线,而不仅仅是一个延迟数字。
这很重要,因为后面的热图评分会直接使用整条互相关曲线。某个候选位置预测出的延迟,如果刚好落在互相关峰值附近,它的得分就高。
为什么没有用 FFT
介绍页提到他们考虑过 FFT 相关方法。理论上,卷积和相关可以通过频域乘法加速,复杂度从平方级降到 N log N。
但这个项目的缓冲区规模是 1024 点,实际收益不明显。更麻烦的是,FFT 方法会把滤波相位、三路采样时序和频域处理细节引进来,调试难度上升。
最终项目选择直接在时域做互相关。这个选择看起来朴素,但适合 RP2040:整数累加容易实现,计算范围受物理最大延迟限制,结果也更容易和波形显示对应起来。
位置求解反过来做
理论上可以写出双曲线方程组,然后求交点。但实际系统里会遇到几个麻烦:
- 双曲线有两支,可能出现多个候选位置。
- 测量误差会让几条曲线无法精确相交。
- 牛顿法一类解析求解依赖初值,可能不收敛。
- 嵌入式系统需要可预测的运行时间。
Audio-Triangulation 的做法很工程化:避开直接求交点,反过来枚举候选位置。
初始化 VGA 热图时,它会遍历显示区域里的每个点。对每个候选点,先计算它到三个麦克风的距离,再换算成 A-B、A-C、B-C 应该出现的样本延迟,并把这些延迟索引存起来。
实时显示时,它拿当前互相关结果给每个候选点打分:
候选点得分 = A-B 在理论延迟处的互相关值 + A-C 在理论延迟处的互相关值 + B-C 在理论延迟处的互相关值
+2
-1
-3
91
84
88
分数越高,说明这个点预测出的三组延迟越接近当前波形测到的延迟。热图显示的就是这个匹配度。

这个设计的好处是稳定。每个网格点独立评分,计算量由网格大小决定,不需要初值,不存在收敛失败。代价是分辨率受网格大小限制,但对实时热图来说,这个取舍很合理。
硬件链路服务于实时性
硬件部分使用三个 MAX4466 麦克风,摆在面包板上形成三角阵列。每路麦克风输出经过二阶 20kHz 低通滤波,再接到 Pico 的 ADC 0、1、2 通道。
采样侧使用 ADC round-robin 和 DMA。DMA 把三路 8 位样本持续搬到一个小数组里,计算循环按 50kHz 节奏读出,转换成 16 位样本并推入三路滚动缓冲区。
声音事件由能量变化触发。系统维护滚动缓冲区的新旧两段能量,检测到明显声音事件后,再取出完整帧做互相关和热图更新。这能减少安静时的无效计算。
VGA 输出也由 Pico 完成。项目用 PIO 和 DMA 生成 VGA 信号,让同一块 RP2040 同时负责采样、定位和显示。

这篇项目的真正启发
Audio-Triangulation 的精彩点在于它把数学问题压成了适合 MCU 的流程:
- 被动监听拿不到发声时刻,所以使用 TDOA。
- TDOA 产生的是双曲线约束,所以不能套用绝对距离的圆相交。
- 互相关把波形对齐问题变成整数偏移评分。
- 网格评分把双曲线求交变成候选点查表。
- 预计算让实时阶段只做数组取值、加法和颜色映射。
这个项目也很适合提醒自己:信号处理要同时看公式、采样、阵列和环境。采样率决定时间分辨率,阵列尺寸决定空间分辨率,环境噪声和混响决定互相关峰值是否可靠。算法、硬件和可视化必须一起设计。
边界和扩展
当前实现主要把声源映射到一个预设平面。声源高度变化较大时,二维热图会把三维位置投影到该平面,结果会带系统偏差。
如果要做完整三维定位,可以增加搜索维度,或者使用非共面的麦克风阵列。网格评分方法本身可以扩展,但内存、刷新率、显示方式和标定难度都会上升。
实际工程还需要处理麦克风增益差异、几何尺寸误差、混响、多声源和环境噪声。VGA 热图表达的是候选位置匹配度,不能直接当成带置信区间的精确坐标。
结论
Audio-Triangulation 把 TDOA 声源定位做成了一个完整的嵌入式演示。三路麦克风提供相对时间差,互相关从波形里估计延迟,网格评分把延迟变成位置热图,VGA 让整个过程可以直接观察。
它的核心是一组非常清楚的工程转化:绝对距离不可得,就用距离差;双曲线难求解,就用网格评分;实时算力有限,就把候选点延迟提前算好。
本文由 AI 辅助生成,可能存在错误或遗漏,请以实际资料和官方文档为准。