# v_istftw

## PURPOSE

V_ISTFTW converts a time-frequency domain signal back into the time domain with the inverse Short-time Fourier Transform [X,IO]=(Y,SO,IOP)

## SYNOPSIS

function [x,io]=v_istftw(y,so,iop)

## DESCRIPTION

    V_ISTFTW converts a time-frequency domain signal back into the time domain with the inverse Short-time Fourier Transform [X,IO]=(Y,SO,IOP)

     For usage information, see v_stftw().

      Inputs: y(f,k,...)    STFT (frame=f, freq=k)
              so           The 'so' output from the call to v_stftw.
                           If processing the signal in chunks, this should come from
                           the v_stftw call corresponding to the most recent
                           chunk.
              iop          The 'io' output from the previous chunk's call to v_istftw.
                           Omit for the first chunk or else use iop=[].

     Outputs: x(t,...)     Output signal
              io           structure used in subsequent call as the iop argument to
                           alllow processing in chunks. Omit this argument for
                           the final chunk.

     Revision History
        2022-04-10 First version

## CROSS-REFERENCE INFORMATION

This function calls:

- v_irfft V_IRFFT Inverse fft of a conjugate symmetric spectrum X=(Y,N,D)

This function is called by:

## SOURCE CODE

    0001 function [x,io]=v_istftw(y,so,iop)
    0002 %V_ISTFTW converts a time-frequency domain signal back into the time domain with the inverse Short-time Fourier Transform [X,IO]=(Y,SO,IOP)
    0003 %
    0004 % For usage information, see v_stftw().
    0005 %
    0006 %  Inputs: y(f,k,...)    STFT (frame=f, freq=k)
    0007 %          so           The 'so' output from the call to v_stftw.
    0008 %                       If processing the signal in chunks, this should come from
    0009 %                       the v_stftw call corresponding to the most recent
    0010 %                       chunk.
    0011 %          iop          The 'io' output from the previous chunk's call to v_istftw.
    0012 %                       Omit for the first chunk or else use iop=[].
    0013 %
    0014 % Outputs: x(t,...)     Output signal
    0015 %          io           structure used in subsequent call as the iop argument to
    0016 %                       alllow processing in chunks. Omit this argument for
    0017 %                       the final chunk.
    0018 %
    0019 % Revision History
    0020 %    2022-04-10 First version
    0021 sy=size(y);
    0022 nf=sy(1);
    0023 nc=prod(sy(3:end));
    0024 % extract quantities from so structure
    0025 nh=so.nh;                       % frame hop
    0026 nt=so.nt;                       % length of transform
    0027 ws=nh*nt*so.wa;                 % synthesis window for perfect reconstruction
    0028 nw=length(ws);                  % length of window
    0029 ov=nw/nh;                       % overlap factor (always an integer)
    0030 if nargin>2 && isstruct(iop)
    0031     md=iop.md;                     % remaining samples to delete at the start
    0032     xx=iop.xx;                     % tail from previous call
    0033     mx=iop.mx;                     % cumulative number of output samples
    0034 else                            % first chunk if iop input is missing
    0035     md=nh*(ov-1)*so.me;         % number of samples to delete at the start of the signal
    0036     xx=zeros(0,nc,1);           % no tail from previous call
    0037     mx=0;                       % cumulative number of output samples
    0038 end
    0039 if nf>0
    0040     y=v_irfft(reshape(y,[sy(1:2) nc]),nt,2);    % inverse dft
    0041     y=y(:,1:nw,:).*repmat(ws,nf,1,nc);          % truncate to nw and apply output window
    0042     om=min(ov,nf);                              % number of occupied overlap sets
    0043     if numel(xx)>0
    0044         x=zeros(nw+nh*(nf-1),nc,min(ov,nf+1));    % space for output including saved data
    0045         x(1:size(xx,1),:,end)=xx;               % insert output speech tail (already overlap-added)
    0046     else
    0047         x=zeros(nw+nh*(nf-1),nc,om);            % space for output
    0048     end
    0049     for i=1:om
    0050         nm=nw*(1+floor((nf-i)/ov));             % number of samples in this column
    0051         x(1+(i-1)*nh:nm+(i-1)*nh,:,i)=reshape(permute(y(i:ov:nf,:,:),[2 1 3]),nm,nc); % concatenate every ov'th frame
    0052     end
    0053     x=sum(x,3);                                 % perform the overlap-add
    0054     if nargout>1
    0055         t0=nw-nh-1;
    0056         io.xx=x(end-t0:end,:);                  % save tail for overlap-adding next chunk
    0057         x(end-t0:end,:)=[];                     % ... and remove it
    0058     end
    0059     if md>0
    0060         mdd=min(md,size(x,1));
    0061         x(1:mdd,:)=[];                          % delete initial samples
    0062         md=md-mdd;
    0063     end
    0064     if so.mp==0 && size(x,1)>0 && mx+size(x,1)>so.mx
    0065         x(end+so.mx-mx-size(x,1)+1:end,:)=[];   % delete unwanted samples at the end
    0066     end
    0067     if nargout>1
    0068         io.md=md;                               % save number of sampes to delete at start
    0069         io.mx=mx+size(x,1);                     % cumulative number of output samples
    0070     end
    0071     if nc>1
    0072         x=reshape(x,[size(x,1) sy(3:end)]);
    0073     end
    0074 else                                            % no input frames
    0075     if nargout>1                                % io output required
    0076         if nargin>2
    0077             io=iop;                             % copy from input structure if available
    0078         else
    0079         end
    0080     end
    0081     if nc>1
    0082         x=zeros([0 sy(3:end)]);
    0083     else
    0084         x=[];
    0085     end
    0086 end
    0087
    0088
    0089
    0090
    0091