% DEMO Demonstrates the use of framing and synthesis routines.
%
% See also VEC2FRAMES, FRAMES2VEC
% Author: Kamil Wojcicki, UTD, July 2011
clear all; close all; clc; rand('seed',0); randn('seed',0); fprintf('.\n');
% signal-to-noise ratio (SNR) computation routine (function handle)
snr = @(signal,noise)(10*log10(norm(signal)./norm(noise)));
% Griffin & Lim's modified Hanning window (function handle)
gnl_hanning = @(L,S)(0.5*sqrt(2*S/(0.75*L))*(1-cos((2*pi*((0:L-1)+0.5))/L)));
% periodogram computation routine (function handle)
psd = @(signal,window,nfft) ...
(10*log10((abs(fftshift(fft(signal(:).*window(:),nfft))).^2)/length(signal)));
fs = 16000; % sampling frequency (Hz)
T = 0.256; % signal duration (seconds)
N = round(T*fs); % signal duration (samples)
n = [ 0:N-1 ]; % discrete-time index vector
time = n/fs; % time vector
w = hanning(N).'; % analysis window samples
nfft = 2^nextpow2(2*N); % FFT analysis length
freq = [ 0:nfft-1 ]/nfft*fs-fs/2; % frequency vector (Hz)
f = [ 500 1500 3500 ]; % vector of frequency components (Hz)
phi = [ pi/4 0 pi/3 ]; % vector of phases (rad)
A = [ 0.125 1 0.5 ]; % vector of amplitudes
% generate signal vector
x = sum( repmat(A.',1,N) .* ...
cos(2*pi*repmat(f.',1,N).*repmat(time,length(f),1)+repmat(phi.',1,N)), 1 );
% compute periodogram of the signal
Pxx = psd( x, w, nfft );
Tw = 32; % analysis frame duration (ms)
Ts = Tw/4; % analysis frame shift (ms)
Nw = round( 0.001*Tw*fs ); % analysis frame duration (samples)
Ns = round( 0.001*Ts*fs ); % analysis frame shift (samples)
direction = 'rows'; % frames as rows
padding = true; % pad with zeros
window = gnl_hanning(Nw,Ns); % window function samples
% divide signal to frames
[ frames, indexes ] = vec2frames( x, Nw, Ns, direction, window, padding );
% reconstruct signal from frames
%[ y ] = frames2vec( frames, indexes, direction, window, 'A&R' );
[ y ] = frames2vec( frames, indexes, direction, window, 'G&L' );
%[ y ] = frames2vec( frames, indexes, direction, window, 'VANILLA' );
% truncate the reconstructed signal back to original length
% i.e., remove any padding
y = y(1:N);
% compute periodogram of the reconstructed signal
Pyy = psd( y, w, nfft );
% display SNR of the original and reconstructed signals
fprintf( 'SNR=%0.2f dB\n', snr(x,y(:)-x(:)) );
% generate time and frequency domain plots
hfig = figure('Position', [800 100 1024 768], ...
'PaperPositionMode', 'auto', 'Visible', 'on', 'color', 'w');
subplot( 2,2,1 );
plot( time, x, 'k-' );
xlim( [0 max(time)*0.15] );
ylim( [min(x)-0.3*max(x) 1.3*max(x)] );
xlabel( sprintf('Time (s)') );
ylabel( sprintf('Amplitude') );
title( sprintf('Original') );
set( gca, 'box', 'off' );
subplot( 2,2,2 );
plot( time, y, 'r-' );
xlim( [0 max(time)*0.15] );
ylim( [min(x)-0.3*max(x) 1.3*max(x)] );
xlabel( sprintf('Time (s)') );
ylabel( sprintf('Amplitude') );
title( sprintf('Reconstructed') );
set( gca, 'box', 'off' );
subplot( 2,2,3 );
plot( freq, Pxx, 'k-' );
xlim( [-fs/2 fs/2] );
xlabel( sprintf('Frequency (Hz)') );
ylabel( sprintf('Power (dB)') );
set( gca, 'xtick', [-6:2:6]*1E3 );
set( gca, 'box', 'off' );
subplot( 2,2,4 );
plot( freq, Pyy, 'r-' );
xlim( [-fs/2 fs/2] );
xlabel( sprintf('Frequency (Hz)') );
ylabel( sprintf('Power (dB)') );
set( gca, 'xtick', [-6:2:6]*1E3 );
set( gca, 'box', 'off' );
print( '-dpng', mfilename );
% EOF