当前位置: 首页 > news >正文

【微实验】基频提取的MATLAB实现(优化版)

前情提要:

【超详细】科普:别再只会用自相关!YIN 和 PYIN 如何破解音频隐藏密码?-CSDN博客

【微实验】妈妈我的MATLAB会识别声音的基频了!-CSDN博客

今天用MATLAB把算法封装成函数,然后调用对比结果。

一、算法简介
  • YIN 算法:一种经典的基频(F0)提取算法,通过计算信号的自相关函数及其累积均值归一化,来定位基频周期,适用于语音、乐器等信号的基频检测,具有较好的抗噪声性能。
  • PYIN 算法:基于 YIN 算法的改进版本,引入了概率模型,通过对基频候选值进行置信度评估,进一步提升了复杂环境下基频提取的准确性,尤其在处理清音 / 浊音过渡、低信噪比信号时表现更优。
二、MATLAB 实现步骤
1. 读取音频文件(voice.mp3)

MATLAB 中可使用audioread函数读取音频,注意 mp3 格式需确保 MATLAB 支持(可先转换为 wav 格式避免兼容问题):

% 读取音频文件
[audio, fs] = audioread('voice.mp3'); % audio为音频数据,fs为采样率
audio = audio(:, 1); % 取单声道
t = (0:length(audio)-1)/fs; % 时间轴
2. YIN 算法实现(基频提取核心)

核心思路:计算归一化累积均值差函数(CMND),寻找最小值对应的周期即为基频周期。

function f0_yin = yin_algorithm(audio, fs, frame_len, hop_len)% 初始化参数n_frames = floor((length(audio) - frame_len) / hop_len) + 1;f0_yin = zeros(n_frames, 1);min_freq = 50; % 最低基频(Hz)max_freq = 500; % 最高基频(Hz)min_period = fs / max_freq;max_period = fs / min_freq;for i = 1:n_frames% 取一帧数据frame = audio((i-1)*hop_len + 1 : (i-1)*hop_len + frame_len);frame = frame - mean(frame); % 去直流% 计算自相关函数r = xcorr(frame, frame);r = r(frame_len:end); % 取后半部分(正延迟)% 计算累积均值差函数(CMND)cmnd = zeros(length(r), 1);cmnd(1) = 1; % 避免除以0for tau = 2:length(r)sum_r = sum(r(1:tau-1));if sum_r == 0cmnd(tau) = 1;elsecmnd(tau) = r(tau) / (sum_r / (tau-1));endend% 寻找最小CMND对应的周期(在有效范围内)tau_range = round(min_period) : round(max_period);[~, min_idx] = min(cmnd(tau_range));tau = tau_range(min_idx);f0_yin(i) = fs / tau;end
end
3. PYIN 算法实现(引入概率模型)

在 YIN 算法基础上,增加基频候选值的置信度计算,筛选最可能的基频:

function [f0_pyin, conf] = pyin_algorithm(audio, fs, frame_len, hop_len)% 调用YIN算法获取初始基频候选f0_initial = yin_algorithm(audio, fs, frame_len, hop_len);n_frames = length(f0_initial);f0_pyin = zeros(n_frames, 1);conf = zeros(n_frames, 1); % 置信度(0-1)% 简化的概率评估(示例):基于基频连续性和CMND最小值for i = 2:n_frames-1% 计算当前帧与前后帧的基频偏差delta = abs(f0_initial(i) - (f0_initial(i-1) + f0_initial(i+1))/2);% 置信度与偏差成反比conf(i) = max(0, 1 - delta / 100); % 假设偏差<100Hz时置信度较高% 根据置信度筛选基频if conf(i) > 0.5f0_pyin(i) = f0_initial(i);elsef0_pyin(i) = NaN; % 低置信度时标记为无效endend
end
4. 可视化结果

将音频波形、YIN 与 PYIN 提取的基频曲线绘制在同一图中,直观对比效果:

% 参数设置
frame_len = 2048; % 帧长
hop_len = 512; % 帧移% 提取基频
f0_yin = yin_algorithm(audio, fs, frame_len, hop_len);
[f0_pyin, ~] = pyin_algorithm(audio, fs, frame_len, hop_len);% 生成基频时间轴
f0_t = (0:length(f0_yin)-1)*hop_len / fs;% 绘图
figure;
subplot(2,1,1);
plot(t, audio);
title('语音波形');
xlabel('时间(s)');
ylabel('振幅');subplot(2,1,2);
plot(f0_t, f0_yin, 'b', 'LineWidth', 1.2);
hold on;
plot(f0_t, f0_pyin, 'r--', 'LineWidth', 1.2);
title('基频提取结果');
xlabel('时间(s)');
ylabel('基频(Hz)');
legend('YIN算法', 'PYIN算法');
grid on;
hold off;

三、效果说明

emm这个音频太长了,密密麻麻看不太出来。

???

把帧移改小一点呢

  • 运行代码后,会显示语音波形图和基频曲线对比图,其中 PYIN 算法的结果(红色虚线)相比 YIN 算法(蓝色实线)更平滑,无效值(NaN)更少,尤其在语音停顿或噪声段表现更稳定。
  • 可通过调整frame_lenhop_lenmin_freqmax_freq等参数优化提取效果,适配不同类型的voice.mp3文件。

对比:

Adobe Audio的自带功能

这个效果只能说是一言难尽,两言也难,千言万语不想说。毕竟它也不是专门服务于语言学、人声音频的软件,所以就这样吧。

Praat的效果应该非常好才对——

Praat

看着不对劲……原来是参数没调好:

把窗长度改大一点——

这样看起来就基本上吻合了。

四、注意事项
  1. 复杂场景下(如多声部、强噪声),建议增加预处理步骤(如滤波、端点检测)。
  2. PYIN 算法的概率模型可进一步细化,优化置信度计算方法提升精度。
五、总结

这是一次失败的实验,下次继续。

http://www.lryc.cn/news/619828.html

相关文章:

  • 基于MATLAB的图像处理与圆弧拟合技术
  • 深度学习(6):参数初始化
  • Jenkins(集群与流水线配置)
  • 卷积神经网络(CNN):卷积和池化
  • 常用 MaxKB 函数库(HTTP、MYSQL)
  • Day 39: 图像数据与显存
  • 智算赋能:移动云助力“世界一流数据强港”建设之路
  • 深度学习·ExCEL
  • RK3568项目(十五)--linux驱动开发之进阶驱动
  • Spring Boot (v3.2.12) + application.yml + jasypt 数据源加密连接设置实例
  • Java Stream API 中常用方法复习及项目实战示例
  • AR技术赋能风电组装:效率提升30%,错误率降低50%
  • 华为悦盒EC6108V9-1+4G版-盒子有【蓝色USB接口】的特殊刷机说明
  • UniApp开发常见问题及解决办法
  • RabbitMQ面试精讲 Day 21:Spring AMQP核心组件详解
  • FluxApi - 使用Spring进行调用Flux接口
  • 后端Web实战-MySQL数据库
  • 【SpringBoot系列-01】Spring Boot 启动原理深度解析
  • 力扣121:买卖股票的最佳时机
  • 敲响变革的钟声:AI 如何重塑前端开发的基础认知
  • Java毕业设计选题推荐 |基于SpringBoot的水产养殖管理系统 智能水产养殖监测系统 水产养殖小程序
  • Kubernetes部署apisix的理论与最佳实践(三)
  • 从原材料到成品,光模块 PCB 制造工艺全剖析
  • JavaWeb-XML、HTTP协议和Tomcat服务器
  • 解析Vue3中集成WPS Web Office SDK的最佳实践
  • DAY42 Grad-CAM与Hook函数
  • Spring Boot调用优化版AI推理微服务 集成 NVIDIA NIM指南
  • 利用生成式AI与大语言模型(LLM)革新自动化软件测试 —— 测试工程师必读深度解析
  • Pycharm选好的env有包,但是IDE环境显示无包
  • Appium-移动端自动测试框架详解