Edinburgh Speech Tools  2.1-release
EST_wave_utils.cc
Go to the documentation of this file.
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 /* Various low-level waveform conversion routines and file format */
37 /* independent i/o functions */
38 /* */
39 /* Acknowledgements */
40 /* ulaw conversion code provided by */
41 /* Craig Reese: IDA/Supercomputing Research Center */
42 /* IEEE extended conversion */
43 /* Apple Computer, Inc. */
44 /* */
45 /*=======================================================================*/
46 #include <cstdio>
47 #include <cstdlib>
48 #include "EST_unix.h"
49 #include <cstring>
50 #include <cmath>
51 #include "EST_wave_utils.h"
52 #include "EST_wave_aux.h"
53 #include "EST_error.h"
54 
55 static short st_ulaw_to_short(unsigned char ulawbyte);
56 static unsigned char st_short_to_ulaw(short sample);
57 static unsigned char st_short_to_alaw(short sample);
58 
59 /*
60  * This table is
61  * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
62  * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
63  * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
64  * take from speak_freely-7.2/gsm/src/toast_alaw.c
65  */
66 static unsigned short a2s[] = {
67  5120,60160, 320,65200,20480,44032, 1280,64192,
68  2560,62848, 64,65456,10240,54784, 640,64864,
69  7168,58112, 448,65072,28672,35840, 1792,63680,
70  3584,61824, 192,65328,14336,50688, 896,64608,
71  4096,61184, 256,65264,16384,48128, 1024,64448,
72  2048,63360, 0,65520, 8192,56832, 512,64992,
73  6144,59136, 384,65136,24576,39936, 1536,63936,
74  3072,62336, 128,65392,12288,52736, 768,64736,
75  5632,59648, 352,65168,22528,41984, 1408,64064,
76  2816,62592, 96,65424,11264,53760, 704,64800,
77  7680,57600, 480,65040,30720,33792, 1920,63552,
78  3840,61568, 224,65296,15360,49664, 960,64544,
79  4608,60672, 288,65232,18432,46080, 1152,64320,
80  2304,63104, 32,65488, 9216,55808, 576,64928,
81  6656,58624, 416,65104,26624,37888, 1664,63808,
82  3328,62080, 160,65360,13312,51712, 832,64672,
83  5376,59904, 336,65184,21504,43008, 1344,64128,
84  2688,62720, 80,65440,10752,54272, 672,64832,
85  7424,57856, 464,65056,29696,34816, 1856,63616,
86  3712,61696, 208,65312,14848,50176, 928,64576,
87  4352,60928, 272,65248,17408,47104, 1088,64384,
88  2176,63232, 16,65504, 8704,56320, 544,64960,
89  6400,58880, 400,65120,25600,38912, 1600,63872,
90  3200,62208, 144,65376,12800,52224, 800,64704,
91  5888,59392, 368,65152,23552,40960, 1472,64000,
92  2944,62464, 112,65408,11776,53248, 736,64768,
93  7936,57344, 496,65024,31744,32768, 1984,63488,
94  3968,61440, 240,65280,15872,49152, 992,64512,
95  4864,60416, 304,65216,19456,45056, 1216,64256,
96  2432,62976, 48,65472, 9728,55296, 608,64896,
97  6912,58368, 432,65088,27648,36864, 1728,63744,
98  3456,61952, 176,65344,13824,51200, 864,64640
99 };
100 
101 #define st_alaw_to_short(a) (a2s[(unsigned char)a])
102 
103 void ulaw_to_short(const unsigned char *ulaw,short *data,int length)
104 {
105  /* Convert ulaw to shorts */
106  int i;
107 
108  for (i=0; i<length; i++)
109  data[i] = st_ulaw_to_short(ulaw[i]); /* ulaw convert */
110 
111 }
112 
113 void alaw_to_short(const unsigned char *alaw,short *data,int length)
114 {
115  /* Convert ulaw to shorts */
116  int i;
117 
118  for (i=0; i<length; i++)
119  {
120  data[i] = st_alaw_to_short(alaw[i])-32768; /* alaw convert */
121  }
122 }
123 
124 void shorten_to_short(unsigned char *ulaw, short *data, int length)
125 {
126  /* Convert Tony Robinson's shorten format to shorts */
127  (void)ulaw;
128  (void)data;
129  (void)length;
130 
131 }
132 
133 void uchar_to_short(const unsigned char *chars,short *data,int length)
134 {
135  /* Convert 8 bit data to shorts UNSIGNED CHAR */
136  int i;
137 
138  for (i=0; i<length; i++)
139  {
140  data[i] = (((int)chars[i])-128)*256;
141  }
142 
143 }
144 
145 void schar_to_short(const unsigned char *chars,short *data,int length)
146 {
147  /* Convert 8 bit data to shorts SIGNED CHAR */
148  int i;
149 
150  for (i=0; i<length; i++)
151  data[i] = (((unsigned char)chars[i]))*256;
152 
153 }
154 
155 void short_to_uchar(const short *data,unsigned char *chars,int length)
156 {
157  /* Convert shorts to 8 bit UNSIGNED CHAR */
158  int i;
159 
160  for (i=0; i<length; i++)
161  chars[i] = (data[i]/256)+128;
162 
163 }
164 
165 void short_to_schar(const short *data,unsigned char *chars,int length)
166 {
167  /* Convert shorts to 8 bit SIGNED CHAR */
168  int i;
169 
170  for (i=0; i<length; i++)
171  chars[i] = (data[i]/256);
172 
173 }
174 
175 #if 0
176 void short_to_adpcm(short *data,signed char *chars,int length)
177 {
178  struct adpcm_state state;
179  state.valprev = 0;
180  state.index = 0;
181 
182  adpcm_coder(data,chars,length,&state);
183 
184 }
185 
186 void adpcm_to_short(signed char *chars, short *data,int length)
187 {
188  struct adpcm_state state;
189  state.valprev = 0;
190  state.index = 0;
191 
192  adpcm_decoder(chars,data,length/2,&state);
193 }
194 #endif
195 
196 void short_to_ulaw(const short *data,unsigned char *ulaw,int length)
197 {
198  /* Convert ulaw to shorts */
199  int i;
200 
201  for (i=0; i<length; i++)
202  ulaw[i] = st_short_to_ulaw(data[i]); /* ulaw convert */
203 
204 }
205 
206 void short_to_alaw(const short *data,unsigned char *alaw,int length)
207 {
208  /* Convert alaw to shorts */
209  int i;
210 
211  for (i=0; i<length; i++)
212  alaw[i] = st_short_to_alaw(data[i]); /* alaw convert */
213 
214 }
215 
216 short *convert_raw_data(unsigned char *file_data,int data_length,
217  enum EST_sample_type_t sample_type,int bo)
218 {
219  /* converts data in file_data to native byte order shorts */
220  /* frees file_data if its not returned */
221  short *d=NULL;
222 
223  if (sample_type == st_short)
224  {
225  // d = walloc(short,data_length);
226  if (bo != EST_NATIVE_BO)
227  swap_bytes_short((short *)file_data,data_length);
228  return (short *)file_data;
229  }
230  else if (sample_type == st_mulaw)
231  {
232  d = walloc(short,data_length);
233  ulaw_to_short(file_data,d,data_length);
234  wfree(file_data);
235  return d;
236  }
237  else if (sample_type == st_alaw)
238  {
239  d = walloc(short,data_length);
240  alaw_to_short(file_data,d,data_length);
241  wfree(file_data);
242  return d;
243  }
244 #if 0
245  else if (sample_type == st_adpcm)
246  { /* Not really checked yet */
247  d = walloc(short,data_length);
248  adpcm_to_short((signed char *)file_data,d,data_length);
249  wfree(file_data);
250  return d;
251  }
252 #endif
253  else if (sample_type == st_schar)
254  {
255  d = walloc(short,data_length);
256  schar_to_short((unsigned char *)file_data,d,data_length);
257  wfree(file_data);
258  return d;
259  }
260  else if (sample_type == st_uchar)
261  {
262  d = walloc(short,data_length);
263  uchar_to_short((unsigned char *)file_data,d,data_length);
264  wfree(file_data);
265  return d;
266  }
267  else
268  EST_error("Convert raw data: unsupported sample type %s(%d)",
269  EST_sample_type_map.name(sample_type), sample_type);
270 
271  /* NOTREACHED */
272  return NULL;
273 }
274 
275 enum EST_write_status save_raw_data(FILE *fp, const short *data, int offset,
276  int num_samples, int num_channels,
277  enum EST_sample_type_t sample_type,
278  int bo)
279 {
280  int i;
281  int n;
282 
283  if (sample_type == st_mulaw)
284  {
285  unsigned char *ulaw = walloc(unsigned char,num_samples*num_channels);
286  short_to_ulaw(data+(offset*num_channels),
287  ulaw,num_samples*num_channels);
288  n = fwrite(ulaw,1,num_channels * num_samples,fp);
289  wfree(ulaw);
290  if (n != (num_channels * num_samples))
291  return misc_write_error;
292  }
293  else if (sample_type == st_alaw)
294  {
295  unsigned char *alaw = walloc(unsigned char,num_samples*num_channels);
296  short_to_alaw(data+(offset*num_channels),
297  alaw,num_samples*num_channels);
298  n = fwrite(alaw,1,num_channels * num_samples,fp);
299  wfree(alaw);
300  if (n != (num_channels * num_samples))
301  return misc_write_error;
302  }
303  else if (sample_type == st_ascii)
304  {
305  for (i=offset*num_channels; i < num_samples*num_channels; i++)
306  fprintf(fp,"%d\n",data[i]);
307  }
308  else if (sample_type == st_schar)
309  {
310  unsigned char *chars = walloc(unsigned char,num_samples*num_channels);
311  short_to_schar(data+(offset*num_channels),
312  chars,num_samples*num_channels);
313  n = fwrite(chars,1,num_channels * num_samples,fp);
314  wfree(chars);
315  if (n != (num_channels * num_samples))
316  return misc_write_error;
317  }
318  else if (sample_type == st_uchar)
319  {
320  unsigned char *chars = walloc(unsigned char,num_samples*num_channels);
321  short_to_uchar(data+(offset*num_channels),
322  chars,num_samples*num_channels);
323  n = fwrite(chars,1,num_channels * num_samples,fp);
324  wfree(chars);
325  if ( n != (num_channels * num_samples))
326  return misc_write_error;
327  }
328 #if 0
329  else if (sample_type == st_adpcm)
330  {
331  signed char *chars = walloc(signed char,num_samples*num_channels);
332  short_to_adpcm(data+(offset*num_channels),
333  chars,num_samples*num_channels);
334  n = fwrite(chars,1,num_channels * num_samples,fp);
335  wfree(chars);
336  if ( n != (num_channels * num_samples))
337  return misc_write_error;
338  }
339 #endif
340  else if (sample_type == st_short)
341  {
342  if (bo != EST_NATIVE_BO)
343  {
344  short *xdata = walloc(short,num_channels*num_samples);
345  memmove(xdata,data+(offset*num_channels),
346  num_channels*num_samples*sizeof(short));
347  swap_bytes_short(xdata,num_channels*num_samples);
348  n = fwrite(xdata, sizeof(short),num_channels * num_samples, fp);
349  wfree(xdata);
350  }
351  else
352  n = fwrite(&data[offset], sizeof(short),
353  num_channels * num_samples, fp);
354  if (n != (num_channels * num_samples))
355  return misc_write_error;
356  }
357  else
358  {
359  fprintf(stderr,"save data file: unsupported sample type\n");
360  return misc_write_error;
361  }
362  return write_ok;
363 }
364 
365 int get_word_size(enum EST_sample_type_t sample_type)
366 {
367  /* Returns word size from type */
368  int word_size;
369 
370  switch (sample_type)
371  {
372  case st_unknown:
373  word_size = 2; break;
374  case st_uchar:
375  case st_schar:
376  word_size = 1; break;
377  case st_mulaw:
378  case st_alaw:
379  word_size = 1; break;
380 #if 0
381  case st_adpcm: /* maybe I mean 0.5 */
382  word_size = 1; break;
383 #endif
384  case st_short:
385  word_size = 2; break;
386  case st_int:
387  /* Yes I mean 4 not sizeof(int) these are machine independent defs */
388  word_size = 4; break;
389  case st_float:
390  word_size = 4; break;
391  case st_double:
392  word_size = 8; break;
393  default:
394  fprintf(stderr,"Unknown encoding format error\n");
395  word_size = 2;
396  }
397  return word_size;
398 }
399 
400 enum EST_sample_type_t str_to_sample_type(const char *type)
401 {
402  /* string to internal value */
403 
404  if (streq(type,"short"))
405  return st_short;
406  if (streq(type,"shorten"))
407  return st_shorten;
408  else if ((streq(type,"ulaw")) || (streq(type,"mulaw")))
409  return st_mulaw;
410  else if ((streq(type,"char")) || (streq(type,"byte")) ||
411  (streq(type,"8bit")))
412  return st_schar;
413  else if ((streq(type,"unsignedchar")) || (streq(type,"unsignedbyte")) ||
414  (streq(type,"unsigned8bit")))
415  return st_uchar;
416  else if (streq(type,"int"))
417  return st_int;
418 #if 0
419  else if (streq(type,"adpcm"))
420  return st_adpcm;
421 #endif
422  else if ((streq(type,"real")) || (streq(type,"float")) ||
423  (streq(type,"real4")))
424  return st_float;
425  else if ((streq(type,"real8")) || (streq(type,"double")))
426  return st_double;
427  else if (streq(type,"alaw"))
428  return st_alaw;
429  else if (streq(type,"ascii"))
430  return st_ascii;
431  else
432  {
433  fprintf(stderr,"Unknown sample type: \"%s\"\n",type);
434  return st_unknown;
435  }
436 }
437 
438 const char *sample_type_to_str(enum EST_sample_type_t type)
439 {
440  switch (type)
441  {
442  case st_short: return "short";
443  case st_shorten: return "shorten";
444  case st_mulaw: return "ulaw";
445  case st_alaw: return "alaw";
446  case st_schar: return "char";
447  case st_uchar: return "unsignedchar";
448  case st_int: return "int";
449 #if 0
450  case st_adpcm: return "adpcm";
451 #endif
452  case st_float: return "float";
453  case st_double: return "double";
454  case st_ascii: return "ascii";
455  case st_unknown: return "unknown";
456  default:
457  fprintf(stderr,"Unknown sample_type %d\n",type);
458  return "very_unknown";
459  }
460 }
461 
462 /*
463 ** This routine converts from linear to ulaw.
464 **
465 ** Craig Reese: IDA/Supercomputing Research Center
466 ** Joe Campbell: Department of Defense
467 ** 29 September 1989
468 **
469 ** References:
470 ** 1) CCITT Recommendation G.711 (very difficult to follow)
471 ** 2) "A New Digital Technique for Implementation of Any
472 ** Continuous PCM Companding Law," Villeret, Michel,
473 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
474 ** 1973, pg. 11.12-11.17
475 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
476 ** for Analog-to_Digital Conversion Techniques,"
477 ** 17 February 1987
478 **
479 ** Input: Signed 16 bit linear sample
480 ** Output: 8 bit ulaw sample
481 */
482 
483 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
484 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
485 #define CLIP 32635
486 
487 static unsigned char st_short_to_ulaw(short sample)
488 {
489  static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
490  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
491  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
492  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
493  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
494  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
495  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
496  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
497  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
498  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
499  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
500  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
501  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
502  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
503  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
504  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
505  int sign, exponent, mantissa;
506  unsigned char ulawbyte;
507 
508  /* Get the sample into sign-magnitude. */
509  sign = (sample >> 8) & 0x80; /* set aside the sign */
510  if ( sign != 0 ) sample = -sample; /* get magnitude */
511  if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
512 
513  /* Convert from 16 bit linear to ulaw. */
514  sample = sample + BIAS;
515  exponent = exp_lut[( sample >> 7 ) & 0xFF];
516  mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
517  ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
518 #ifdef ZEROTRAP
519  if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
520 #endif
521 
522  return ulawbyte;
523 }
524 
525 /*
526 ** This routine converts from ulaw to 16 bit linear.
527 **
528 ** Craig Reese: IDA/Supercomputing Research Center
529 ** 29 September 1989
530 **
531 ** References:
532 ** 1) CCITT Recommendation G.711 (very difficult to follow)
533 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
534 ** for Analog-to_Digital Conversion Techniques,"
535 ** 17 February 1987
536 **
537 ** Input: 8 bit ulaw sample
538 ** Output: signed 16 bit linear sample
539 */
540 
541 static short st_ulaw_to_short( unsigned char ulawbyte )
542 {
543  static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
544  int sign, exponent, mantissa;
545  short sample;
546 
547  ulawbyte = ~ ulawbyte;
548  sign = ( ulawbyte & 0x80 );
549  exponent = ( ulawbyte >> 4 ) & 0x07;
550  mantissa = ulawbyte & 0x0F;
551  sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
552  if ( sign != 0 ) sample = -sample;
553 
554  return sample;
555 }
556 
557 
558 /* The following is copied from sox:g711.c */
559 /*
560  * This source code is a product of Sun Microsystems, Inc. and is provided
561  * for unrestricted use. Users may copy or modify this source code without
562  * charge.
563  * [ no warranties or liabilities whatsoever; see there for details. ]
564  */
565 /* copy from CCITT G.711 specifications */
566 static unsigned char _u2a[128] = { /* u- to A-law conversions */
567  1, 1, 2, 2, 3, 3, 4, 4,
568  5, 5, 6, 6, 7, 7, 8, 8,
569  9, 10, 11, 12, 13, 14, 15, 16,
570  17, 18, 19, 20, 21, 22, 23, 24,
571  25, 27, 29, 31, 33, 34, 35, 36,
572  37, 38, 39, 40, 41, 42, 43, 44,
573  46, 48, 49, 50, 51, 52, 53, 54,
574  55, 56, 57, 58, 59, 60, 61, 62,
575  64, 65, 66, 67, 68, 69, 70, 71,
576  72, 73, 74, 75, 76, 77, 78, 79,
577  80, 82, 83, 84, 85, 86, 87, 88,
578  89, 90, 91, 92, 93, 94, 95, 96,
579  97, 98, 99, 100, 101, 102, 103, 104,
580  105, 106, 107, 108, 109, 110, 111, 112,
581  113, 114, 115, 116, 117, 118, 119, 120,
582  121, 122, 123, 124, 125, 126, 127, 128};
583 
584 static unsigned char _a2u[128] = { /* A- to u-law conversions */
585  1, 3, 5, 7, 9, 11, 13, 15,
586  16, 17, 18, 19, 20, 21, 22, 23,
587  24, 25, 26, 27, 28, 29, 30, 31,
588  32, 32, 33, 33, 34, 34, 35, 35,
589  36, 37, 38, 39, 40, 41, 42, 43,
590  44, 45, 46, 47, 48, 48, 49, 49,
591  50, 51, 52, 53, 54, 55, 56, 57,
592  58, 59, 60, 61, 62, 63, 64, 64,
593  65, 66, 67, 68, 69, 70, 71, 72,
594  73, 74, 75, 76, 77, 78, 79, 80,
595  80, 81, 82, 83, 84, 85, 86, 87,
596  88, 89, 90, 91, 92, 93, 94, 95,
597  96, 97, 98, 99, 100, 101, 102, 103,
598  104, 105, 106, 107, 108, 109, 110, 111,
599  112, 113, 114, 115, 116, 117, 118, 119,
600  120, 121, 122, 123, 124, 125, 126, 127};
601 
602 /* A-law to u-law conversion */
603 static inline unsigned char st_alaw2ulaw(
604  unsigned char aval)
605 {
606  aval &= 0xff;
607  return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
608  (0x7F ^ _a2u[aval ^ 0x55]));
609 }
610 
611 /* u-law to A-law conversion */
612 static inline unsigned char st_ulaw2alaw(
613  unsigned char uval)
614 {
615  uval &= 0xff;
616  return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
617  (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
618 }
619 /* end of Sun code */
620 
621 /* This is somewhat simple-minded, but ... */
622 static unsigned char st_short_to_alaw(short sample)
623 {
624  return st_ulaw2alaw(st_short_to_ulaw(sample));
625 }
626 
627 
628 /*
629  * C O N V E R T T O I E E E E X T E N D E D
630  */
631 
632 /* Copyright (C) 1988-1991 Apple Computer, Inc.
633  * All rights reserved.
634  *
635  * Machine-independent I/O routines for IEEE floating-point numbers.
636  *
637  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
638  * happens to be infinity on IEEE machines. Unfortunately, it is
639  * impossible to preserve NaN's in a machine-independent way.
640  * Infinities are, however, preserved on IEEE machines.
641  *
642  * These routines have been tested on the following machines:
643  * Apple Macintosh, MPW 3.1 C compiler
644  * Apple Macintosh, THINK C compiler
645  * Silicon Graphics IRIS, MIPS compiler
646  * Cray X/MP and Y/MP
647  * Digital Equipment VAX
648  *
649  *
650  * Implemented by Malcolm Slaney and Ken Turkowski.
651  *
652  * Malcolm Slaney contributions during 1988-1990 include big- and little-
653  * endian file I/O, conversion to and from Motorola's extended 80-bit
654  * floating-point format, and conversions to and from IEEE single-
655  * precision floating-point format.
656  *
657  * In 1991, Ken Turkowski implemented the conversions to and from
658  * IEEE double-precision format, added more precision to the extended
659  * conversions, and accommodated conversions involving +/- infinity,
660  * NaN's, and denormalized numbers.
661  */
662 
663 #ifndef HUGE_VAL
664 # define HUGE_VAL HUGE
665 #endif /*HUGE_VAL*/
666 
667 # define FloatToUnsigned(f) ((unsigned long)(((long)(f - 2147483648.0)) + 2147483647L) + 1)
668 
669 void ConvertToIeeeExtended(double num,unsigned char *bytes)
670 {
671  int sign;
672  int expon;
673  double fMant, fsMant;
674  unsigned long hiMant, loMant;
675 
676  if (num < 0) {
677  sign = 0x8000;
678  num *= -1;
679  } else {
680  sign = 0;
681  }
682 
683  if (num == 0) {
684  expon = 0; hiMant = 0; loMant = 0;
685  }
686  else {
687  fMant = frexp(num, &expon);
688  if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
689  expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
690  }
691  else { /* Finite */
692  expon += 16382;
693  if (expon < 0) { /* denormalized */
694  fMant = ldexp(fMant, expon);
695  expon = 0;
696  }
697  expon |= sign;
698  fMant = ldexp(fMant, 32);
699  fsMant = floor(fMant);
700  hiMant = FloatToUnsigned(fsMant);
701  fMant = ldexp(fMant - fsMant, 32);
702  fsMant = floor(fMant);
703  loMant = FloatToUnsigned(fsMant);
704  }
705  }
706 
707  bytes[0] = expon >> 8;
708  bytes[1] = expon;
709  bytes[2] = hiMant >> 24;
710  bytes[3] = hiMant >> 16;
711  bytes[4] = hiMant >> 8;
712  bytes[5] = hiMant;
713  bytes[6] = loMant >> 24;
714  bytes[7] = loMant >> 16;
715  bytes[8] = loMant >> 8;
716  bytes[9] = loMant;
717 }
718 
719 
720 /*
721  * C O N V E R T F R O M I E E E E X T E N D E D
722  */
723 
724 /*
725  * Copyright (C) 1988-1991 Apple Computer, Inc.
726  * All rights reserved.
727  *
728  * Machine-independent I/O routines for IEEE floating-point numbers.
729  *
730  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
731  * happens to be infinity on IEEE machines. Unfortunately, it is
732  * impossible to preserve NaN's in a machine-independent way.
733  * Infinities are, however, preserved on IEEE machines.
734  *
735  * These routines have been tested on the following machines:
736  * Apple Macintosh, MPW 3.1 C compiler
737  * Apple Macintosh, THINK C compiler
738  * Silicon Graphics IRIS, MIPS compiler
739  * Cray X/MP and Y/MP
740  * Digital Equipment VAX
741  *
742  *
743  * Implemented by Malcolm Slaney and Ken Turkowski.
744  *
745  * Malcolm Slaney contributions during 1988-1990 include big- and little-
746  * endian file I/O, conversion to and from Motorola's extended 80-bit
747  * floating-point format, and conversions to and from IEEE single-
748  * precision floating-point format.
749  *
750  * In 1991, Ken Turkowski implemented the conversions to and from
751  * IEEE double-precision format, added more precision to the extended
752  * conversions, and accommodated conversions involving +/- infinity,
753  * NaN's, and denormalized numbers.
754  */
755 
756 #ifndef HUGE_VAL
757 # define HUGE_VAL HUGE
758 #endif /*HUGE_VAL*/
759 
760 # define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
761 
762 /****************************************************************
763  * Extended precision IEEE floating-point conversion routine.
764  ****************************************************************/
765 
766 double ConvertFromIeeeExtended(unsigned char *bytes)
767 {
768  double f;
769  int expon;
770  unsigned long hiMant, loMant;
771 
772  expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
773  hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
774  | ((unsigned long)(bytes[3] & 0xFF) << 16)
775  | ((unsigned long)(bytes[4] & 0xFF) << 8)
776  | ((unsigned long)(bytes[5] & 0xFF));
777  loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
778  | ((unsigned long)(bytes[7] & 0xFF) << 16)
779  | ((unsigned long)(bytes[8] & 0xFF) << 8)
780  | ((unsigned long)(bytes[9] & 0xFF));
781 
782  if (expon == 0 && hiMant == 0 && loMant == 0) {
783  f = 0;
784  }
785  else {
786  if (expon == 0x7FFF) { /* Infinity or NaN */
787  f = HUGE_VAL;
788  }
789  else {
790  expon -= 16383;
791  f = ldexp((double)(hiMant), expon-=31);
792  f += ldexp((double)(loMant), expon-=32);
793  }
794  }
795 
796  if (bytes[0] & 0x80)
797  return -f;
798  else
799  return f;
800 }
801 
enum EST_sample_type_t str_to_sample_type(const char *type)
#define walloc(TYPE, SIZE)
Definition: EST_walloc.h:52
void alaw_to_short(const unsigned char *alaw, short *data, int length)
EST_write_status
enum EST_write_status save_raw_data(FILE *fp, const short *data, int offset, int num_samples, int num_channels, enum EST_sample_type_t sample_type, int bo)
void ulaw_to_short(const unsigned char *ulaw, short *data, int length)
#define st_alaw_to_short(a)
EST_TNamedEnum< EST_sample_type_t > EST_sample_type_map
void uchar_to_short(const unsigned char *chars, short *data, int length)
const char * sample_type_to_str(enum EST_sample_type_t type)
short * convert_raw_data(unsigned char *file_data, int data_length, enum EST_sample_type_t sample_type, int bo)
#define streq(X, Y)
Definition: EST_cutils.h:57
void schar_to_short(const unsigned char *chars, short *data, int length)
void short_to_alaw(const short *data, unsigned char *alaw, int length)
#define CLIP
#define BIAS
#define misc_write_error
void short_to_ulaw(const short *data, unsigned char *ulaw, int length)
double ConvertFromIeeeExtended(unsigned char *bytes)
The file was written successfully.
int get_word_size(enum EST_sample_type_t sample_type)
void swap_bytes_short(short *data, int length)
Definition: EST_swapping.cc:97
#define HUGE_VAL
NULL
Definition: EST_WFST.cc:55
#define EST_error
Definition: EST_error.h:104
f
Definition: EST_item_aux.cc:48
getString int
Definition: EST_item_aux.cc:50
void short_to_schar(const short *data, unsigned char *chars, int length)
void short_to_uchar(const short *data, unsigned char *chars, int length)
void ConvertToIeeeExtended(double num, unsigned char *bytes)
EST_sample_type_t
Definition: EST_wave_aux.h:105
#define EST_NATIVE_BO
Definition: EST_cutils.h:72
void shorten_to_short(unsigned char *ulaw, short *data, int length)
LISP fp
Definition: kkcompile.cc:63
void wfree(void *p)
Definition: walloc.c:131
#define FloatToUnsigned(f)