V_READSFS Read a .SFS format sound file [Y,FS,HD,FFX]=(FF,TY,SUB,MODE,NMAX,NSKIP,XPATH) Usage: [s,fs]=v_readsfs(filename,1); % read the last speech item in a file Input Parameters: FF gives the name of the file or alternatively can be the ffx output from a previous call to v_readsfs TY gives the type of data item required e.g.: 0 Main header, 1 Speech data, 2 Laryngograph, 5 Annotation SUB specifies the instance of type TY in the file: 0 for first (default), -1 for last or else it can specify the start of the processing history field as a string (e.g. 'hqtx') MODE specifies the following (*=default): File I/O: 'f' Do not close file on exit 'd' Look in data directory: v_voicebox('dir_data') Int Format: 'i' Force integer data to be at least 16 bits (some sfs files have a header error which falsely indicates 8-bit data) Create item: 'c' Create item if necessary Errors: 'x' Ignore errors NMAX maximum number of samples to read (or -1 for unlimited [default]) NSKIP number of samples or frames to skip from start of file (or -1 to continue from previous read when FFX is given instead of a filename [default]) XPATH (used with 'c' option) gives the full name of the program needed to generate the data or the directory containing it. Output Parameters: Y data matrix or cell matrix whose format depends on TY: TY=0: empty TY=5: cell array {nf,3} = {position length annotation} TY=1,2: column vector containing data TY=11: data array with one row per frame FS sample frequency in Hz HD cell matrix whose format depends on TY: TY=0: cell{14,1} {1} row vector {1}(1) = serial_date (see DATENUM() for format) {1}(2) = file_number {1}(3) = machine_type {2} = File type (= 'UC2') {3} = username of creator {4} = site of creator {5} = source {6} = database {7} = speaker name {8} = session code {9} = session date (as a string) {10} = name of token {11} = token repetition code {12} = recording conditions {13} = archiving details {14} = general comments TY>0: cell{4,1} {1} = (1,14) array: {1}(1) = processdate (see DATENUM() for format) {1}(2) = datatype: 1=speech, 2=lx, 3=tx cycle lengths, 4=fx freq 5=annotations, 6=phonetic, 7=synthesiser, 8=words 9=grey-level, 10=voicing, 11=energy, 12=formants 13=energy, 14=lpc, 15=markov, 16=acoustic, 17=?, 18=geometry, 19=aerodynamics, 20=articulatory 21=source, 22=physiological, 23=rational filter 24=poles/zeros, 25=glottal flow, 26=excitation model 27=nose, 28=calibration, 29=area {1}(3) = subtype {1}(4) = floating: 1=float, 0=int, -1=structure+ {1}(5) = datasize in bytes {1}(6) = framesize in units of datasize {1}(7) = numframes {1}(8) = length in bytes of data {1}(9) = frameduration=1/sample_rate {1}(10) = datapresent: 0=deleted, 1=present, 2=link {1}(11) = time offset {1}(12) = windowsize {1}(13) = overlap {1}(14) = lxsync {2} = processing history {3} = parameter field {4} = comment FFX cell array containing: {1} = filename {2} = (1,4) = [fid byte_order item_row values_read] {3} = (nitem,5) = one row per item [type subtype length position byteorder] with deleted items having a negative type and zero length {4} = {nitem,3} = cell: one row per item {processing parameters comment} text strings The SFS (Speech Filing System) is a package mostly written by Mark Huckvale and is available for UNIX and PC systems from http://www.phon.ucl.ac.uk/resource/sfs/
0001 function [y,fs,hd,ffx]=v_readsfs(ff,ty,sub,mode,nmax,nskip,xpath) 0002 %V_READSFS Read a .SFS format sound file [Y,FS,HD,FFX]=(FF,TY,SUB,MODE,NMAX,NSKIP,XPATH) 0003 % 0004 % Usage: [s,fs]=v_readsfs(filename,1); % read the last speech item in a file 0005 % 0006 % Input Parameters: 0007 % 0008 % FF gives the name of the file or alternatively 0009 % can be the ffx output from a previous call to v_readsfs 0010 % TY gives the type of data item required e.g.: 0011 % 0 Main header, 1 Speech data, 2 Laryngograph, 5 Annotation 0012 % SUB specifies the instance of type TY in the file: 0 for first (default), -1 for last or else 0013 % it can specify the start of the processing history field as a string (e.g. 'hqtx') 0014 % MODE specifies the following (*=default): 0015 % 0016 % File I/O: 'f' Do not close file on exit 0017 % 'd' Look in data directory: v_voicebox('dir_data') 0018 % Int Format: 'i' Force integer data to be at least 16 bits 0019 % (some sfs files have a header error which falsely indicates 8-bit data) 0020 % Create item: 'c' Create item if necessary 0021 % Errors: 'x' Ignore errors 0022 % 0023 % NMAX maximum number of samples to read (or -1 for unlimited [default]) 0024 % NSKIP number of samples or frames to skip from start of file 0025 % (or -1 to continue from previous read when FFX is given instead of a filename [default]) 0026 % XPATH (used with 'c' option) gives the full name of the program needed to generate the data or 0027 % the directory containing it. 0028 % 0029 % Output Parameters: 0030 % 0031 % Y data matrix or cell matrix whose format depends on TY: 0032 % TY=0: empty 0033 % TY=5: cell array {nf,3} = {position length annotation} 0034 % TY=1,2: column vector containing data 0035 % TY=11: data array with one row per frame 0036 % FS sample frequency in Hz 0037 % HD cell matrix whose format depends on TY: 0038 % TY=0: cell{14,1} 0039 % {1} row vector 0040 % {1}(1) = serial_date (see DATENUM() for format) 0041 % {1}(2) = file_number 0042 % {1}(3) = machine_type 0043 % {2} = File type (= 'UC2') 0044 % {3} = username of creator 0045 % {4} = site of creator 0046 % {5} = source 0047 % {6} = database 0048 % {7} = speaker name 0049 % {8} = session code 0050 % {9} = session date (as a string) 0051 % {10} = name of token 0052 % {11} = token repetition code 0053 % {12} = recording conditions 0054 % {13} = archiving details 0055 % {14} = general comments 0056 % TY>0: cell{4,1} 0057 % {1} = (1,14) array: 0058 % {1}(1) = processdate (see DATENUM() for format) 0059 % {1}(2) = datatype: 1=speech, 2=lx, 3=tx cycle lengths, 4=fx freq 0060 % 5=annotations, 6=phonetic, 7=synthesiser, 8=words 0061 % 9=grey-level, 10=voicing, 11=energy, 12=formants 0062 % 13=energy, 14=lpc, 15=markov, 16=acoustic, 17=?, 0063 % 18=geometry, 19=aerodynamics, 20=articulatory 0064 % 21=source, 22=physiological, 23=rational filter 0065 % 24=poles/zeros, 25=glottal flow, 26=excitation model 0066 % 27=nose, 28=calibration, 29=area 0067 % {1}(3) = subtype 0068 % {1}(4) = floating: 1=float, 0=int, -1=structure+ 0069 % {1}(5) = datasize in bytes 0070 % {1}(6) = framesize in units of datasize 0071 % {1}(7) = numframes 0072 % {1}(8) = length in bytes of data 0073 % {1}(9) = frameduration=1/sample_rate 0074 % {1}(10) = datapresent: 0=deleted, 1=present, 2=link 0075 % {1}(11) = time offset 0076 % {1}(12) = windowsize 0077 % {1}(13) = overlap 0078 % {1}(14) = lxsync 0079 % {2} = processing history 0080 % {3} = parameter field 0081 % {4} = comment 0082 % 0083 % FFX cell array containing: 0084 % {1} = filename 0085 % {2} = (1,4) = [fid byte_order item_row values_read] 0086 % {3} = (nitem,5) = one row per item [type subtype length position byteorder] 0087 % with deleted items having a negative type and zero length 0088 % {4} = {nitem,3} = cell: one row per item {processing parameters comment} text strings 0089 % 0090 % 0091 % The SFS (Speech Filing System) is a package mostly written by Mark Huckvale 0092 % and is available for UNIX and PC systems from 0093 % http://www.phon.ucl.ac.uk/resource/sfs/ 0094 0095 % Features yet to be implemented: 0096 % 0097 % (1) If no output parameters are specified, header information will be printed. 0098 % (2) following link items 0099 % (3) MODE options: 0100 % Scaling: 's' Auto scale to make data peak = +-1 0101 % 'r' Raw unscaled data (integer values) 0102 % 'q' Scaled to make 0dBm0 be unity mean square 0103 % 'p' * Scaled to make +-1 equal full scale 0104 % Errors 'r' Return if file is non-existant 0105 0106 0107 % Copyright (C) Mike Brookes 1998 0108 % Version: $Id: v_readsfs.m 10865 2018-09-21 17:22:45Z dmb $ 0109 % 0110 % VOICEBOX is a MATLAB toolbox for speech processing. 0111 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0112 % 0113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0114 % This program is free software; you can redistribute it and/or modify 0115 % it under the terms of the GNU General Public License as published by 0116 % the Free Software Foundation; either version 2 of the License, or 0117 % (at your option) any later version. 0118 % 0119 % This program is distributed in the hope that it will be useful, 0120 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0121 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0122 % GNU General Public License for more details. 0123 % 0124 % You can obtain a copy of the GNU General Public License from 0125 % http://www.gnu.org/copyleft/gpl.html or by writing to 0126 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0128 0129 if nargin<7 0130 xpath=v_voicebox('sfsbin'); % path for sfs programs 0131 end 0132 EXESUF=v_voicebox('sfssuffix'); % suffix for executable O/S dependent 0133 if nargin<4 || ~numel(mode) 0134 mode='p'; 0135 else 0136 mode = [mode(:).' 'p']; 0137 end 0138 if nargout==0 0139 if nargin<2 || ~numel(ty) || ty<=0 0140 [yy,fs,hd,ffx]=v_readsfs(ff,0,0,mode); 0141 fprintf(1,'File: %s\n',ffx{1}); 0142 fprintf(1,'Database: %s, Speaker: %s, Date: %s, Token: %s\n',hd{6},hd{7},hd{9},hd{10}); 0143 lst=ffx{3}; 0144 for it=2:size(lst,1); 0145 [yy,fs,hd,ffx]=v_readsfs(ffx,lst(it,1),lst(it,2),mode,0); 0146 nf=hd{1}(7); 0147 fd=hd{1}(9); 0148 fprintf(1,'%3d.%02d %ss @ %sHz (%d frames): %s\n',lst(it,1),lst(it,2),v_sprintsi(nf*fd),v_sprintsi(1/fd),nf,ffx{4}{it,1}); 0149 end 0150 end 0151 else 0152 it=[]; 0153 xfid=[]; % xfid will be non-empty second time around 0154 while (isempty(it)) % may go round this loop twice 0155 if ischar(ff) % If ff is a string we must read file 0156 if any(mode=='d') 0157 ff=fullfile(v_voicebox('dir_data'),ff); 0158 end 0159 fid=fopen(ff,'rb','b'); 0160 if fid == -1 error('Can''t open %s for input',ff); end 0161 0162 t=fread(fid,512,'uchar').'; 0163 if (t(1:3)~='UC2') 0164 error(sprintf('%s is not an SFS file type UC2',ff)) 0165 end 0166 itemlist = [0 1 0 0 t(512)]; 0167 proglist={}; 0168 for i=2:200 0169 pos = ftell(fid); 0170 [t,n]=fread(fid,512,'uchar'); 0171 if (n < 512) break; end 0172 mm=pow2(1,8*([0 1 2 3]+(t(512)==0)*[3 1 -1 -3])); 0173 itemlist(i,:)=[mm*[t(389:392) t(393:396) t(413:416)] pos t(512)]; 0174 if itemlist(i,1)>=2^31 0175 itemlist(i,1)=itemlist(i,1)-2^32; 0176 end 0177 if abs(itemlist(i,1))>29 0178 if any(mode=='x') 0179 itemlist(i,:)=[]; 0180 break; 0181 else 0182 error('%s: %d is not a valid SFS item type',ff,itemlist(i,1)); 0183 end 0184 end 0185 proglist{i,1}=char(zerotrim(t(1:256)')); 0186 proglist{i,2}=char(zerotrim(t(257:384)')); 0187 proglist{i,3}=char(zerotrim(t(437:456)')); 0188 seekstat=fseek(fid,itemlist(i,3),'cof'); 0189 if seekstat 0190 if any(mode=='x') 0191 itemlist(i,:)=[]; 0192 break; 0193 else 0194 error('%s: Unexpected end of file',ff); 0195 end 0196 end 0197 end 0198 ffx={ff; [fid 0 0 0]; itemlist; proglist}; 0199 else 0200 ffx=ff; 0201 ff=ffx{1}; 0202 fid=ffx{2}(1); 0203 if fid<0 0204 fid=fopen(ffx{1},'rb',char('b'+(ffx{2}(2)~=0)*('l'-'b'))); 0205 end 0206 end 0207 0208 % now try to find the requested item 0209 0210 list=ffx{3}; 0211 if nargin<2 ty=0; end 0212 if nargin<3 sub=0; end 0213 if ty<0 ty=list(1,1); end 0214 if ischar(sub) 0215 lsub=length(sub); 0216 proglist=ffx{4}; 0217 0218 for itt=size(proglist,1):-1:2 0219 if list(itt,1)==ty & length(proglist{itt,1})>=lsub 0220 if strcmpi(sub,proglist{itt,1}(1:lsub)) 0221 it=itt; 0222 end 0223 end 0224 end 0225 if (isempty(it)) 0226 if any(mode=='c') & isempty(xfid) % try to create item if we haven't tried before 0227 xfid=-1; 0228 if nargin>=7 0229 xname=xpath; 0230 xfid=fopen(xname); 0231 end 0232 if xfid<0 0233 if any('/\'==xpath(end)) % would be better to use fullfile() 0234 xname=[xpath sub EXESUF]; 0235 else 0236 xname=[xpath '/' sub EXESUF]; 0237 end 0238 xfid=fopen(xname); 0239 end 0240 if xfid<0 0241 error(sprintf('Cannot find executable program %s',sub)); 0242 else 0243 fclose(xfid); 0244 fclose(fid); % close this file 0245 doscom=['cmd /c "' xname '" ' ffx{1}]; 0246 %fprintf(1,'Executing: %s\n',doscom); 0247 if dos(doscom) % run the program 0248 error(sprintf('Error running DOS command: %s',doscom)); 0249 end 0250 ff=ffx{1}; % force reread of header information 0251 end 0252 else 0253 error(sprintf('Cannot find item %d.%s in file: %s',ty,sub,ff)); 0254 end 0255 end 0256 else % numeric subitem specification 0257 if sub>0 0258 it = find(list(:,1)==ty & list(:,2)==sub); 0259 elseif sub==0 0260 it = min(find(list(:,1)==ty)); 0261 else 0262 it = max(find(list(:,1)==ty)); 0263 end 0264 if (isempty(it)) 0265 error(sprintf('Cannot find item %d.%d in file: %s',ty,sub,ff)); 0266 end 0267 end 0268 end % loop up to two times while (isempty(it)) 0269 lit=list(it,:); 0270 if ffx{2}(3)~=it 0271 ffx{2}(3)=it; 0272 ffx{2}(4)=0; 0273 end 0274 0275 % read the selected item with the correct byte order 0276 0277 if lit(5)~=ffx{2}(2) 0278 fclose(fid); 0279 fid=fopen(ffx{1},'rb',char('b'+(lit(5)~=0)*('l'-'b'))); 0280 ffx{2}(1:2)=[fid lit(5)]; 0281 if fid == -1 error(sprintf('Can''t open %s for input',ff)); end 0282 end 0283 fseek(fid,lit(4),'bof'); 0284 0285 0286 y=[]; 0287 fs=0; 0288 if ~lit(1) % read main header 0289 mb=fread(fid,512,'uchar').'; 0290 if nargout>2 0291 mc=[1 4; 9 28; 29 32; 37 56; 57 76; 77 96; 97 116; 117 136; 137 296; 297 304; 305 312; 313 332; 333 412]; 0292 hd=cell(14,1); 0293 hd{1}=[pow2(1,8*([2 3 0 1]+(mb(512)==0)*[1 -1 1 -1]))*[mb(5:8); mb(33:36)].' mb(512)]; 0294 hd{1}(1)=hd{1}(1)/86400+719529; % convert date format 0295 for i=1:13 0296 hd{i+1}=char(v_zerotrim(mb(mc(i,1):mc(i,2)))); 0297 end 0298 end 0299 else 0300 0301 % read the item header 0302 0303 hd=cell(4,1); 0304 hdr=zeros(1,14); 0305 0306 [str,n]=fread(fid,256,'uchar'); 0307 if (n<256) error(sprintf('Error reading item %d.%d in file: %s',ty,sub,file)); end 0308 hd{2}=char(zerotrim(str')); 0309 0310 [str,n]=fread(fid,128,'uchar'); 0311 if (n<128) error(sprintf('Error reading item %d.%d in file: %s',ty,sub,file)); end 0312 hd{3}=char(zerotrim(str')); 0313 0314 hdr(1:8)=fread(fid,8,'long'); 0315 hdr(9)=fread(fid,1,'double'); 0316 if hdr(9) fs=1/hdr(9); end 0317 hdr(10)=fread(fid,1,'long'); 0318 hdr(11)=fread(fid,1,'double'); 0319 0320 [str,n]=fread(fid,20,'uchar'); 0321 if (n<20) error(sprintf('Error reading item %d.%d in file: %s',ty,sub,file)); end 0322 hd{4}=char(zerotrim(str')); 0323 0324 [hdr(12:14),n]=fread(fid,3,'long'); 0325 if (n<3) error(sprintf('Error reading item %d.%d in file: %s',ty,sub,file)); end 0326 fseek(fid,44,'cof'); 0327 hd{1}=hdr; 0328 hd{1}(1)=hd{1}(1)/86400+719529; % convert date format 0329 0330 % now read the actual data 0331 0332 if nargin<6 nskip=ffx{2}(4); 0333 elseif nskip<0 nskip=ffx{2}(4); 0334 end 0335 0336 ksamples=hdr(7)-nskip; 0337 if nargin>4 0338 if nmax>=0 0339 ksamples=min(nmax,ksamples); 0340 end 0341 end 0342 0343 if ksamples>0 0344 ffx{2}(4)=nskip+ksamples; 0345 fsz=hdr(6); 0346 if(hdr(10)==1) % data present 0347 if(hdr(4)>=0) % non-structured 0348 ds=hdr(5); 0349 if(hdr(4)>0) 0350 if(ds==4) fmt='float'; 0351 elseif (ds==8) fmt='double'; 0352 else error('error in sfs file'); end 0353 else 0354 if(ds==1 & all(mode~='i')) fmt='uchar'; 0355 elseif(ds<=2) fmt='short'; fsz=ceil(fsz*ds/2); 0356 elseif(ds==4) fmt='long'; 0357 else error('error in sfs file'); end 0358 end 0359 fseek(fid,lit(4)+512+nskip*fsz*ds,'bof'); 0360 nd=fsz*ksamples; 0361 [y,n]=fread(fid,nd,fmt); 0362 if (n<nd) error(sprintf('Error reading item %d.%d in file: %s',ty,sub,file)); end 0363 y = reshape(y,fsz,ksamples)'; 0364 else 0365 if (hdr(2)==5) 0366 y = cell(ksamples,3); 0367 for ifr=1:nskip 0368 lf=fread(fid,1,'uchar'); 0369 fseek(fid,lf,'cof'); 0370 end 0371 0372 for ifr=1:ksamples 0373 lf=fread(fid,1,'uchar'); 0374 tdat=fread(fid,2,'long'); 0375 y(ifr,:)={tdat(1) tdat(2) char(fread(fid,lf-9,'uchar').')}; 0376 lf=fread(fid,1,'uchar'); 0377 end 0378 else 0379 error(sprintf('Cannot convert item %d.%d in file: %s',ty,sub,file)); 0380 end 0381 end 0382 end 0383 end 0384 end 0385 if all(mode~='f') fclose(fid); ffx{2}(1)=-1; end 0386 end 0387 0388 0389 0390 0391 0392