V_FRAM2WAV converts frame values to a continuous waveform [W]=(X,TT,MODE) Inputs: x(nf,p) is the input signal: one row per frame tt(nf,3) specifies the frames. Each row has the form [start_sample end_sample flag] where flag = 1 for the start of a new spurt. If tt(:,3) is omitted, a new spurt will be started whenever there is a gap of more than one between the end of one frame and the beginning or the next. A new spurt is automatically started if x() = NaN. mode consists of one or more of the following letters: z for zero-order hold interpolation (i.e. constant within each frame) l for linear interpolation within each spurt [default] Outputs: w(n,p) contains the interpolated waveforms. Their length is n = tt(nf,2) s(ns,2) gives the starting and ending sample numbers of each spurt (excluding NaN spurts) This routine converts frame-based values to continuous waveforms by performing a chosen method of interpolation. Interpolation is restarted at the beginning of each spurt.
0001 function [w,s]=v_fram2wav(x,tt,mode) 0002 %V_FRAM2WAV converts frame values to a continuous waveform [W]=(X,TT,MODE) 0003 % Inputs: 0004 % x(nf,p) is the input signal: one row per frame 0005 % tt(nf,3) specifies the frames. Each row has the form [start_sample end_sample flag] 0006 % where flag = 1 for the start of a new spurt. 0007 % If tt(:,3) is omitted, a new spurt will be started whenever there is a gap 0008 % of more than one between the end of one frame and the beginning or the next. 0009 % A new spurt is automatically started if x() = NaN. 0010 % mode consists of one or more of the following letters: 0011 % z for zero-order hold interpolation (i.e. constant within each frame) 0012 % l for linear interpolation within each spurt [default] 0013 % 0014 % Outputs: 0015 % w(n,p) contains the interpolated waveforms. Their length is n = tt(nf,2) 0016 % s(ns,2) gives the starting and ending sample numbers of each spurt (excluding NaN spurts) 0017 % 0018 % This routine converts frame-based values to continuous waveforms by performing 0019 % a chosen method of interpolation. Interpolation is restarted at the beginning of each spurt. 0020 0021 % Bugs/Suggestions 0022 % (1) Additional mode option for cubic interpolation 0023 % (2) Additional mode option for interpolation in log domain 0024 % (3) Additional mode option for x values being 0025 % frame averages rather than mid-frame values. 0026 0027 % Copyright (C) Mike Brookes 1997 0028 % Version: $Id: v_fram2wav.m 10865 2018-09-21 17:22:45Z dmb $ 0029 % 0030 % VOICEBOX is a MATLAB toolbox for speech processing. 0031 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0032 % 0033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0034 % This program is free software; you can redistribute it and/or modify 0035 % it under the terms of the GNU General Public License as published by 0036 % the Free Software Foundation; either version 2 of the License, or 0037 % (at your option) any later version. 0038 % 0039 % This program is distributed in the hope that it will be useful, 0040 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0041 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0042 % GNU General Public License for more details. 0043 % 0044 % You can obtain a copy of the GNU General Public License from 0045 % http://www.gnu.org/copyleft/gpl.html or by writing to 0046 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0048 0049 if nargin<3 0050 mode='l'; 0051 end 0052 [nf,m]=size(x); 0053 n=round(tt(end,2)); 0054 w=repmat(NaN,n,m); 0055 nt=size(tt,2); 0056 ix1=ceil(tt(:,1)); % start of frame sample 0057 ix2=floor(tt(:,2)); % end of frame sample 0058 0059 % determine the start and end of spurts 0060 0061 if nt>2 0062 ty=tt(:,3)>0; % frame type set by user 0063 else 0064 ty=zeros(nf,1); 0065 ty(2:end)=ix1(2:end)>ix2(1:end-1)+1; % new spurt whenever a gap 0066 end 0067 ty(1)=1; % first frame always starts a spurt 0068 ty(isnan(x))=1; % NaN always ends previous spurt 0069 ty(1+find(isnan(x(1:end-1))))=1; % NaN always forces a new spurt 0070 ty=double(ty); 0071 ty(1:end-1)=ty(1:end-1)+2*ty(2:end); 0072 ty(end)=ty(end)+2; % last frame always ends a spurtw=repmat(NaN,n,m); % initialize output to all NaN 0073 nx=ix2-ix1+1; 0074 0075 if any(mode=='z') % zero-order hold 0076 for i=1:nf 0077 if nx(i) 0078 w(ix1(i):ix2(i),:)=repmat(x(i,:),nx(i),1); 0079 end 0080 end 0081 else % linear interpolation is the default 0082 ttm=(tt(:,1)+tt(:,2))/2; % mid point of frame 0083 ixm=floor(ttm); % end of first half of frame 0084 for i=1:nf 0085 if i==176 0086 i 0087 end 0088 if nx(i) 0089 tyi=ty(i); 0090 if tyi==3 % use a zero order hold 0091 w(ix1(i):ix2(i),:)=repmat(x(i,:),nx(i),1); 0092 else 0093 nxm=ixm(i)-ix1(i)+1; 0094 if nxm 0095 if tyi==1 0096 grad=(x(i+1,:)-x(i,:))/(ttm(i+1)-ttm(i)); 0097 else 0098 grad=(x(i,:)-x(i-1,:))/(ttm(i)-ttm(i-1)); 0099 end 0100 w(ix1(i):ixm(i),:)=repmat(x(i,:),nxm,1)+((ix1(i):ixm(i))'-ttm(i))*grad; 0101 end 0102 if nx(i)>nxm 0103 if tyi==2 0104 grad=(x(i,:)-x(i-1,:))/(ttm(i)-ttm(i-1)); 0105 else 0106 grad=(x(i+1,:)-x(i,:))/(ttm(i+1)-ttm(i)); 0107 end 0108 w(ixm(i)+1:ix2(i),:)=repmat(x(i,:),ix2(i)-ixm(i),1)+((ixm(i)+1:ix2(i))'-ttm(i))*grad; 0109 end 0110 end 0111 end 0112 end 0113 end 0114 0115 % now sort out the start and end spurt positions 0116 0117 ty(isnan(x))=0; % Don't count NaN spurts 0118 s=repmat(ix1(bitand(ty,1)>0),1,2); 0119 s(:,2)=ix2(bitand(ty,2)>0); 0120 if ~nargout 0121 tw=(1:n)'; 0122 for i=size(s,1):-1:2 0123 j=s(i,1); % start of new spurt 0124 tw=[tw(1:j-1); tw(j); tw(j:end)]; 0125 w=[w(1:j-1); NaN; w(j:end)]; % insert a NaN to force a plotting break 0126 end 0127 plot(tt(:,1:2)',repmat(x(:)',2,1),'r-+',tw,w,'b-'); 0128 end 0129