Hotdry.

Article

Shazam 音频指纹核心算法:从频谱图到哈希匹配的工程实现

深入解析 Shazam 如何通过 FFT 生成频谱图、提取频谱峰值构建星座图、生成 32 位哈希并进行哈希表匹配,揭示音频指纹识别系统的核心技术路径与工程参数。

2026-04-23systems

当我们打开 Shazam 应用,按下识别按钮并将其靠近扬声器时,这看似简单的操作背后实际上经历了一段复杂的信号处理旅程。从原始音频的采集到最终曲目的匹配,整个系统需要在极短时间内完成频谱分析、特征提取、哈希生成和数据库检索等多个关键步骤。理解这一技术路径不仅有助于掌握音频指纹识别领域的核心原理,也能为其他相似场景提供宝贵的工程实践经验。

从时域到频域的转换:FFT 与短时傅里叶变换

音频信号在计算机中最初以振幅随时间变化的波形形式存在,这种表示方式被称为时域。然而,直接对波形进行比较存在显著缺陷:即使对同一首歌曲进行录音,由于环境噪声、录音设备差异、音频压缩等因素的影响,两段录音的波形可能存在较大差异,导致直接匹配失败。因此,Shazam 选择将音频转换到频域进行分析,利用频率成分之间的相对关系来实现鲁棒匹配。

快速傅里叶变换(Fast Fourier Transform,FFT)是实现这一转换的核心数学工具。FFT 能够将复杂的时域信号分解为其组成频率,揭示在任何给定时刻存在哪些音符或音调。然而,音乐并非静态信号,音符和谐波随时间不断变化。为此,Shazam 采用短时傅里叶变换(Short-Time Fourier Transform,STFT)技术,对音频信号进行分帧处理,使用重叠的短时窗口重复执行 FFT,从而生成频谱图(Spectrogram)。频谱图的横轴代表时间,纵轴代表频率,亮度则表示每个频率在每个时刻的振幅或音量。这种表示方式将音频从振幅 — 时间域转换为频率 — 时间域,使得音乐结构以机器可读的热力图形式呈现。

从频谱图到星座图:峰值检测与特征稀疏化

生成的频谱图包含了丰富的频率信息,但数据量过大,直接用于匹配会面临存储成本高和检索速度慢的问题。更重要的是,频谱图中并非所有频率都具有识别价值 —— 背景噪声、低能量频率成分在不同录音条件下往往表现出较大差异,而高能量的突出频率则相对稳定,能够更好地代表音频特征。

Shazam 进一步对频谱图进行峰值检测(Peak Picking),过滤掉低能量频率,仅保留最突出的点。这一步骤将密集的频谱图转换为稀疏的特征点集合,被称为星座图(Constellation Map)。可以将星座图理解为音乐的可视化散点图,每个点代表一个显著频率在特定时刻的出现。这些高能量峰值如同频谱中的 “地标”,具有较强的抗噪声能力和抗失真能力,是构建指纹的理想基础。

在工程实现中,峰值检测通常采用局部极大值算法,即在频谱图的每个时间帧内寻找能量超过邻域阈值的频率点。阈值的设定需要在召回率和精确率之间取得平衡:阈值过低会导致过多噪声点被纳入,阈值过高则可能遗漏有价值的特征点。实际系统中还会结合频带能量统计和自适应阈值等技术来优化检测效果。

哈希生成:频点对与时间偏移的编码

获取星座图后,Shazam 并不直接存储这些峰值点,而是进一步从中提取哈希(Hash)以生成紧凑的音频指纹。这一步骤的核心思想是将局部频谱模式转化为可快速比较的紧凑代码。

具体而言,系统选取每个显著峰值作为 “锚点”(Anchor),在其后的一定时间窗口内寻找其他目标峰值(Target),将锚点与目标点配对,并对配对结果进行哈希编码。哈希元组通常包含三个核心元素:锚点频率、目标频率以及两者之间的时间差。这种编码方式可以用数学公式表示为(锚点频率、目标频率、时间增量),形成 Shazam 指纹的基本单元。

在典型实现中,一个 Shazam 哈希使用 32 位存储空间,其中约 10 位编码锚点频率,约 10 位编码目标频率,剩余约 12 位编码时间差。这种位分配方式在频率分辨率和时间分辨率之间取得了合理折衷,同时将每个哈希的存储空间控制在极小范围内。值得注意的是,哈希编码的是频率之间的相对关系而非绝对值,这使得系统对整体音高偏移(Pitch Shift)具有天然的鲁棒性。

哈希生成的关键参数包括时间窗口大小(通常在 0.5 至 1 秒范围内)、频率量化精度以及哈希函数的具体实现。时间窗口的选择直接影响能够捕获的音频特征数量:窗口过小则配对数量不足,窗口过大则可能引入过多无关特征点,增加匹配复杂度。

哈希表匹配与数据库检索

生成本地音频的哈希序列后,Shazam 需要在包含数千万首歌曲的数据库中找到匹配曲目。传统数据库查询在如此大规模数据下的延迟难以接受,因此 Shazam 采用哈希表(HashMap)数据结构实现近似常数时间(O (1))的查找性能。

匹配过程的核心逻辑如下:将生成的每个哈希作为键在哈希表中检索,获取拥有相同哈希值的数据库歌曲记录;统计所有匹配的哈希数量;最终返回匹配数量最多的歌曲作为识别结果。这一过程利用了哈希的局部敏感性:即使录音存在噪声或失真,只要关键的频谱特征点被正确捕获,对应的哈希值仍能命中数据库中的原始指纹。

实际匹配中还有一个重要细节:Shazam 并不知道用户录音来自歌曲的哪个位置(intro、verse、chorus 或 bridge),因此系统不依赖绝对时间戳,而是依赖哈希之间的时间差相对关系。这意味着即使录音从歌曲的不同段落开始,只要两个哈希之间的时间差与数据库中对应哈希的时间差一致,就能够成功匹配。

为支持全球规模的高速识别,Shazam 在系统架构层面进行了多项优化。数据库通过分片(Sharding)技术划分为多个子集,可按时间范围、哈希前缀或地理区域进行划分;热数据保留在内存中以实现毫秒级访问,冷数据则迁移至磁盘以降低成本。全球部署的分布式架构确保用户请求能够被路由至最近的数据中心,从而将网络延迟降至最低。据公开资料显示,Shazam 系统目前支持每分钟超过 23000 次识别请求。

工程参数与实践要点

构建类似的音频指纹系统需要在多个维度进行参数调优。在信号处理层面,FFT 窗口大小通常选择 2048 或 4096 采样点,窗口重叠率在 50% 至 75% 之间,窗函数可选用汉宁窗或汉明窗以减少频谱泄漏。峰值检测的能量阈值通常根据整体频谱能量的统计分布设定,例如采用中位数倍数或自适应百分比的方式。哈希生成的时间窗口是另一个关键参数,需要在捕获足够特征与避免冗余之间取得平衡。

对于希望实现类似系统的工程师而言,以下几点实践经验值得关注:首先,峰值检测的质量直接决定后续匹配效果,应投入充分精力进行阈值优化和噪声过滤;其次,哈希的位分配策略影响频率和时间分辨率,应根据实际应用场景的音频特性进行调整;再次,数据库设计需考虑查询热点和写入压力的平衡,合理选择内存与磁盘的数据分布比例;最后,系统应具备良好的容错机制,能够处理识别失败的情况并向用户提供有意义的反馈。

Shazam 的音频指纹技术自 2003 年论文发表以来已运行超过二十年,期间虽有小规模演进但核心算法框架保持稳定。这一成就充分证明了基于频谱峰值哈希的方案在工程上的可行性和可扩展性,也 为音频识别领域树立了一个经典的技术标杆。

资料来源:本文技术细节主要参考 Avery Wang 于 2003 年发表的 Shazam 核心算法论文及 Towards Data Science 的深度解析文章。

systems