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')))=sum(x.^2) 'd' make options 's' and 'S' give power/energy per Hz: sum(mean(v_enframe(x,win,hop,'sp'),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 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.
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')))=sum(x.^2) 0036 % 'd' make options 's' and 'S' give power/energy per Hz: sum(mean(v_enframe(x,win,hop,'sp'),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 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 0050 % Bugs/Suggestions: 0051 % (1) Possible additional mode options: 0052 % 'u' modify window for first and last few frames to ensure WOLA 0053 % 'a' normalize window to give a mean of unity after overlaps 0054 % 'e' normalize window to give an energy of unity after overlaps 0055 % 'wm' use Hamming window 0056 % 'wn' use Hanning window 0057 % 'x' hoplude all frames that hoplude any of the x samples 0058 0059 % Copyright (C) Mike Brookes 1997-2014 0060 % Version: $Id: v_enframe.m 10865 2018-09-21 17:22:45Z dmb $ 0061 % 0062 % VOICEBOX is a MATLAB toolbox for speech processing. 0063 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0064 % 0065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0066 % This program is free software; you can redistribute it and/or modify 0067 % it under the terms of the GNU General Public License as published by 0068 % the Free Software Foundation; either version 2 of the License, or 0069 % (at your option) any later version. 0070 % 0071 % This program is distributed in the hope that it will be useful, 0072 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0073 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0074 % GNU General Public License for more details. 0075 % 0076 % You can obtain a copy of the GNU General Public License from 0077 % http://www.gnu.org/copyleft/gpl.html or by writing to 0078 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0080 0081 nx=length(x(:)); 0082 if nargin<2 || isempty(win) 0083 win=nx; 0084 end 0085 if nargin<4 || isempty(m) 0086 m=''; 0087 end 0088 nwin=length(win); 0089 if nwin == 1 0090 lw = win; 0091 w = ones(1,lw); 0092 else 0093 lw = nwin; 0094 w = win(:).'; 0095 end 0096 if (nargin < 3) || isempty(hop) 0097 hop = lw; % if no hop given, make non-overlapping 0098 elseif hop<1 0099 hop=lw*hop; 0100 end 0101 if any(m=='a') 0102 w=w*sqrt(hop/sum(w.^2)); % scale to give unity gain for overlap-add 0103 elseif any(m=='s') 0104 w=w/sqrt(w*w'*lw); 0105 elseif any(m=='S') 0106 w=w/sqrt(w*w'*lw/hop); 0107 end 0108 if any(m=='d') % scale to give power/energy densities 0109 if nargin<5 || isempty(fs) 0110 w=w*sqrt(lw); 0111 else 0112 w=w*sqrt(lw/fs); 0113 end 0114 end 0115 nli=nx-lw+hop; 0116 nf = max(fix(nli/hop),0); % number of full frames 0117 na=nli-hop*nf+(nf==0)*(lw-hop); % number of samples left over 0118 fx=nargin>3 && (any(m=='z') || any(m=='r')) && na>0; % need an extra row 0119 f=zeros(nf+fx,lw); 0120 indf= hop*(0:(nf-1)).'; 0121 inds = (1:lw); 0122 if fx 0123 f(1:nf,:) = x(indf(:,ones(1,lw))+inds(ones(nf,1),:)); 0124 if any(m=='r') 0125 ix=1+mod(nf*hop:nf*hop+lw-1,2*nx); 0126 f(nf+1,:)=x(ix+(ix>nx).*(2*nx+1-2*ix)); 0127 else 0128 f(nf+1,1:nx-nf*hop)=x(1+nf*hop:nx); 0129 end 0130 nf=size(f,1); 0131 else 0132 f(:) = x(indf(:,ones(1,lw))+inds(ones(nf,1),:)); 0133 end 0134 if (nwin > 1) % if we have a non-unity window 0135 f = f .* w(ones(nf,1),:); 0136 end 0137 if any(lower(m)=='p') % 'pP' = calculate the power spectrum 0138 f=fft(f,[],2); 0139 f=real(f.*conj(f)); 0140 if any(m=='p') 0141 imx=fix((lw+1)/2); % highest replicated frequency 0142 f(:,2:imx)=f(:,2:imx)+f(:,lw:-1:lw-imx+2); 0143 f=f(:,1:fix(lw/2)+1); 0144 end 0145 elseif any(lower(m)=='f') % 'fF' = take the DFT 0146 f=fft(f,[],2); 0147 if any(m=='f') 0148 f=f(:,1:fix(lw/2)+1); 0149 end 0150 end 0151 if nargout>1 0152 if any(m=='E') 0153 t0=sum((1:lw).*w.^2)/sum(w.^2); 0154 elseif any(m=='A') 0155 t0=sum((1:lw).*w)/sum(w); 0156 else 0157 t0=(1+lw)/2; 0158 end 0159 t=t0+hop*(0:(nf-1)).'; 0160 end 0161 0162