THE AUDITORY MODELING TOOLBOX

Applies to version: 1.4.0

View the help

Go to function

JOERGENSEN2011_SEPSUB - estimates the clean signal output_Y

Program code:

function [output_Y, output_N] = joergensen2011_sepsub(input,noise,W,padz,SP,factor)
%JOERGENSEN2011_SEPSUB estimates the clean signal output_Y
%
%   Usage: [output Nzeros] = joergensen2011_sepsub(input,noise,W,padz,SP,factor,fs)
%
%   Input parameters:
%     input     : Vector containg the noisy input (time) signal.
%     noise     : Vector containg the noise (time) signal that was added to the clean signal to create the noisy signal.
%     W         : Frame length  
%     padz      : zero padding (pad with padz/2 from the left and padz/2 from the right )
%     SP        : Shift percentage (overlap)
%     factor    : the over-subtraction factor
% 
%   Output parameters:
%     output    : the estimated "clean" time signal
%
%   This function calculates an estimate of the clean signal Y_hat from the
%   noisy signal (signal) and noise alone using spectral subtraction as
%   defined by Berouti et al. (1979).
%
%   Url: http://amtoolbox.org/amt-1.4.0/doc/modelstages/joergensen2011_sepsub.php


%   #StatusDoc: Submitted
%   #StatusCode: Submitted
%   #Verification: Untrusted
%   #Requirements: M-Signal M-Stats
%   #Author: Søren Jørgensen (2011)
%   #Author: Peter L. Sondergaard (2014)

% This file is licensed unter the GNU General Public License (GPL) either 
% version 3 of the license, or any later version as published by the Free Software 
% Foundation. Details of the GPLv3 can be found in the AMT directory "licences" and 
% at <https://www.gnu.org/licenses/gpl-3.0.html>. 
% You can redistribute this file and/or modify it under the terms of the GPLv3. 
% This file is distributed without any warranty; without even the implied warranty 
% of merchantability or fitness for a particular purpose. 


% Typical values:

% fs=44100; %sampling frequency
% W=1024; % frame length
% padz=1024; %zero padding (pad with padz/2 from the left and padz/2 from the right )
% % Note that (W+padz) is the final frame window and hence the fft length (it is normally chose as a power of 2)
% SP=0.5; %Shift percentage is 50%

if nargin < 6
    error('Insufficient amount of arguments');
    return;
end

stim = zeros(2,length(input));
stim(1,:) = input;
stim(2,:) = noise;

%  CALCULATE BASIC VALUES

wnd=(hanning(W)); %create hanning window with length = W
% fr=ceil((2*RT*fs-2*W)/W+1); %fr is the number of past frames that the method will take into account in order to extract the reverberation spectrum estimation

for k = 1:2
    % CUT THE THE APPROPRIATE SIGNAL FRAMES
    
    wnd1=wnd(:); %make it a column vector
    L=length(stim(k,:));
    SP1=fix(W.*SP);
    N1=fix((L-W)/SP1 +1); %number of segments
    Index=(repmat(1:W,N1,1)+repmat((0:(N1-1))'*SP1,1,W))';
    hw=repmat(wnd1,1,N1);
    y_tmp =stim(k,:);
    y_tmp=y_tmp(Index).*hw;
    
    % PAD WITH ZEROS
    
    pad=zeros((padz/2),length(y_tmp(10,:)));
    y_pad=[pad' y_tmp' pad'];
    y_tmp=y_pad';
    y(k,:,:) = y_tmp;
    clear y_pad y_tmp;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  FREQUENCY DOMAIN

% signal:
y_tmp = reshape(y(1,:,:),size(y,2),size(y,3));
Y=(fft(y_tmp));
YY=(Y(1:round(end/2)+1,:)); % Half window (exploite the symmmetry)
YPhase=angle(Y(1:round(end/2)+1,:)); % Phase
Y1=abs(Y(1:round(end/2)+1,:)); % Spectrum
Y2=abs(Y(1:round(end/2)+1,:)).^2;% Power Spectrum
numberOfFrames=size(Y,2);
FreqResol=size(Y,1);

%  noise:
y_tmp = reshape(y(2,:,:),size(y,2),size(y,3));
Y_N=(fft(y_tmp));
YY_N=(Y_N(1:round(end/2)+1,:)); % Half window (exploite the symmmetry)
Y_NPhase=angle(Y_N(1:round(end/2)+1,:)); % Phase
Y_N1=abs(Y_N(1:round(end/2)+1,:)); % Spectrum
Y_N2=abs(Y_N(1:round(end/2)+1,:)).^2;% Power Spectrum

for i=3:numberOfFrames
    
%   The noise "estimate" is simply the average of the noise power spectral
%   density in the frame:
    P_N=mean(Y_N2((1:length(Y_N2(:,1))/1),i));   % Power of the noise frames is mean across frequency
%   Subtraction of the noise estimate from the noisy signal: 
    Y_hat(:,i)=Y2(:,i) - factor*P_N; % subtraction
    PN_hat(:,i)=Y_N2(:,i) - factor*P_N; % subtraction for noise alone 
%   Truncating the result to be <= 0:
    Y_hat(:,i)=max(Y_hat(:,i),0); % Makes the minimum equal zeros
    zero_INDEXES = Y_hat(:,i) == 0;
    PN_hat(zero_INDEXES,i) = 0;
   %  
end
% Y_hat = Y_hat(:,3:end);
 Nzeros = find(Y_hat(:,3:end) == 0);
 if isempty(Nzeros), Nzeros = 0; end
 Nzeros = length(Nzeros);    
% Combining the estimated power spectrum with the original noisy phase, and
% add the frames using an overlap-add technique
% 
output_Y=joergensen2011_overlapadd3(Y_hat.^(1/2),YPhase,(W+padz),SP*W);
output_N=joergensen2011_overlapadd3(PN_hat.^(1/2),Y_NPhase,(W+padz),SP*W);