Edinburgh Speech Tools  2.4-release
EST_wave_io.cc
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 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 Black and Paul Taylor */
34 /* Date : June 1996 */
35 /*-----------------------------------------------------------------------*/
36 /* File I/O functions specific to various file formats */
37 /* */
38 /* Note that internally data will always be shorts and */
39 /* native byte order, conversions to/from other byte formats */
40 /* or encodings happend at read/write time */
41 /* */
42 /*=======================================================================*/
43 #include <cstdlib>
44 #include <cstdio>
45 #include "EST_unix.h"
46 #include <cstring>
47 #include "EST_wave_aux.h"
48 #include "EST_wave_utils.h"
49 #include "EST_strcasecmp.h"
50 #include "waveP.h"
51 #include "EST_FileType.h"
52 
53 static int def_load_sample_rate = 16000;
54 
55 /*************************************************************************/
56 /* */
57 /* Functions specific for each file format */
58 /* */
59 /*************************************************************************/
60 
61 /*=======================================================================*/
62 /* Sphere Nist files */
63 /*=======================================================================*/
64 
65 static const char *NIST_SIG = "NIST_1A\n 1024\n";
66 static const char *NIST_END_SIG = "end_head\n";
67 #define NIST_HDR_SIZE 1024
68 
69 int nist_get_param_int(const char *hdr, const char *field, int def_val)
70 {
71  const char *p;
72  int val;
73 
74  if (((p=strstr(hdr,field)) != NULL) &&
75  (strncmp(" -i ",p+strlen(field),4) == 0))
76  {
77  sscanf(p+strlen(field)+4,"%d",&val);
78  return val;
79  }
80  else
81  return def_val;
82 
83 }
84 
85 char *nist_get_param_str(const char *hdr, const char *field, const char *def_val)
86 {
87  const char *p;
88  char *val;
89  int size;
90 
91  if (((p=strstr(hdr,field)) != NULL) &&
92  (strncmp(" -s",p+strlen(field),3) == 0))
93  {
94  sscanf(p+strlen(field)+3,"%d",&size);
95  val = walloc(char,size+1);
96  /* Hmm don't know how long the %d is so do it again */
97  sscanf(p+strlen(field)+3,"%d %s",&size,val);
98  return val;
99  }
100  else
101  return wstrdup(def_val);
102 
103 
104 }
105 
106 const char *sample_type_to_nist(enum EST_sample_type_t sample_type)
107 {
108  const char *c;
109  switch (sample_type) {
110  case st_unknown:
111  c = ""; break;
112  case st_schar:
113  c = "PCM-1"; break;
114  case st_alaw:
115  c = "ALAW"; break;
116  case st_mulaw:
117  c = "ULAW"; break;
118  case st_short:
119  c = "pcm"; break;
120  case st_int:
121  c = "PCM-4"; break;
122  case st_float:
123  c = "REAL"; break;
124  case st_double:
125  c = "REAL"; break;
126  default:
127  fprintf(stderr,"Unknown sample type for nist");
128  c = "";
129  }
130  return c;
131 }
132 
133 enum EST_sample_type_t nist_to_sample_type(char *type)
134 {
135  if ((streq(type,"pcm")) ||
136  (streq(type,"PCM")) ||
137  (streq(type,"pcm-2")))
138  return st_short;
139  if (strcmp(type,"pcm,embedded-shorten-v1.1") == 0)
140  return st_shorten;
141  else if ((EST_strcasecmp(type,"ULAW",NULL) == 0) ||
142  (EST_strcasecmp(type,"U-LAW",NULL) == 0) ||
143  (EST_strcasecmp(type,"mu-law",NULL) == 0) ||
144  (EST_strcasecmp(type,"mulaw",NULL) == 0))
145  return st_mulaw;
146  else if ((EST_strcasecmp(type,"ALAW",NULL) == 0) ||
147  (EST_strcasecmp(type,"A-LAW",NULL) == 0))
148  return st_alaw;
149  else if (strcmp(type,"alaw") == 0)
150  return st_alaw;
151  else if (strcmp(type,"PCM-1") == 0)
152  return st_schar;
153  else if (strcmp(type,"PCM-4") == 0)
154  return st_int;
155  else if (strcmp(type,"REAL") == 0)
156  return st_float;
157  else
158 
159  {
160  fprintf(stderr,"NIST: unknown sample type: %s\n",type);
161  return st_unknown;
162  }
163 }
164 
165 enum EST_read_status load_wave_nist(EST_TokenStream &ts, short **data, int
166  *num_samples, int *num_channels, int
167  *word_size, int *sample_rate, enum
168  EST_sample_type_t *sample_type, int *bo , int
169  offset, int length)
170 
171 {
172  char header[NIST_HDR_SIZE];
173  int samps,sample_width,data_length,actual_bo;
174  unsigned char *file_data;
175  enum EST_sample_type_t actual_sample_type;
176  char *byte_order, *sample_coding;
177  int n;
178  int current_pos;
179 
180  current_pos = ts.tell();
181  if (ts.fread(header,NIST_HDR_SIZE,1) != 1)
182  return wrong_format;
183 
184  if (strncmp(header,NIST_SIG,strlen(NIST_SIG)) != 0)
185  return wrong_format;
186 
187  samps = nist_get_param_int(header,"sample_count",-1);
188  *num_channels = nist_get_param_int(header,"channel_count",1);
189  sample_width = nist_get_param_int(header,"sample_n_bytes",2);
190  *sample_rate =
191  nist_get_param_int(header,"sample_rate",def_load_sample_rate);
192  byte_order = nist_get_param_str(header,"sample_byte_format",
193  (EST_BIG_ENDIAN ? "10" : "01"));
194  sample_coding = nist_get_param_str(header,"sample_coding","pcm");
195  if (streq(byte_order,"mu-law"))
196  {
197  byte_order = wstrdup((EST_BIG_ENDIAN ? "10" : "01"));
198  sample_coding = wstrdup("ULAW");
199  }
200  if (streq(byte_order,"a-law"))
201  {
202  byte_order = wstrdup((EST_BIG_ENDIAN ? "10" : "01"));
203  sample_coding = wstrdup("ALAW");
204  }
205 
206  /* code for reading in Tony Robinson's shorten files.
207  This is a temporary fix which calls the unshorten program on the
208  speech file and reads in the answer by calling this function.
209  It would be nice to have a simple library routine which did the
210  unshortening.
211  removed Jun 14th 2016 by awb , security risk, and only works in CSTR
212  */
213 
214  if (streq(sample_coding,"pcm,embedded-shorten-v1.1"))
215  {
216 #if 0
217  char *tmpfile, *cmdstr;
218  enum EST_read_status rval;
219 #endif
220 
221  fprintf(stderr,"WAVE read: nist type is shorten\n");
222  fprintf(stderr,"WAVE read: no support for shorten -- you need to use some external program to unshorten the data\n");
223  return misc_read_error;
224 
225 #if 0
226  tmpfile = cmake_tmp_filename();
227  cmdstr = walloc(char,strlen(tmpfile)+200);
228  /* This doesn't work, unless you have cstrshorten, and */
229  /* doesn't work if your file name is interesting */
230  sprintf(cmdstr,"cstrshorten %s %s",
231  (const char*)ts.filename(),tmpfile);
232  printf("Command: %s\n", cmdstr);
233  system(cmdstr);
234  EST_TokenStream tt;
235  tt.open(tmpfile);
236 
237  rval = load_wave_nist(tt, data, num_samples,
238  num_channels, word_size, sample_rate,
239  sample_type, bo, offset, length);
240  unlink(tmpfile);
241  wfree(tmpfile);
242  wfree(cmdstr);
243  tt.close();
244  return rval;
245 #endif
246  }
247 
248  if (length == 0)
249  data_length = (samps - offset)*(*num_channels);
250  else
251  data_length = length*(*num_channels);
252 
253  file_data = walloc(unsigned char,sample_width * data_length);
254 
255  ts.seek(current_pos+NIST_HDR_SIZE+(sample_width*offset*(*num_channels)));
256 
257  n = ts.fread(file_data,sample_width,data_length);
258 
259  if ((n < 1) && (n != data_length))
260  {
261  wfree(file_data);
262  wfree(sample_coding);
263  wfree(byte_order);
264  return misc_read_error;
265  }
266  else if ((n < data_length) && (data_length/(*num_channels) == n))
267  {
268  fprintf(stderr,"WAVE read: nist header is (probably) non-standard\n");
269  fprintf(stderr,"WAVE read: assuming different num_channel interpretation\n");
270  data_length = n; /* wrongly headered file */
271  }
272  else if (n < data_length)
273  {
274  fprintf(stderr,"WAVE read: short file %s\n",
275  (const char *)ts.filename());
276  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
277  offset,n,data_length);
278  data_length = n;
279  }
280 
281  actual_sample_type = nist_to_sample_type(sample_coding);
282  actual_bo = ((strcmp(byte_order,"10") == 0) ? bo_big : bo_little);
283 
284  *data = convert_raw_data(file_data,data_length,
285  actual_sample_type,actual_bo);
286 
287  *num_samples = data_length/ (*num_channels);
288  *sample_type = st_short;
289  *bo = EST_NATIVE_BO;
290  *word_size = 2;
291  wfree(sample_coding);
292  wfree(byte_order);
293 
294  return format_ok;
295 }
296 
297 enum EST_write_status save_wave_nist_header(FILE *fp,
298  int num_samples, int num_channels,
299  int sample_rate,
300  enum EST_sample_type_t sample_type, int bo)
301 {
302  char h[1024], p[1024];
303  const char *t;
304 
305  memset(h,0,1024);
306 
307  strcat(h, NIST_SIG);
308  sprintf(p, "channel_count -i %d\n", num_channels);
309  strcat(h, p);
310  sprintf(p, "sample_count -i %d\n", num_samples);
311  strcat(h, p);
312  sprintf(p, "sample_rate -i %d\n", sample_rate);
313  strcat(h, p);
314 
315  t = sample_type_to_nist(sample_type);
316  if (t)
317  {
318  sprintf(p, "sample_coding -s%d %s\n", (signed)strlen(t), t);
319  strcat(h, p);
320  sprintf(p, "sample_n_bytes -i %d\n", get_word_size(sample_type));
321  strcat(h, p);
322  }
323 
324  if (get_word_size(sample_type) > 1)
325  {
326  sprintf(p, "sample_byte_format -s%d %s\n", 2,
327  ((bo == bo_big) ? "10" : "01"));
328  strcat(h, p);
329  }
330 
331  strcat(h, NIST_END_SIG);
332  /*makes it nice to read */
333  strcat(h, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
334 
335  if (fwrite(&h, 1024, 1, fp) != 1)
336  return misc_write_error;
337 
338  return write_ok;
339 }
340 
341 
342 enum EST_write_status save_wave_nist_data(FILE *fp, const short *data, int offset,
343  int num_samples, int num_channels,
344  int sample_rate,
345  enum EST_sample_type_t sample_type, int bo)
346 {
347  if (data == NULL)
348  return write_ok;
349 
350  return save_raw_data(fp,data,offset,num_samples,num_channels,
351  sample_type,bo);
352 
353 }
354 
355 enum EST_write_status save_wave_nist(FILE *fp, const short *data, int offset,
356  int num_samples, int num_channels,
357  int sample_rate,
358  enum EST_sample_type_t sample_type, int bo)
359 {
360  save_wave_nist_header(fp, num_samples, num_channels,
361  sample_rate, sample_type, bo);
362  return save_wave_nist_data(fp, data, offset,
363  num_samples, num_channels,
364  sample_rate, sample_type, bo);
365 }
366 
367 /*=======================================================================*/
368 /* EST's own format */
369 /*=======================================================================*/
370 
371 enum EST_read_status load_wave_est(EST_TokenStream &ts, short **data, int
372  *num_samples, int *num_channels, int
373  *word_size, int *sample_rate, enum
374  EST_sample_type_t *sample_type, int *bo,
375  int offset, int length)
376 {
377  int data_length, actual_bo;
378  short *file_data;
379  EST_String byte_order;
380  int n;
381  EST_EstFileType t;
382  EST_Option hinfo;
383  bool ascii;
384  EST_read_status r;
385  EST_sample_type_t actual_sample_type;
386 
387  offset = 0;
388 
389  if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
390  return r;
391  if (t != est_file_wave)
392  return misc_read_error;
393 
394  *num_samples = hinfo.ival("NumSamples");
395  *num_channels = hinfo.ival("NumChannels");
396  *sample_rate = hinfo.ival("SampleRate");
397 
398  byte_order = hinfo.val("ByteOrder");
399 
400  if (length == 0)
401  data_length = (*num_samples)*(*num_channels);
402  else
403  data_length = length*(*num_channels);
404 
405  file_data = walloc(short, data_length);
406 
407  n = ts.fread(file_data, sizeof(short), data_length);
408  if ((n != data_length) && (n < 1))
409  {
410  cerr << "EST wave load: " << ts.pos_description() << endl;
411  cerr << "failed to read file\n";
412  wfree(file_data);
413  return misc_read_error;
414  }
415  else if (n != data_length)
416  {
417  cerr << "Wrong number of samples/channels in EST wave file\n";
418  cerr << ts.pos_description() << " ";
419  cerr << "expected " << data_length << " got " << n << endl;
420  data_length = n;
421  }
422 
423  actual_bo = (byte_order == "10") ? bo_big : bo_little;
424  if (hinfo.present("SampleType"))
425  actual_sample_type = str_to_sample_type(hinfo.val("SampleType"));
426  else
427  actual_sample_type = st_short; // some older files don't have this
428 
429  *data = convert_raw_data((unsigned char *)file_data,
430  data_length, actual_sample_type, actual_bo);
431  // because internally data is always shorts
432  *sample_type = st_short;
433  *bo = EST_NATIVE_BO;
434  *word_size = 2;
435 
436  return format_ok;
437 }
438 
439 enum EST_write_status save_wave_est_header(FILE *fp,
440  int num_samples, int num_channels,
441  int sample_rate,
442  enum EST_sample_type_t sample_type, int bo)
443 {
444  fprintf(fp, "EST_File wave\n");
445  fprintf(fp, "DataType binary\n");
446  fprintf(fp, "SampleRate %d\n", sample_rate);
447  fprintf(fp, "NumSamples %d\n", num_samples);
448  fprintf(fp, "NumChannels %d\n", num_channels);
449  fprintf(fp, "SampleType %s\n", sample_type_to_str(sample_type));
450  if (get_word_size(sample_type) > 1)
451  fprintf(fp, "ByteOrder %s\n", ((bo == bo_big) ? "10" : "01"));
452 
453  fprintf(fp, "EST_Header_End\n");
454  return write_ok;
455 }
456 
457 enum EST_write_status save_wave_est_data(FILE *fp, const short *data, int offset,
458  int num_samples, int num_channels,
459  int sample_rate,
460  enum EST_sample_type_t sample_type, int bo)
461 {
462  if (data == NULL)
463  return write_ok;
464 
465  return save_raw_data(fp, data, offset, num_samples, num_channels,
466  sample_type, bo);
467 }
468 
469 enum EST_write_status save_wave_est(FILE *fp, const short *data, int offset,
470  int num_samples, int num_channels,
471  int sample_rate,
472  enum EST_sample_type_t sample_type, int bo)
473 {
474  save_wave_est_header(fp, num_samples, num_channels,
475  sample_rate, sample_type, bo);
476 
477  return save_wave_est_data(fp, data, offset,
478  num_samples, num_channels,
479  sample_rate, sample_type, bo);
480 }
481 
482 /*=======================================================================*/
483 /* Microsoft RIFF (.wav) audio files */
484 /* */
485 /* The information on this format was gained by reading a document */
486 /* found on the net called "Multimedia Programming Interface and */
487 /* Data Specification v1.0" and by looking at Rick Richardson, */
488 /* Lance Norskog And Sundry Contributors code in SOX. All this code */
489 /* is rewritten from scratch though, but I couldn't do it without */
490 /* other's explanations. I would have used the SOX code directly but */
491 /* was not really in the right form so starting again was easier */
492 /*=======================================================================*/
493 #define WAVE_FORMAT_PCM 0x0001
494 #define WAVE_FORMAT_ADPCM 0x0002
495 #define WAVE_FORMAT_ALAW 0x0006
496 #define WAVE_FORMAT_MULAW 0x0007
497 
498 enum EST_read_status load_wave_riff(EST_TokenStream &ts, short **data, int
499  *num_samples, int *num_channels, int
500  *word_size, int *sample_rate, enum
501  EST_sample_type_t *sample_type, int *bo , int
502  offset, int length)
503 {
504  char info[4];
505  int samps,sample_width,data_length;
506  short shortdata;
507  int dsize,intdata;
508  unsigned char *file_data;
509  enum EST_sample_type_t actual_sample_type;
510 
511  if (ts.fread(info,sizeof(char),4) != 4)
512  return wrong_format; /* its almost definitely an error */
513  if (strncmp(info,"RIFF",4) != 0)
514  return wrong_format;
515 
516  /* We've got a riff file */
517  /* Next 4 bytes are the file size */
518  if(ts.fread(&dsize,4,1) != 1) return misc_read_error;
519  /* .wav files are always little endian */
520  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
521  if ((ts.fread(info,sizeof(char),4) != 4) ||
522  (strncmp(info,"WAVE",4) != 0))
523  {
524  fprintf(stderr, "RIFF file is not of type WAVE\n");
525  return misc_read_error; /* not a wave file */
526  }
527  if ((ts.fread(info,sizeof(char),4) != 4) ||
528  (strncmp(info,"fmt ",4) != 0))
529  return misc_read_error; /* something else wrong */
530 
531  if (ts.fread(&dsize,4,1) != 1) return misc_read_error;
532  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
533  if (ts.fread(&shortdata,2,1) != 1) return misc_read_error;
534  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
535 
536  switch (shortdata)
537  {
538  /* This is a non-proprietary format */
539  case WAVE_FORMAT_PCM:
540  actual_sample_type = st_short; break;
541  /* The follow are registered proprietary WAVE formats (?) */
542  case WAVE_FORMAT_MULAW:
543  actual_sample_type = st_mulaw; break;
544  case WAVE_FORMAT_ALAW:
545  actual_sample_type = st_alaw; break;
546  case WAVE_FORMAT_ADPCM:
547  fprintf(stderr, "RIFF file: unsupported proprietary sample format ADPCM\n");
548  actual_sample_type = st_short;
549  break;
550  /* actual_sample_type = st_adpcm; break; */ /* yes but which adpcm ! */
551  default:
552  fprintf(stderr, "RIFF file: unknown sample format\n");
553  actual_sample_type = st_short;
554  /* return misc_read_error; */
555  }
556  if (ts.fread(&shortdata,2,1) != 1) return misc_read_error;
557  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
558  *num_channels = shortdata;
559  if (ts.fread(sample_rate,4,1) != 1) return misc_read_error;
560  if (EST_BIG_ENDIAN) *sample_rate = SWAPINT(*sample_rate);
561  if (ts.fread(&intdata,4,1) != 1) return misc_read_error; /* average bytes per second -- ignored */
562  if (EST_BIG_ENDIAN) intdata = SWAPINT(intdata);
563  if (ts.fread(&shortdata,2,1) != 1) return misc_read_error; /* block align ? */
564  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
565  if (ts.fread(&shortdata,2,1) != 1) return misc_read_error;
566  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
567 
568  sample_width = (shortdata+7)/8;
569  if ((sample_width == 1) && (actual_sample_type == st_short))
570  actual_sample_type = st_uchar; /* oops I meant 8 bit */
571 
572  ts.seek((dsize-16)+ts.tell()); /* skip rest of header */
573  while (1)
574  {
575  if (ts.fread(info,sizeof(char),4) != 4)
576  {
577  fprintf(stderr,"RIFF file truncated\n");
578  return misc_read_error; /* something else wrong */
579  }
580  if (strncmp(info,"data",4) == 0)
581  {
582  if (ts.fread(&samps,4,1) != 1) return misc_read_error;
583  if (EST_BIG_ENDIAN) samps = SWAPINT(samps);
584  samps /= (sample_width*(*num_channels));
585  break;
586  }
587  else if (strncmp(info,"fact",4) == 0)
588  { /* some other type of chunk -- skip it */
589  if (ts.fread(&samps,4,1) != 1) return misc_read_error;
590  if (EST_BIG_ENDIAN) samps = SWAPINT(samps);
591  ts.seek(samps+ts.tell()); /* skip rest of header */
592  /* Hope this is the right amount */
593  }
594  else
595  {
596  // fprintf(stderr,"Ignoring unsupported chunk type \"%c%c%c%c\" in RIFF file\n",
597  // info[0],info[1],info[2],info[3]);
598  //return misc_read_error;
599  if(ts.fread(&dsize,4,1) != 1) return misc_read_error;
600  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
601  ts.seek(dsize+ts.tell()); /* skip this chunk */
602  }
603  }
604  if (length == 0)
605  data_length = (samps - offset)*(*num_channels);
606  else
607  data_length = length*(*num_channels);
608 
609  file_data = walloc(unsigned char,sample_width * data_length);
610 
611  ts.seek((sample_width*offset*(*num_channels))+ts.tell());
612  if ((dsize=ts.fread(file_data,sample_width,data_length)) != data_length)
613  {
614  /* It seems so many WAV files have their datasize wrong I'll */
615  /* let it through -- I think SOX is a major culprit */
616  if (length == 0) /* the file did the identification */
617  fprintf(stderr,"Unexpected end of file but continuing (apparently missing %d samples)\n",data_length-dsize);
618  else
619  {
620  fprintf(stderr,"Unexpected end of file: (missing %d samples)\n",data_length-dsize);
621  wfree(file_data);
622  return misc_read_error;
623  }
624  }
625 
626  *data = convert_raw_data(file_data,dsize,
627  actual_sample_type, bo_little);
628 
629  *num_samples = dsize / (*num_channels);
630  *sample_type = st_short;
631  *bo = EST_NATIVE_BO;
632  *word_size = 2;
633 
634  return format_ok;
635 }
636 
637 enum EST_write_status save_wave_riff_header(FILE *fp, int num_samples,
638  int num_channels, int sample_rate,
639  enum EST_sample_type_t sample_type, int bo)
640 {
641  (void)bo;
642  const char *info;
643  int data_size, data_int;
644  short data_short;
645 
646  if (sample_type == st_schar)
647  {
648  EST_warning("RIFF format: Signed 8-bit not allowed by this file format");
649  sample_type=st_uchar;
650  }
651 
652  info = "RIFF"; fwrite(info,4,1,fp);
653  data_size = num_channels*num_samples*get_word_size(sample_type)+ 8+16+12;
654  /* WAV files are always LITTLE_ENDIAN (i.e. intel x86 format) */
655  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
656  fwrite(&data_size,1,4,fp); /* total number of bytes in file */
657  info = "WAVE"; fwrite(info,4,1,fp);
658  info = "fmt "; fwrite(info,4,1,fp);
659  data_size = 16;
660  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
661  fwrite(&data_size,1,4,fp); /* size of header */
662  switch (sample_type)
663  {
664  case st_short: data_short = WAVE_FORMAT_PCM; break;
665  case st_uchar: data_short = WAVE_FORMAT_PCM; break;
666  case st_mulaw: data_short = WAVE_FORMAT_MULAW; break;
667  case st_alaw: data_short = WAVE_FORMAT_ALAW; break;
668  case st_adpcm: data_short = WAVE_FORMAT_ADPCM; break;
669  default:
670  fprintf(stderr,"RIFF format: unsupported data format %d\n",
671  sample_type);
672  return misc_write_error;
673  }
674  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
675  fwrite(&data_short,1,2,fp); /* sample type */
676  data_short = num_channels;
677  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
678  fwrite(&data_short,1,2,fp); /* number of channels */
679  data_int = sample_rate;
680  if (EST_BIG_ENDIAN) data_int = SWAPINT(data_int);
681  fwrite(&data_int,1,4,fp); /* sample rate */
682  data_int = sample_rate * num_channels * get_word_size(sample_type);
683  if (EST_BIG_ENDIAN) data_int = SWAPINT(data_int);
684  fwrite(&data_int,1,4,fp); /* Average bytes per second */
685  data_short = num_channels * get_word_size(sample_type);
686  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
687  fwrite(&data_short,1,2,fp); /* block align */
688  data_short = get_word_size(sample_type) * 8;
689  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
690  fwrite(&data_short,1,2,fp); /* bits per sample */
691  info = "data"; fwrite(info,4,1,fp);
692  data_size = num_channels*num_samples*get_word_size(sample_type);
693  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
694  fwrite(&data_size,1,4,fp); /* total number of bytes in data */
695 
696  return write_ok;
697 }
698 
699 enum EST_write_status save_wave_riff_data(FILE *fp, const short *data,
700  int offset, int num_samples, int num_channels,
701  int sample_rate,
702  enum EST_sample_type_t sample_type, int bo)
703 {
704  if (data == NULL)
705  return write_ok;
706 
707  return save_raw_data(fp,data,offset,num_samples,num_channels,
708  sample_type,bo_little);
709 }
710 
711 
712 enum EST_write_status save_wave_riff(FILE *fp, const short *data, int offset,
713  int num_samples, int num_channels,
714  int sample_rate,
715  enum EST_sample_type_t sample_type, int bo)
716 {
717  save_wave_riff_header(fp, num_samples, num_channels, sample_rate,
718  sample_type, bo);
719 
720  return save_wave_riff_data(fp, data, offset, num_samples,
721  num_channels, sample_rate, sample_type, bo);
722 
723 }
724 
725 /*=======================================================================*/
726 /* Amiga/Apple AIFF waveform format */
727 /* This was constructed using info in AudioIFF1.3.hqx found on the web */
728 /* and also I did look at SOX's aiff.c written by Guido van Rossum */
729 /* and Sundry Contributors. */
730 /*=======================================================================*/
731 
732 struct AIFFchunk {
733  char id[4];
734  int size;
735 };
736 
737 struct AIFFssnd { /* Sound Data Chunk */
738  int offset;
739  int blocksize;
740 };
741 
742 enum EST_read_status load_wave_aiff(EST_TokenStream &ts, short **data, int
743  *num_samples, int *num_channels, int
744  *word_size, int *sample_rate, enum
745  EST_sample_type_t *sample_type, int *bo , int
746  offset, int length)
747 {
748  char info[4];
749  struct AIFFchunk chunk;
750  short comm_channels;
751  int comm_samples;
752  short comm_bits;
753  unsigned char ieee_ext_sample_rate[10];
754  struct AIFFssnd ssndchunk;
755  enum EST_sample_type_t actual_sample_type;
756  int dsize,data_length,n;
757  unsigned char *file_data;
758 
759  if (ts.fread(info,sizeof(char),4) != 4)
760  return wrong_format; /* but its almost definitely an error */
761  if (strncmp(info,"FORM",4) != 0)
762  return wrong_format;
763 
764  /* We've got an aiff file, I hope */
765  if (ts.fread(&dsize,4,1) != 1) return misc_read_error;
766  if (EST_LITTLE_ENDIAN) /* file is in different byte order */
767  dsize = SWAPINT(dsize);
768  if ((ts.fread(info,sizeof(char),4) != 4) ||
769  (strncmp(info,"AIFF",4) != 0))
770  {
771  fprintf(stderr, "AIFF file does not have AIFF chunk\n");
772  return misc_read_error;
773  }
774 
775  for ( ; ts.fread(&chunk, sizeof(chunk), 1) == 1 ; )
776  { /* for each chunk in the file */
777  if (EST_LITTLE_ENDIAN) /* file is in different byte order */
778  chunk.size = SWAPINT(chunk.size);
779  if (strncmp(chunk.id,"COMM",4) == 0)
780  {
781  if (chunk.size != 18)
782  {
783  fprintf(stderr,"AIFF chunk: bad size\n");
784  return misc_read_error;
785  }
786  if (ts.fread(&comm_channels, sizeof(short), 1) != 1)
787  return misc_read_error;
788  if (ts.fread(&comm_samples, sizeof(int), 1) != 1)
789  return misc_read_error;
790  if (ts.fread(&comm_bits, sizeof(short), 1) != 1)
791  return misc_read_error;
792  if (ts.fread(ieee_ext_sample_rate, 10, 1) != 1)
793  {
794  fprintf(stderr,"AIFF chunk: eof within COMM chunk\n");
795  return misc_read_error;
796  }
797  if (EST_LITTLE_ENDIAN)
798  {
799  comm_channels = SWAPSHORT(comm_channels);
800  comm_samples = SWAPINT(comm_samples);
801  comm_bits = SWAPSHORT(comm_bits);
802  }
803  *sample_rate = (int)ConvertFromIeeeExtended(ieee_ext_sample_rate);
804  }
805  else if (strncmp(chunk.id,"SSND",4) == 0)
806  {
807  if (ts.fread(&ssndchunk, sizeof(ssndchunk), 1) != 1)
808  {
809  fprintf(stderr,"AIFF chunk: eof within SSND chunk\n");
810  return misc_read_error;
811  }
812  if (EST_LITTLE_ENDIAN)
813  {
814  ssndchunk.offset = SWAPINT(ssndchunk.offset);
815  ssndchunk.blocksize = SWAPINT(ssndchunk.blocksize);
816  }
817 
818  *num_channels = comm_channels;
819  switch (comm_bits)
820  {
821  case 8: actual_sample_type = st_uchar; break;
822  case 16: actual_sample_type = st_short; break;
823  default:
824  fprintf(stderr,"AIFF: unsupported sample width %d bits\n",
825  comm_bits);
826  return misc_read_error;
827  }
828 
829  ts.seek(ssndchunk.offset+(comm_channels*offset)+ts.tell());
830  if (length == 0)
831  data_length = (comm_samples-offset)*comm_channels;
832  else
833  data_length = length*comm_channels;
834  file_data = walloc(unsigned char,
835  data_length*comm_channels*
836  get_word_size(actual_sample_type));
837  if ((n=ts.fread(file_data,get_word_size(actual_sample_type),
838  data_length)) != data_length)
839  {
840  fprintf(stderr,"AIFF read: short file %s\n",
841  (const char *)ts.filename());
842  fprintf(stderr,"AIFF read: at %d got %d instead of %d samples\n",
843  offset,n,data_length);
844  data_length = n;
845  }
846 
847  *data = convert_raw_data(file_data,data_length,
848  actual_sample_type,bo_big);
849  *num_samples = data_length/comm_channels;
850  *sample_type = st_short;
851  *word_size = 2;
852  *bo = EST_NATIVE_BO;
853  break; /* only care about the first SSND chunk */
854  }
855  else
856  { /* skip bytes in chunk */
857  ts.seek(ts.tell()+chunk.size);
858  }
859  }
860 
861  return format_ok;
862 }
863 
864 
865 enum EST_write_status save_wave_aiff_header(FILE *fp,
866  int num_samples, int num_channels,
867  int sample_rate,
868  enum EST_sample_type_t sample_type, int bo)
869 {
870  (void)bo;
871  const char *info;
872  int data_size, data_int;
873  unsigned char ieee_ext_buf[10];
874  short data_short;
875 
876  info = "FORM";
877  fwrite(info,1,4,fp);
878  /* This number seems to be derived different for each example */
879  data_size = 54+(num_samples*num_channels*get_word_size(sample_type));
880  if (EST_LITTLE_ENDIAN)
881  data_size = SWAPINT(data_size);
882  fwrite(&data_size,1,4,fp);
883  info = "AIFF";
884  fwrite(info,1,4,fp);
885  info = "COMM";
886  fwrite(info,1,4,fp);
887  data_int = 18;
888  if (EST_LITTLE_ENDIAN)
889  data_int = SWAPINT(data_int);
890  fwrite(&data_int,1,4,fp);
891  data_short = num_channels;
892  if (EST_LITTLE_ENDIAN)
893  data_short = SWAPSHORT(data_short);
894  fwrite(&data_short,1,2,fp);
895  data_int = num_samples;
896  if (EST_LITTLE_ENDIAN)
897  data_int = SWAPINT(data_int);
898  fwrite(&data_int,1,4,fp);
899  data_short = 8*get_word_size(sample_type);
900  if (EST_LITTLE_ENDIAN)
901  data_short = SWAPSHORT(data_short);
902  fwrite(&data_short,1,2,fp);
903  ConvertToIeeeExtended((double)sample_rate,ieee_ext_buf);
904  fwrite(ieee_ext_buf,1,10,fp);
905  info = "SSND";
906  fwrite(info,1,4,fp);
907  data_int = 8 + (num_samples*num_channels*get_word_size(sample_type));
908  if (EST_LITTLE_ENDIAN)
909  data_int = SWAPINT(data_int);
910  fwrite(&data_int,1,4,fp);
911  data_int = 0;
912  if (EST_LITTLE_ENDIAN)
913  data_int = SWAPINT(data_int);
914  fwrite(&data_int,1,4,fp); /* offset */
915  if (EST_LITTLE_ENDIAN)
916  data_int = SWAPINT(data_int);
917  fwrite(&data_int,1,4,fp); /* blocksize */
918 
919  return write_ok;
920 
921 }
922 
923 enum EST_write_status save_wave_aiff_data(FILE *fp, const short *data, int offset,
924  int num_samples, int num_channels,
925  int sample_rate,
926  enum EST_sample_type_t sample_type, int bo)
927 {
928 
929  if (data == NULL)
930  return write_ok;
931  if ((sample_type == st_short) || (sample_type == st_uchar))
932  return save_raw_data(fp,data, offset, num_samples, num_channels,
933  sample_type, bo_big);
934  else
935  {
936  fprintf(stderr,"AIFF: requested data type not uchar or short\n");
937  return misc_write_error;
938  }
939 }
940 
941 
942 enum EST_write_status save_wave_aiff(FILE *fp, const short *data, int offset,
943  int num_samples, int num_channels,
944  int sample_rate,
945  enum EST_sample_type_t sample_type, int bo)
946 {
947  save_wave_aiff_header(fp, num_samples, num_channels,
948  sample_rate, sample_type, bo);
949 
950  return save_wave_aiff_data(fp, data, offset,
951  num_samples, num_channels,
952  sample_rate, sample_type, bo);
953 }
954 
955 /*=======================================================================*/
956 /* ulaw EST_filetype are just raw data with 8K ulaw contents */
957 /*=======================================================================*/
958 
959 enum EST_read_status load_wave_ulaw(EST_TokenStream &ts, short **data, int
960  *num_samples, int *num_channels, int *word_size, int
961  *sample_rate, enum EST_sample_type_t *sample_type, int *bo,
962  int offset, int length)
963 
964 {
965  unsigned char *ulaw;
966  int data_length,samps;
967 
968  ts.seek_end();
969  samps = ts.tell();
970 
971  if (length == 0)
972  data_length = samps - offset;
973  else
974  data_length = length;
975 
976  ulaw = walloc(unsigned char, data_length);
977  ts.seek(offset);
978  if (ts.fread(ulaw,1,data_length) != data_length)
979  {
980  wfree(ulaw);
981  return misc_read_error;
982  }
983 
984  *data = walloc(short,data_length);
985  ulaw_to_short(ulaw,*data,data_length);
986  wfree(ulaw);
987 
988  *num_samples = data_length;
989  *sample_rate = 8000;
990  *num_channels = 1;
991  *sample_type = st_short;
992  *word_size = 2;
993  *bo = EST_NATIVE_BO;
994 
995  return format_ok;
996 }
997 
998 enum EST_write_status save_wave_ulaw_header(FILE *fp,
999  int num_samples, int num_channels,
1000  int sample_rate,
1001  enum EST_sample_type_t sample_type, int bo)
1002 {
1003  (void) sample_rate;
1004  (void) sample_type;
1005  (void) fp;
1006  (void) num_samples;
1007  (void) num_channels;
1008  (void) bo;
1009  return write_ok;
1010 }
1011 
1012 enum EST_write_status save_wave_ulaw_data(FILE *fp, const short *data, int offset,
1013  int num_samples, int num_channels,
1014  int sample_rate,
1015  enum EST_sample_type_t sample_type, int bo)
1016 {
1017  if (data == NULL)
1018  return write_ok;
1019 
1020  return save_wave_raw(fp,data,offset,num_samples,num_channels,
1021  8000,st_mulaw,bo);
1022 }
1023 
1024 enum EST_write_status save_wave_ulaw(FILE *fp, const short *data, int offset,
1025  int num_samples, int num_channels,
1026  int sample_rate,
1027  enum EST_sample_type_t sample_type, int bo)
1028 {
1029  save_wave_ulaw_header(fp, num_samples, num_channels,
1030  sample_rate, sample_type, bo);
1031 
1032  return save_wave_ulaw_data(fp, data, offset,
1033  num_samples, num_channels,
1034  sample_rate, sample_type, bo);
1035 }
1036 
1037 
1038 
1039 enum EST_read_status load_wave_alaw(EST_TokenStream &ts, short **data, int
1040  *num_samples, int *num_channels, int *word_size, int
1041  *sample_rate, enum EST_sample_type_t *sample_type, int *bo,
1042  int offset, int length)
1043 
1044 {
1045  unsigned char *alaw;
1046  int data_length,samps;
1047 
1048  ts.seek_end();
1049  samps = ts.tell();
1050 
1051  if (length == 0)
1052  data_length = samps - offset;
1053  else
1054  data_length = length;
1055 
1056  alaw = walloc(unsigned char, data_length);
1057  ts.seek(offset);
1058  if (ts.fread(alaw,1,data_length) != data_length)
1059  {
1060  wfree(alaw);
1061  return misc_read_error;
1062  }
1063 
1064  *data = walloc(short,data_length);
1065  alaw_to_short(alaw,*data,data_length);
1066  wfree(alaw);
1067 
1068  *num_samples = data_length;
1069  *sample_rate = 8000;
1070  *num_channels = 1;
1071  *sample_type = st_short;
1072  *word_size = 2;
1073  *bo = EST_NATIVE_BO;
1074 
1075  return format_ok;
1076 }
1077 
1078 enum EST_write_status save_wave_alaw_header(FILE *fp,
1079  int num_samples, int num_channels,
1080  int sample_rate,
1081  enum EST_sample_type_t sample_type, int bo)
1082 {
1083  (void) sample_rate;
1084  (void) sample_type;
1085  (void) fp;
1086  (void) num_samples;
1087  (void) num_channels;
1088  (void) bo;
1089  return write_ok;
1090 }
1091 
1092 enum EST_write_status save_wave_alaw_data(FILE *fp, const short *data, int offset,
1093  int num_samples, int num_channels,
1094  int sample_rate,
1095  enum EST_sample_type_t sample_type, int bo)
1096 {
1097  (void)sample_rate;
1098  (void)sample_type;
1099  if (data == NULL)
1100  return write_ok;
1101  return save_wave_raw(fp,data,offset,num_samples,num_channels,
1102  8000,st_alaw,bo);
1103 }
1104 
1105 enum EST_write_status save_wave_alaw(FILE *fp, const short *data, int offset,
1106  int num_samples, int num_channels,
1107  int sample_rate,
1108  enum EST_sample_type_t sample_type, int bo)
1109 {
1110  save_wave_alaw_header(fp, num_samples, num_channels,
1111  sample_rate, sample_type, bo);
1112 
1113  return save_wave_alaw_data(fp, data, offset,
1114  num_samples, num_channels,
1115  sample_rate, sample_type, bo);
1116 }
1117 
1118 
1119 /*=======================================================================*/
1120 /* Sun and Next snd files */
1121 /*=======================================================================*/
1122 
1123 typedef struct {
1124  unsigned int magic; /* magic number */
1125  unsigned int hdr_size; /* size of this header */
1126  int data_size; /* length of data (optional) */
1127  unsigned int encoding; /* data encoding format */
1128  unsigned int sample_rate; /* samples per second */
1129  unsigned int channels; /* number of interleaved channels */
1130 } Sun_au_header;
1131 
1132 enum EST_read_status load_wave_snd(EST_TokenStream &ts, short **data, int
1133  *num_samples, int *num_channels, int *word_size, int
1134  *sample_rate,enum EST_sample_type_t *sample_type, int *bo ,
1135  int offset, int length)
1136 {
1137  /* Header structures */
1138  Sun_au_header header;
1139  enum EST_sample_type_t encoding_type;
1140  int data_length, sample_width, bytes, samps, n;
1141  unsigned char *file_data;
1142  int current_pos;
1143 
1144  current_pos = ts.tell();
1145  if (ts.fread(&header, sizeof(Sun_au_header), 1) != 1)
1146  return misc_read_error;
1147 
1148  /* test for magic number */
1149  if ((EST_LITTLE_ENDIAN) &&
1150  ((unsigned int)0x2e736e64 == SWAPINT(header.magic)))
1151  { /* wrong byte order, swap header */
1152  header.hdr_size = SWAPINT(header.hdr_size);
1153  header.data_size = SWAPINT(header.data_size);
1154  header.encoding = SWAPINT(header.encoding);
1155  header.sample_rate = SWAPINT(header.sample_rate);
1156  header.channels = SWAPINT(header.channels);
1157  }
1158  else if ((unsigned int)0x2e736e64 != header.magic)
1159  return wrong_format;
1160 
1161  switch (header.encoding)
1162  {
1163  case 1:
1164  encoding_type = st_mulaw;
1165  break;
1166  case 2:
1167  encoding_type = st_uchar;
1168  break;
1169  case 3:
1170  encoding_type = st_short;
1171  break;
1172  default:
1173  fprintf(stderr, "Unsupported data type in SND header\n");
1174  return misc_read_error;
1175  }
1176 
1177  *num_channels = header.channels;
1178  sample_width = get_word_size(encoding_type);
1179  *sample_rate = header.sample_rate;
1180 
1181  if ((header.data_size == 0) ||
1182  (header.data_size == -1))
1183  {
1184  ts.seek_end();
1185  bytes = ts.tell() - header.hdr_size;
1186  }
1187  else
1188  bytes = header.data_size;
1189  samps = bytes/sample_width;
1190 
1191  if (length == 0)
1192  data_length = (samps - offset)*(*num_channels);
1193  else
1194  data_length = length *(*num_channels);
1195 
1196  file_data = walloc(unsigned char, sample_width * data_length);
1197  ts.seek(current_pos+header.hdr_size+(sample_width*offset*(*num_channels)));
1198  if ((n=ts.fread(file_data,sample_width,data_length)) != data_length)
1199  {
1200  fprintf(stderr,"WAVE read: short file %s\n",
1201  (const char *)ts.filename());
1202  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
1203  offset,n,data_length);
1204  data_length = n;
1205  }
1206 
1207  *data = convert_raw_data(file_data,data_length,encoding_type,bo_big);
1208 
1209  if (*data == NULL)
1210  return read_error;
1211 
1212  *num_samples = data_length/ (*num_channels);
1213  *sample_type = st_short;
1214  *bo = EST_NATIVE_BO;
1215  *word_size = 2;
1216  return read_ok;
1217 }
1218 
1219 enum EST_write_status save_wave_snd_header(FILE *fp,
1220  int num_samples, int num_channels,
1221  int sample_rate,
1222  enum EST_sample_type_t sample_type, int bo)
1223 {
1224  (void)bo;
1225  /* Header structures */
1226  Sun_au_header header;
1227 
1228  /* Fill in header structure */
1229  header.magic = (unsigned int)0x2e736e64; /* should be a macro surely */
1230  header.hdr_size = sizeof(header); /* ! */
1231  header.data_size = get_word_size(sample_type) * num_channels * num_samples;
1232 
1233  switch (sample_type) {
1234  case st_mulaw:
1235  header.encoding = 1;
1236  break;
1237  case st_uchar:
1238  header.encoding = 2;
1239  break;
1240  case st_short:
1241  header.encoding = 3;
1242  break;
1243 
1244  default:
1245  fprintf(stderr,
1246  "Unsupported sample type cannot be saved in SND format\n");
1247  return misc_write_error;
1248 
1249  }
1250 
1251  /* check consistency */
1252 
1253  header.sample_rate = sample_rate;
1254 
1255  header.channels = num_channels;
1256 
1257  if (EST_LITTLE_ENDIAN)
1258  {
1259  /* snd files all in big endian format */
1260  header.magic = SWAPINT(header.magic);
1261  header.hdr_size = SWAPINT(header.hdr_size);
1262  header.data_size = SWAPINT(header.data_size);
1263  header.encoding = SWAPINT(header.encoding);
1264  header.sample_rate = SWAPINT(header.sample_rate);
1265  header.channels = SWAPINT(header.channels);
1266 
1267  }
1268  /* write header */
1269  if (fwrite(&header, sizeof(header), 1, fp) != 1)
1270  return misc_write_error;
1271 
1272  return write_ok;
1273 }
1274 
1275 enum EST_write_status save_wave_snd_data(FILE *fp, const short *data, int offset,
1276  int num_samples, int num_channels,
1277  int sample_rate,
1278  enum EST_sample_type_t sample_type, int bo)
1279 {
1280  if (data == NULL)
1281  return write_ok;
1282 
1283  /* snd files are always in BIG_ENDIAN (sun) byte order */
1284  return save_raw_data(fp,data,offset,num_samples,num_channels,
1285  sample_type,bo_big);
1286 }
1287 
1288 
1289 enum EST_write_status save_wave_snd(FILE *fp, const short *data, int offset,
1290  int num_samples, int num_channels,
1291  int sample_rate,
1292  enum EST_sample_type_t sample_type, int bo)
1293 {
1294  save_wave_snd_header(fp, num_samples, num_channels, sample_rate,
1295  sample_type, bo);
1296  return save_wave_snd_data(fp, data, offset, num_samples,
1297  num_channels, sample_rate, sample_type, bo);
1298 }
1299 
1300 
1301 /*=======================================================================*/
1302 /* CSTR Audlab files (from the last century) */
1303 /* They are always bigendian */
1304 /*=======================================================================*/
1305 struct s1 {
1306  char c[17];
1307  float f1;
1308  float f2;
1309 };
1310 
1311 struct s2 {
1312  float f1;
1313  float f2;
1314  float f3;
1315  char c1;
1316  char c2;
1317  int i1;
1318  int i2;
1319 };
1320 
1321 struct audlabfh {
1322  struct s1 z;
1323  char file_type[8];
1324  char c1[17];
1325  char c2[17];
1326  char c3[17];
1327  int start;
1328  char data_type;
1329  char c5[64];
1330 };
1331 
1332 struct audlabsh {
1333  int channel_count;
1334  char serial;
1335  int sample_rate;
1336  char c1[20];
1337  int i1;
1338  char c2;
1339  char c3[121];
1340  char c4[121];
1341 
1342 };
1343 struct audlabsd {
1344  char descr[17];
1345  int sample_count;
1346  int nbits;
1347  float f1;
1348  struct s2 z;
1349 };
1350 
1351 enum EST_read_status load_wave_audlab(EST_TokenStream &ts, short **data, int
1352  *num_samples, int *num_channels, int *word_size, int
1353  *sample_rate, enum EST_sample_type_t *sample_type, int *bo, int
1354  offset, int length)
1355 {
1356  /* Header structures */
1357  struct audlabfh fh;
1358  struct audlabsh sh;
1359  struct audlabsd sd;
1360  int data_length,sample_count;
1361  int hdr_length;
1362  int current_pos;
1363 
1364  /* Read header structures from char array */
1365  current_pos = ts.tell();
1366 
1367  if (ts.fread(&fh, sizeof(struct audlabfh), 1) != 1)
1368  return misc_read_error;
1369  if (strcmp(fh.file_type, "Sample") != 0)
1370  return wrong_format;
1371 
1372  if (ts.fread(&sh, sizeof(struct audlabsh), 1) != 1)
1373  return misc_read_error;
1374  if (ts.fread(&sd, sizeof(struct audlabsd), 1) != 1)
1375  return misc_read_error;
1376  hdr_length = sizeof(struct audlabfh) +
1377  sizeof(struct audlabsh) +
1378  sizeof(struct audlabsd);
1379 
1380  if (EST_BIG_ENDIAN)
1381  {
1382  *num_channels = sh.channel_count;
1383  *sample_rate = sh.sample_rate;
1384  sample_count = sd.sample_count;
1385  }
1386  else // audlab files are bigendian
1387  {
1388  *num_channels = SWAPINT(sh.channel_count);
1389  *sample_rate = SWAPINT(sh.sample_rate);
1390  sample_count = SWAPINT(sd.sample_count);
1391  }
1392  if (length == 0)
1393  data_length = (sample_count - offset) * (*num_channels);
1394  else
1395  data_length = length *(*num_channels);
1396 
1397  *data = walloc(short,sizeof(short) * data_length);
1398  ts.seek(current_pos+hdr_length+(sizeof(short)*offset*(*num_channels)));
1399 
1400  if ((int)ts.fread(*data, sizeof(short), data_length) != data_length)
1401  {
1402  wfree(*data);
1403  return misc_read_error;
1404  }
1405  if (EST_LITTLE_ENDIAN)
1406  swap_bytes_short(*data,data_length);
1407 
1408  *num_samples = data_length / (*num_channels);
1409  *sample_type = st_short; /* set internal type*/
1410  *word_size = sizeof(short);
1411  *bo = EST_NATIVE_BO;
1412 
1413  return format_ok;
1414 }
1415 
1416 enum EST_write_status save_wave_audlab_header(FILE *fp,
1417  int num_samples, int num_channels,
1418  int sample_rate,
1419  enum EST_sample_type_t sample_type, int bo)
1420 {
1421  (void)bo;
1422  (void)sample_type;
1423  /* Header structures */
1424  struct audlabfh fh;
1425  struct audlabsh sh;
1426  struct audlabsd sd;
1427 
1428  fh.start = sizeof (struct audlabfh) +
1429  sizeof (struct audlabsh) + sizeof (struct audlabsd);
1430  fh.data_type = 2;
1431  strcpy(fh.file_type, "Sample");
1432 
1433  if (EST_LITTLE_ENDIAN)
1434  { // need to swap some of those numbers
1435  sh.channel_count = SWAPINT(num_channels);
1436  sh.serial = 1;
1437  sh.sample_rate = SWAPINT(sample_rate);
1438 
1439  sd.sample_count = SWAPINT(num_samples);
1440  sd.nbits = SWAPINT(16);
1441  }
1442  else
1443  {
1444  sh.channel_count = num_channels;
1445  sh.serial = 1;
1446  sh.sample_rate = sample_rate;
1447 
1448  sd.sample_count = num_samples;
1449  sd.nbits = 16;
1450  }
1451  sprintf(sd.descr, "Filter 1");
1452 
1453  /* write headers */
1454  fwrite (&fh, sizeof(fh), 1, fp);
1455  fwrite (&sh, sizeof(sh), 1, fp);
1456  fwrite (&sd, sizeof(sd), 1, fp);
1457  return write_ok;
1458 }
1459 
1460 enum EST_write_status save_wave_audlab_data(FILE *fp, const short *data, int offset,
1461  int num_samples, int num_channels,
1462  int sample_rate,
1463  enum EST_sample_type_t sample_type, int bo)
1464 {
1465  if (data == NULL)
1466  return write_ok;
1467 
1468  /* write data*/
1469  return save_raw_data(fp,data,offset,num_samples,num_channels,
1470  st_short,bo_big);
1471 }
1472 
1473 enum EST_write_status save_wave_audlab(FILE *fp, const short *data, int offset,
1474  int num_samples, int num_channels,
1475  int sample_rate,
1476  enum EST_sample_type_t sample_type, int bo)
1477 {
1478  save_wave_audlab_header(fp, num_samples, num_channels,
1479  sample_rate, sample_type, bo);
1480  return save_wave_audlab_data(fp, data, offset,
1481  num_samples, num_channels,
1482  sample_rate, sample_type, bo);
1483 }
1484 
1485 /*=======================================================================*/
1486 /* Entropic ESPS SD files: portable (non-proprietary) method */
1487 /*=======================================================================*/
1488 
1489 /* Deep thanks go to Peter Kabal from McGill University whose AF code */
1490 /* showed me this was even possible. I looked at his code to find */
1491 /* parts I couldn't work out myself. Also to Rodney Johnson of */
1492 /* Entropic whose document "ESPS APPLICATION NOTE: Non-ESPS Programs */
1493 /* and the ESPS File System" gave details of how to access ESPS files */
1494 /* without using the ESPS library code. */
1495 
1496 #include "esps_utils.h"
1497 enum EST_read_status load_wave_sd(EST_TokenStream &ts, short **data, int
1498  *num_samples, int *num_channels, int
1499  *word_size, int *sample_rate, enum
1500  EST_sample_type_t *sample_type, int *bo , int
1501  offset, int length)
1502 {
1503  /* A license free version of an esps file reading program */
1504  FILE *fd;
1505  esps_hdr hdr;
1506  int actual_bo, sample_width, data_length;
1507  enum EST_read_status rv;
1508  int dl;
1509  enum EST_sample_type_t actual_sample_type;
1510  double d;
1511  unsigned char *file_data;
1512 
1513  if ((fd = ts.filedescriptor()) == NULL)
1514  {
1515  fprintf(stderr, "Can't open esps file %s for reading\n",
1516  (const char *)ts.filename());
1517  return misc_read_error;
1518  }
1519 
1520  if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
1521  return rv;
1522 
1523  if (hdr->file_type != ESPS_SD)
1524  {
1525  fprintf(stderr,"ESPS file: not an FEA_SD file\n");
1526  delete_esps_hdr(hdr);
1527  return misc_read_error;
1528  }
1529 
1530  if (fea_value_d("record_freq",0,hdr,&d) != 0)
1531  {
1532  fprintf(stderr,"ESPS file: can't find sample_rate in header assuming 16000\n");
1533  *sample_rate = 16000;
1534  }
1535  else
1536  *sample_rate = (int)d;
1537  actual_sample_type = st_short; /* you're not trying hard enough */
1538  sample_width = get_word_size(actual_sample_type);
1539  *num_channels = hdr->field_dimension[0];
1540  if (hdr->swapped)
1541  actual_bo = (EST_BIG_ENDIAN ? bo_little : bo_big);
1542  else
1543  actual_bo = (EST_BIG_ENDIAN ? bo_big : bo_little);
1544 
1545  if (length == 0)
1546  data_length = (hdr->num_records - offset)*(*num_channels);
1547  else
1548  data_length = length *(*num_channels);
1549 
1550  file_data = walloc(unsigned char, sample_width * data_length);
1551  fseek(fd,hdr->hdr_size+(sample_width*offset*(*num_channels)),
1552  SEEK_SET);
1553  if ((dl=fread(file_data,sample_width,data_length,fd)) != data_length)
1554  {
1555  fprintf(stderr,"WAVE read: esps short file %s\n",
1556  (const char *)ts.filename());
1557  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
1558  offset,dl,data_length);
1559  data_length = dl;
1560  }
1561 
1562  *data = convert_raw_data(file_data,data_length,
1563  actual_sample_type,
1564  actual_bo);
1565 
1566  *num_samples = data_length/ (*num_channels);
1567  *sample_type = st_short;
1568  *bo = EST_NATIVE_BO;
1569  *word_size = 2;
1570  delete_esps_hdr(hdr);
1571  return format_ok;
1572 
1573 }
1574 
1575 
1576 enum EST_write_status save_wave_sd_header(FILE *fp,
1577  int num_samples, int num_channels,
1578  int sample_rate,
1579  enum EST_sample_type_t sample_type, int bo)
1580 
1581 {
1582  (void)bo;
1583  esps_hdr hdr = make_esps_sd_hdr();
1584  enum EST_write_status rv;
1585  short esps_type;
1586 
1587  hdr->num_records = num_samples;
1588  switch (sample_type)
1589  {
1590  case st_short: esps_type = ESPS_SHORT; break;
1591  case st_schar: esps_type = ESPS_CHAR; break; /* maybe should be BYTE */
1592  case st_int: esps_type = ESPS_INT; break;
1593  case st_float: esps_type = ESPS_FLOAT; break;
1594  case st_double: esps_type = ESPS_DOUBLE; break;
1595  default:
1596  fprintf(stderr,"ESPS file: no support for sample_type %s\n",
1597  sample_type_to_str(sample_type));
1598  return misc_write_error;
1599  }
1600  /* I believe all of the following are necessary and in this order */
1601  add_field(hdr,"samples",esps_type,num_channels);
1602  /* FIXME: What is doing this path here?? */
1603  add_fea_special(hdr,ESPS_FEA_DIRECTORY,"margo:/disk/disk10/home/awb/projects/speech_tools/main");
1604  add_fea_special(hdr,ESPS_FEA_COMMAND,
1605  "EDST waveform written as ESPS FEA_SD.\n\
1606  ");
1607  add_fea_d(hdr,"start_time",0,(double)0);
1608  add_fea_d(hdr,"record_freq",0,(double)sample_rate);
1609  add_fea_d(hdr,"max_value",0,(double)27355);
1610 
1611  if ((rv=write_esps_hdr(hdr,fp)) != write_ok)
1612  {
1613  delete_esps_hdr(hdr);
1614  return rv;
1615  }
1616  /* lets ignore desired bo and sample type for the time being */
1617  delete_esps_hdr(hdr);
1618  return write_ok;
1619 }
1620 
1621 
1622 enum EST_write_status save_wave_sd_data(FILE *fp, const short *data,
1623  int offset,
1624  int num_samples, int num_channels,
1625  int sample_rate,
1626  enum EST_sample_type_t sample_type, int bo)
1627 
1628 {
1629  if (data == NULL)
1630  return write_ok;
1631 
1632  return save_raw_data(fp,data,offset,num_samples,num_channels,
1633  sample_type,EST_NATIVE_BO);
1634 }
1635 
1636 enum EST_write_status save_wave_sd(FILE *fp, const short *data, int offset,
1637  int num_samples, int num_channels,
1638  int sample_rate,
1639  enum EST_sample_type_t sample_type, int bo)
1640 
1641 {
1642  save_wave_sd_header(fp, num_samples, num_channels, sample_rate,
1643  sample_type, bo);
1644  return save_wave_sd_data(fp, data, offset, num_samples,
1645  num_channels, sample_rate, sample_type, bo);
1646 
1647 }
1648 
1649 /*=======================================================================*/
1650 /* Raw data files -- unheadered */
1651 /* THESE FUNCTIONS ARE DIFFERENT FROM THE REST */
1652 /* These function have more parameters than the standard file i/o */
1653 /* as information cannot be gleamed from the file */
1654 /*=======================================================================*/
1655 
1656 enum EST_read_status load_wave_raw(EST_TokenStream &ts, short **data, int
1657  *num_samples, int *num_channels,
1658  int *word_size, int
1659  *sample_rate,
1660  enum EST_sample_type_t *sample_type,
1661  int *bo, int offset, int length,
1662  int isample_rate,
1663  enum EST_sample_type_t isample_type,
1664  int ibo, int inc)
1665 {
1666  unsigned char *file_data;
1667  int data_length,samps,sample_width;
1668  int guess,i,samp;
1669  short *ndata;
1670 
1671  if (isample_type == st_ascii)
1672  {
1673  /* Guess the size */
1674  if ((offset != 0) || (length != 0))
1675  {
1676  fprintf(stderr,"Load ascii wave: doesn't support offsets and lengths\n");
1677  return misc_read_error;
1678  }
1679 
1680  ts.seek_end();
1681  guess = (int)(1.2*ts.tell()/7)+10; /* rough guess of the num of samps */
1682  ts.seek(0);
1683  *data = walloc(short, guess);
1684  i=0;
1685  while (!ts.eof())
1686  {
1687  samp = atoi(ts.get().string());
1688  if (i == guess)
1689  {
1690  ndata = walloc(short,(int)(guess*1.2));
1691  memmove(ndata,*data,guess*sizeof(short));
1692  wfree(*data);
1693  *data = ndata;
1694  guess = (int)(guess*1.2);
1695  }
1696  if (samp < -32768)
1697  {
1698  fprintf(stderr,"Load ascii wave: sample %d underflow clipping\n",
1699  i);
1700  (*data)[i] = -32768;
1701  }
1702  else if (samp > 32767)
1703  {
1704  fprintf(stderr,"Load ascii wave: sample %d overflow clipping\n",
1705  i);
1706  (*data)[i] = 32767;
1707  }
1708  else
1709  (*data)[i] = (short)samp;
1710  i++;
1711  }
1712  data_length = i;
1713  }
1714  else
1715  {
1716  ts.seek_end();
1717  sample_width = get_word_size(isample_type);
1718  samps = ts.tell()/sample_width;
1719 
1720  if (length == 0)
1721  data_length = samps - offset;
1722  else
1723  data_length = length;
1724 
1725  file_data = walloc(unsigned char, data_length * sample_width *inc);
1726  ts.seek(offset*sample_width*inc);
1727  if ((int)ts.fread(file_data,sample_width,data_length) != data_length)
1728  return misc_read_error;
1729 
1730  *data = convert_raw_data(file_data,data_length,isample_type,ibo);
1731  }
1732 
1733  *num_samples = data_length/inc;
1734  *sample_rate = isample_rate;
1735  *num_channels = inc;
1736  *sample_type = st_short;
1737  *word_size = 2;
1738  *bo = EST_NATIVE_BO;
1739 
1740  return format_ok;
1741 }
1742 
1743 enum EST_write_status save_wave_raw_header(FILE *fp,
1744  int num_samples, int num_channels,
1745  int sample_rate,
1746  enum EST_sample_type_t sample_type, int bo)
1747 {
1748  return write_ok;
1749 }
1750 
1751 enum EST_write_status save_wave_raw_data(FILE *fp, const short *data,
1752  int offset,
1753  int num_samples, int num_channels,
1754  int sample_rate,
1755  enum EST_sample_type_t sample_type, int bo)
1756 {
1757  if (data == NULL)
1758  return write_ok;
1759 
1760  return save_raw_data(fp,data,offset,num_samples,num_channels,
1761  sample_type,bo);
1762 }
1763 
1764 enum EST_write_status save_wave_raw(FILE *fp, const short *data,
1765  int offset,
1766  int num_samples, int num_channels,
1767  int sample_rate,
1768  enum EST_sample_type_t sample_type, int bo)
1769 {
1770  (void)sample_rate;
1771 
1772  return save_wave_raw_data(fp, data, offset, num_samples,
1773  num_channels, sample_rate, sample_type, bo);
1774 }
1775 
1776 /***********************************************************************/
1777 /* */
1778 /* end of file type specific functions */
1779 /* */
1780 /***********************************************************************/
1781 
1782 enum EST_write_status wave_io_save_header(FILE *fp,
1783  const int num_samples, const int num_channels,
1784  const int sample_rate,
1785  const EST_String& stype, const int bo,
1786  const EST_String& ftype)
1787 {
1788  EST_WaveFileType t = EST_WaveFile::map.token(ftype);
1789  EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
1790  switch(t)
1791  {
1792  case wff_nist:
1793  return save_wave_nist_header(fp, num_samples, num_channels,
1794  sample_rate, sample_type, bo);
1795  break;
1796  case wff_esps:
1797  return save_wave_sd_header(fp, num_samples, num_channels,
1798  sample_rate, sample_type, bo);
1799  break;
1800  case wff_est:
1801  return save_wave_est_header(fp, num_samples, num_channels,
1802  sample_rate, sample_type, bo);
1803  break;
1804  case wff_audlab:
1805  return save_wave_audlab_header(fp, num_samples, num_channels,
1806  sample_rate, sample_type, bo);
1807  break;
1808  case wff_snd:
1809  return save_wave_snd_header(fp, num_samples, num_channels,
1810  sample_rate, sample_type, bo);
1811  break;
1812  case wff_aiff:
1813  return save_wave_aiff_header(fp, num_samples, num_channels,
1814  sample_rate, sample_type, bo);
1815  break;
1816  case wff_riff:
1817  return save_wave_riff_header(fp, num_samples, num_channels,
1818  sample_rate, sample_type, bo);
1819  break;
1820  case wff_raw:
1821  return save_wave_raw_header(fp, num_samples, num_channels,
1822  sample_rate, sample_type, bo);
1823  break;
1824  case wff_ulaw:
1825  return save_wave_ulaw_header(fp, num_samples, num_channels,
1826  sample_rate, sample_type, bo);
1827  break;
1828  default:
1829  case wff_none:
1830  cerr << "Can't save wave header to files type " << ftype << endl;
1831  break;
1832  }
1833  return write_ok;
1834 }
1835 
1836 
1837 enum EST_write_status wave_io_save_data(FILE *fp, const short * data,
1838  const int offset,
1839  const int num_samples, const int num_channels,
1840  const int sample_rate,
1841  const EST_String& stype, const int bo,
1842  const EST_String& ftype)
1843 {
1844  EST_WaveFileType t = EST_WaveFile::map.token(ftype);
1845  EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
1846  switch(t)
1847  {
1848  case wff_nist:
1849  return save_wave_nist_data(fp, data, offset, num_samples, num_channels,
1850  sample_rate, sample_type, bo);
1851  break;
1852  case wff_esps:
1853  return save_wave_sd_data(fp, data, offset, num_samples, num_channels,
1854  sample_rate, sample_type, bo);
1855  break;
1856  case wff_est:
1857  return save_wave_est_data(fp, data, offset, num_samples, num_channels,
1858  sample_rate, sample_type, bo);
1859  break;
1860  case wff_audlab:
1861  return save_wave_audlab_data(fp, data, offset, num_samples, num_channels,
1862  sample_rate, sample_type, bo);
1863  break;
1864  case wff_snd:
1865  return save_wave_snd_data(fp, data, offset, num_samples, num_channels,
1866  sample_rate, sample_type, bo);
1867  break;
1868  case wff_aiff:
1869  return save_wave_aiff_data(fp, data, offset, num_samples, num_channels,
1870  sample_rate, sample_type, bo);
1871  break;
1872  case wff_riff:
1873  return save_wave_riff_data(fp, data, offset, num_samples, num_channels,
1874  sample_rate, sample_type, bo);
1875  break;
1876  case wff_raw:
1877  return save_wave_raw_data(fp, data, offset, num_samples, num_channels,
1878  sample_rate, sample_type, bo);
1879  break;
1880  case wff_ulaw:
1881  return save_wave_ulaw_data(fp, data, offset, num_samples, num_channels,
1882  sample_rate, sample_type, bo);
1883  break;
1884  default:
1885  case wff_none:
1886  cerr << "Can't save wave data to files type " << ftype << endl;
1887  break;
1888  }
1889  return write_ok;
1890 }
int ival(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:76
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
const int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
int eof()
end of file
Definition: EST_Token.h:356
int fread(void *buff, int size, int nitems) EST_WARN_UNUSED_RESULT
Reading binary data, (don't use peek() immediately beforehand)
Definition: EST_Token.cc:355
const EST_String filename() const
The originating filename (if there is one)
Definition: EST_Token.h:372
const EST_String pos_description()
A string describing current position, suitable for error messages.
Definition: EST_Token.cc:875
FILE * filedescriptor()
For the people who need the actual description (if possible)
Definition: EST_Token.h:374
void close(void)
Close stream.
Definition: EST_Token.cc:406
int tell(void) const
tell, synonym for filepos
Definition: EST_Token.h:363
int open(const EST_String &filename)
open a \Ref{EST_TokenStream} for a file.
Definition: EST_Token.cc:200
EST_TokenStream & get(EST_Token &t)
get next token in stream
Definition: EST_Token.cc:486
int seek(int position)
seek, reposition file pointer
Definition: EST_Token.cc:305