基本谱减法降噪

news/2024/11/24 5:59:26/
  • 设计目的和设计要求

在接收到的语音信号大多含有噪声,并且噪声有大有小。由于在处理语音信号(例如语音识别,语音编码)之前往往要对带噪的语音进行减噪。这实质上就是语音信号处理中的语音增强。本组在此选用基本谱减法进行语音降噪。一般来说,随着信噪比的减小,减噪方法处理的效果也随之变差,而且往往会使语音信号丢字或者波形失真。基本谱减法虽然简单易行,有一定效果,但要在信噪比很低的情况下进行降噪,还需寻找更有效的语音增强方法。

具体设计要求为通过读入“bluessky.wav”数据(内容为:蓝天,白云,碧绿的大海),叠加上5dB的白噪声,通过调用谱减法函数simplesubspec对带噪语音进行减噪。

  • 原理、结构和功能

设语音信号的时间序列为x(n),加窗分帧处理后得到第i。帧语音信号为xi(m),帧长为 N。任何一帧语音信号xi(m)做DFT后为

 

k=0,1,2...,N-1.

要对Xi求出每个分量的幅值和相角,幅值为|Xi(k)|,它的相角为:

 

在减谱中要把这两组数都给保存。

已知前导无话段(噪声段)时长为IS,对应的帧数为NIS,可以求出该噪声段的平均能量值为

 

谱减算法为

 

式中,a和b是两个常数,a称为过减因子;b称为增益补偿因子。

求出了谱减后幅值为丨Xi(k)丨,结合了保存的X’angle(k),就能经快速傅里叶逆变换(In-Werse Fast Fourier Tramsform,IFFT)求出谱减后的语音序列xi(m)。属中利用了谱最佳信号对相位不灵敏的特性,把谱减前的相位角信息直接用到谱减后的信号中。

基本谱减法的原理如图所示:

 

   

根据原理图可把减谱法的计算编写成一个函数,方便使用。

名称:simplesubspec

功能:用基本谱减法对带噪语音进行减噪

调用格式:output = simplesubspec(signal,wlen,inc,NIS,a,b)

说明:输入参数 signal 是带噪语音序列;wlen是帧长;inc是帧移;NIS是前导无话段的帧数;a是过减因子;b为增益补偿因子。输出参数output是谱减法减噪后的语音序列。

程序在Matlab章节具体说明。

通过读入“bluessky.wav”数据(内容为:蓝天,白云,碧绿的大海),叠加上5dB的白噪声,通过调用谱减法函数simplesubspec对带噪语音进行减噪。

  • MATLAB程序(包含注释)

simplesubspec函数

function output=simplesubspec(signal,wlen,inc,NIS,a,b)

wnd=hamming(wlen);                   % 设置窗函数

N=length(signal);                       % 计算信号长度

y=enframe(signal,wnd,inc)';              % 分帧

fn=size(y,2);                           % 求帧数

y_fft = fft(y);                           %  FFT

y_a = abs(y_fft);                        % 求取幅值

y_phase=angle(y_fft);                    % 求取相位角

y_a2=y_a.^2;                           %  求能量

Nt=mean(y_a2(:,1:NIS),2);            

 % 计算噪声段平均能量

nl2=wlen/2+1;                     % 求出正频率的区间

for i = 1:fn;                           % 进行谱减

    for k= 1:nl2

        if y_a2(k,i)>a*Nt(k)

            temp(k) = y_a2(k,i) - a*Nt(k);

        else

            temp(k)=b*y_a2(k,i);

        end

        U(k)=sqrt(temp(k));           

  % 把能量开方得幅值

    end

    X(:,i)=U;

end;

output=OverlapAdd2(X,y_phase(1:nl2,:),wlen,inc);   

% 合成谱减后的语音

Nout=length(output);                    

% 把谱减后的数据长度补足与输入等长

if Nout>N

    output=output(1:N);

elseif Nout<N

    output=[output; zeros(N-Nout,1)];

end

output=output/max(abs(output));         % 幅值归一

说明:程序中参数a和b按输入参数带入,可根据语音的具体情况进行改变。程序中调用到的函数OverlapAdd2是重叠相加法。

主函数

%

% pr7_2_1   

clear all; clc; close all;

filedir=[];                             % 指定文件路径

filename='bluesky1.wav';                % 指定文件名

fle=[filedir filename]                 

 % 构成路径和文件名的字符串

[xx,fs]=wavread(fle);                   % 读入数据文件

xx=xx-mean(xx);                         % 消除直流分量

x=xx/max(abs(xx));                      % 幅值归一化

IS=0.25;                               

 % 设置前导无话段长度

wlen=200;                               % 设置帧长为25ms

inc=80;                                 % 设置帧移为10ms

SNR=5;                                  % 设置信噪比SNR

N=length(x);                            % 信号长度

time=(0:N-1)/fs;                        % 设置时间

signal=Gnoisegen(x,SNR);                % 叠加噪声

snr1=SNR_singlech(x,signal);            % 计算初始信噪比

overlap=wlen-inc;                       % 求重叠区长度

NIS=fix((IS*fs-wlen)/inc +1);          

 % 求前导无话段帧数

a=4; b=0.001;                           % 设置参数a和b

output=simplesubspec(signal,wlen,inc,NIS,a,b);% 谱减

snr2=SNR_singlech(x,output);           

 % 计算谱减后的信噪比

snr=snr2-snr1;

fprintf('snr1=%5.4f   snr2=%5.4f    snr=%5.4f\n',snr1,snr2,snr);

wavplay(signal,fs);

pause(1)

wavplay(output,fs);

% 作图

subplot 311; plot(time,x,'k'); grid; axis tight;

title('纯语音波形'); ylabel('幅值')

subplot 312; plot(time,signal,'k'); grid; axis tight;

title(['带噪语音 信噪比=' num2str(SNR) 'dB']);

  ylabel('幅值')

subplot 313; plot(time,output,'k');grid;%hold on;

title('谱减后波形'); ylabel('幅值'); xlabel('时间/s');

     

  • 程序运行结果和解释说

纯语音波形

 

带噪语音 信噪比=5dB

 

谱减后波形

 

运行程序后得到消噪后的波形如上图所示。

调用Gnoisegen函数产生带躁语音,调用SNR_singlech函数计算信噪比。程序中调用函数simplesubspec,其中a和b参数分别为a=4,b=0.001

计算出信噪比的变化:初始信噪比为5 dB,谱减后的信噪比为11.3 dB,信噪比增加了6.3 dB。Snr1=5.0000  snr2=11.3051  snr=6.3051

  • 最终结果和结论

噪声是完全随机的,有可能在某个时段某条谱线的谱值会大于a×D(k),相滅后并没有把噪声完全消除,而把它的峰值保留下来了,称为噪声残留,在谱减后的合成语音中就造成了“音乐噪声”。

消噪后的语音有明显的“音乐噪声”,增加过减因子a的数值,有时能减少“音乐噪声”,但过大时也会使波形失真,因此同样要选用一个折中的值。又由于在语音信号上叠加随机噪声,每一次叠加上的随机噪声都是不相同的,所以计算减噪后信噪比的结果snr2都不完全一样,会有一些偏差。


http://www.ppmy.cn/news/428719.html

相关文章

EEMD去噪算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、EEMD去噪二、使用步骤1.代码展示2.function [spmax, spmin, flag] extrema(in_data)2.functi代码如下&#xff08;示例&#xff09;&#xff1a; 结果展示 …

主动降噪技术

当你每天乘坐交通工具的时候&#xff0c;是否注意到了周围环境的噪声污染&#xff1f;面对耳朵里跑进来恼人的噪音&#xff0c;除了堵住耳朵这种被动的方法&#xff0c;我们现在还可以主动出击&#xff0c;用声音将噪声消灭掉。 用一句话来概括主动降噪的原理&#xff1a;通过…

SSM框架搭建

SSM环境搭建 1 IDE的话&#xff0c;我用的MyEcplise&#xff0c;如果用Ecplise的话&#xff0c;需要自行配置服务器。 首先&#xff0c;建一个Dynamic工程&#xff0c;需要注意的是一定要勾选上web.xml。 将Spring框架包、jstl包、standard包、common-logging包、aopallian…

C#异步详解

异步编程是指在程序执行过程中&#xff0c;不需要等待某个操作完成&#xff0c;就可以继续执行后续的代码。比如我们开发了一个web页面中有一个上传文件功能&#xff0c;我们上传文件时使用异步操作&#xff0c;就不用等待文件的上传时间&#xff0c;可以先在网页上进行其他操作…

DecimalFormat基本用法

1.保留两位小数(截断&#xff09; 下面展示一些 内联代码片。 double num 11.256;DecimalFormat df new DecimalFormat("#.##");//指定RoundingModedf.setRoundingMode(RoundingMode.DOWN);String str df.format(num);double formatNum Double.parseDouble(str)…

宽带拨号连接显示被远程计算机终止

搜索框打开设备管理器 找到网络适配器 找到IP协议 卸载设备之后重启电脑

C++ STL中stack栈(简单讲解+例题运用)

运用stack函数首先需要头文件#include<stack>&#xff0c;栈是先进后出 stack的常用函数&#xff1a; push&#xff08;&#xff09;——向栈顶压入元素pop &#xff08;&#xff09;——弹出栈顶元素top &#xff08;&#xff09;——访问栈顶元素empty&#xff08…

账号被计算机远程终止,宽带远程连接被终止怎么办

宽带远程连接被终止?拨号上网的时候突然出现错误629,连接被远程计算机终止,这到底是怎么回事?面对连接宽带错误,下面让小编教你解决629被远程计算机终止的问题. 今天小编教你遇到宽带远程连接被终止&#xff0c;如何快速解决吧。 1.操作系统中存在错误&#xff0c;并提示您正…