Search code examples
matlabconcatenationoverlapsubtraction

How do I add each frame back together after spectral subtraction (MATLAB)?


I'm following this guide in order to perform spectral subtraction and so far I have the following code but I can't work out how to successfully concatenate each overlapping frame back together at the end. Thanks for your help.

function [ cleanFile ] = spectralSubtraction( noisyFile )

SamplingFrequency = 44100;
frameLengthMs = 20;
frameLength = (frameLengthMs/1000)*SamplingFrequency;
numSamples = length(noisyFile);
noiseMagEstimate=0;
cleanFrame=0;

%imaginary number
j=sqrt(-1);

%spectrally flatten the speech
noisyFile = preEmphasis(noisyFile);

%frames overlap by 50% so number of frames is double.
numFrames = floor( numSamples / frameLength )*2;

for frame = 1:numFrames-2,
    %get the first and last samples for this frame
    first = (frame-1)*(frameLength/2)+1;
    last = first+frameLength;

    %get the samples for this frame
    shortTimeFrame = noisyFile(first:last);

    %apply a hamming window to this frame
    shortTimeFrame = hann(frameLength+1).*shortTimeFrame;

    %do the fft for the frame
    shortTimeFrame = fft(shortTimeFrame);

    %get the absolute value for the magnitude part
    mag = abs(shortTimeFrame);

    %calculate the phase
    phase=angle(shortTimeFrame);

    if frame<6
        %average spectra of first 5 frames to get noise estimate
        noiseMagEstimate=noiseMagEstimate+mag;
    elseif frame==6
        noiseMagEstimate=noiseMagEstimate/6;
    else
        %perform spectral subtraction on the rest of the file using
        %the noise estimate from the first 5 frames
        mag=mag-noiseMagEstimate;
        %Flooring
        if mag<0
            mag=0;
        end
        %Merge clean mag and phase
        cleanFrame=mag.*exp(j*phase);

        %Inverse fourier transform of cleaned frame
        cleanFrame=ifft(cleanFrame);

        %Overlap and add clean frame to clean file

    end    
end
end

Solution

  •     cleanFrame=real(cleanFrame);
        if lastFrame~=0
            cleanFile=[cleanFile;lastFrame(442:883)+cleanFrame(1:442)];
        end
        lastFrame=cleanFrame;
    

    It's not great but that's what I've added after

        cleanFrame=ifft(cleanFrame);