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