"Fossies" - the Fresh Open Source Software Archive 
Member "speech_tools/speech_class/esps_utils.cc" (4 Sep 2017, 34616 Bytes) of package /linux/misc/speech_tools-2.5.0-release.tar.gz:
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1994,1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Alan W Black (and Paul Taylor) */
34 /* Date : June 1996 */
35 /*-----------------------------------------------------------------------*/
36 /* These routines form a basis for reading and writing Entropic's ESPS */
37 /* headered files. The reason we wrote them was to avoid including */
38 /* Entropic's own (large and cumbersome) code into all our programs. */
39 /* No Entropic proprietary code is included in this code which means */
40 /* you do not needs an Entropic licence to use it. */
41 /* */
42 /* However this should not be seen as anti-Entropic in anyway it is for */
43 /* our and your convenience. We would like to specifically thank */
44 /* Rodney Johnson of Entropic for giving us help and confirming to us */
45 /* the header format is in fact more complex than one can imagine, */
46 /* mostly for very bad reasons, (backward compatibility cripples all */
47 /* software in the long run). Hence this code is almost definitely */
48 /* incomplete and is not guaranteed to read or create all ESPS files */
49 /* properly but it is adequate for many tasks. */
50 /* */
51 /* Also thanks go to Peter Kabal from McGill University whose AF code */
52 /* showed me this might be worth attempting, his code gave me something */
53 /* to look at to start with. */
54 /* */
55 /* I should add, this wasn't easy to write, though I'm much better at */
56 /* octal and hex dumps now. */
57 /*=======================================================================*/
58
59 #include <cstdio>
60 #include <cstdlib>
61 #include "EST_unix.h"
62 #include <cstring>
63 #include <time.h>
64 #include "EST_wave_utils.h"
65 #include "esps_utils.h"
66
67 /* First you must realise there is in fact a number of very similar but */
68 /* subtly different header formats that appear on ESPS files. */
69 /* ESPS_FEA and ESPS_SD (others for filters, spectrograms, etc) */
70 /* The basic format is */
71 /* preamble */
72 /* fixed header */
73 /* variable header */
74 /* field descriptions (type and dimensions) */
75 /* field names */
76 /* header FEAs (maybe with values) */
77 /* old and foreign headers (mostly ignored here) */
78 /* data records themselves */
79
80 /* esps_fea contain a name and possibly a value. They appear in the */
81 /* variable part of the header */
82 esps_fea new_esps_fea()
83 {
84 esps_fea r = walloc(struct ESPS_FEA_struct,1);
85 r->type = 0;
86 r->clength = 0;
87 r->name = NULL;
88 r->dtype = 0;
89 r->count = 0;
90 r->v.ival = NULL;
91 return r;
92 }
93
94 void delete_esps_fea(esps_fea r)
95 {
96 esps_fea t,u;
97
98 for (t=r; t != NULL; t=u)
99 {
100 if (t->clength != 0)
101 wfree(t->name);
102 if (t->count != 0) /* this wont work if fields in v aren't aligned */
103 wfree(t->v.ival);
104 u = t->next;
105 wfree(t);
106 }
107 }
108
109 void print_esps_fea(esps_fea r)
110 {
111 /* Print out the information in the FEA record */
112 int i;
113
114 fprintf(stdout,"type: %d\n",r->type);
115 fprintf(stdout,"name: %s\n",r->name);
116 fprintf(stdout,"size: %d\n",r->count);
117 fprintf(stdout,"dtype: %d\n",r->dtype);
118 for (i=0; i<r->count; i++)
119 switch (r->dtype)
120 {
121 case ESPS_DOUBLE:
122 fprintf(stdout," %d: %g\n",i,r->v.dval[i]); break;
123 case ESPS_FLOAT:
124 fprintf(stdout," %d: %f\n",i,r->v.fval[i]); break;
125 case ESPS_INT:
126 fprintf(stdout," %d: %d\n",i,r->v.ival[i]); break;
127 case ESPS_SHORT:
128 fprintf(stdout," %d: %d\n",i,r->v.sval[i]); break;
129 case ESPS_CHAR:
130 fprintf(stdout," %d: %d\n",i,r->v.cval[i]); break;
131 default:
132 fprintf(stdout," %d: unknown\n",i);
133 }
134 }
135
136 void add_field(esps_hdr hdr, const char *name, int type, int dimension)
137 {
138 /* Add a new field to the record */
139 char **names = hdr->field_name;
140 short *types = hdr->field_type;
141 int *dims = hdr->field_dimension;
142 int i;
143
144 hdr->field_name = walloc(char *,hdr->num_fields+1);
145 hdr->field_type = walloc(short,hdr->num_fields+1);
146 hdr->field_dimension = walloc(int,hdr->num_fields+1);
147 for (i=0; i < hdr->num_fields; i++)
148 {
149 hdr->field_name[i] = names[i];
150 hdr->field_type[i] = types[i];
151 hdr->field_dimension[i] = dims[i];
152 }
153 wfree(names);
154 wfree(types);
155 wfree(dims);
156 hdr->field_name[hdr->num_fields] = wstrdup(name);
157 hdr->field_type[hdr->num_fields] = type;
158 hdr->field_dimension[hdr->num_fields] = dimension;
159 hdr->num_fields++;
160
161 return;
162
163 }
164
165 void add_fea_d(esps_hdr hdr,const char *name, int pos, double d)
166 {
167 /* Add a double FEA field to the header */
168 esps_fea t = new_esps_fea();
169 int i;
170
171 t->type = 13; /* must be lucky for some !! */
172 t->clength = strlen(name);
173 t->name = wstrdup(name);
174 if (t->count < pos+1)
175 {
176 double *dval = t->v.dval;
177 t->v.dval = walloc(double,pos+1);
178 for (i=0; i<t->count; i++)
179 t->v.dval[i] = dval[i];
180 for (; i < pos+1; i++)
181 t->v.dval[i] = 0.0;
182 wfree(dval);
183 t->count = pos+1;
184 }
185 t->dtype = ESPS_DOUBLE;
186 t->v.dval[pos] = d;
187
188 t->next = hdr->fea;
189 hdr->fea = t;
190
191 return;
192 }
193
194 void add_fea_f(esps_hdr hdr,const char *name, int pos, float d)
195 {
196 /* Add a float FEA field to the header */
197 esps_fea t = new_esps_fea();
198 int i;
199
200 t->type = 13;
201 t->clength = strlen(name);
202 t->name = wstrdup(name);
203 if (t->count < pos+1)
204 {
205 float *fval = t->v.fval;
206 t->v.fval = walloc(float,pos+1);
207 for (i=0; i<t->count; i++)
208 t->v.fval[i] = fval[i];
209 for (; i < pos+1; i++)
210 t->v.fval[i] = 0.0;
211 wfree(fval);
212 t->count = pos+1;
213 }
214 t->dtype = ESPS_FLOAT;
215 t->v.fval[pos] = d;
216
217 t->next = hdr->fea;
218 hdr->fea = t;
219
220 return;
221 }
222
223 void add_fea_i(esps_hdr hdr,const char *name, int pos, int d)
224 {
225 /* Add an int FEA field to the header */
226 esps_fea t = new_esps_fea();
227 int i;
228
229 t->type = 13;
230 t->clength = strlen(name);
231 t->name = wstrdup(name);
232 if (t->count < pos+1)
233 {
234 int *ival = t->v.ival;
235 t->v.ival = walloc(int,pos+1);
236 for (i=0; i<t->count; i++)
237 t->v.ival[i] = ival[i];
238 for (; i < pos+1; i++)
239 t->v.ival[i] = 0;
240 wfree(ival);
241 t->count = pos+1;
242 }
243 t->dtype = ESPS_INT;
244 t->v.ival[pos] = d;
245
246 t->next = hdr->fea;
247 hdr->fea = t;
248
249 return;
250 }
251
252 void add_fea_s(esps_hdr hdr,const char *name, int pos, short d)
253 {
254 /* Add a short FEA field to the header */
255 esps_fea t = new_esps_fea();
256 int i;
257
258 t->type = 13;
259 t->clength = strlen(name);
260 t->name = wstrdup(name);
261 if (t->count < pos+1)
262 {
263 short *sval = t->v.sval;
264 t->v.sval = walloc(short,pos+1);
265 for (i=0; i<t->count; i++)
266 t->v.sval[i] = sval[i];
267 for (; i < pos+1; i++)
268 t->v.sval[i] = (short)0;
269 wfree(sval);
270 t->count = pos+1;
271 }
272 t->dtype = ESPS_SHORT;
273 t->v.sval[pos] = d;
274
275 t->next = hdr->fea;
276 hdr->fea = t;
277
278 return;
279 }
280
281 void add_fea_c(esps_hdr hdr,const char *name, int pos, char d)
282 {
283 /* Add a char FEA field to the header */
284 esps_fea t = new_esps_fea();
285 int i;
286
287 t->type = 13;
288 t->clength = strlen(name);
289 t->name = wstrdup(name);
290 if (t->count < pos+1)
291 {
292 char *cval = t->v.cval;
293 t->v.cval = walloc(char,pos+1);
294 for (i=0; i<t->count; i++)
295 t->v.cval[i] = cval[i];
296 for (; i < pos+1; i++)
297 t->v.cval[i] = (char)0;
298 wfree(cval);
299 t->count = pos+1;
300 }
301 t->dtype = ESPS_CHAR;
302 t->v.cval[pos] = d;
303
304 t->next = hdr->fea;
305 hdr->fea = t;
306
307 return;
308 }
309
310 void add_fea_special(esps_hdr hdr,int type,const char *name)
311 {
312 /* Add a special FEA field to the header */
313 esps_fea t = new_esps_fea();
314
315 t->type = type;
316 t->clength = strlen(name);
317 t->name = wstrdup(name);
318 t->count = 0;
319
320 t->next = hdr->fea;
321 hdr->fea = t;
322
323 return;
324 }
325
326 int fea_value_d(const char *name,int pos,esps_hdr hdr, double *d)
327 {
328 /* Get value of double FEA */
329 esps_fea t;
330
331 for (t=hdr->fea; t != NULL; t=t->next)
332 if (streq(name,t->name))
333 {
334 if (t->dtype != ESPS_DOUBLE)
335 {
336 fprintf(stderr,"ESPS hdr: access non-double field \"%s\" as double\n",
337 name);
338 return -1;
339 }
340 *d = t->v.dval[pos];
341 return 0;
342 }
343
344 return -1; /* failed to find it */
345 }
346
347 int fea_value_f(const char *name,int pos,esps_hdr hdr, float *d)
348 {
349 /* Get value of float FEA */
350 esps_fea t;
351
352 for (t=hdr->fea; t != NULL; t=t->next)
353 if (streq(name,t->name))
354 {
355 if (t->dtype != ESPS_FLOAT)
356 {
357 fprintf(stderr,"ESPS hdr: access non-float field \"%s\" as float\n",
358 name);
359 return -1;
360 }
361 *d = t->v.fval[pos];
362 return 0;
363 }
364
365 return -1; /* failed to find it */
366 }
367
368 int fea_value_s(const char *name,int pos,esps_hdr hdr, short *d)
369 {
370 /* Get value of short FEA */
371 esps_fea t;
372
373 for (t=hdr->fea; t != NULL; t=t->next)
374 if (streq(name,t->name))
375 {
376 if (t->dtype != ESPS_SHORT)
377 {
378 fprintf(stderr,"ESPS hdr: access non-short field \"%s\" as short\n",
379 name);
380 return -1;
381 }
382 *d = t->v.sval[pos];
383 return 0;
384 }
385
386 return -1; /* failed to find it */
387 }
388
389 int fea_value_i(const char *name,int pos,esps_hdr hdr, int *d)
390 {
391 /* Get value of int FEA */
392 esps_fea t;
393
394 for (t=hdr->fea; t != NULL; t=t->next)
395 if (streq(name,t->name))
396 {
397 if (t->dtype != ESPS_INT)
398 {
399 fprintf(stderr,"ESPS hdr: access non-int field \"%s\" as int\n",
400 name);
401 return -1;
402 }
403 *d = t->v.ival[pos];
404 return 0;
405 }
406
407 return -1; /* failed to find it */
408 }
409
410 int fea_value_c(const char *name,int pos,esps_hdr hdr, char *d)
411 {
412 /* Get value of int FEA */
413 esps_fea t;
414
415 for (t=hdr->fea; t != NULL; t=t->next)
416 if (streq(name,t->name))
417 {
418 if (t->dtype != ESPS_CHAR)
419 {
420 fprintf(stderr,"ESPS hdr: access non-char field \"%s\" as char\n",
421 name);
422 return -1;
423 }
424 *d = t->v.cval[pos];
425 return 0;
426 }
427
428 return -1; /* failed to find it */
429 }
430
431 static int esps_alloc_fea(esps_fea r)
432 {
433 switch (r->dtype)
434 {
435 case 0: /* nothing */
436 break;
437 case ESPS_DOUBLE:
438 r->v.dval = walloc(double,r->count); break;
439 case ESPS_FLOAT:
440 r->v.fval = walloc(float,r->count); break;
441 case ESPS_INT:
442 r->v.ival = walloc(int,r->count); break;
443 case ESPS_SHORT:
444 r->v.sval = walloc(short,r->count); break;
445 case ESPS_CHAR:
446 r->v.cval = walloc(char,r->count); break;
447 default:
448 fprintf(stderr,"ESPS file: unsupported FEA dtype\n");
449 return -1;
450 }
451
452 return 0;
453 }
454
455 void write_esps_fea(FILE *fd, esps_fea t,esps_hdr hdr)
456 {
457 /* write out this fea */
458 (void)hdr;
459 short clength;
460 char *nspace;
461 int i;
462
463 fwrite(&t->type,2,1,fd);
464 clength = (strlen(t->name)+3)/4;
465 fwrite(&clength,2,1,fd);
466 nspace = walloc(char, clength*4);
467 memset(nspace,0,clength*4);
468 memmove(nspace,t->name,strlen(t->name));
469 fwrite(nspace,1,clength*4,fd);
470 wfree(nspace);
471 if ((t->type == 11) ||
472 (t->type == 1) ||
473 (t->type == 15))
474 return;
475 fwrite(&t->count,4,1,fd);
476 fwrite(&t->dtype,2,1,fd);
477
478 for (i=0; i<t->count; i++)
479 {
480 switch(t->dtype)
481 {
482 case ESPS_DOUBLE:
483 fwrite(&t->v.dval[i],8,1,fd); break;
484 case ESPS_FLOAT:
485 fwrite(&t->v.fval[i],4,1,fd); break;
486 case ESPS_INT:
487 fwrite(&t->v.ival[i],4,1,fd); break;
488 case ESPS_SHORT:
489 fwrite(&t->v.sval[i],2,1,fd); break;
490 case ESPS_CHAR:
491 fwrite(&t->v.cval[i],1,1,fd); break;
492 default:
493 fprintf(stderr,"ESPS write_hdr: unsupported FEA dtype %d\n",
494 t->dtype);
495 }
496 }
497 return;
498 }
499
500 int write_esps_rec(esps_rec r, esps_hdr h, FILE *fd)
501 {
502 /* will have to worry about swap someday */
503 (void)h;
504 int i;
505
506 for (i=0; i < r->num_fields; i++)
507 {
508 switch(r->field[i]->type)
509 {
510 case ESPS_DOUBLE:
511 fwrite(r->field[i]->v.dval,8,r->field[i]->dimension,fd);
512 break;
513 case ESPS_FLOAT:
514 fwrite(r->field[i]->v.fval,4,r->field[i]->dimension,fd);
515 break;
516 case ESPS_INT:
517 fwrite(r->field[i]->v.ival,4,r->field[i]->dimension,fd);
518 break;
519 case ESPS_SHORT:
520 fwrite(r->field[i]->v.sval,2,r->field[i]->dimension,fd);
521 break;
522 case ESPS_CHAR:
523 fwrite(r->field[i]->v.cval,1,r->field[i]->dimension,fd);
524 break;
525 case ESPS_CODED:
526 fwrite(r->field[i]->v.sval,2,r->field[i]->dimension,fd);
527 break;
528
529 default:
530 fprintf(stderr,"ESPS file: unsupported field type %d\n",
531 r->field[i]->type);
532 }
533 }
534 return 0;
535 }
536
537 esps_fea read_esps_fea(FILE *fd, esps_hdr hdr)
538 {
539 /* read next FEA record at point */
540 esps_fea r = new_esps_fea();
541 short sdata;
542 int i;
543 int idata;
544 float fdata;
545 double ddata;
546 char cdata;
547
548 fread(&sdata,2,1,fd);
549 if (hdr->swapped) sdata = SWAPSHORT(sdata);
550 r->type = sdata;
551 if (r->type == 0) /* a field name */
552 { /* next short is the size in bytes */
553 fread(&sdata,2,1,fd);
554 if (hdr->swapped) sdata = SWAPSHORT(sdata);
555 r->clength = sdata;
556 }
557 else if ((r->type == 13) || /* a feature and value */
558 (r->type == 11) || /* a single string (comment ?) */
559 (r->type == 1) || /* a filename */
560 (r->type == 4) || /* a filename */
561 (r->type == 15)) /* directory name */
562 {
563 fread(&sdata,2,1,fd);
564 if (hdr->swapped) sdata = SWAPSHORT(sdata);
565 r->clength = sdata * 4;
566 }
567 else
568 {
569 fprintf(stderr,"ESPS: fea record unknown type\n");
570 wfree(r);
571 return NULL;
572 }
573 r->name = walloc(char,r->clength+1);
574 fread(r->name,1,r->clength,fd);
575 r->name[r->clength] = '\0';
576 if ((r->type == 11) || /* a single string */
577 (r->type == 1) || /* a filename */
578 (r->type == 15)) /* directory name */
579 return r;
580 fread(&idata,4,1,fd);
581 if (hdr->swapped) idata = SWAPINT(idata);
582 r->count = idata;
583 fread(&sdata,2,1,fd);
584 if (hdr->swapped) sdata = SWAPSHORT(sdata);
585 r->dtype = sdata;
586 if (esps_alloc_fea(r) == -1)
587 return NULL;
588 for (i=0; i<r->count; i++)
589 {
590 switch (r->dtype)
591 {
592 case ESPS_DOUBLE:
593 fread(&ddata,8,1,fd);
594 if (hdr->swapped) swapdouble(&ddata);
595 r->v.dval[i] = ddata;
596 break;
597 case ESPS_FLOAT:
598 fread(&fdata,4,1,fd);
599 if (hdr->swapped) swapfloat(&fdata);
600 r->v.fval[i] = fdata;
601 break;
602 case ESPS_INT:
603 fread(&idata,4,1,fd);
604 if (hdr->swapped) idata = SWAPINT(idata);
605 r->v.ival[i] = idata;
606 break;
607 case ESPS_SHORT:
608 fread(&sdata,2,1,fd);
609 if (hdr->swapped) sdata = SWAPSHORT(sdata);
610 r->v.sval[i] = sdata;
611 break;
612 case ESPS_CHAR:
613 fread(&cdata,1,1,fd);
614 r->v.cval[i] = cdata;
615 break;
616 default:
617 fprintf(stderr,"ESPS read_hdr: unsupported FEA dtype %d\n",r->dtype);
618 wfree(r);
619 return NULL;
620 }
621 }
622
623 return r;
624 }
625
626 static char *esps_get_field_name(FILE *fd, esps_hdr hdr, int expect_source)
627 {
628 /* read the next field name */
629 short size=0; /* bet its really a short */
630 char *name;
631
632 if (fread(&size,2,1,fd) != 1)
633 {
634 fputs("error reading field name size\n", stderr);
635 return wstrdup("ERROR");
636 }
637 if (hdr->swapped) size = SWAPSHORT(size);
638 name = walloc(char,size+1);
639 if (fread(name,1,size,fd) != (unsigned)size)
640 {
641 fputs("error reading field name\n", stderr);
642 strncpy(name, "ERROR", size);
643 }
644 name[size] = '\0';
645 if (hdr->file_type == ESPS_SD || expect_source)
646 fseek(fd,6,SEEK_CUR); /* skip some zeroes */
647 else
648 fseek(fd,2,SEEK_CUR);
649
650 if (expect_source)
651 {
652 fread(&size,2,1,fd);
653 if (hdr->swapped) size = SWAPSHORT(size);
654 fseek(fd,size,SEEK_CUR);
655 }
656
657 return name;
658 }
659
660 static void esps_put_field_name(char *name,FILE *fd, esps_hdr hdr)
661 {
662 /* write the next field name */
663 short size = strlen(name);
664 short shortdata;
665
666 shortdata = 0;
667 fwrite(&shortdata,2,1,fd);
668 fwrite(&size,2,1,fd);
669 fwrite(name,1,size,fd);
670 if (hdr->file_type == ESPS_SD)
671 {
672 shortdata = 0;
673 fwrite(&shortdata,2,1,fd);
674 fwrite(&shortdata,2,1,fd);
675 fwrite(&shortdata,2,1,fd);
676 }
677 return;
678 }
679
680 esps_hdr new_esps_hdr(void)
681 {
682 esps_hdr h = walloc(struct ESPS_HDR_struct,1);
683 h->file_type = ESPS_FEA;
684 h->swapped = FALSE;
685 h->num_records = 0;
686 h->num_fields = 0;
687 h->field_name = NULL;
688 h->field_type = NULL;
689 h->field_dimension = NULL;
690 h->fea = NULL;
691 return h;
692 }
693
694 void delete_esps_hdr(esps_hdr h)
695 {
696 int i;
697 if (h != NULL)
698 {
699 if (h->field_name != NULL)
700 {
701 for (i=0; i < h->num_fields; i++)
702 wfree(h->field_name[i]);
703 wfree(h->field_name);
704 }
705 delete_esps_fea(h->fea);
706 }
707 }
708
709 esps_rec new_esps_rec(esps_hdr hdr)
710 {
711 /* New esps record */
712 esps_rec r = walloc(struct ESPS_REC_struct,1);
713 int i,size;
714
715 r->field = walloc(esps_field,hdr->num_fields);
716 for (size=0,i=0; i < hdr->num_fields; i++)
717 {
718 r->field[i]=walloc(struct ESPS_FIELD_struct,1);
719 r->field[i]->type = hdr->field_type[i];
720 r->field[i]->dimension = hdr->field_dimension[i];
721 switch(r->field[i]->type)
722 {
723 case ESPS_DOUBLE:
724 r->field[i]->v.dval = walloc(double,r->field[i]->dimension);
725 size += 8;
726 break;
727 case ESPS_FLOAT:
728 r->field[i]->v.fval = walloc(float,r->field[i]->dimension);
729 size += 4;
730 break;
731 case ESPS_INT:
732 r->field[i]->v.ival = walloc(int,r->field[i]->dimension);
733 size += 4;
734 break;
735 case ESPS_SHORT:
736 r->field[i]->v.sval = walloc(short,r->field[i]->dimension);
737 size += 2;
738 break;
739 case ESPS_CHAR:
740 r->field[i]->v.cval = walloc(char,r->field[i]->dimension);
741 size += 1;
742 break;
743 case ESPS_CODED:
744 r->field[i]->v.sval = walloc(short,r->field[i]->dimension);
745 size += 2;
746 break;
747 default:
748 fprintf(stderr,"ESPS file: unsupported field type %d\n",
749 r->field[i]->type);
750 }
751 }
752 r->num_fields = hdr->num_fields;
753 r->size = size;
754 return r;
755
756 }
757
758 void delete_esps_rec(esps_rec r)
759 {
760 int i;
761
762 for (i=0; i<r->num_fields; i++)
763 {
764 wfree(r->field[i]->v.ival);
765 wfree(r->field[i]);
766 }
767 wfree(r->field);
768 return;
769 }
770
771 int read_esps_rec(esps_rec r, esps_hdr hdr, FILE *fd)
772 {
773 /* read the next record at point */
774 int i,j;
775 double doubledata;
776 float floatdata;
777 int intdata;
778 short shortdata;
779
780 for (i=0; i< r->num_fields; i++)
781 {
782 switch (r->field[i]->type)
783 {
784 case ESPS_DOUBLE:
785 for(j=0; j < r->field[i]->dimension; j++)
786 {
787 if (fread(&doubledata,8,1,fd) == 0) return EOF;
788 if (hdr->swapped) swapdouble(&doubledata);
789 r->field[i]->v.dval[j] = doubledata;
790 }
791 break;
792 case ESPS_FLOAT:
793 for(j=0; j < r->field[i]->dimension; j++)
794 {
795 if (fread(&floatdata,4,1,fd) == 0) return EOF;
796 if (hdr->swapped) swapfloat(&floatdata);
797 r->field[i]->v.fval[j] = floatdata;
798 }
799 break;
800 case ESPS_INT:
801 for(j=0; j < r->field[i]->dimension; j++)
802 {
803 if (fread(&intdata,4,1,fd) == 0) return EOF;
804 if (hdr->swapped) intdata = SWAPINT(intdata);
805 r->field[i]->v.ival[j] = intdata;
806 }
807 break;
808 case ESPS_SHORT:
809 for(j=0; j < r->field[i]->dimension; j++)
810 {
811 if (fread(&shortdata,2,1,fd) == 0) return EOF;
812 if (hdr->swapped) shortdata = SWAPSHORT(shortdata);
813 r->field[i]->v.sval[j] = shortdata;
814 }
815 break;
816 case ESPS_CHAR:
817 if (fread(r->field[i]->v.cval,1,r->field[i]->dimension,fd) !=
818 (unsigned)r->field[i]->dimension) return EOF;
819 break;
820 case ESPS_CODED:
821 for(j=0; j < r->field[i]->dimension; j++)
822 {
823 if (fread(&shortdata,2,1,fd) == 0) return EOF;
824 if (hdr->swapped) shortdata = SWAPSHORT(shortdata);
825 r->field[i]->v.sval[j] = shortdata;
826 }
827 break;
828 default:
829 fprintf(stderr,"ESPS file: unsupported field type %d\n",
830 r->field[i]->type);
831 return EOF;
832 }
833
834 }
835
836 return 0;
837
838 }
839
840 double get_field_d(esps_rec r, int field, int pos)
841 {
842 return r->field[field]->v.dval[pos];
843 }
844 float get_field_f(esps_rec r, int field, int pos)
845 {
846 return r->field[field]->v.fval[pos];
847 }
848 int get_field_i(esps_rec r, int field, int pos)
849 {
850 return r->field[field]->v.ival[pos];
851 }
852 short get_field_s(esps_rec r, int field, int pos)
853 {
854 return r->field[field]->v.sval[pos];
855 }
856 char get_field_c(esps_rec r, int field, int pos)
857 {
858 return r->field[field]->v.cval[pos];
859 }
860 void set_field_d(esps_rec r, int field, int pos, double d)
861 {
862 r->field[field]->v.dval[pos] = d;
863 }
864 void set_field_f(esps_rec r, int field, int pos, float d)
865 {
866 r->field[field]->v.fval[pos] = d;
867 }
868 void set_field_i(esps_rec r, int field, int pos, int d)
869 {
870 r->field[field]->v.ival[pos] = d;
871 }
872 void set_field_s(esps_rec r, int field, int pos, short d)
873 {
874 r->field[field]->v.sval[pos] = d;
875 }
876 void set_field_c(esps_rec r, int field, int pos, char d)
877 {
878 r->field[field]->v.cval[pos] = d;
879 }
880
881 int esps_record_size(esps_hdr hdr)
882 {
883 /* works out the number of bytes in a record */
884 esps_rec r = new_esps_rec(hdr);
885 int size = r->size;
886 delete_esps_rec(r);
887
888 return size;
889 }
890
891 static int esps_num_of_type(int type,esps_hdr hdr)
892 {
893 /* counts up the number of occurrences of fields of type in a record */
894 int i;
895 int sum;
896
897 for (sum=i=0; i < hdr->num_fields; i++)
898 if (hdr->field_type[i] == type)
899 sum++;
900 return sum;
901 }
902
903
904 esps_hdr make_esps_sd_hdr(void)
905 {
906 /* returns a basic header for an ESPS_SD file */
907 esps_hdr hdr = new_esps_hdr();
908 hdr->file_type = ESPS_SD;
909 return hdr;
910
911 }
912
913 esps_hdr make_esps_hdr(void)
914 {
915 /* returns a basic header for an ESPS_SD file */
916 esps_hdr hdr = new_esps_hdr();
917 hdr->file_type = ESPS_FEA;
918 return hdr;
919
920 }
921
922 enum EST_read_status read_esps_hdr(esps_hdr *uhdr,FILE *fd)
923 {
924 /* reads an ESPS header from fd at point (should be position 0) */
925 /* leaves point at start of data (immediately after header) */
926 struct ESPS_PREAMBLE preamble;
927 struct ESPS_FIXED_HDR fhdr;
928 esps_hdr hdr;
929 int end,pos,intdata,i;
930 short shortdata;
931 double sd_sample_rate;
932 int typematch;
933 int swap;
934 short name_flag;
935
936 fread(&preamble,sizeof(preamble),1,fd);
937 if (preamble.check == ESPS_MAGIC)
938 swap = FALSE;
939 else if (preamble.check == SWAPINT(ESPS_MAGIC))
940 swap = TRUE;
941 else
942 return wrong_format;
943
944 hdr = new_esps_hdr();
945 hdr->swapped = swap;
946 fread(&fhdr,sizeof(fhdr),1,fd);
947 if (hdr->swapped)
948 {
949 preamble.data_offset = SWAPINT(preamble.data_offset);
950 preamble.record_size = SWAPINT(preamble.record_size);
951 fhdr.num_samples = SWAPINT(fhdr.num_samples);
952 fhdr.num_doubles = SWAPINT(fhdr.num_doubles);
953 fhdr.num_floats = SWAPINT(fhdr.num_floats);
954 fhdr.num_ints = SWAPINT(fhdr.num_ints);
955 fhdr.num_shorts = SWAPINT(fhdr.num_shorts);
956 fhdr.num_chars = SWAPINT(fhdr.num_chars);
957 fhdr.fea_type = SWAPSHORT(fhdr.fea_type);
958 fhdr.num_fields = SWAPSHORT(fhdr.num_fields);
959 }
960 pos = ftell(fd);
961 if (fhdr.num_samples == 0) /* has to be derived from the file size */
962 {
963 pos = ftell(fd);
964 fseek(fd,0,SEEK_END);
965 end = ftell(fd);
966 fseek(fd,pos,SEEK_SET);
967 fhdr.num_samples = (end - preamble.data_offset)/preamble.record_size;
968 }
969 hdr->num_records = fhdr.num_samples;
970 hdr->num_fields = fhdr.num_fields;
971 hdr->hdr_size = preamble.data_offset;
972 if (fhdr.thirteen == 9)
973 { /* esps identifies such files are as Sample Data Files */
974 hdr->file_type = ESPS_SD;
975 /* fake the rest to make it appear like other SD files */
976 hdr->num_fields = 1;
977 hdr->field_dimension = walloc(int,hdr->num_fields);
978 hdr->field_dimension[0] = 1;
979 hdr->field_type = walloc(short,hdr->num_fields);
980 hdr->field_type[0] = ESPS_SHORT;
981 hdr->field_name = walloc(char *,1);
982 hdr->field_name[0] = wstrdup("samples");
983 fseek(fd,hdr->hdr_size,SEEK_SET);
984 /* In this cases its just in the header as a float */
985 sd_sample_rate = *((float *)(void *)&fhdr.fil4[0]);
986 add_fea_d(hdr,"record_freq",0,(double)sd_sample_rate);
987 *uhdr = hdr;
988 return format_ok;
989 }
990 else if ((fhdr.fea_type == 8) &&
991 (hdr->num_fields == 1) &&
992 ((fhdr.num_shorts*2) == preamble.record_size))
993 hdr->file_type = ESPS_SD; /* this is a heuristic */
994 else
995 hdr->file_type = ESPS_FEA;
996 /* Now we have the field descriptions */
997
998 /* 0000 0001 dimensions */
999 hdr->field_dimension = walloc(int,hdr->num_fields);
1000 for (i=0; i<hdr->num_fields; i++)
1001 {
1002 fread(&intdata,4,1,fd); /* dimensions */
1003 if (hdr->swapped) intdata = SWAPINT(intdata);
1004 hdr->field_dimension[i] = intdata;
1005 }
1006 /* 0 -> num_fields-1 -- probably ordering information */
1007 fseek(fd,hdr->num_fields*4,SEEK_CUR); /* ordering info */
1008 fseek(fd,hdr->num_fields*2,SEEK_CUR); /* zeros */
1009 hdr->field_type = walloc(short,hdr->num_fields);
1010 for (i=0; i<hdr->num_fields; i++)
1011 {
1012 fread(&shortdata,2,1,fd); /* field types */
1013 if (hdr->swapped) shortdata = SWAPSHORT(shortdata);
1014 hdr->field_type[i] = shortdata;
1015 }
1016 typematch = TRUE;
1017 fread(&intdata,4,1,fd); /* number of doubles */
1018 if (hdr->swapped) intdata = SWAPINT(intdata);
1019 if (fhdr.num_doubles != intdata) typematch = FALSE;
1020 fread(&intdata,4,1,fd); /* number of floats */
1021 if (hdr->swapped) intdata = SWAPINT(intdata);
1022 if (fhdr.num_floats != intdata) typematch = FALSE;
1023 fread(&intdata,4,1,fd); /* number of ints */
1024 if (hdr->swapped) intdata = SWAPINT(intdata);
1025 if (fhdr.num_ints != intdata) typematch = FALSE;
1026 fread(&intdata,4,1,fd); /* number of shorts */
1027 if (hdr->swapped) intdata = SWAPINT(intdata);
1028 if (fhdr.num_shorts != intdata) typematch = FALSE;
1029 fread(&intdata,4,1,fd); /* number of chars */
1030 if (hdr->swapped) intdata = SWAPINT(intdata);
1031 if (fhdr.num_chars != intdata) typematch = FALSE;
1032 if ((hdr->file_type != ESPS_SD) && (typematch == FALSE))
1033 {
1034 fprintf(stderr,"ESPS hdr: got lost in the header (record description)\n");
1035 delete_esps_hdr(hdr);
1036 return misc_read_error;
1037 }
1038 /* other types ... */
1039 fseek(fd,9*2,SEEK_CUR); /* other types */
1040 fseek(fd,hdr->num_fields*2,SEEK_CUR); /* zeros */
1041 /* Now we can read the field names */
1042 hdr->field_name = walloc(char *,hdr->num_fields);
1043
1044 fread(&name_flag, 2, 1, fd);
1045 if (hdr->swapped) name_flag = SWAPSHORT(name_flag);
1046
1047 for (i=0; i < hdr->num_fields; i++)
1048 hdr->field_name[i] = esps_get_field_name(fd,hdr,name_flag); /* field names */
1049 if (hdr->file_type == ESPS_SD)
1050 { /* Only one field 'samples' */
1051 if (!streq(hdr->field_name[0],"samples"))
1052 {
1053 fprintf(stderr,"ESPS hdr: guessed wrong about FEA_SD file (no 'samples' field)\n");
1054 delete_esps_hdr(hdr);
1055 return misc_read_error;
1056 }
1057 }
1058
1059 /* Now fea, feature and value -- but how many are there ? */
1060 while (ftell(fd) < preamble.data_offset-4)
1061 {
1062 esps_fea r = read_esps_fea(fd,hdr); /* feas */
1063 if (r == NULL) break;
1064 /* print_esps_fea(r); */
1065 r->next = hdr->fea;
1066 hdr->fea = r;
1067 if (r->type == 1)
1068 break; /* I think this (filename) is last FEA */
1069 }
1070 /* There's other gunk after this but I think I've done enough */
1071 /* The rest seems to be mostly previous headers */
1072
1073 fseek(fd,hdr->hdr_size,SEEK_SET); /* skip the rest of the header */
1074 *uhdr = hdr;
1075
1076 return format_ok;
1077 }
1078
1079
1080 enum EST_write_status write_esps_hdr(esps_hdr hdr,FILE *fd)
1081 {
1082 /* well here's the scary part, try to write a valid file hdr to */
1083 /* the file */
1084 struct ESPS_PREAMBLE preamble;
1085 struct ESPS_FIXED_HDR fhdr;
1086 time_t tx = time(0);
1087 esps_fea t;
1088 int i,intdata;
1089 short shortdata;
1090
1091 memset(&preamble,0,sizeof(preamble));
1092 memset(&fhdr,0,sizeof(fhdr));
1093 /* I can't really make the machine code work properly, so I'll */
1094 /* just fix it for the two major byte orders to Sun and Suni386 */
1095 if (EST_NATIVE_BO == bo_big)
1096 preamble.machine_code = 4; /* a sun */
1097 else
1098 preamble.machine_code = 6; /* a suni386 */
1099 preamble.check_code = 3000; /* ? */
1100 preamble.data_offset = 0; /* will come back and fix this later */
1101 preamble.record_size = esps_record_size(hdr);
1102 preamble.check = ESPS_MAGIC;
1103 preamble.edr = 0;
1104 preamble.fil1 = 0;
1105 preamble.foreign_hd = 0; /* docs say it should be -1, but its always 0 */
1106
1107 fhdr.thirteen = 13; /* must be for luck */
1108 fhdr.sdr_size = 0;
1109 fhdr.magic = ESPS_MAGIC;
1110 strncpy(fhdr.date,ctime(&tx),26);
1111 sprintf(fhdr.version,"1.91"); /* that's what all the others have */
1112 sprintf(fhdr.prog,"EDST");
1113 sprintf(fhdr.vers,"0.1");
1114 strncpy(fhdr.progcompdate,ctime(&tx),26);
1115 fhdr.num_samples = hdr->num_records;
1116 fhdr.filler = 0;
1117 /* in each record */
1118 fhdr.num_doubles = esps_num_of_type(ESPS_DOUBLE,hdr);
1119 fhdr.num_floats = esps_num_of_type(ESPS_FLOAT,hdr);
1120 fhdr.num_ints = esps_num_of_type(ESPS_INT,hdr);
1121 fhdr.num_shorts = esps_num_of_type(ESPS_SHORT,hdr);
1122 fhdr.num_chars = esps_num_of_type(ESPS_CHAR,hdr);
1123 fhdr.fsize = 40;
1124 fhdr.hsize = 0; /* given value below on second shot */
1125 if (hdr->file_type == ESPS_SD)
1126 fhdr.fea_type = 8;
1127 else
1128 fhdr.fea_type = 0;
1129 fhdr.num_fields = hdr->num_fields;
1130
1131 fwrite(&preamble,sizeof(preamble),1,fd);
1132 fwrite(&fhdr,sizeof(fhdr),1,fd);
1133 /* The following cover dimensions, type and ordering info */
1134 for (i=0; i < hdr->num_fields; i++)
1135 { /* Dimensions (i.e. number of channels) */
1136 intdata = 1;
1137 fwrite(&intdata,4,1,fd); /* dimensions */
1138 }
1139 for (i=0; i < hdr->num_fields; i++) /* ordering info (?) */
1140 fwrite(&i,4,1,fd);
1141 if (hdr->file_type == ESPS_SD) /* zeros hmm should be zeroes only */
1142 shortdata = 1; /* is FEA case, 1 in ESPS_SD case */
1143 else /* fixed 24/7/98 */
1144 shortdata = 0;
1145 for (i=0; i < hdr->num_fields; i++)
1146 fwrite(&shortdata,2,1,fd);
1147 for (i=0; i < hdr->num_fields; i++)
1148 {
1149 shortdata = hdr->field_type[0]; /* field types */
1150 fwrite(&shortdata,2,1,fd);
1151 }
1152 intdata = fhdr.num_doubles; /* number of doubles */
1153 fwrite(&intdata,4,1,fd);
1154 intdata = fhdr.num_floats; /* number of floats */
1155 fwrite(&intdata,4,1,fd);
1156 intdata = fhdr.num_ints; /* number of ints */
1157 fwrite(&intdata,4,1,fd);
1158 intdata = fhdr.num_shorts; /* number of shorts */
1159 fwrite(&intdata,4,1,fd);
1160 intdata = fhdr.num_chars; /* number of chars */
1161 fwrite(&intdata,4,1,fd);
1162 shortdata = 0;
1163 for (i=0; i < 9; i++)
1164 fwrite(&shortdata,2,1,fd); /* other types */
1165 for (i=0; i < hdr->num_fields; i++)
1166 fwrite(&shortdata,2,1,fd); /* zeros */
1167 /* Now dump the filednames */
1168 for (i=0; i < hdr->num_fields; i++)
1169 esps_put_field_name(hdr->field_name[i],fd,hdr); /* field names */
1170 if (hdr->file_type != ESPS_SD)
1171 fwrite(&shortdata,2,1,fd); /* another 0 */
1172 /* Now the feas */
1173 for (t=hdr->fea; t != NULL; t=t->next)
1174 write_esps_fea(fd,t,hdr); /* feas */
1175 /* now have to go back and fix the header size */
1176 intdata = 0;
1177 fwrite(&intdata,4,1,fd);
1178 preamble.data_offset = ftell(fd);
1179 fhdr.hsize = (preamble.data_offset-249)/2;
1180 if (fseek(fd,0,SEEK_SET) == -1)
1181 {
1182 fprintf(stderr,"esps write header: can't fseek to start of file\n");
1183 return misc_write_error;
1184 }
1185 fwrite(&preamble,sizeof(preamble),1,fd);
1186 fwrite(&fhdr,sizeof(fhdr),1,fd);
1187 fseek(fd,preamble.data_offset,SEEK_SET);
1188
1189 return write_ok;
1190 }