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
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