Mercurial > hg > emotion-detection-top-level
comparison Code/Descriptors/yin/private/src/sf_info.m @ 4:92ca03a8fa99 tip
Update to ICASSP 2013 benchmark
author | Dawn Black |
---|---|
date | Wed, 13 Feb 2013 11:02:39 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:e1cfa7765647 | 4:92ca03a8fa99 |
---|---|
1 function i = sf_info(i) | |
2 % i=sf_info(i) - extract useful info from file | |
3 | |
4 % Alain de Cheveigné, CNRS/Ircam, 2002. | |
5 % Copyright (c) 2002 Centre National de la Recherche Scientifique. | |
6 % | |
7 % Permission to use, copy, modify, and distribute this software without | |
8 % fee is hereby granted FOR RESEARCH PURPOSES only, provided that this | |
9 % copyright notice appears in all copies and in all supporting | |
10 % documentation, and that the software is not redistributed for any | |
11 % fee (except for a nominal shipping charge). | |
12 % | |
13 % For any other uses of this software, in original or modified form, | |
14 % including but not limited to consulting, production or distribution | |
15 % in whole or in part, specific prior permission must be obtained from CNRS. | |
16 % Algorithms implemented by this software may be claimed by patents owned | |
17 % by CNRS, France Telecom, Ircam or others. | |
18 % | |
19 % The CNRS makes no representations about the suitability of this | |
20 % software for any purpose. It is provided "as is" without express | |
21 % or implied warranty. Beware of the bugs. | |
22 | |
23 if ~nargin ; error('sf_info: no input arguement'); end | |
24 if ~isa(i, 'struct') | |
25 j.fname=i; | |
26 i=j; | |
27 i=sf_info(i); | |
28 return | |
29 end | |
30 if ~isfield(i, 'fname'); error('sf_info: no fname field'); end | |
31 | |
32 % guess format only if unknown | |
33 if ~isfield(i, 'format') | isempty(i.format); | |
34 i = sf_format(i); | |
35 if ~strcmp(i.format, 'matrix') disp(i.format); end | |
36 end | |
37 | |
38 % handle workspace matrices as if they were files | |
39 if strcmp(i.format, 'matrix') | |
40 [nrows, ncols] = size(i.fname); | |
41 i.nchans=ncols; | |
42 i.nsamples=nrows; | |
43 i.totalsamples = i.nsamples*i.nchans; | |
44 i.sr=[]; | |
45 return; | |
46 end | |
47 | |
48 % close file if open | |
49 if exist('i.fd') & fopen(i.fd) | |
50 fclose(i.fd); | |
51 end | |
52 | |
53 % use standard matlab functions for AU and WAV and MACSND | |
54 if strcmp(i.format, 'AU') | |
55 if isempty(findstr('.', i.fname)) | |
56 disp(['WARNING: matlab function AUREAD requires '... | |
57 '.au or .snd suffix on file name: ' i.fname]); | |
58 end | |
59 sz = auread(i.fname, 'size'); | |
60 i.nsamples=sz(1); | |
61 i.nchans=sz(2); | |
62 i.totalsamples = i.nsamples*i.nchans; | |
63 [dummy, i.sr, i.samplebits] = auread(i.fname, 1); | |
64 return; | |
65 end | |
66 if strcmp(i.format, 'WAV') | |
67 if isempty(findstr('.wav', i.fname)) & isempty(findstr('.WAV', i.fname)) | |
68 disp(['WARNING: matlab function WAVREAD requires '... | |
69 '.wav suffix on file name: ' i.fname]); | |
70 end | |
71 sz = wavread(i.fname, 'size'); | |
72 i.nsamples=sz(1); | |
73 i.nchans=sz(2); | |
74 i.totalsamples = i.nsamples*i.nchans; | |
75 [dummy, i.sr, i.samplebits] = wavread(i.fname, 1); | |
76 return; | |
77 end | |
78 if strcmp(i.format, 'MACSND') | |
79 % must load the data to get info - this is stupid | |
80 if ~isempty(findstr(':', i.fname)) | |
81 disp(['matlab function READSND cannot handle an '... | |
82 'indirect path: ' i.fname]); | |
83 end | |
84 if 3==exist('readsnd') | |
85 [data, i.sr] = eval('readsnd(i.fname)'); | |
86 else | |
87 error('cannot read MACSND on this platform'); | |
88 end | |
89 i.nsamples = size(data,2); | |
90 i.nchans = size(data,1); | |
91 i.totalsamples = i.nsamples*i.nchans; | |
92 return | |
93 end | |
94 | |
95 % reopen file | |
96 if strcmp(i.format, 'ascii') ... | |
97 | strcmp(i.format, 'csv') | strcmp(i.format, '|WAVE') | |
98 [i.fd, msg] = fopen(i.fname, 'rt'); | |
99 else | |
100 [i.fd, msg] = fopen(i.fname, 'r', 'ieee-be.l64'); | |
101 end | |
102 if i.fd == -1 | |
103 if isempty(msg) | |
104 error(['could not open: ', i.fname]); | |
105 else | |
106 error(msg) | |
107 end | |
108 end | |
109 fd = i.fd; | |
110 if ~isfield(i, 'nbytes') | |
111 if (-1 == fseek(i.fd, 0, 1)) ; error ('fseek failed'); end; | |
112 i.nbytes = ftell(i.fd); | |
113 end | |
114 fseek(fd, 0, -1); % rewind | |
115 | |
116 | |
117 switch i.format | |
118 %%%%%%%%%%%%%%%%%%% AIFF %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
119 case {'AIFF','AIFC'} | |
120 fseek(fd, 12, 0); % skip container chunk | |
121 % skip over spurious chunks | |
122 idx=ftell(fd); | |
123 while 1 | |
124 magic=char(fread(fd,4,'uchar'))'; | |
125 if strcmp(magic,'COMM'); break; end; | |
126 idx = idx+1; | |
127 status = fseek(fd,idx,-1); | |
128 if status == -1 | |
129 error('expected COMM magic word, found eof'); | |
130 end; | |
131 end; | |
132 | |
133 %ckSize=fread(fd,1,'int32'); | |
134 %status = fseek(fd, ckSize, 0); % skip to end of chunk | |
135 %if status == -1 | |
136 % error('unexpected eof'); | |
137 %end | |
138 | |
139 %while (1) | |
140 % magic = char(fread(fd, 4, 'char'))'; | |
141 % if ~strcmp(magic, 'SSND') | |
142 % fseek(fd, -4, 0); % skip back | |
143 % break; | |
144 % end | |
145 % ckSize = fread(fd, 1, 'long'); | |
146 % fseek(fd, ckSize, 0); % skip to end of sound chunk | |
147 %end | |
148 %magic = char(fread (fd, 4, 'char'))'; | |
149 %if ~strcmp(magic, 'COMM'); error(['expected COMM, found ', magic]) ; end | |
150 commsz = fread(fd, 1, 'int32'); | |
151 i.nchans = fread(fd, 1, 'int16'); | |
152 i.nsamples = fread(fd, 1, 'uint32'); | |
153 i.totalsamples = i.nsamples*i.nchans; | |
154 i.samplebits = fread(fd, 1, 'int16'); | |
155 switch i.samplebits | |
156 case 16 | |
157 i.sample_bytes = 2; | |
158 i.sample_type = 'int16'; | |
159 case 32 | |
160 i.sample_bytes = 4; | |
161 i.sample_type = 'int32'; % or float? | |
162 otherwise | |
163 error(['unexpected samplebits: ' num2str(i.samplebits) ]); | |
164 end | |
165 % read sampling rate using Hideki Kawahara's code: | |
166 srex1=fread(fd,1,'uint16'); | |
167 srex2=fread(fd,1,'uint64'); | |
168 if strcmp(char(i.format),'AIFC') | |
169 compress=fread(fd,4,'uchar'); | |
170 if ~strcmp(char(compress),'NONE') | |
171 error('Compression is not supported.'); | |
172 end; | |
173 fseek(fd, commsz-22, 0); | |
174 end; | |
175 i.sr = 2^(srex1-16383)*srex2/hex2dec('8000000000000000'); | |
176 %fseek(fd, 12, -1); % skip back to end of container chunk | |
177 % skip over eventual common chunk | |
178 %while(1) | |
179 % magic = char(fread(fd, 4, 'char'))'; | |
180 % if ~strcmp(magic, 'COMM') | |
181 % fseek(fd, -4, 0); % skip back | |
182 % break; | |
183 % end | |
184 % ckSize = fread(fd, 1, 'long'); | |
185 % fseek(fd, ckSize, 0); % skip over chunk | |
186 %end | |
187 magic=char(fread(fd,4,'uchar'))'; | |
188 while ~strcmp(char(magic),'SSND') | |
189 [ckSize, count]=fread(fd,1,'int32'); | |
190 if ~count; | |
191 error('expected chunk size field, found eof'); | |
192 return | |
193 end | |
194 status = fseek(fd, ckSize, 0); % skip to end of chunk | |
195 if status == -1 | |
196 error('expected SSND magic word, found eof'); | |
197 return | |
198 end; | |
199 magic=char(fread(fd,4,'uchar'))'; | |
200 end; | |
201 | |
202 %magic = char(fread(fd, 4, 'char'))'; | |
203 %if ~strcmp(magic, 'SSND') | |
204 % error (['expected SSND, found' magic]); | |
205 %end | |
206 fseek(fd, 12, 0); % skip over ckSize, offset and blocksize fields | |
207 i.bytes_to_data = ftell(fd); | |
208 if i.totalsamples*i.sample_bytes ~= i.nbytes-i.bytes_to_data | |
209 disp(['WARNING: header fields sample_bytes: ' ... | |
210 num2str(i.sample_bytes)]); | |
211 disp (['and sample and channel count: ' num2str(i.nsamples) ... | |
212 ', ' num2str(i.nchans)]); | |
213 disp(['are inconsistent with offset to data: ' ... | |
214 num2str(i.bytes_to_data) ' and file size: ' ... | |
215 num2str(i.nbytes)]); | |
216 disp (['(' num2str(i.totalsamples*i.sample_bytes) ... | |
217 ' ~= ' num2str(i.nbytes-i.bytes_to_data) ')']); | |
218 end | |
219 | |
220 return | |
221 %%%%%%%%%%%%%%%%%%% NIST %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
222 case 'NIST' | |
223 % fseek(fd, 0, -1); | |
224 % line = fscanf(fd, '%s' , 1); | |
225 % if ~strcmp(line, 'NIST_1A'); error(['expected NIST_1A, found ', magic]); end | |
226 fseek(fd, 8, 0); % skip over magic string | |
227 i.bytes_to_data = fscanf(fd, '%d', 1); | |
228 while (1) | |
229 key = fscanf(fd, '%s', 1); | |
230 if strcmp(key, 'end_head'); break; end; | |
231 % read third field according to spec in second field (type) | |
232 % this may need refining... | |
233 type = fscanf(fd, '%s', 1); | |
234 if strcmp(type(1:2), '-s') | |
235 bytes_to_read = sscanf(type(3:end), '%d', 1); | |
236 fseek(fd, 1, 0); % skip blank | |
237 value = char(fread(fd, bytes_to_read, 'char'))'; | |
238 else | |
239 value = fscanf(fd, '%f', 1); | |
240 end | |
241 i = setfield(i, key, value); | |
242 end | |
243 % give standard names to useful fields | |
244 if isfield(i, 'channel_count'); i.nchans = i.channel_count; end | |
245 if isfield(i, 'sample_count'); i.nsamples = i.sample_count; end | |
246 i.totalsamples = i.nsamples*i.nchans; | |
247 if isfield(i, 'sample_rate'); | |
248 i.sr = i.sample_rate; | |
249 i.xunits = 's'; | |
250 end | |
251 if ~isfield(i, 'sample_coding'); i.sample_coding = 'pcm'; end | |
252 i.bytes_to_data = 1024; % needs checking | |
253 i.sample_bytes=2; | |
254 i.sample_type='int16'; | |
255 return | |
256 %%%%%%%%%%%%%%%%%%% |WAVE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
257 case '|WAV' | |
258 line = fscanf(fd, '%s' , 1); % skip first line | |
259 i.nsamples = fscanf(fd, '%d', 1); | |
260 i.nchans = fscanf(fd, '%d', 1); | |
261 i.totalsamples = i.nsamples*i.nchans; | |
262 i.bytes_to_data = ftell(fd); | |
263 % channel info handled during data read | |
264 i.totalsamples = i.nsamples * i.nchans; | |
265 return | |
266 %%%%%%%%%%%%%%%%%%% WFF %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
267 case 'wff' | |
268 fseek(fd, 4, 0); % skip magic number | |
269 i.version = fread(fd, 1, 'long'); | |
270 i.type_code = fread(fd, 1, 'long'); | |
271 i.nchans = fread(fd, 1, 'long'); | |
272 i.info.channel_flags = fread(fd, 1, 'long'); | |
273 i.bytes_to_data = fread(fd, 1, 'long'); | |
274 fseek(fd, 40, 0); | |
275 i.gen_prog_name = fread(fd, 32, 'char'); | |
276 i.comment = fread(fd, 32, 'char'); | |
277 i.sample_bytes = 2; | |
278 i.sample_type = 'int16'; | |
279 return; | |
280 % channel info handled later during channel read | |
281 %%%%%%%%%%%%%%%%%%% ESPS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
282 case 'ESPS' | |
283 % Based on Peter Kabal's afsp package. | |
284 % This handles at least one kind of ESPS waveform file. Others? | |
285 i.machine_code = fread(fd, 1, 'uint'); | |
286 i.version_check_code = fread(fd, 1, 'uint'); | |
287 i.bytes_to_data = fread(fd, 1, 'uint'); | |
288 i.record_size = fread(fd, 1, 'uint'); | |
289 fseek(fd, 20, -1); | |
290 i.EDR_ESPS_flag = fread(fd, 1, 'uint'); | |
291 i.align_pad_size = fread(fd, 1, 'uint'); | |
292 fseek(fd, 32, -1); | |
293 i.file_type = fread(fd, 1, 'uint16'); | |
294 fseek(fd, 40, -1); | |
295 i.file_creation_date_time = char(fread(fd, 26, 'char'))'; | |
296 i.header_version = char(fread(fd, 8, 'char'))'; | |
297 i.program_name = char(fread(fd, 16, 'char'))'; | |
298 i.program_version = char(fread(fd, 8, 'char'))'; | |
299 i.compile_date = char(fread(fd, 26, 'char'))'; | |
300 i.tag = fread(fd, 1, 'uint'); | |
301 fseek(fd, 132, -1); | |
302 i.ndoubles = fread(fd, 1, 'uint'); | |
303 i.nfloats = fread(fd, 1, 'uint'); | |
304 i.nlongs = fread(fd, 1, 'uint'); | |
305 i.nshorts = fread(fd, 1, 'uint'); | |
306 i.nchars = fread(fd, 1, 'uint'); | |
307 i.fixed_header_size = fread(fd, 1, 'uint'); | |
308 i.var_header_size = fread(fd, 1, 'uint'); | |
309 %w.dunno_what = fread(fd, 1, 'uint'); | |
310 fseek(fd, 160, -1); | |
311 i.user = char(fread(fd, 8, 'char'))'; | |
312 % scan the rest of the header to find sampling rate | |
313 a = ftell(fd); | |
314 bytes_left_in_header = i.bytes_to_data - ftell(fd); | |
315 hunk = char(fread(fd, bytes_left_in_header, 'uchar'))'; | |
316 b = findstr(hunk, 'record_freq'); | |
317 %fseek(fd, a+b-1, -1); | |
318 %w.xxxx = char(fread(fd, 12, 'char'))'; | |
319 %w.count = fread(fd, 1, 'uint'); | |
320 %w.data_code = fread(fd, 1, 'ushort'); | |
321 fseek(fd, a+b-1+12+2+4, -1); | |
322 i.sr = fread(fd, 1, 'double'); | |
323 i.nchans = i.ndoubles+i.nfloats+i.nlongs ... | |
324 +i.nshorts+i.nchars; | |
325 recordsize = i.ndoubles*8 + i.nfloats*4 + i.nlongs*4 ... | |
326 +i.nshorts*2+i.nchars; | |
327 i.nsamples = (i.nbytes - i.bytes_to_data) / recordsize; | |
328 i.totalsamples = i.nsamples * i.nchans; | |
329 i.sample_bytes = 2; % bug | |
330 i.sample_type = 'int16'; % bug | |
331 return; | |
332 %%%%%%%%%%%%% PLAIN ASCII %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
333 case 'ascii' | |
334 if isfield(i, 'bytes_to_data') | |
335 fseek(fd, i.bytes_to_data, 0); | |
336 else | |
337 i.bytes_to_data = 0; | |
338 end | |
339 line = fgetl(fd); | |
340 i.nchans = size(sscanf(line, '%f'), 1); | |
341 nlines = 1; | |
342 while (1) | |
343 line = fgets(i.fd); | |
344 if isa(line, 'double') & -1 == line; break; end | |
345 nlines = nlines+1; | |
346 end | |
347 i.nsamples = nlines; | |
348 i.totalsamples = i.nsamples*i.nchans; | |
349 i.sr=1; | |
350 return | |
351 %%%%%%%%%%%%% COMMA-SEPARATED VALUES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
352 case 'csv'; | |
353 if isfield(i, 'bytes_to_data') | |
354 fseek(fd, i.bytes_to_data, 0); | |
355 else | |
356 i.bytes_to_data = 0; | |
357 end | |
358 % todo | |
359 return | |
360 %%%%%%%%%%%%% Binary %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
361 case {'uchar'}; % should take care of signed/unsigned | |
362 i.sample_bytes = 1; | |
363 i.sample_type = 'uchar'; | |
364 if isfield(i, 'bytes_to_data') | |
365 fseek(fd, i.bytes_to_data, 0); | |
366 else | |
367 i.bytes_to_data = 0; | |
368 end | |
369 if ~isfield(i, 'nchans') | |
370 i.nchans = 1; | |
371 end | |
372 i.nsamples = (i.nbytes-i.bytes_to_data)/i.sample_bytes; | |
373 i.totalsamples = i.nsamples * i.nchans; | |
374 i.sr=1; | |
375 return | |
376 case {'short', 'int16'}; | |
377 i.sample_bytes = 2; | |
378 i.sample_type = 'int16'; | |
379 if isfield(i, 'bytes_to_data') | |
380 fseek(fd, i.bytes_to_data, 0); | |
381 else | |
382 i.bytes_to_data = 0; | |
383 end | |
384 if ~isfield(i, 'nchans') | |
385 i.nchans = 1; | |
386 end | |
387 i.nsamples = (i.nbytes-i.bytes_to_data)/i.sample_bytes; | |
388 i.totalsamples = i.nsamples * i.nchans; | |
389 i.sr=1; | |
390 return | |
391 case {'long', 'int32'}; | |
392 i.sample_bytes = 4; | |
393 i.sample_type = 'int32'; | |
394 if isfield(i, 'bytes_to_data') | |
395 fseek(fd, i.bytes_to_data, 0); | |
396 else | |
397 i.bytes_to_data = 0; | |
398 end | |
399 if ~isfield(i, 'nchans') | |
400 i.nchans = 1; | |
401 end | |
402 i.nsamples = (i.nbytes-i.bytes_to_data)/i.sample_bytes; | |
403 i.totalsamples = i.nsamples * i.nchans; | |
404 i.sr=1; | |
405 return | |
406 case {'float', 'float32'}; | |
407 i.sample_bytes = 4; | |
408 i.sample_type = 'float32'; | |
409 if isfield(i, 'bytes_to_data') | |
410 fseek(fd, i.bytes_to_data, 0); | |
411 else | |
412 i.bytes_to_data = 0; | |
413 end | |
414 if ~isfield(i, 'nchans') | |
415 i.nchans = 1; | |
416 end | |
417 i.nsamples = (i.nbytes-i.bytes_to_data)/i.sample_bytes; | |
418 i.totalsamples = i.nsamples * i.nchans; | |
419 i.sr=1; | |
420 return | |
421 case {'double', 'float64'}; | |
422 i.sample_bytes = 8; | |
423 i.sample_type = 'float64'; | |
424 if isfield(i, 'bytes_to_data') | |
425 fseek(fd, i.bytes_to_data, 0); | |
426 else | |
427 i.bytes_to_data = 0; | |
428 end | |
429 if ~isfield(i, 'nchans') | |
430 i.nchans = 1; | |
431 end | |
432 i.nsamples = (i.nbytes-i.bytes_to_data)/i.sample_bytes; | |
433 i.totalsamples = i.nsamples * i.nchans; | |
434 i.sr=1; | |
435 return | |
436 otherwise | |
437 error(['unknown format: >' i.format '<']); | |
438 end |