I'm coding an analysis/synthesis system on MATLAB. I was able to recover the original signal when the length of the window (winLen
) is set equal to the length of the FFT (FFTLen
). When they are not equal, the results becomes erroneous. What is the cause of this error?
The analysis side consists of a time-domain input which is windowed with a Bartlett window followed by a FFT. The window shift corresponds to half of the window length. The FFT-ed sequence is decomposed into log magnitude and phase components. (Since the sequence is real, only the first half of the magnitude is stored.)
The synthesis side consists of concatenating the magnitude with its flipped version multiplied by the phase, which gives the initial FFT results before decomposition. Then IFFT is performed where the length is equal to the length of the time-domain window. The result is obtained from OLA process (since the Bartlett window is used in the analysis stage, a simple OLA will yield the original sequence).
% load input
cc = cc(1,:);
[~,T] = size(cc);
% window parameters
winLen = 32; % perfect reconstruction when winLen=FFTLen
winShift = winLen/2;
FFTLen = 64;
N = ceil((T-winLen)/winShift) + 1; % number of frames
% ANALYSIS PART
ms = zeros(1,(FFTLen/2)+1,N);
mp = zeros(1,FFTLen,N);
y = [cc(1,:) zeros(1,(winLen + winShift * N) - T)]; % zeropad sequence
for n = 1:N
ibeg = 1 + (n-1) * winShift;
iend = winLen + (n-1) * winShift;
buffer = y(ibeg:iend) .* bartlett(winLen)';
buffer = fft(buffer,FFTLen);
ms(1,:,n) = log(abs(buffer(1:(end/2)+1)));
mp(1,:,n) = unwrap(angle(buffer));
end
% SYNTHESIS PART
ccinv = zeros(1,winLen + (N-1) * winShift);
for n = 1:N
ibeg = 1 + (n-1) * winShift;
iend = winLen + (n-1) * winShift;
msbuf = exp([ms(1,:,n) fliplr(ms(1,2:end-1,n))]) .* exp(1i * mp(1,:,n));
buffer = ifft(msbuf,winLen);
ccinv(1,ibeg:iend) = ccinv(1,ibeg:iend) + buffer;
end
ccinv = real(ccinv);
% PLOT RESULTS
figure(1)
index = 50:100;
hold on
plot(cc(index),'k:')
plot(ccinv(index),'r:')