Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
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_mulaw:
115  c = "ULAW"; break;
116  case st_short:
117  c = "pcm"; break;
118  case st_int:
119  c = "PCM-4"; break;
120  case st_float:
121  c = "REAL"; break;
122  case st_double:
123  c = "REAL"; break;
124  default:
125  fprintf(stderr,"Unknown sample type for nist");
126  c = "";
127  }
128  return c;
129 }
130 
131 enum EST_sample_type_t nist_to_sample_type(char *type)
132 {
133  if ((streq(type,"pcm")) ||
134  (streq(type,"PCM")) ||
135  (streq(type,"pcm-2")))
136  return st_short;
137  if (strcmp(type,"pcm,embedded-shorten-v1.1") == 0)
138  return st_shorten;
139  else if ((EST_strcasecmp(type,"ULAW",NULL) == 0) ||
140  (EST_strcasecmp(type,"U-LAW",NULL) == 0) ||
141  (EST_strcasecmp(type,"mu-law",NULL) == 0) ||
142  (EST_strcasecmp(type,"mulaw",NULL) == 0))
143  return st_mulaw;
144  else if (strcmp(type,"alaw") == 0)
145  return st_alaw;
146  else if (strcmp(type,"PCM-1") == 0)
147  return st_schar;
148  else if (strcmp(type,"PCM-4") == 0)
149  return st_int;
150  else if (strcmp(type,"REAL") == 0)
151  return st_float;
152  else
153 
154  {
155  fprintf(stderr,"NIST: unknown sample type: %s\n",type);
156  return st_unknown;
157  }
158 }
159 
160 enum EST_read_status load_wave_nist(EST_TokenStream &ts, short **data, int
161  *num_samples, int *num_channels, int
162  *word_size, int *sample_rate, enum
163  EST_sample_type_t *sample_type, int *bo , int
164  offset, int length)
165 
166 {
167  char header[NIST_HDR_SIZE];
168  int samps,sample_width,data_length,actual_bo;
169  unsigned char *file_data;
170  enum EST_sample_type_t actual_sample_type;
171  char *byte_order, *sample_coding;
172  int n;
173  int current_pos;
174 
175  current_pos = ts.tell();
176  if (ts.fread(header,NIST_HDR_SIZE,1) != 1)
177  return wrong_format;
178 
179  if (strncmp(header,NIST_SIG,strlen(NIST_SIG)) != 0)
180  return wrong_format;
181 
182  samps = nist_get_param_int(header,"sample_count",-1);
183  *num_channels = nist_get_param_int(header,"channel_count",1);
184  sample_width = nist_get_param_int(header,"sample_n_bytes",2);
185  *sample_rate =
186  nist_get_param_int(header,"sample_rate",def_load_sample_rate);
187  byte_order = nist_get_param_str(header,"sample_byte_format",
188  (EST_BIG_ENDIAN ? "10" : "01"));
189  sample_coding = nist_get_param_str(header,"sample_coding","pcm");
190  if (streq(byte_order,"mu-law"))
191  {
192  byte_order = wstrdup((EST_BIG_ENDIAN ? "10" : "01"));
193  sample_coding = wstrdup("ULAW");
194  }
195 
196  /* code for reading in Tony Robinson's shorten files.
197  This is a temporary fix which calls the unshorten program on the
198  speech file and reads in the answer by calling this function.
199  It would be nice to have a simple library routine which did the
200  unshortening.
201  */
202 
203  if (streq(sample_coding,"pcm,embedded-shorten-v1.1"))
204  {
205  char *tmpfile, *cmdstr;
206  enum EST_read_status rval;
207 
208  tmpfile = cmake_tmp_filename();
209  cmdstr = walloc(char,strlen(tmpfile)+200);
210  sprintf(cmdstr,"cstrshorten %s %s",
211  (const char*)ts.filename(),tmpfile);
212  printf("Command: %s\n", cmdstr);
213  system(cmdstr);
214  EST_TokenStream tt;
215  tt.open(tmpfile);
216 
217  rval = load_wave_nist(tt, data, num_samples,
218  num_channels, word_size, sample_rate,
219  sample_type, bo, offset, length);
220  unlink(tmpfile);
221  wfree(tmpfile);
222  wfree(cmdstr);
223  tt.close();
224  return rval;
225  }
226 
227  if (length == 0)
228  data_length = (samps - offset)*(*num_channels);
229  else
230  data_length = length*(*num_channels);
231 
232  file_data = walloc(unsigned char,sample_width * data_length);
233 
234  ts.seek(current_pos+NIST_HDR_SIZE+(sample_width*offset*(*num_channels)));
235 
236  n = ts.fread(file_data,sample_width,data_length);
237 
238  if ((n < 1) && (n != data_length))
239  {
240  wfree(file_data);
241  wfree(sample_coding);
242  wfree(byte_order);
243  return misc_read_error;
244  }
245  else if ((n < data_length) && (data_length/(*num_channels) == n))
246  {
247  fprintf(stderr,"WAVE read: nist header is (probably) non-standard\n");
248  fprintf(stderr,"WAVE read: assuming different num_channel interpretation\n");
249  data_length = n; /* wrongly headered file */
250  }
251  else if (n < data_length)
252  {
253  fprintf(stderr,"WAVE read: short file %s\n",
254  (const char *)ts.filename());
255  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
256  offset,n,data_length);
257  data_length = n;
258  }
259 
260  actual_sample_type = nist_to_sample_type(sample_coding);
261  actual_bo = ((strcmp(byte_order,"10") == 0) ? bo_big : bo_little);
262 
263  *data = convert_raw_data(file_data,data_length,
264  actual_sample_type,actual_bo);
265 
266  *num_samples = data_length/ (*num_channels);
267  *sample_type = st_short;
268  *bo = EST_NATIVE_BO;
269  *word_size = 2;
270  wfree(sample_coding);
271  wfree(byte_order);
272 
273  return format_ok;
274 }
275 
276 enum EST_write_status save_wave_nist(FILE *fp, const short *data, int offset,
277  int num_samples, int num_channels,
278  int sample_rate,
279  enum EST_sample_type_t sample_type, int bo)
280 {
281  char h[1024], p[1024];
282  const char *t;
283 
284  memset(h,0,1024);
285 
286  strcat(h, NIST_SIG);
287  sprintf(p, "channel_count -i %d\n", num_channels);
288  strcat(h, p);
289  sprintf(p, "sample_count -i %d\n", num_samples);
290  strcat(h, p);
291  sprintf(p, "sample_rate -i %d\n", sample_rate);
292  strcat(h, p);
293 
294  t = sample_type_to_nist(sample_type);
295  if (t)
296  {
297  sprintf(p, "sample_coding -s%d %s\n", (signed)strlen(t), t);
298  strcat(h, p);
299  sprintf(p, "sample_n_bytes -i %d\n", get_word_size(sample_type));
300  strcat(h, p);
301  }
302 
303  if (get_word_size(sample_type) > 1)
304  {
305  sprintf(p, "sample_byte_format -s%d %s\n", 2,
306  ((bo == bo_big) ? "10" : "01"));
307  strcat(h, p);
308  }
309 
310  strcat(h, NIST_END_SIG);
311  /*makes it nice to read */
312  strcat(h, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
313 
314  if (fwrite(&h, 1024, 1, fp) != 1)
315  return misc_write_error;
316 
317  return save_raw_data(fp,data,offset,num_samples,num_channels,
318  sample_type,bo);
319 
320 }
321 
322 /*=======================================================================*/
323 /* EST's own format */
324 /*=======================================================================*/
325 
326 enum EST_read_status load_wave_est(EST_TokenStream &ts, short **data, int
327  *num_samples, int *num_channels, int
328  *word_size, int *sample_rate, enum
329  EST_sample_type_t *sample_type, int *bo,
330  int offset, int length)
331 {
332  int data_length, actual_bo;
333  short *file_data;
334  EST_String byte_order;
335  int n;
336  EST_EstFileType t;
337  EST_Option hinfo;
338  bool ascii;
339  EST_read_status r;
340  EST_sample_type_t actual_sample_type;
341 
342  offset = 0;
343 
344  if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
345  return r;
346  if (t != est_file_wave)
347  return misc_read_error;
348 
349  *num_samples = hinfo.ival("NumSamples");
350  *num_channels = hinfo.ival("NumChannels");
351  *sample_rate = hinfo.ival("SampleRate");
352 
353  byte_order = hinfo.val("ByteOrder");
354 
355  if (length == 0)
356  data_length = (*num_samples)*(*num_channels);
357  else
358  data_length = length*(*num_channels);
359 
360  file_data = walloc(short, data_length);
361 
362  n = ts.fread(file_data, sizeof(short), data_length);
363  if ((n != data_length) && (n < 1))
364  {
365  cerr << "EST wave load: " << ts.pos_description() << endl;
366  cerr << "failed to read file\n";
367  wfree(file_data);
368  return misc_read_error;
369  }
370  else if (n != data_length)
371  {
372  cerr << "Wrong number of samples/channels in EST wave file\n";
373  cerr << ts.pos_description() << " ";
374  cerr << "expected " << data_length << " got " << n << endl;
375  data_length = n;
376  }
377 
378  actual_bo = (byte_order == "10") ? bo_big : bo_little;
379  if (hinfo.present("SampleType"))
380  actual_sample_type = str_to_sample_type(hinfo.val("SampleType"));
381  else
382  actual_sample_type = st_short; // some older files don't have this
383 
384  *data = convert_raw_data((unsigned char *)file_data,
385  data_length, actual_sample_type, actual_bo);
386  // because internally data is always shorts
387  *sample_type = st_short;
388  *bo = EST_NATIVE_BO;
389  *word_size = 2;
390 
391  return format_ok;
392 }
393 
394 enum EST_write_status save_wave_est(FILE *fp, const short *data, int offset,
395  int num_samples, int num_channels,
396  int sample_rate,
397  enum EST_sample_type_t sample_type, int bo)
398 {
399  fprintf(fp, "EST_File wave\n");
400  fprintf(fp, "DataType binary\n");
401  fprintf(fp, "SampleRate %d\n", sample_rate);
402  fprintf(fp, "NumSamples %d\n", num_samples);
403  fprintf(fp, "NumChannels %d\n", num_channels);
404  fprintf(fp, "SampleType %s\n", sample_type_to_str(sample_type));
405  if (get_word_size(sample_type) > 1)
406  fprintf(fp, "ByteOrder %s\n", ((bo == bo_big) ? "10" : "01"));
407 
408  fprintf(fp, "EST_Header_End\n");
409 
410  return save_raw_data(fp, data, offset, num_samples, num_channels,
411  sample_type, bo);
412 
413 }
414 
415 /*=======================================================================*/
416 /* Microsoft RIFF (.wav) audio files */
417 /* */
418 /* The information on this format was gained by reading a document */
419 /* found on the net called "Multimedia Programming Interface and */
420 /* Data Specification v1.0" and by looking at Rick Richardson, */
421 /* Lance Norskog And Sundry Contributors code in SOX. All this code */
422 /* is rewritten from scratch though, but I couldn't do it without */
423 /* other's explanations. I would have used the SOX code directly but */
424 /* was not really in the right form so starting again was easier */
425 /*=======================================================================*/
426 #define WAVE_FORMAT_PCM 0x0001
427 #define WAVE_FORMAT_ADPCM 0x0002
428 #define WAVE_FORMAT_ALAW 0x0006
429 #define WAVE_FORMAT_MULAW 0x0007
430 
431 enum EST_read_status load_wave_riff(EST_TokenStream &ts, short **data, int
432  *num_samples, int *num_channels, int
433  *word_size, int *sample_rate, enum
434  EST_sample_type_t *sample_type, int *bo , int
435  offset, int length)
436 {
437  char info[4];
438  int samps,sample_width,data_length;
439  short shortdata;
440  int dsize,intdata;
441  unsigned char *file_data;
442  enum EST_sample_type_t actual_sample_type;
443 
444  if (ts.fread(info,sizeof(char),4) != 4)
445  return wrong_format; /* its almost definitely an error */
446  if (strncmp(info,"RIFF",4) != 0)
447  return wrong_format;
448 
449  /* We've got a riff file */
450  ts.fread(&dsize,4,1);
451  /* .wav files are always little endian */
452  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
453  if ((ts.fread(info,sizeof(char),4) != 4) ||
454  (strncmp(info,"WAVE",4) != 0))
455  {
456  fprintf(stderr, "RIFF file is not of type WAVE\n");
457  return misc_read_error; /* not a wave file */
458  }
459  if ((ts.fread(info,sizeof(char),4) != 4) ||
460  (strncmp(info,"fmt ",4) != 0))
461  return misc_read_error; /* something else wrong */
462 
463  ts.fread(&dsize,4,1);
464  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
465  ts.fread(&shortdata,2,1);
466  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
467 
468  switch (shortdata)
469  {
470  /* This is a non-proprietary format */
471  case WAVE_FORMAT_PCM:
472  actual_sample_type = st_short; break;
473  /* The follow are registered proprietary WAVE formats (?) */
474  case WAVE_FORMAT_MULAW:
475  actual_sample_type = st_mulaw; break;
476  case WAVE_FORMAT_ADPCM:
477  fprintf(stderr, "RIFF file: unsupported proprietary sample format ADPCM\n");
478  actual_sample_type = st_short;
479  break;
480  /* actual_sample_type = st_adpcm; break; */ /* yes but which adpcm ! */
481  case WAVE_FORMAT_ALAW:
482  default:
483  fprintf(stderr, "RIFF file: unknown sample format\n");
484  actual_sample_type = st_short;
485  /* return misc_read_error; */
486  }
487  ts.fread(&shortdata,2,1);
488  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
489  *num_channels = shortdata;
490  ts.fread(sample_rate,4,1);
491  if (EST_BIG_ENDIAN) *sample_rate = SWAPINT(*sample_rate);
492  ts.fread(&intdata,4,1); /* average bytes per second -- ignored */
493  if (EST_BIG_ENDIAN) intdata = SWAPINT(intdata);
494  ts.fread(&shortdata,2,1); /* block align ? */
495  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
496  ts.fread(&shortdata,2,1);
497  if (EST_BIG_ENDIAN) shortdata = SWAPSHORT(shortdata);
498 
499  sample_width = (shortdata+7)/8;
500  if ((sample_width == 1) && (actual_sample_type == st_short))
501  actual_sample_type = st_uchar; /* oops I meant 8 bit */
502 
503  ts.seek((dsize-16)+ts.tell()); /* skip rest of header */
504  while (1)
505  {
506  if (ts.fread(info,sizeof(char),4) != 4)
507  {
508  fprintf(stderr,"RIFF file truncated\n");
509  return misc_read_error; /* something else wrong */
510  }
511  if (strncmp(info,"data",4) == 0)
512  {
513  ts.fread(&samps,4,1);
514  if (EST_BIG_ENDIAN) samps = SWAPINT(samps);
515  samps /= (sample_width*(*num_channels));
516  break;
517  }
518  else if (strncmp(info,"fact",4) == 0)
519  { /* some other type of chunk -- skip it */
520  ts.fread(&samps,4,1);
521  if (EST_BIG_ENDIAN) samps = SWAPINT(samps);
522  ts.seek(samps+ts.tell()); /* skip rest of header */
523  /* Hope this is the right amount */
524  }
525  else
526  {
527  // fprintf(stderr,"Ignoring unsupported chunk type \"%c%c%c%c\" in RIFF file\n",
528  // info[0],info[1],info[2],info[3]);
529  //return misc_read_error;
530  ts.fread(&dsize,4,1);
531  if (EST_BIG_ENDIAN) dsize = SWAPINT(dsize);
532  ts.seek(dsize+ts.tell()); /* skip this chunk */
533  }
534  }
535  if (length == 0)
536  data_length = (samps - offset)*(*num_channels);
537  else
538  data_length = length*(*num_channels);
539 
540  file_data = walloc(unsigned char,sample_width * data_length);
541 
542  ts.seek((sample_width*offset*(*num_channels))+ts.tell());
543  if ((dsize=ts.fread(file_data,sample_width,data_length)) != data_length)
544  {
545  /* It seems so many WAV files have their datasize wrong I'll */
546  /* let it through -- I think SOX is a major culprit */
547  if (length == 0) /* the file did the identification */
548  fprintf(stderr,"Unexpected end of file but continuing (apparently missing %d samples)\n",data_length-dsize);
549  else
550  {
551  fprintf(stderr,"Unexpected end of file: (missing %d samples)\n",data_length-dsize);
552  wfree(file_data);
553  return misc_read_error;
554  }
555  }
556 
557  *data = convert_raw_data(file_data,dsize,
558  actual_sample_type, bo_little);
559 
560  *num_samples = dsize / (*num_channels);
561  *sample_type = st_short;
562  *bo = EST_NATIVE_BO;
563  *word_size = 2;
564 
565  return format_ok;
566 }
567 
568 enum EST_write_status save_wave_riff(FILE *fp, const short *data, int offset,
569  int num_samples, int num_channels,
570  int sample_rate,
571  enum EST_sample_type_t sample_type, int bo)
572 {
573  (void)bo;
574  const char *info;
575  int data_size, data_int;
576  short data_short;
577 
578  if (sample_type == st_schar)
579  {
580  EST_warning("RIFF format: Signed 8-bit not allowed by this file format");
581  sample_type=st_uchar;
582  }
583 
584  info = "RIFF"; fwrite(info,4,1,fp);
585  data_size = num_channels*num_samples*get_word_size(sample_type)+ 8+16+12;
586  /* WAV files are always LITTLE_ENDIAN (i.e. intel x86 format) */
587  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
588  fwrite(&data_size,1,4,fp); /* total number of bytes in file */
589  info = "WAVE"; fwrite(info,4,1,fp);
590  info = "fmt "; fwrite(info,4,1,fp);
591  data_size = 16;
592  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
593  fwrite(&data_size,1,4,fp); /* size of header */
594  switch (sample_type)
595  {
596  case st_short: data_short = WAVE_FORMAT_PCM; break;
597  case st_uchar: data_short = WAVE_FORMAT_PCM; break;
598  case st_mulaw: data_short = WAVE_FORMAT_MULAW; break;
599  case st_alaw: data_short = WAVE_FORMAT_ALAW; break;
600  case st_adpcm: data_short = WAVE_FORMAT_ADPCM; break;
601  default:
602  fprintf(stderr,"RIFF format: unsupported data format %d\n",
603  sample_type);
604  return misc_write_error;
605  }
606  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
607  fwrite(&data_short,1,2,fp); /* sample type */
608  data_short = num_channels;
609  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
610  fwrite(&data_short,1,2,fp); /* number of channels */
611  data_int = sample_rate;
612  if (EST_BIG_ENDIAN) data_int = SWAPINT(data_int);
613  fwrite(&data_int,1,4,fp); /* sample rate */
614  data_int = sample_rate * num_channels * get_word_size(sample_type);
615  if (EST_BIG_ENDIAN) data_int = SWAPINT(data_int);
616  fwrite(&data_int,1,4,fp); /* Average bytes per second */
617  data_short = num_channels * get_word_size(sample_type);
618  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
619  fwrite(&data_short,1,2,fp); /* block align */
620  data_short = get_word_size(sample_type) * 8;
621  if (EST_BIG_ENDIAN) data_short = SWAPSHORT(data_short);
622  fwrite(&data_short,1,2,fp); /* bits per sample */
623  info = "data"; fwrite(info,4,1,fp);
624  data_size = num_channels*num_samples*get_word_size(sample_type);
625  if (EST_BIG_ENDIAN) data_size = SWAPINT(data_size);
626  fwrite(&data_size,1,4,fp); /* total number of bytes in data */
627 
628  return save_raw_data(fp,data,offset,num_samples,num_channels,
629  sample_type,bo_little);
630 }
631 
632 /*=======================================================================*/
633 /* Amiga/Apple AIFF waveform format */
634 /* This was constructed using info in AudioIFF1.3.hqx found on the web */
635 /* and also I did look at SOX's aiff.c written by Guido van Rossum */
636 /* and Sundry Contributors. */
637 /*=======================================================================*/
638 
639 struct AIFFchunk {
640  char id[4];
641  int size;
642 };
643 
644 struct AIFFssnd { /* Sound Data Chunk */
645  int offset;
646  int blocksize;
647 };
648 
649 enum EST_read_status load_wave_aiff(EST_TokenStream &ts, short **data, int
650  *num_samples, int *num_channels, int
651  *word_size, int *sample_rate, enum
652  EST_sample_type_t *sample_type, int *bo , int
653  offset, int length)
654 {
655  char info[4];
656  struct AIFFchunk chunk;
657  short comm_channels;
658  int comm_samples;
659  short comm_bits;
660  unsigned char ieee_ext_sample_rate[10];
661  struct AIFFssnd ssndchunk;
662  enum EST_sample_type_t actual_sample_type;
663  int dsize,data_length,n;
664  unsigned char *file_data;
665 
666  if (ts.fread(info,sizeof(char),4) != 4)
667  return wrong_format; /* but its almost definitely an error */
668  if (strncmp(info,"FORM",4) != 0)
669  return wrong_format;
670 
671  /* We've got an aiff file, I hope */
672  ts.fread(&dsize,4,1);
673  if (EST_LITTLE_ENDIAN) /* file is in different byte order */
674  dsize = SWAPINT(dsize);
675  if ((ts.fread(info,sizeof(char),4) != 4) ||
676  (strncmp(info,"AIFF",4) != 0))
677  {
678  fprintf(stderr, "AIFF file does not have AIFF chunk\n");
679  return misc_read_error;
680  }
681 
682  for ( ; ts.fread(&chunk,1,sizeof(chunk)) == sizeof(chunk) ; )
683  { /* for each chunk in the file */
684  if (EST_LITTLE_ENDIAN) /* file is in different byte order */
685  chunk.size = SWAPINT(chunk.size);
686  if (strncmp(chunk.id,"COMM",4) == 0)
687  {
688  if (chunk.size != 18)
689  {
690  fprintf(stderr,"AIFF chunk: bad size\n");
691  return misc_read_error;
692  }
693  ts.fread(&comm_channels,1,sizeof(short));
694  ts.fread(&comm_samples,1,sizeof(int));
695  ts.fread(&comm_bits,1,sizeof(short));
696  if (ts.fread(ieee_ext_sample_rate,1,10) != 10)
697  {
698  fprintf(stderr,"AIFF chunk: eof within COMM chunk\n");
699  return misc_read_error;
700  }
701  if (EST_LITTLE_ENDIAN)
702  {
703  comm_channels = SWAPSHORT(comm_channels);
704  comm_samples = SWAPINT(comm_samples);
705  comm_bits = SWAPSHORT(comm_bits);
706  }
707  *sample_rate = (int)ConvertFromIeeeExtended(ieee_ext_sample_rate);
708  }
709  else if (strncmp(chunk.id,"SSND",4) == 0)
710  {
711  if (ts.fread(&ssndchunk,1,sizeof(ssndchunk)) != sizeof(ssndchunk))
712  {
713  fprintf(stderr,"AIFF chunk: eof within SSND chunk\n");
714  return misc_read_error;
715  }
716  if (EST_LITTLE_ENDIAN)
717  {
718  ssndchunk.offset = SWAPINT(ssndchunk.offset);
719  ssndchunk.blocksize = SWAPINT(ssndchunk.blocksize);
720  }
721 
722  *num_channels = comm_channels;
723  switch (comm_bits)
724  {
725  case 8: actual_sample_type = st_uchar; break;
726  case 16: actual_sample_type = st_short; break;
727  default:
728  fprintf(stderr,"AIFF: unsupported sample width %d bits\n",
729  comm_bits);
730  return misc_read_error;
731  }
732 
733  ts.seek(ssndchunk.offset+(comm_channels*offset)+ts.tell());
734  if (length == 0)
735  data_length = (comm_samples-offset)*comm_channels;
736  else
737  data_length = length*comm_channels;
738  file_data = walloc(unsigned char,
739  data_length*comm_channels*
740  get_word_size(actual_sample_type));
741  if ((n=ts.fread(file_data,get_word_size(actual_sample_type),
742  data_length)) != data_length)
743  {
744  fprintf(stderr,"AIFF read: short file %s\n",
745  (const char *)ts.filename());
746  fprintf(stderr,"AIFF read: at %d got %d instead of %d samples\n",
747  offset,n,data_length);
748  data_length = n;
749  }
750 
751  *data = convert_raw_data(file_data,data_length,
752  actual_sample_type,bo_big);
753  *num_samples = data_length/comm_channels;
754  *sample_type = st_short;
755  *word_size = 2;
756  *bo = EST_NATIVE_BO;
757  break; /* only care about the first SSND chunk */
758  }
759  else
760  { /* skip bytes in chunk */
761  ts.seek(ts.tell()+chunk.size);
762  }
763  }
764 
765  return format_ok;
766 }
767 
768 enum EST_write_status save_wave_aiff(FILE *fp, const short *data, int offset,
769  int num_samples, int num_channels,
770  int sample_rate,
771  enum EST_sample_type_t sample_type, int bo)
772 {
773  (void)bo;
774  const char *info;
775  int data_size, data_int;
776  unsigned char ieee_ext_buf[10];
777  short data_short;
778 
779  info = "FORM";
780  fwrite(info,1,4,fp);
781  /* This number seems to be derived different for each example */
782  data_size = 54+(num_samples*num_channels*get_word_size(sample_type));
783  if (EST_LITTLE_ENDIAN)
784  data_size = SWAPINT(data_size);
785  fwrite(&data_size,1,4,fp);
786  info = "AIFF";
787  fwrite(info,1,4,fp);
788  info = "COMM";
789  fwrite(info,1,4,fp);
790  data_int = 18;
791  if (EST_LITTLE_ENDIAN)
792  data_int = SWAPINT(data_int);
793  fwrite(&data_int,1,4,fp);
794  data_short = num_channels;
795  if (EST_LITTLE_ENDIAN)
796  data_short = SWAPSHORT(data_short);
797  fwrite(&data_short,1,2,fp);
798  data_int = num_samples;
799  if (EST_LITTLE_ENDIAN)
800  data_int = SWAPINT(data_int);
801  fwrite(&data_int,1,4,fp);
802  data_short = 8*get_word_size(sample_type);
803  if (EST_LITTLE_ENDIAN)
804  data_short = SWAPSHORT(data_short);
805  fwrite(&data_short,1,2,fp);
806  ConvertToIeeeExtended((double)sample_rate,ieee_ext_buf);
807  fwrite(ieee_ext_buf,1,10,fp);
808  info = "SSND";
809  fwrite(info,1,4,fp);
810  data_int = 8 + (num_samples*num_channels*get_word_size(sample_type));
811  if (EST_LITTLE_ENDIAN)
812  data_int = SWAPINT(data_int);
813  fwrite(&data_int,1,4,fp);
814  data_int = 0;
815  if (EST_LITTLE_ENDIAN)
816  data_int = SWAPINT(data_int);
817  fwrite(&data_int,1,4,fp); /* offset */
818  if (EST_LITTLE_ENDIAN)
819  data_int = SWAPINT(data_int);
820  fwrite(&data_int,1,4,fp); /* blocksize */
821 
822  if ((sample_type == st_short) ||
823  (sample_type == st_uchar))
824  return save_raw_data(fp,data,offset,num_samples,num_channels,
825  sample_type,bo_big);
826  else
827  {
828  fprintf(stderr,"AIFF: requested data type not uchar or short\n");
829  return misc_write_error;
830  }
831 
832 }
833 
834 /*=======================================================================*/
835 /* ulaw EST_filetype are just raw data with 8K ulaw contents */
836 /*=======================================================================*/
837 
838 enum EST_read_status load_wave_ulaw(EST_TokenStream &ts, short **data, int
839  *num_samples, int *num_channels, int *word_size, int
840  *sample_rate, enum EST_sample_type_t *sample_type, int *bo,
841  int offset, int length)
842 
843 {
844  unsigned char *ulaw;
845  int data_length,samps;
846 
847  ts.seek_end();
848  samps = ts.tell();
849 
850  if (length == 0)
851  data_length = samps - offset;
852  else
853  data_length = length;
854 
855  ulaw = walloc(unsigned char, data_length);
856  ts.seek(offset);
857  if (ts.fread(ulaw,1,data_length) != data_length)
858  {
859  wfree(ulaw);
860  return misc_read_error;
861  }
862 
863  *data = walloc(short,data_length);
864  ulaw_to_short(ulaw,*data,data_length);
865  wfree(ulaw);
866 
867  *num_samples = data_length;
868  *sample_rate = 8000;
869  *num_channels = 1;
870  *sample_type = st_short;
871  *word_size = 2;
872  *bo = EST_NATIVE_BO;
873 
874  return format_ok;
875 }
876 
877 enum EST_write_status save_wave_ulaw(FILE *fp, const short *data, int offset,
878  int num_samples, int num_channels,
879  int sample_rate,
880  enum EST_sample_type_t sample_type, int bo)
881 {
882  (void)sample_rate;
883  (void)sample_type;
884  return save_wave_raw(fp,data,offset,num_samples,num_channels,
885  8000,st_mulaw,bo);
886 
887 
888 }
889 
890 /*=======================================================================*/
891 /* Sun and Next snd files */
892 /*=======================================================================*/
893 
894 typedef struct {
895  unsigned int magic; /* magic number */
896  unsigned int hdr_size; /* size of this header */
897  int data_size; /* length of data (optional) */
898  unsigned int encoding; /* data encoding format */
899  unsigned int sample_rate; /* samples per second */
900  unsigned int channels; /* number of interleaved channels */
901 } Sun_au_header;
902 
903 enum EST_read_status load_wave_snd(EST_TokenStream &ts, short **data, int
904  *num_samples, int *num_channels, int *word_size, int
905  *sample_rate,enum EST_sample_type_t *sample_type, int *bo ,
906  int offset, int length)
907 {
908  /* Header structures */
909  Sun_au_header header;
910  enum EST_sample_type_t encoding_type;
911  int data_length, sample_width, bytes, samps, n;
912  unsigned char *file_data;
913  int current_pos;
914 
915  current_pos = ts.tell();
916  ts.fread(&header, sizeof(Sun_au_header), 1);
917 
918  /* test for magic number */
919  if ((EST_LITTLE_ENDIAN) &&
920  ((unsigned int)0x2e736e64 == SWAPINT(header.magic)))
921  { /* wrong byte order, swap header */
922  header.hdr_size = SWAPINT(header.hdr_size);
923  header.data_size = SWAPINT(header.data_size);
924  header.encoding = SWAPINT(header.encoding);
925  header.sample_rate = SWAPINT(header.sample_rate);
926  header.channels = SWAPINT(header.channels);
927  }
928  else if ((unsigned int)0x2e736e64 != header.magic)
929  return wrong_format;
930 
931  switch (header.encoding)
932  {
933  case 1:
934  encoding_type = st_mulaw;
935  break;
936  case 2:
937  encoding_type = st_uchar;
938  break;
939  case 3:
940  encoding_type = st_short;
941  break;
942  default:
943  fprintf(stderr, "Unsupported data type in SND header\n");
944  return misc_read_error;
945  }
946 
947  *num_channels = header.channels;
948  sample_width = get_word_size(encoding_type);
949  *sample_rate = header.sample_rate;
950 
951  if ((header.data_size == 0) ||
952  (header.data_size == -1))
953  {
954  ts.seek_end();
955  bytes = ts.tell() - header.hdr_size;
956  }
957  else
958  bytes = header.data_size;
959  samps = bytes/sample_width;
960 
961  if (length == 0)
962  data_length = (samps - offset)*(*num_channels);
963  else
964  data_length = length *(*num_channels);
965 
966  file_data = walloc(unsigned char, sample_width * data_length);
967  ts.seek(current_pos+header.hdr_size+(sample_width*offset*(*num_channels)));
968  if ((n=ts.fread(file_data,sample_width,data_length)) != data_length)
969  {
970  fprintf(stderr,"WAVE read: short file %s\n",
971  (const char *)ts.filename());
972  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
973  offset,n,data_length);
974  data_length = n;
975  }
976 
977  *data = convert_raw_data(file_data,data_length,encoding_type,bo_big);
978 
979  if (*data == NULL)
980  return read_error;
981 
982  *num_samples = data_length/ (*num_channels);
983  *sample_type = st_short;
984  *bo = EST_NATIVE_BO;
985  *word_size = 2;
986  return read_ok;
987 }
988 
989 enum EST_write_status save_wave_snd(FILE *fp, const short *data, int offset,
990  int num_samples, int num_channels,
991  int sample_rate,
992  enum EST_sample_type_t sample_type, int bo)
993 {
994  (void)bo;
995  /* Header structures */
996  Sun_au_header header;
997 
998  /* Fill in header structure */
999  header.magic = (unsigned int)0x2e736e64; /* should be a macro surely */
1000  header.hdr_size = sizeof(header); /* ! */
1001  header.data_size = get_word_size(sample_type) * num_channels * num_samples;
1002 
1003  switch (sample_type) {
1004  case st_mulaw:
1005  header.encoding = 1;
1006  break;
1007  case st_uchar:
1008  header.encoding = 2;
1009  break;
1010  case st_short:
1011  header.encoding = 3;
1012  break;
1013 
1014  default:
1015  fprintf(stderr,
1016  "Unsupported sample type cannot be saved in SND format\n");
1017  return misc_write_error;
1018 
1019  }
1020 
1021  /* check consistency */
1022 
1023  header.sample_rate = sample_rate;
1024 
1025  header.channels = num_channels;
1026 
1027  if (EST_LITTLE_ENDIAN)
1028  {
1029  /* snd files all in big endian format */
1030  header.magic = SWAPINT(header.magic);
1031  header.hdr_size = SWAPINT(header.hdr_size);
1032  header.data_size = SWAPINT(header.data_size);
1033  header.encoding = SWAPINT(header.encoding);
1034  header.sample_rate = SWAPINT(header.sample_rate);
1035  header.channels = SWAPINT(header.channels);
1036 
1037  }
1038  /* write header */
1039  if (fwrite(&header, sizeof(header), 1, fp) != 1)
1040  return misc_write_error;
1041 
1042  /* snd files are always in BIG_ENDIAN (sun) byte order */
1043  return save_raw_data(fp,data,offset,num_samples,num_channels,
1044  sample_type,bo_big);
1045 }
1046 
1047 /*=======================================================================*/
1048 /* CSTR Audlab files (from the last century) */
1049 /* They are always bigendian */
1050 /*=======================================================================*/
1051 struct s1 {
1052  char c[17];
1053  float f1;
1054  float f2;
1055 };
1056 
1057 struct s2 {
1058  float f1;
1059  float f2;
1060  float f3;
1061  char c1;
1062  char c2;
1063  int i1;
1064  int i2;
1065 };
1066 
1067 struct audlabfh {
1068  struct s1 z;
1069  char file_type[8];
1070  char c1[17];
1071  char c2[17];
1072  char c3[17];
1073  int start;
1074  char data_type;
1075  char c5[64];
1076 };
1077 
1078 struct audlabsh {
1079  int channel_count;
1080  char serial;
1081  int sample_rate;
1082  char c1[20];
1083  int i1;
1084  char c2;
1085  char c3[121];
1086  char c4[121];
1087 
1088 };
1089 struct audlabsd {
1090  char descr[17];
1091  int sample_count;
1092  int nbits;
1093  float f1;
1094  struct s2 z;
1095 };
1096 
1097 enum EST_read_status load_wave_audlab(EST_TokenStream &ts, short **data, int
1098  *num_samples, int *num_channels, int *word_size, int
1099  *sample_rate, enum EST_sample_type_t *sample_type, int *bo, int
1100  offset, int length)
1101 {
1102  /* Header structures */
1103  struct audlabfh fh;
1104  struct audlabsh sh;
1105  struct audlabsd sd;
1106  int data_length,sample_count;
1107  int hdr_length;
1108  int current_pos;
1109 
1110  /* Read header structures from char array */
1111  current_pos = ts.tell();
1112  ts.fread(&fh, sizeof(struct audlabfh), 1);
1113  if (strcmp(fh.file_type, "Sample") != 0)
1114  return wrong_format;
1115 
1116  ts.fread(&sh, sizeof(struct audlabsh), 1);
1117  ts.fread(&sd, sizeof(struct audlabsd), 1);
1118  hdr_length = sizeof(struct audlabfh) +
1119  sizeof(struct audlabsh) +
1120  sizeof(struct audlabsd);
1121 
1122  if (EST_BIG_ENDIAN)
1123  {
1124  *num_channels = sh.channel_count;
1125  *sample_rate = sh.sample_rate;
1126  sample_count = sd.sample_count;
1127  }
1128  else // audlab files are bigendian
1129  {
1130  *num_channels = SWAPINT(sh.channel_count);
1131  *sample_rate = SWAPINT(sh.sample_rate);
1132  sample_count = SWAPINT(sd.sample_count);
1133  }
1134  if (length == 0)
1135  data_length = (sample_count - offset) * (*num_channels);
1136  else
1137  data_length = length *(*num_channels);
1138 
1139  *data = walloc(short,sizeof(short) * data_length);
1140  ts.seek(current_pos+hdr_length+(sizeof(short)*offset*(*num_channels)));
1141 
1142  if ((int)ts.fread(*data, sizeof(short), data_length) != data_length)
1143  {
1144  wfree(*data);
1145  return misc_read_error;
1146  }
1147  if (EST_LITTLE_ENDIAN)
1148  swap_bytes_short(*data,data_length);
1149 
1150  *num_samples = data_length / (*num_channels);
1151  *sample_type = st_short; /* set internal type*/
1152  *word_size = sizeof(short);
1153  *bo = EST_NATIVE_BO;
1154 
1155  return format_ok;
1156 }
1157 
1158 enum EST_write_status save_wave_audlab(FILE *fp, const short *data, int offset,
1159  int num_samples, int num_channels,
1160  int sample_rate,
1161  enum EST_sample_type_t sample_type, int bo)
1162 {
1163  (void)bo;
1164  (void)sample_type;
1165  /* Header structures */
1166  struct audlabfh fh;
1167  struct audlabsh sh;
1168  struct audlabsd sd;
1169 
1170  fh.start = sizeof (struct audlabfh) +
1171  sizeof (struct audlabsh) + sizeof (struct audlabsd);
1172  fh.data_type = 2;
1173  strcpy(fh.file_type, "Sample");
1174 
1175  if (EST_LITTLE_ENDIAN)
1176  { // need to swap some of those numbers
1177  sh.channel_count = SWAPINT(num_channels);
1178  sh.serial = 1;
1179  sh.sample_rate = SWAPINT(sample_rate);
1180 
1181  sd.sample_count = SWAPINT(num_samples);
1182  sd.nbits = SWAPINT(16);
1183  }
1184  else
1185  {
1186  sh.channel_count = num_channels;
1187  sh.serial = 1;
1188  sh.sample_rate = sample_rate;
1189 
1190  sd.sample_count = num_samples;
1191  sd.nbits = 16;
1192  }
1193  sprintf(sd.descr, "Filter 1");
1194 
1195  /* write headers */
1196  fwrite (&fh, sizeof(fh), 1, fp);
1197  fwrite (&sh, sizeof(sh), 1, fp);
1198  fwrite (&sd, sizeof(sd), 1, fp);
1199 
1200  /* write data*/
1201  return save_raw_data(fp,data,offset,num_samples,num_channels,
1202  st_short,bo_big);
1203 }
1204 
1205 /*=======================================================================*/
1206 /* Entropic ESPS SD files: portable (non-proprietary) method */
1207 /*=======================================================================*/
1208 
1209 /* Deep thanks go to Peter Kabal from McGill University whose AF code */
1210 /* showed me this was even possible. I looked at his code to find */
1211 /* parts I couldn't work out myself. Also to Rodney Johnson of */
1212 /* Entropic whose document "ESPS APPLICATION NOTE: Non-ESPS Programs */
1213 /* and the ESPS File System" gave details of how to access ESPS files */
1214 /* without using the ESPS library code. */
1215 
1216 #include "esps_utils.h"
1217 enum EST_read_status load_wave_sd(EST_TokenStream &ts, short **data, int
1218  *num_samples, int *num_channels, int
1219  *word_size, int *sample_rate, enum
1220  EST_sample_type_t *sample_type, int *bo , int
1221  offset, int length)
1222 {
1223  /* A license free version of an esps file reading program */
1224  FILE *fd;
1225  esps_hdr hdr;
1226  int actual_bo, sample_width, data_length;
1227  enum EST_read_status rv;
1228  int dl;
1229  enum EST_sample_type_t actual_sample_type;
1230  double d;
1231  unsigned char *file_data;
1232 
1233  if ((fd = ts.filedescriptor()) == NULL)
1234  {
1235  fprintf(stderr, "Can't open esps file %s for reading\n",
1236  (const char *)ts.filename());
1237  return misc_read_error;
1238  }
1239 
1240  if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
1241  return rv;
1242 
1243  if (hdr->file_type != ESPS_SD)
1244  {
1245  fprintf(stderr,"ESPS file: not an FEA_SD file\n");
1246  delete_esps_hdr(hdr);
1247  return misc_read_error;
1248  }
1249 
1250  if (fea_value_d("record_freq",0,hdr,&d) != 0)
1251  {
1252  fprintf(stderr,"ESPS file: can't find sample_rate in header assuming 16000\n");
1253  *sample_rate = 16000;
1254  }
1255  else
1256  *sample_rate = (int)d;
1257  actual_sample_type = st_short; /* you're not trying hard enough */
1258  sample_width = get_word_size(actual_sample_type);
1259  *num_channels = hdr->field_dimension[0];
1260  if (hdr->swapped)
1261  actual_bo = (EST_BIG_ENDIAN ? bo_little : bo_big);
1262  else
1263  actual_bo = (EST_BIG_ENDIAN ? bo_big : bo_little);
1264 
1265  if (length == 0)
1266  data_length = (hdr->num_records - offset)*(*num_channels);
1267  else
1268  data_length = length *(*num_channels);
1269 
1270  file_data = walloc(unsigned char, sample_width * data_length);
1271  fseek(fd,hdr->hdr_size+(sample_width*offset*(*num_channels)),
1272  SEEK_SET);
1273  if ((dl=fread(file_data,sample_width,data_length,fd)) != data_length)
1274  {
1275  fprintf(stderr,"WAVE read: esps short file %s\n",
1276  (const char *)ts.filename());
1277  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
1278  offset,dl,data_length);
1279  data_length = dl;
1280  }
1281 
1282  *data = convert_raw_data(file_data,data_length,
1283  actual_sample_type,
1284  actual_bo);
1285 
1286  *num_samples = data_length/ (*num_channels);
1287  *sample_type = st_short;
1288  *bo = EST_NATIVE_BO;
1289  *word_size = 2;
1290  delete_esps_hdr(hdr);
1291  return format_ok;
1292 
1293 }
1294 
1295 enum EST_write_status save_wave_sd(FILE *fp, const short *data, int offset,
1296  int num_samples, int num_channels,
1297  int sample_rate,
1298  enum EST_sample_type_t sample_type, int bo)
1299 
1300 {
1301  (void)bo;
1302  esps_hdr hdr = make_esps_sd_hdr();
1303  enum EST_write_status rv;
1304  short esps_type;
1305 
1306  hdr->num_records = num_samples;
1307  switch (sample_type)
1308  {
1309  case st_short: esps_type = ESPS_SHORT; break;
1310  case st_schar: esps_type = ESPS_CHAR; break; /* maybe should be BYTE */
1311  case st_int: esps_type = ESPS_INT; break;
1312  case st_float: esps_type = ESPS_FLOAT; break;
1313  case st_double: esps_type = ESPS_DOUBLE; break;
1314  default:
1315  fprintf(stderr,"ESPS file: no support for sample_type %s\n",
1316  sample_type_to_str(sample_type));
1317  return misc_write_error;
1318  }
1319  /* I believe all of the following are necessary and in this order */
1320  add_field(hdr,"samples",esps_type,num_channels);
1321  add_fea_special(hdr,ESPS_FEA_DIRECTORY,"margo:/disk/disk10/home/awb/projects/speech_tools/main");
1322  add_fea_special(hdr,ESPS_FEA_COMMAND,
1323  "EDST waveform written as ESPS FEA_SD.\n\
1324  ");
1325  add_fea_d(hdr,"start_time",0,(double)0);
1326  add_fea_d(hdr,"record_freq",0,(double)sample_rate);
1327  add_fea_d(hdr,"max_value",0,(double)27355);
1328 
1329  if ((rv=write_esps_hdr(hdr,fp)) != write_ok)
1330  {
1331  delete_esps_hdr(hdr);
1332  return rv;
1333  }
1334  /* lets ignore desired bo and sample type for the time being */
1335  delete_esps_hdr(hdr);
1336 
1337  return save_raw_data(fp,data,offset,num_samples,num_channels,
1338  sample_type,EST_NATIVE_BO);
1339 }
1340 
1341 /*=======================================================================*/
1342 /* Raw data files -- unheadered */
1343 /* THESE FUNCTIONS ARE DIFFERENT FROM THE REST */
1344 /* These function have more parameters than the standard file i/o */
1345 /* as information cannot be gleamed from the file */
1346 /*=======================================================================*/
1347 
1348 enum EST_read_status load_wave_raw(EST_TokenStream &ts, short **data, int
1349  *num_samples, int *num_channels,
1350  int *word_size, int
1351  *sample_rate,
1352  enum EST_sample_type_t *sample_type,
1353  int *bo, int offset, int length,
1354  int isample_rate,
1355  enum EST_sample_type_t isample_type,
1356  int ibo, int inc)
1357 {
1358  unsigned char *file_data;
1359  int data_length,samps,sample_width;
1360  int guess,i,samp;
1361  short *ndata;
1362 
1363  if (isample_type == st_ascii)
1364  {
1365  /* Guess the size */
1366  if ((offset != 0) || (length != 0))
1367  {
1368  fprintf(stderr,"Load ascii wave: doesn't support offets and lengths\n");
1369  return misc_read_error;
1370  }
1371 
1372  ts.seek_end();
1373  guess = (int)(1.2*ts.tell()/7)+10; /* rough guess of the num of samps */
1374  ts.seek(0);
1375  *data = walloc(short, guess);
1376  i=0;
1377  while (!ts.eof())
1378  {
1379  samp = atoi(ts.get().string());
1380  if (i == guess)
1381  {
1382  ndata = walloc(short,(int)(guess*1.2));
1383  memmove(ndata,*data,guess*sizeof(short));
1384  wfree(*data);
1385  *data = ndata;
1386  guess = (int)(guess*1.2);
1387  }
1388  if (samp < -32768)
1389  {
1390  fprintf(stderr,"Load ascii wave: sample %d underflow clipping\n",
1391  i);
1392  (*data)[i] = -32768;
1393  }
1394  else if (samp > 32767)
1395  {
1396  fprintf(stderr,"Load ascii wave: sample %d overflow clipping\n",
1397  i);
1398  (*data)[i] = 32767;
1399  }
1400  else
1401  (*data)[i] = (short)samp;
1402  i++;
1403  }
1404  data_length = i;
1405  }
1406  else
1407  {
1408  ts.seek_end();
1409  sample_width = get_word_size(isample_type);
1410  samps = ts.tell()/sample_width;
1411 
1412  if (length == 0)
1413  data_length = samps - offset;
1414  else
1415  data_length = length;
1416 
1417  file_data = walloc(unsigned char, data_length * sample_width *inc);
1418  ts.seek(offset*sample_width*inc);
1419  if ((int)ts.fread(file_data,sample_width,data_length) != data_length)
1420  return misc_read_error;
1421 
1422  *data = convert_raw_data(file_data,data_length,isample_type,ibo);
1423  }
1424 
1425  *num_samples = data_length/inc;
1426  *sample_rate = isample_rate;
1427  *num_channels = inc;
1428  *sample_type = st_short;
1429  *word_size = 2;
1430  *bo = EST_NATIVE_BO;
1431 
1432  return format_ok;
1433 }
1434 
1435 enum EST_write_status save_wave_raw(FILE *fp, const short *data,
1436  int offset,
1437  int num_samples, int num_channels,
1438  int sample_rate,
1439  enum EST_sample_type_t sample_type, int bo)
1440 {
1441  (void)sample_rate;
1442 
1443  return save_raw_data(fp,data,offset,num_samples,num_channels,
1444  sample_type,bo);
1445 }
1446 
1447 /***********************************************************************/
1448 /* */
1449 /* end of file type specific functions */
1450 /* */
1451 /***********************************************************************/
1452