在R中从WAV文件提取频率时间DataFrame及区分说话人方法
在R中从WAV文件生成时间-频率对应DataFrame(用于说话人区分)
嘿,刚好做过类似的说话人分离任务,给你捋个最简实现方案——其实seewave里的函数完全能满足你的需求,只是你可能没注意到参数设置~
方案1:提取基频(F0)时间序列(最适合说话人区分)
基频是区分不同说话人的核心特征之一,男性基频通常在80-160Hz,女性在160-250Hz,用seewave的dfreq()函数可以直接生成时间-基频的DataFrame,完全匹配你的需求:
# 加载必备包 library(tuneR) library(seewave) # 读取WAV文件(如果是立体声,先转单声道) wav <- readWave("your_audio.wav") wav <- mono(wav, "left") # 或选"right",取任意声道即可 # 计算基频随时间的变化,直接返回DataFrame freq_time_df <- dfreq(wav, plot = FALSE) # 查看结果:第一列是时间(秒),第二列是基频(Hz) head(freq_time_df)
dfreq()会自动按合适的时间窗口计算每个片段的基频,plot=FALSE关闭默认绘图,直接输出数据框。拿到这个结果后,你可以用kmeans之类的聚类方法直接分两类,初步区分两位说话人。
方案2:提取完整频谱(时间-全频率-振幅)
如果需要更细致的频率信息(比如每个时间窗口的所有频率成分振幅),可以用短时傅里叶变换(STFT),同样用seewave实现:
用tidyverse简化整理(推荐)
library(tidyr) library(dplyr) # 计算STFT,关闭绘图 stft_result <- stft(wav, plot = FALSE) # 转换为长格式DataFrame full_freq_df <- as.data.frame(stft_result$amp) %>% mutate(time = stft_result$time) %>% pivot_longer(cols = -time, names_to = "frequency", values_to = "amplitude") %>% mutate(frequency = as.numeric(frequency)) head(full_freq_df)
基础R版本(无需额外包)
# 提取STFT的核心数据 time_points <- stft_result$time freq_points <- stft_result$freq amp_matrix <- stft_result$amp # 拼接成DataFrame full_freq_df <- data.frame( time = rep(time_points, each = length(freq_points)), frequency = rep(freq_points, length(time_points)), amplitude = as.vector(amp_matrix) )
这个DataFrame包含了每个时间点、每个频率对应的振幅,适合做更复杂的特征提取和说话人分类。
小提示
如果你的WAV文件采样率很高,dfreq()或stft()的计算速度可能会慢,可以先用downsample()降低采样率(比如降到16000Hz),完全不影响说话人区分的效果:
wav <- downsample(wav, 16000)
内容的提问来源于stack exchange,提问作者mowglis_diaper
相关产品推荐
相关产品推荐

