# v_overlapadd

## PURPOSE

V_OVERLAPADD join overlapping frames together X=(F,WIN,INC)

## SYNOPSIS

function [x,zo]=v_overlapadd(f,win,inc)

## DESCRIPTION

    V_OVERLAPADD join overlapping frames together X=(F,WIN,INC)

     Usage for frequency-domain processing:
           S=...;                              % input signal
           OV=2;                               % overlap factor of 2 (4 is also often used)
           INC=20;                             % set frame increment in samples
           NW=INC*OV;                          % DFT window length
           W=sqrt(hamming(NW,'periodic'));     % omit sqrt if OV=4
           W=W/sqrt(sum(W(1:INC:NW).^2));      % normalize window
           F=v_rfft(v_enframe(S,W,INC),NW,2);      % do STFT: one row per time frame, +ve frequencies only
           ... process frames ...
           X=v_overlapadd(v_irfft(F,NW,2),W,INC);  % reconstitute the time waveform (omit "X=" to plot waveform)

     Inputs:  F(NR,NW) contains the frames to be added together, one
                       frame per row.
              WIN(NW)  contains a window function to multiply each frame.
                       WIN may be omitted to use a default rectangular window
                       If processing the input in chunks, WIN should be replaced by
                       ZI on the second and subsequent calls where ZI is the saved
                       output state from the previous call.
              INC      gives the time increment (in samples) between
                       succesive frames [default = NW].

     Outputs: X(N,1) is the output signal. The number of output samples is N=NW+(NR-1)*INC.
              ZO     Contains the saved state to allow a long signal
                     to be processed in chunks. In this case X will contain only N=NR*INC
                     output samples.

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

## SOURCE CODE

    0001 function [x,zo]=v_overlapadd(f,win,inc)
    0002 %V_OVERLAPADD join overlapping frames together X=(F,WIN,INC)
    0003 %
    0004 % Usage for frequency-domain processing:
    0005 %       S=...;                              % input signal
    0006 %       OV=2;                               % overlap factor of 2 (4 is also often used)
    0007 %       INC=20;                             % set frame increment in samples
    0008 %       NW=INC*OV;                          % DFT window length
    0009 %       W=sqrt(hamming(NW,'periodic'));     % omit sqrt if OV=4
    0010 %       W=W/sqrt(sum(W(1:INC:NW).^2));      % normalize window
    0011 %       F=v_rfft(v_enframe(S,W,INC),NW,2);      % do STFT: one row per time frame, +ve frequencies only
    0012 %       ... process frames ...
    0013 %       X=v_overlapadd(v_irfft(F,NW,2),W,INC);  % reconstitute the time waveform (omit "X=" to plot waveform)
    0014 %
    0015 % Inputs:  F(NR,NW) contains the frames to be added together, one
    0016 %                   frame per row.
    0017 %          WIN(NW)  contains a window function to multiply each frame.
    0018 %                   WIN may be omitted to use a default rectangular window
    0019 %                   If processing the input in chunks, WIN should be replaced by
    0020 %                   ZI on the second and subsequent calls where ZI is the saved
    0021 %                   output state from the previous call.
    0022 %          INC      gives the time increment (in samples) between
    0023 %                   succesive frames [default = NW].
    0024 %
    0025 % Outputs: X(N,1) is the output signal. The number of output samples is N=NW+(NR-1)*INC.
    0026 %          ZO     Contains the saved state to allow a long signal
    0027 %                 to be processed in chunks. In this case X will contain only N=NR*INC
    0028 %                 output samples.
    0029 %
    0030
    0031 %       Copyright (C) Mike Brookes 2009
    0032 %      Version: $Id: v_overlapadd.m 10865 2018-09-21 17:22:45Z dmb $
    0033 %
    0034 %   VOICEBOX is a MATLAB toolbox for speech processing.
    0035 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
    0036 %
    0037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0038 %   This program is free software; you can redistribute it and/or modify
    0039 %   it under the terms of the GNU Lesser General Public License as published by
    0040 %   the Free Software Foundation; either version 3 of the License, or
    0041 %   (at your option) any later version.
    0042 %
    0043 %   This program is distributed in the hope that it will be useful,
    0044 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
    0045 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0046 %   GNU Lesser General Public License for more details.
    0047 %
    0048 %   You can obtain a copy of the GNU Lesser General Public License from
    0049 %   https://www.gnu.org/licenses/ .
    0050 %
    0051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0052 [nr,nf]=size(f);            % number of frames and frame length
    0053 if nargin<2
    0054     win=nf;                 % default increment
    0055 end
    0056 if isstruct(win)
    0057     w=win.w;
    0058     if ~numel(w) && length(w)~=nf
    0059         error('window length does not match frames size');
    0060     end
    0061     inc=win.inc;
    0062     xx=win.xx;
    0063 else
    0064     if nargin<3
    0065         inc=nf;
    0066     end
    0067     if numel(win)==1 && win==fix(win) && nargin<3       % win has been omitted
    0068         inc=win;
    0069         w=[];
    0070     else
    0071         w=win(:).';
    0072         if length(w)~=nf
    0073             error('window length does not match frames size');
    0074         end
    0075         if all(w==1)
    0076             w=[];
    0077         end
    0078     end
    0079     xx=[];      % partial output from previous call is null
    0080 end
    0081 nb=ceil(nf/inc);        % number of overlap buffers
    0082 no=nf+(nr-1)*inc;       % buffer length
    0083 z=zeros(no,nb);                      % space for overlapped output speech
    0084 if numel(w)
    0085     z(repmat(1:nf,nr,1)+repmat((0:nr-1)'*inc+rem((0:nr-1)',nb)*no,1,nf))=f.*repmat(w,nr,1);
    0086 else
    0087     z(repmat(1:nf,nr,1)+repmat((0:nr-1)'*inc+rem((0:nr-1)',nb)*no,1,nf))=f;
    0088 end
    0089 x=sum(z,2);
    0090 if ~isempty(xx)
    0091     x(1:length(xx))=x(1:length(xx))+xx;     % add on leftovers from previous call
    0092 end
    0093 if nargout>1            % check if we want to preserve the state
    0094     mo=inc*nr;          % completed output samples
    0095     if no<mo
    0096         x(mo,1)=0;
    0097         zo.xx=[];
    0098     else
    0099         zo.xx=x(mo+1:end);
    0100         zo.w=w;
    0101         zo.inc=inc;
    0102         x=x(1:mo);
    0103     end
    0104 elseif ~nargout
    0105     if isempty(xx)
    0106         k1=nf-inc;  % dubious samples at start
    0107     else
    0108         k1=0;
    0109     end
    0110     k2=nf-inc;      % dubious samples at end
    0111     plot(1+(0:nr-1)*inc,x(1+(0:nr-1)*inc),'>r',nf+(0:nr-1)*inc,x(nf+(0:nr-1)*inc),'<r', ...
    0112         1:k1+1,x(1:k1+1),':b',k1+1:no-k2,x(k1+1:end-k2),'-b',no-k2:no,x(no-k2:no),':b');
    0113     xlabel('Sample Number');
    0114     title(sprintf('%d frames of %d samples with %.0f%% overlap = %d samples',nr,nf,100*(1-inc/nf),no));
    0115 end