MATLAB环境下一种音频降噪优化方法—基于时频正则化重叠群收缩

语音增强是语音信号处理领域中的一个重大分支,这一分支已经得到国内外学者的广泛研究。当今时代,随着近六十年来的不断发展,己经产生了许多有效的语音增强算法。根据语音增强过程中是否利用语音和噪声的先验信息,语音增强算法一般被归类为两类, 一类是无先验信息的语音增强算法,另外一类则是具有先验信息的语音增强算法。在第一类无先验信息语音增强算法中,比较常用的语音增强算法有谱减算法、基于统计模型的算法、基于信号子空间的算法、维纳滤波算法之类。这些算法对于平稳噪声具有很好的增强效果,但是对于特征很快变化的非平稳噪声,降噪性能经常无法满足需求。与上面的无先验信息语音增强算法相比,有先验信息语音增强算法能够弥补上述的缺点,能够有效的处理于非平稳噪声,达到合适的效果。有先验信息语音增强算法主要有隐马尔科夫模型语音增强算法以及码数驱动的语音增强算法。有先验信息语音增强算法能够通过线下提取语音和噪声的先验信息,然后利用HMM或者码数分别对获取的语音和噪声先验信息进行建模,结合线上语音和噪声的先验HMM 或者码数估计的语音谱和噪声谱,并构建维纳滤波器增强声音中的语音部分。由于利用到了语音和噪声的先验信息,这类算法能够很好地追踪线上语音和噪声特征的变化,实现对非平稳噪声很好的降噪效果。语音增强的主要目包含两个方面:1. 降低含噪语音中的噪音;2 尽量保留甚至增强原语音的质量。

提出一种基于时频正则化重叠群收缩的音频降噪优化方法,该方法使用可分解凸优化问题的预定结构知识对语音信号进行降噪,利用语音谱图观察聚类特性,使用混合范数惩罚项迭代地获得稀疏干净的语音信号。并在重叠群收缩算法基础上,在代价函数中引入时频权值。

% Reading in our audio files
[clean_signal, clean_speech_rate] = audioread("data/speech_files/sp01.wav");
[noise_signal, noise_signal_rate] = audioread("data/noise_files/keyboard_noise.wav");
noise_signal = noise_signal'; clean_signal = clean_signal';

% Ensuring noise signal length matches clean signl length through reptition and cropping
noise_signal = noise_signal(mod(0:length(clean_signal)-1, numel(noise_signal)) + 1);
assert(length(clean_signal) == length(noise_signal));

% Combining to create noisy signal
SNR = -10; % in dB
noisy_signal = clean_signal + (noise_signal / norm(noise_signal) * norm(clean_signal) / 10.0^(0.05*SNR));
% Uncomment the following line following line for using gaussian noise
%noisy_signal = awgn(clean_signal, SNR, "measured");

% Setting this changes what we take the STFT of
yo = noisy_signal;

% Some parameters for our test
noise_type = "impulsive"; % Noise types are impulsive, clean, stationary, used for weighting
lambda = 30; % Higher values when using both T & F weightings
Nit = 6;
K1 = 2;
K2 = 8;
window = sqrt(hann(256, 'periodic')); 
overlap_length = 128;
fft_length = 512;

%% Preprocess Data
% Take STFT
% ensure to use both a cola compliant window and overlap length and k needs to
% be an int in this eq. k = (length(yo) - overlap_length) / (length(window) - overlap_length)
% otherwise we can pad signal to make k an integer and remove padded 0's
% from our output
if (~iscola(window, overlap_length))
    error("COLA noncompliant parameters, imperfect reconstruction");
end
k = (length(yo) - overlap_length) / (length(window) - overlap_length);
if (k ~= floor(k))
    warning("Padding signal to provide sample reconstruction post istft, results may be off for groups that stretch across to these padded zeros");
    padding = ceil(k) * overlap_length + overlap_length - length(noisy_signal);
    yo = [yo zeros(1, padding)];
else
    padding = 0;
end
tf = stft(yo, noise_signal_rate, 'Window', window, 'OverlapLength', overlap_length, 'FFTLength', fft_length);

%% Creating our frequency weighting 
% For noise with varying energy across the bands
if noise_type == "clean" || noise_type == "impulsive" || noise_type == "stationary"
    [N, Fo, Ao, W] = firpmord([4000, 6000]/(noise_signal_rate/2), [1 0.8], [0.01, 0.01]);
    b = firpm(10, Fo, Ao, W);
    [filter_magnitudes, ~] = freqz(b, 1, size(tf, 1));
    filter_magnitudes = abs(filter_magnitudes);
elseif noise_type == "stationary"
    filter_magnitudes = ones(fft_length, 1);
end
frequency_weighting = repmat(filter_magnitudes, [1, size(tf, 2)]);

%% Denoising Signal
% Running algorithm
[tf_denoised, cost, weights, energy_ratios] = tfs(tf, K1, K2, lambda, Nit, frequency_weighting);
denoised_signal = real(istft(tf_denoised, noise_signal_rate, 'Window', window, 'OverlapLength', overlap_length, 'FFTLength', fft_length)');

% Undoing the padding if any was necessary
if (padding ~= 0)
    yo = yo(1:length(yo)-padding);
    denoised_signal = denoised_signal(1:length(denoised_signal)-padding);
end

%% Plots, SNR Readout & Playing Denoised Signal
time = (1:length(denoised_signal))/noise_signal_rate;
figure(1)
clf;
subplot(3,3,1);
hold on;
plot(time, denoised_signal, 'Color', [1, 0, 0, 0.2]);
plot(time, clean_signal, 'Color', [0, 1, 0, 0.05]);
axis tight;
hold off;
title("Clean vs Denoised Signal");
legend("Denoised Signal", "Clean Signal");

subplot(3,3,2);
plot(time, clean_signal - denoised_signal, 'Color', [1, 0, 0, 1]);
axis tight;
title("Delta of Clean vs Denoised");

subplot(3,3,3);
hold on;
plot(time, denoised_signal, 'Color', [1, 0, 0, 0.2]);
plot(time, noisy_signal, 'Color', [0, 1, 0, 0.05]);
axis tight;
hold off;
title("Noisy vs Denoised Signal");
legend("Denoised Signal", "Noisy Signal");

subplot(3,3,4);
plot(cost)
title("Cost Per Iteration");
legend("Cost");

subplot(3, 3, 5);
mesh(mag2db(weights));
c = colorbar;
c.Label.String = "Power/Frequency db/Hz";
shading interp;
view(0, 90);
xlim([0 size(weights, 2)])
ylim([0 size(weights, 1)])
title ("Time & Frequency Attenutation Weighting");

subplot(3, 3, 6);
spectrogram(clean_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Clean Signal");

subplot(3, 3, 7);
spectrogram(noisy_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Noisy Signal");

subplot(3, 3, 8);
spectrogram(denoised_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Denoised Signal");

subplot(3, 3, 9);
spectrogram(clean_signal - denoised_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Delta Between Clean & Denoised Signal");

if noise_type ~= "stationary"
    figure(2)
    freqz(b, 1, size(tf, 1));
end

figure(3)
subplot(2, 1, 1);
plot((1:fft_length).*(noise_signal_rate/2)/fft_length, smooth(filter_magnitudes));
xlabel("Frequency Hz");
ylabel("Weight");
title("Frequency Weights")

subplot(2, 1, 2);
plot(energy_ratios);
axis tight;
xlabel("Time");
ylabel("Weight");
title("Time Weights")

% Get the SNR and play the denoised signal
if (sum(clean_signal(:).^2) == 0) || (sum((clean_signal(:)-yo(:)).^2) == 0)
    preSNR = 0;
else
    preSNR = 10*log10(sum(clean_signal(:).^2) / (sum((clean_signal(:)-yo(:)).^2)));
end

if (sum(clean_signal(:).^2) == 0) || (sum((clean_signal(:)-denoised_signal(:)).^2) == 0)
    postSNR = 0;
else
    postSNR = 10*log10(sum(clean_signal(:).^2) / (sum((clean_signal(:)-denoised_signal(:)).^2)));
end
fprintf("SNR Pre-Denoising: %.2f SNR Post-Denoising: %.2f dB\n", preSNR, postSNR);
sound(denoised_signal, noise_signal_rate);

工学博士,担任《Mechanical System and Signal Processing》审稿专家,担任《中国电机工程学报》优秀审稿专家,《控制与决策》,《系统工程与电子技术》,《电力系统保护与控制》,《宇航学报》等EI期刊审稿专家,担任《计算机科学》,《电子器件》 , 《现代制造过程》 ,《电源学报》,《船舶工程》 ,《轴承》 ,《工矿自动化》 ,《重庆理工大学学报》 ,《噪声与振动控制》 ,《机械传动》 ,《机械强度》 ,《机械科学与技术》 ,《机床与液压》,《声学技术》,《应用声学》,《石油机械》,《西安工业大学学报》等中文核心审稿专家。

擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/347083.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文件备份管理软件系统

1、我解决的问题 避免因为硬盘故障,导致数据丢失; 避免因为中了病毒,文件被加密,无法取回; 避免了员工恶意删除文件; 规范企业内部的文件管理,使它井井有条; 防范于未然,不必再为可能的风险担忧; 2、我的优点 我支持定…

语义分割 | 基于 VGG16 预训练网络和 Segnet 架构实现迁移学习

Hi,大家好,我是源于花海。本文主要使用数据标注工具 Labelme 对猫(cat)和狗(dog)这两种训练样本进行标注,使用预训练模型 VGG16 作为卷积基,并在其之上添加了全连接层。基于标注样本…

什么是调频直放站,调频直放站的功能和作用是什么?

调频直放站,顾名思义是一种对调频广播信号进行放大处理的通信设备,将调频广播信号引入到地下空间或隧道内,实现调频广播信号覆盖,扩大调频广播信号的覆盖范围。 1、调频直放站的组成 调频直放站从结构上来讲,一般由远…

线性代数:矩阵的定义

目录 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩阵 八、矩阵相等 九、零矩阵 十、方阵的行列式 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩…

python数据和分析——pandas基础内容

Pandas 的两个主要的数据结构是 Series 和 DataFrame: Series 是一维标记数组,类似于带有标签的列表。它可以包含不同类型的数据,并且可以通过索引进行访问和操作。DataFrame 是二维表格型数据结构,类似于 SQL 表或 Excel 电子表…

jQuery遍历(树遍历)

1、.children&#xff08;&#xff09;: 获得匹配元素集合中每个元素的直接子元素&#xff0c;选择器选择性筛选。 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script src"jQuery.js"&g…

go api(get post传参,数据库,redis) 测试

介绍&#xff1a;分别测试get请求&#xff0c;post请求&#xff0c;请求链接数据库&#xff0c;以及redis操作。 1.api代码 package mainimport (_ "database/sql""encoding/json""github.com/gin-gonic/gin""go-test/com.zs/database&quo…

橘子学Mybatis08之Mybatis关于一级缓存的使用和适配器设计模式

前面我们说了mybatis的缓存设计体系&#xff0c;这里我们来正式看一下这玩意到底是咋个用法。 首先我们是知道的&#xff0c;Mybatis中存在两级缓存。分别是一级缓存(会话级)&#xff0c;和二级缓存(全局级)。 下面我们就来看看这两级缓存。 一、准备工作 1、准备数据库 在此之…

自动化网络故障管理

故障管理是网络管理的组成部分&#xff0c;涉及检测、隔离和解决问题&#xff0c;如果实施得当&#xff0c;网络故障管理可以使连接、应用程序和服务保持在最佳水平&#xff0c;提供容错能力并最大限度地减少停机时间&#xff0c;专门为此目的设计的平台或工具称为故障管理系统…

UDS Flash刷写用例简单介绍

文章目录 1.Boot的功能1.1 目的1.2 功能 2.测试用例设计2.1 设计框架2.2 正向测试2.1.1 刷写流程2.1.2 重复刷写2.1.3压力刷写 2.3 逆向测试2.2.1 断电后刷写2.2.2 中断通讯后刷写2.2.3 篡改刷写数据2.2.4 修改软件校验数据2.2.5 修改刷写流程2.2.6 高负载刷写2.2.7 高低压刷写…

C++数据结构——红黑树

一&#xff0c;关于红黑树 红黑树也是一种平衡二叉搜索树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;颜色右两种&#xff0c;红与黑&#xff0c;因此也称为红黑树。 通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树可以…

ChatGLM论文解读

GLM GLM: General Language Model Pretraining with Autoregressive Blank Infilling 论文地址 1. 背景介绍 1)主流预训练框架 模型介绍结构特点训练目标autoregressive自回归模型,代表GPT,本质上是一个从左到右的语言模型,常用于无条件生成任务(unconditional generat…

[BJDCTF2020]ZJCTF,不过如此(特详解)

php特性 1.先看代码&#xff0c;提示了next.php&#xff0c;绕过题目的要求去回显next.php 2.可以看到要求存在text内容而且text内容强等于后面的字符串&#xff0c;而且先通过这个if才能执行下面的file参数。 3.看到用的是file_get_contents()函数打开text。想到用data://协…

Airflow【部署 01】Airflow官网Quick Start实操(一篇学会部署Airflow)

Airflow官网Quick Start实操 1.环境变量设置2.使用约束文件进行安装3.启动单机版3.1 快速启动3.2 分步骤启动3.3 启动后3.4 服务启动停止脚本 4.访问4.1 登录4.2 测试 来自官网的介绍&#xff1a; https://airflow.apache.org/ Airflow™是一个由社区创建的平台&#xff0c;以…

【Unity学习笔记】第十一 · 动画基础(Animation、状态机、root motion、bake into pose、blendTree、大量案例)

转载引用请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/132081959 作者&#xff1a;CSDN|Ringleader| 如果本文对你有帮助&#xff0c;不妨点赞收藏关注一下&#xff0c;你的鼓励是我前进最大的动力&#xff01;ヾ(≧▽≦*)o 主…

SSL证书 DV、OV、EV等级的证书适用群体

DV&#xff08;Domain Validation&#xff0c;域名验证&#xff09;证书 特点&#xff1a;DV证书是最基础的SSL/TLS证书类型&#xff0c;仅验证申请证书的实体是否对该域名有控制权。验证过程相对简单快速&#xff0c;通常只需要验证域名的所有权即可。 适用人群&#xff1a;…

教学方法有哪些种类

作为一位老师&#xff0c;面对不同的学生和课程&#xff0c;掌握多种教学方法是必不可少的。你知道吗&#xff1f;教学方法不仅关乎教学效果&#xff0c;还直接影响学生的学习热情和兴趣。这篇文章将为你揭秘教学方法的神秘面纱&#xff0c;看看有哪些种类的教学方法&#xff0…

初识计算机网络 | 计算机网络的发展 | 协议初识

1.计算机网络的发展 “矛盾是普遍存在的&#xff0c;矛盾是事物联系的实质内容和事物发展的根本动力&#xff01;” 计算机在诞生之初&#xff0c;在军事上用来计算导弹的弹道轨迹&#xff01;在发展的过程中&#xff08;商业的推动&#xff0c;国家政策推动&#xff09;&…

Nginx 配置解析:从基础到高级应用指南

Nginx 配置解析&#xff1a;从基础到高级应用指南 Nginx 配置解析&#xff1a;从基础到高级应用指南1. 安装和基本配置安装 Nginx基本配置 2. 虚拟主机配置3. 反向代理配置4. 负载均衡配置5. SSL 配置6. 高级配置选项结语 Nginx 配置解析&#xff1a;从基础到高级应用指南 Ngi…

rank是MySQL关键字

MySQL有rank关键字&#xff0c;建议将rank替换为rank 。不是单引号 是键盘1左边的符号。 rank()&#xff1a;返回的相关等级会跳跃&#xff1b; dense_rank()&#xff1a;返回的相关等级不会跳跃&#xff1b; row_number()&#xff1a;返回的是行信息&#xff0c;没有排名&a…