% SOLA_Time_Stretch.m
% Modified from TimeScaleSOLA.m
% Time Scaling with Synchronized Overlap and Add %
% Parameters:
%
% analysis hop size         Sa = 256 (default parmater)
% block length              N  = 2048 (default parameter)
% time scaling factor       0.25 <= alpha <= 2
% overlap interval          L  = 256*alpha/2

function Overlap = SOLA_Time_Stretch(DAFx_in, FS, alpha)

Original_length = length(DAFx_in); 
Modified_length = ceil(Original_length * alpha); 
DAFx_in = DAFx_in';
Sa = 256;
N = 2048;
if Sa > N
   disp('Sa must be less than N !!!')
end

if (N > length(DAFx_in))
    Overlap = DAFx_in;
    return;
end

M   =   ceil(length(DAFx_in)/Sa);

% Segmentation into blocks of length N every Sa samples 
% leads to M segments

Ss = round(Sa*alpha);
L = 256*alpha/2;

if Ss >= N disp('alpha is not correct, Ss is >= N') 
elseif Ss > N-L disp('alpha is not correct, Ss is > N-L') 
end

DAFx_in(M*Sa+N)=0;
Overlap  =  DAFx_in(1:N);

% **** Main TimeScaleSOLA loop ****
tic
for ni=1:M-1
    ni;
    grain=DAFx_in(ni*Sa+1:N+ni*Sa); 
    XCORRsegment=xcorr(grain(1:L),Overlap(1,ni*Ss:ni*Ss+(L-1))); 
    [xmax(1,ni),index(1,ni)]=max(XCORRsegment); 
    fadeout=1:(-1/(length(Overlap)-(ni*Ss-(L-1)+index(1,ni)-1))):0; 
    fadein=0:(1/(length(Overlap)-(ni*Ss-(L-1)+index(1,ni)-1))):1;
    Tail=Overlap(1,(ni*Ss-(L-1))+ index(1,ni)- 1:length(Overlap)).*fadeout;
    Begin=grain(1:length(fadein)).*fadein; Add=Tail+Begin; 
    Overlap=[Overlap(1,1:ni*Ss-L+index(1,ni)-1) Add grain(length(fadein)+1:N)];
end;
toc
% **** end TimeScaleSOLA loop ****

Overlap = Overlap';
Overlap = Overlap(1:Modified_length);








