传统语音增强——Boll的改进谱减法

一、Boll的改进谱减法基本理论

1979年,S.F.Boll提出一种改进的谱减法。主要的改进点如下。
(1)在谱减法中使用信号的频谱幅值或功率谱
改进的谱减公式为

噪声段的平均谱值为

当y=1时,算法相当于用谱幅值做谱减法;当y=2时,算法相当于用功率谱做谱减法。式中,a为过减因子;β为增益补偿因子。
(2)计算平均谱值
在相邻帧之间计算平均值:

利用Yi(k)取代Xi(k),可以得到较小的谱估算方差。
(3)减少噪声残留
在减噪过程中保留噪声的最大值,从而在谱减法中尽可能地减少噪声残留,从而削弱“音乐噪声”。

此处,max|NR(k)|代表最大噪声残余。

二、基本谱减法的实验

Boll的改进谱减法函数SpectralSubIm

名称:SpectralSubIm
功能:基于Boll的改进谱减法语音降噪。
调用格式:
output = SpectralSubIm(signal,wind, inc, NIS, Gamma, Beta)
说明:输入参数signal是输入的含噪语音信号;wind为窗函数或窗长;inc是帧移;NIS是前导无话段帧数;Gamma和Beta是算法参数。output是降噪后的信号。

函数代码如下:

function output=SpectralSubIm(signal,wind,inc,NIS,Gamma,Beta)

nwin=length(wind);
if (nwin == 1)              % 判断窗长是否为1,若为1,即表示没有设窗函数
   W = wind;               % 是,帧长=wind
   wnd=hamming(W);
else
   W = nwin;              % 否,帧长=窗长
   wnd=wind;
end
nfft=W;

y=enframe(signal,W,inc)';
Y=fft(y,nfft);
YPhase=angle(Y(1:fix(end/2)+1,:));          %含噪语音的相位
Y=abs(Y(1:fix(end/2)+1,:)).^Gamma;      %功率谱
numberOfFrames=size(Y,2);

N=mean(Y(:,1:NIS)')';                           %初始的能量谱均值D(k)
NRM=zeros(size(N));                           %噪声残余量最大值
NoiseCounter=0;
NoiseLength=9;                                  %噪声平滑因子


YS=Y;                                               %平均谱值
for i=2:(numberOfFrames-1)
    YS(:,i)=(Y(:,i-1)+Y(:,i)+Y(:,i+1))/3;
end

for i=1:numberOfFrames
    [NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad_LogSpec(Y(:,i).^(1/Gamma),N.^(1/Gamma),NoiseCounter);       %基于频谱距离的VAD检测
    if SpeechFlag==0
        N=(NoiseLength*N+Y(:,i))/(NoiseLength+1);                               %更新并平滑噪声
        NRM=max(NRM,YS(:,i)-N);                                                          %更新最大的噪声残余
        X(:,i)=Beta*Y(:,i);
    else
        D=YS(:,i)-N;                                                                                 %谱减
        if i>1 && i<numberOfFrames                                                      %减少噪声残留项            
            for j=1:length(D)
                if D(j)<NRM(j)
                    D(j)=min([D(j) YS(j,i-1)-N(j) YS(j,i+1)-N(j)]);
                end
            end
        end
        X(:,i)=max(D,0);
    end
end
output=OverlapAdd2(X.^(1/Gamma),YPhase,W,inc);

信噪比计算函数SNR_Calc

名称:SNR_Calc
功能:计算信噪比。
调用格式:
snr=SNR_Calc(x,xn)

说明:输入信号x是输入的纯净语音信号;xn是输入的含噪信号。输出参数snr是计算的信噪比。

函数程序如下:

function snr=SNR_Calc(I,In)
% 计算带噪语音信号的信噪比
% I 是纯语音信号
% In 是带噪的语音信号
% 信噪比计算公式是
% snr=10*log10(Esignal/Enoise)
I=I(:)';                             % 把数据转为一列
In=In(:)';
Ps=sum((I-mean(I)).^2);              % 信号的能量
Pn=sum((I-In).^2);                      % 噪声的能量
snr=10*log10(Ps/Pn);                 % 信号的能量与噪声的能量之比,再求分贝值

案例、使用Boll改进的谱减法给带噪语音降噪

程序如下:

clear all; clc; close all;

[xx,fs]=audioread('C5_2_y.wav');                   % 读入数据文件
xx=xx-mean(xx);                         % 消除直流分量
x=xx/max(abs(xx));                      % 幅值归一化
SNR=10;                                 % 设置信噪比
signal=awgn(x,SNR,'measured','db');                % 叠加噪声
snr1=SNR_Calc(x,signal);            % 计算叠加噪声后的信噪比
N=length(x);                            % 信号长度
time=(0:N-1)/fs;                        % 设置时间刻度
IS=.15;                                 % % 设置前导无话段长度
wlen=200;                               % 设置帧长为25ms
inc=80;                                 % 设置帧移为10ms
Gamma=1;                                %幅度加权(改进谱减法的参数)
Beta=.03;
NIS=fix((IS*fs-wlen)/inc +1);           % 求前导无话段帧数
output=SpectralSubIm(signal,wlen,inc,NIS,Gamma,Beta);          % 调用SSBoll79函数做谱减
output=output/max(abs(output));
ol=length(output);                      % 把output补到与x等长
if ol<N
    output=[output; zeros(N-ol,1)];
end
snr2=SNR_Calc(x,output);            % 计算谱减后的信噪比
snr=snr2-snr1;
fprintf('snr1=%5.4f   snr2=%5.4f   snr=%5.4f\n',snr1,snr2,snr);

% 作图
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; ylim([-1 1]);
title('谱减后波形'); ylabel('幅值'); xlabel('时间/s');

运行结果如下:

实验使用到的语音数据下载链接如下:

传统语音增强——最小方均(LMS)自适应滤波算法-数据集文档类资源-CSDN下载

参考文献:语音信号处理实验教程;梁瑞宇、赵力、魏昕(编著) 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值