如何在R中计算指定时间窗口内声音的整体基频?
解决R中提取音频指定时间段单一基频的问题
1. 利用seewave包处理现有结果
seewave的fund函数默认会返回指定时间段内的基频时间序列,你之前用type='p'只是触发了绘图,关闭绘图并提取返回的数值后,就能对基频序列做汇总计算:
library(seewave) data(sheep) # 提取0.5-2秒的基频数据(不绘图) f0_results <- fund(sheep, from = 0.5, to = 2, plot = FALSE) # 计算时间段内的平均基频(忽略NA值) mean_f0 <- mean(f0_results$freq, na.rm = TRUE) # 或者计算中位数(抗极端值干扰) median_f0 <- median(f0_results$freq, na.rm = TRUE)
如果需要更贴合听觉感知的加权平均(按音频能量权重分配),可以结合cutw和env函数实现:
# 截取目标时间段的音频片段 sheep_segment <- cutw(sheep, from = 0.5, to = 2, output = "Wave") # 提取片段的能量包络(与基频的时间分辨率匹配) energy_env <- env(sheep_segment, f = sheep@samp.rate, envt = "abs", plot = FALSE) # 计算能量加权的平均基频 weighted_f0 <- weighted.mean(f0_results$freq, w = energy_env, na.rm = TRUE)
2. 其他可用R包
phonTools包
phonTools的pitch函数可以直接提取音频片段的基频序列,再做汇总:
library(phonTools) # 将Wave对象转为数值向量 sheep_vec <- as.vector(sheep@left) # 计算目标时间段的样本点范围 start_idx <- round(0.5 * sheep@samp.rate) end_idx <- round(2 * sheep@samp.rate) # 截取音频片段 segment_vec <- sheep_vec[start_idx:end_idx] # 提取基频序列 pitch_seq <- pitch(segment_vec, fs = sheep@samp.rate, timestep = 0.01) # 计算平均基频 mean_pitch <- mean(pitch_seq$pitch, na.rm = TRUE)
3. 关于“现成单一基频”的说明
目前没有直接返回指定时间段单一基频的现成函数——因为基频在时间窗口内本身是动态变化的,单一值本质是对这段时间的基频序列做统计汇总。你需要根据研究需求选择合适的统计方式:
- 普通均值:适合基频波动较小的场景
- 加权平均:更贴近听觉对能量强的部分的感知
- 中位数:能避免极端值的干扰
内容的提问来源于stack exchange,提问作者sheep
相关产品推荐
相关产品推荐

