V_ENFRAME split signal up into (overlapping) frames: one per row. [F,T]=(X,WIN,HOP) Usage: (1) f=v_enframe(x,n) % split into frames of length n (2) f=v_enframe(x,hamming(n,'periodic'),n/4) % use a 75% overlapped Hamming window of length n (3) calculate spectrogram in units of power per Hz W=hamming(NW); % analysis window (NW = fft length) P=v_enframe(S,W,HOP,'sdp',FS); % computer first half of PSD (HOP = frame increment in samples) (3) frequency domain frame-based processing: S=...; % input signal OV=2; % overlap factor of 2 (4 is also often used) NW=160; % DFT window length W=sqrt(hamming(NW,'periodic')); % omit sqrt if OV=4 [F,T,WS]=v_enframe(S,W,1/OV,'fa'); % do STFT: one row per time frame, +ve frequencies only ... process frames ... X=v_overlapadd(v_irfft(F,NW,2),WS,HOP); % reconstitute the time waveform with scaled window (omit "X=" to plot waveform) Inputs: x input signal win window or window length in samples hop frame increment or hop in samples or fraction of window [window length] m mode input: 'z' zero pad to fill up final frame 'r' reflect last few samples for final frame 'A' calculate the t output as the centre of mass 'E' calculate the t output as the centre of energy 'f' perform a 1-sided dft on each frame (like v_rfft) 'F' perform a 2-sided dft on each frame using fft 'p' calculate the 1-sided power/energy spectrum of each frame 'P' calculate the 2-sided power/energy spectrum of each frame 'a' scale window to give unity gain with overlap-add 's' scale window so that power is preserved: sum(mean(v_enframe(x,win,hop,'sp'),1))=mean(x.^2) 'S' scale window so that total energy is preserved: sum(sum(v_enframe(x,win,hop,'Sp'),2),1)=sum(x.^2) 'd' make options 's' and 'S' give power/energy per Hz: sum(mean(v_enframe(x,win,hop,'spd',fs),1))*fs/length(win)=mean(x.^2) fs sample frequency (only needed for 'd' option) [1] Outputs: f enframed data - one frame per row t fractional time in samples at the centre of each frame with the first sample being 1. w window function used including scaling By default, the number of frames will be rounded down to the nearest integer and the last few samples of x() will be ignored unless its length is lw more than a multiple of hop. If the 'z' or 'r' options are given, the number of frame will instead be rounded up and no samples will be ignored. The scaling options available in the 'm' input imply the follwoing approximate constraints which are only exact if the window is rectangular with no overlap and the input length is an exact number of frames. In the expressions below, ff=sum(f,2), lw=frame length, win is the unscaled window 'P','P' mean(ff) = mean(x.^2) * lw*sum(win.^2) 'ps','Ps' mean(ff) = mean(x.^2) 'pS','PS' sum(ff) = sum(x.^2) 'psd','Psd' mean(ff) * fs/lw = mean(x.^2) 'pSd','PSd' sum(ff) * fs/lw = sum(x.^2) / fs
0001 function [f,t,w]=v_enframe(x,win,hop,m,fs) 0002 %V_ENFRAME split signal up into (overlapping) frames: one per row. [F,T]=(X,WIN,HOP) 0003 % 0004 % Usage: (1) f=v_enframe(x,n) % split into frames of length n 0005 % (2) f=v_enframe(x,hamming(n,'periodic'),n/4) % use a 75% overlapped Hamming window of length n 0006 % (3) calculate spectrogram in units of power per Hz 0007 % 0008 % W=hamming(NW); % analysis window (NW = fft length) 0009 % P=v_enframe(S,W,HOP,'sdp',FS); % computer first half of PSD (HOP = frame increment in samples) 0010 % 0011 % (3) frequency domain frame-based processing: 0012 % 0013 % S=...; % input signal 0014 % OV=2; % overlap factor of 2 (4 is also often used) 0015 % NW=160; % DFT window length 0016 % W=sqrt(hamming(NW,'periodic')); % omit sqrt if OV=4 0017 % [F,T,WS]=v_enframe(S,W,1/OV,'fa'); % do STFT: one row per time frame, +ve frequencies only 0018 % ... process frames ... 0019 % X=v_overlapadd(v_irfft(F,NW,2),WS,HOP); % reconstitute the time waveform with scaled window (omit "X=" to plot waveform) 0020 % 0021 % Inputs: x input signal 0022 % win window or window length in samples 0023 % hop frame increment or hop in samples or fraction of window [window length] 0024 % m mode input: 0025 % 'z' zero pad to fill up final frame 0026 % 'r' reflect last few samples for final frame 0027 % 'A' calculate the t output as the centre of mass 0028 % 'E' calculate the t output as the centre of energy 0029 % 'f' perform a 1-sided dft on each frame (like v_rfft) 0030 % 'F' perform a 2-sided dft on each frame using fft 0031 % 'p' calculate the 1-sided power/energy spectrum of each frame 0032 % 'P' calculate the 2-sided power/energy spectrum of each frame 0033 % 'a' scale window to give unity gain with overlap-add 0034 % 's' scale window so that power is preserved: sum(mean(v_enframe(x,win,hop,'sp'),1))=mean(x.^2) 0035 % 'S' scale window so that total energy is preserved: sum(sum(v_enframe(x,win,hop,'Sp'),2),1)=sum(x.^2) 0036 % 'd' make options 's' and 'S' give power/energy per Hz: sum(mean(v_enframe(x,win,hop,'spd',fs),1))*fs/length(win)=mean(x.^2) 0037 % fs sample frequency (only needed for 'd' option) [1] 0038 % 0039 % Outputs: f enframed data - one frame per row 0040 % t fractional time in samples at the centre of each frame 0041 % with the first sample being 1. 0042 % w window function used including scaling 0043 % 0044 % By default, the number of frames will be rounded down to the nearest 0045 % integer and the last few samples of x() will be ignored unless its length 0046 % is lw more than a multiple of hop. If the 'z' or 'r' options are given, 0047 % the number of frame will instead be rounded up and no samples will be ignored. 0048 % 0049 % The scaling options available in the 'm' input imply the follwoing approximate 0050 % constraints which are only exact if the window is rectangular with no overlap 0051 % and the input length is an exact number of frames. 0052 % In the expressions below, ff=sum(f,2), lw=frame length, win is the unscaled window 0053 % 'P','P' mean(ff) = mean(x.^2) * lw*sum(win.^2) 0054 % 'ps','Ps' mean(ff) = mean(x.^2) 0055 % 'pS','PS' sum(ff) = sum(x.^2) 0056 % 'psd','Psd' mean(ff) * fs/lw = mean(x.^2) 0057 % 'pSd','PSd' sum(ff) * fs/lw = sum(x.^2) / fs 0058 0059 % Bugs/Suggestions: 0060 % (1) Possible additional mode options: 0061 % 'u' modify window for first and last few frames to ensure WOLA 0062 % 'a' normalize window to give a mean of unity after overlaps 0063 % 'e' normalize window to give an energy of unity after overlaps 0064 % 'wm' use Hamming window 0065 % 'wn' use Hanning window 0066 % 'x' hoplude all frames that hoplude any of the x samples 0067 0068 % Copyright (C) Mike Brookes 1997-2014 0069 % Version: $Id: v_enframe.m 10865 2018-09-21 17:22:45Z dmb $ 0070 % 0071 % VOICEBOX is a MATLAB toolbox for speech processing. 0072 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0073 % 0074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0075 % This program is free software; you can redistribute it and/or modify 0076 % it under the terms of the GNU General Public License as published by 0077 % the Free Software Foundation; either version 2 of the License, or 0078 % (at your option) any later version. 0079 % 0080 % This program is distributed in the hope that it will be useful, 0081 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0082 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0083 % GNU General Public License for more details. 0084 % 0085 % You can obtain a copy of the GNU General Public License from 0086 % http://www.gnu.org/copyleft/gpl.html or by writing to 0087 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0089 0090 nx=length(x(:)); 0091 if nargin<2 || isempty(win) 0092 win=nx; 0093 end 0094 if nargin<4 || isempty(m) 0095 m=''; 0096 end 0097 nwin=length(win); 0098 if nwin == 1 0099 lw = win; 0100 w = ones(1,lw); 0101 else 0102 lw = nwin; 0103 w = win(:).'; % force w to be a row vector 0104 end 0105 if (nargin < 3) || isempty(hop) 0106 hop = lw; % if no hop given, make non-overlapping 0107 elseif hop<1 0108 hop=round(lw*hop); % if hop<1 then it is a fraction of lw 0109 end 0110 wsc=1; % window scale factor 0111 if any(m=='a') 0112 wsc=sqrt(hop/(w*w')); % scale to give unity gain for overlap-add 0113 elseif any(m=='d') 0114 if nargin<5 || isempty(fs) 0115 fs=1; % default is fs=1 0116 end 0117 if any(m=='s') 0118 wsc=sqrt(1/(w*w'*fs)); 0119 elseif any(m=='S') 0120 wsc=sqrt(hop/(w*w'))/fs; 0121 end 0122 else 0123 if any(m=='s') 0124 wsc=sqrt(1/(w*w'*lw)); 0125 elseif any(m=='S') 0126 wsc=sqrt(hop/(w*w'*lw)); 0127 end 0128 end 0129 nli=nx-lw+hop; 0130 nf = max(fix(nli/hop),0); % number of full frames 0131 na=nli-hop*nf+(nf==0)*(lw-hop); % number of samples left over 0132 fx=nargin>3 && (any(m=='z') || any(m=='r')) && na>0; % need an extra row 0133 f=zeros(nf+fx,lw); 0134 indf= hop*(0:(nf-1)).'; 0135 inds = (1:lw); 0136 if fx 0137 f(1:nf,:) = x(indf(:,ones(1,lw))+inds(ones(nf,1),:)); 0138 if any(m=='r') 0139 ix=1+mod(nf*hop:nf*hop+lw-1,2*nx); 0140 f(nf+1,:)=x(ix+(ix>nx).*(2*nx+1-2*ix)); 0141 else 0142 f(nf+1,1:nx-nf*hop)=x(1+nf*hop:nx); 0143 end 0144 nf=size(f,1); 0145 else 0146 f(:) = x(indf(:,ones(1,lw))+inds(ones(nf,1),:)); 0147 end 0148 w=wsc*w; % scale the window 0149 if (nwin > 1) % if we have a non-unity window 0150 f = f .* repmat(w,nf,1); % ... multiply by the scaled window 0151 else % else if the unscaled window is unit-rectangular 0152 f = wsc*f; % ... just multiply by the scale factor 0153 end 0154 if any(lower(m)=='p') % 'pP' = calculate the power spectrum 0155 f=fft(f,[],2); % complex spectrum 0156 f=real(f.*conj(f)); % power spectrum 0157 if any(m=='p') % if need a 1-sided spectrum 0158 imx=fix((lw+1)/2); % highest replicated frequency 0159 f(:,2:imx)=f(:,2:imx)+f(:,lw:-1:lw-imx+2); % double all except DC and Nyquist 0160 f=f(:,1:fix(lw/2)+1); % keep only the positive frequencies 0161 end 0162 elseif any(lower(m)=='f') % 'fF' = take the DFT 0163 f=fft(f,[],2); 0164 if any(m=='f') 0165 f=f(:,1:fix(lw/2)+1); 0166 end 0167 end 0168 if nargout>1 0169 if any(m=='E') 0170 t0=sum((1:lw).*w.^2)/sum(w.^2); 0171 elseif any(m=='A') 0172 t0=sum((1:lw).*w)/sum(w); 0173 else 0174 t0=(1+lw)/2; 0175 end 0176 t=t0+hop*(0:(nf-1)).'; 0177 end 0178 0179