--- vmconvert.c-orig 2005-08-03 13:14:36.000000000 +0200 +++ vmconvert.c 2005-08-03 13:05:14.000000000 +0200 @@ -1,3 +1,5 @@ +/* vmconvert.c - adapted by Peter Fokker ; deal with endianness 2005-08-03 */ + #include #include @@ -48,6 +50,17 @@ rh->filesize = sizeof(struct riff_header) + wav_data_size - 8; rh->datasize = wav_data_size; + /* take care of endian anomaly; make it little endian */ + rh->filesize = endian_l(rh->filesize); + rh->fmthsize = endian_l(rh->fmthsize); + rh->format = endian_s(rh->format); + rh->channels = endian_s(rh->channels); + rh->rate = endian_l(rh->rate); + rh->bsec = endian_l(rh->bsec); + rh->align = endian_s(rh->align); + rh->bits = endian_s(rh->bits); + rh->datasize = endian_l(rh->datasize); + return sizeof(struct riff_header); } @@ -68,6 +81,7 @@ gsm_frame s; gsm_byte *p; + gsm_signal *w; /* used to step through output for endianness */ int i; p = (gsm_byte *)vmo_frame; @@ -84,7 +98,12 @@ /* invalid frame */ bzero(buffer, 160 * sizeof(gsm_signal)); } - + else { + /* valid frame, but how about endianness? */ + for (w = (gsm_signal *) buffer, i=160; (i-- > 0); ++w) { + *w = endian_s(*w); + } + } return; } @@ -94,3 +113,45 @@ } +/* These two routines convert shorts (16 bits) and + * longs (32 bits) to little endian format. Trick is to let the + * compiler store a multibyte number in endian_test. On a little + * endian machine, this will result in the LSB being 1 whereas + * on a big endian machine it will be 0. By casting a pointer + * to unsigned char, we can determine the endianness automagically. + * If we discover we are running on a big endian, we swap, otherwise + * we do nothing. + */ + +short endian_s(short i) { + static short endian_test = 0x0001; + unsigned char *little_endian = (unsigned char *) &endian_test; + unsigned char b0,b1; + + if (*little_endian) { + return i; + } + else { + b0 = (i & 0x00FF); + b1 = ((i & 0xFF00) >> 8); + return (b0 << 8) | b1; + } +} + +long endian_l(long i) { + static short endian_test = 0x0001; + unsigned char *little_endian = (unsigned char *) &endian_test; + unsigned char b0,b1,b2,b3; + + if (*little_endian) { + return i; + } + else { + b0 = (i & 0x000000FF); + b1 = ((i & 0x0000FF00) >> 8); + b2 = ((i & 0x00FF0000) >> 16); + b3 = ((i & 0xFF000000) >> 24); + return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; + } +} +