
本文介绍使用 python 批量检测多个 wav 音频文件中是否含有 10 khz 以上显著能量成分的方法,通过 fft 频谱分析提取高频能量强度,并输出可导入 excel 的结构化结果。
本文介绍使用 python 批量检测多个 wav 音频文件中是否含有 10 khz 以上显著能量成分的方法,通过 fft 频谱分析提取高频能量强度,并输出可导入 excel 的结构化结果。
在生态声学监测(如蝙蝠洞录音分析)中,常需从大量 WAV 录音中快速筛选出含特定高频生物声(如蝙蝠回声定位声,通常 >10 kHz)的有效样本。直接“查找最高频率”在实际音频中意义有限——受采样率、噪声和瞬态特性影响,单个峰值频率易失真且不可靠;更稳健的做法是:评估目标频段(如 10–96 kHz)内的总能量强度,即计算该频段 FFT 幅值谱的能量和(或其对数尺度 dB 值)。
以下是一个完整、可运行的 Python 教程方案,基于 scipy 和 numpy 实现:
✅ 核心步骤概览
- 读取 WAV 文件(自动适配单/双声道,重采样至统一采样率)
- 分帧加窗(推荐汉宁窗 + 50% 重叠),对每帧做 FFT
- 计算功率谱,映射频率轴,提取 ≥10 kHz 频段的能量均值(线性或 dB)
- 汇总各文件的高频能量指标,生成 CSV 表格供 Excel 导入
? 示例代码(完整可执行)
import os
import numpy as np
import pandas as pd
from scipy.io import wavfile
from scipy.fft import fft, fftfreq
from pathlib import Path
def analyze_high_freq_energy(file_path, freq_threshold=10000, target_band=(10000, 96000)):
"""
提取 WAV 文件中指定高频区间的平均能量(dBFS)
返回:文件名、采样率、高频能量(dB)、是否超过阈值(布尔)
"""
try:
sr, data = wavfile.read(file_path)
# 转为浮点型并归一化到 [-1.0, 1.0]
if data.dtype == np.int16:
data = data.astype(np.float32) / 32768.0
elif data.dtype == np.int32:
data = data.astype(np.float32) / 2147483648.0
else:
data = data.astype(np.float32)
# 单声道处理(取左声道或均值)
if data.ndim > 1:
data = data.mean(axis=1)
# 分帧(2048 点,约 46 ms @ 44.1 kHz)
n_fft = 2048
hop_length = n_fft // 2
frames = [data[i:i+n_fft] for i in range(0, len(data)-n_fft, hop_length)]
if not frames:
return file_path.name, sr, np.nan, False
# 对每帧计算功率谱
energies = []
for frame in frames:
if len(frame) = target_band[0]) & (freqs 0:
energies.append(10 * np.log10(band_power + 1e-12)) # 转 dB,防 log0
avg_dB = np.mean(energies) if energies else -np.inf
is_bat_like = avg_dB > -60 # 经验阈值:-60 dBFS 以上视为存在显著高频活动
return file_path.name, sr, round(avg_dB, 2), is_bat_like
except Exception as e:
return file_path.name, None, np.nan, False
# 批量处理目录下所有 .wav 文件
wav_dir = Path("bat_recordings/") # 替换为你的文件夹路径
results = []
for wav_file in wav_dir.glob("*.wav"):
res = analyze_high_freq_energy(wav_file)
results.append(res)
# 生成结构化表格
df = pd.DataFrame(results, columns=["Filename", "SampleRate", "HF_Energy_dB", "Has_Bat_Signal"])
df.to_csv("bat_detection_report.csv", index=False, encoding="utf-8-sig")
print("✅ 分析完成!结果已保存至 bat_detection_report.csv")
print(df.head())
⚠️ 关键注意事项
- 采样率决定上限:根据奈奎斯特定律,若原始录音采样率为 44.1 kHz,则理论最高分析频率为 22.05 kHz;若需分析 96 kHz 声音,请确保录音设备支持 ≥192 kHz 采样(否则高频信息已丢失)。
- 避免“虚假峰值”:不建议仅依赖单帧 FFT 的最大频率点——环境电噪声、ADC 量化伪影可能在高频区产生孤立尖峰;应统计多帧、宽频带的能量分布。
-
阈值需校准:
-60 dBFS是常见起始阈值,但实际应结合空白录音(无蝙蝠)的本底噪声水平调整,推荐先用 5–10 个已知正/负样本标定。 -
性能优化提示:对千级文件,可启用
concurrent.futures.ProcessPoolExecutor并行加速;大文件建议流式分块读取(soundfile库支持)。
通过该流程,你将获得一份清晰的 CSV 报表,包含每个文件的高频能量强度与初步判别结果,无缝对接 Excel 进行排序、筛选与可视化——真正实现从原始音频到科研决策的高效闭环。










