/**************************************************************************** | Digital Audio Processor | ======================= | | Filename : ieee.c | | Object : None | | Description : Audiofile replacement code for linux | | (c) Richard Kent 1997 | | $Id: ieee.c,v 1.1 2003/09/10 00:06:24 rk Exp $ | ****************************************************************************/ static char ieee_c [] = "$Id: ieee.c,v 1.1 2003/09/10 00:06:24 rk Exp $"; #include "ieee.h" #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #define FloatToUnsigned(f) \ ((unsigned int)(((int)(f - 2147483648.0)) + 2147483647L) + 1) #define UnsignedToFloat(u)\ (((double)((int)(u - 2147483647L - 1))) + 2147483648.0) /*--------------------------------------------------------------------------- | FUNCTION convertToIeeeExtended ---------------------------------------------------------------------------*/ void convertToIeeeExtended (double num,unsigned char *bytes) { int sign; int expon; double fMant; double fsMant; unsigned int hiMant; unsigned int loMant; if (num < 0) { sign = 0x8000; num *= -1; } else { sign = 0; } if (num == 0) { expon = 0; hiMant = 0; loMant = 0; } else { fMant = frexp (num,&expon); if ((expon > 16384) || !(fMant < 1)) { // Infinity or NaN expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */ } else { // Finite expon += 16382; if (expon < 0) { // denormalized fMant = ldexp (fMant,expon); expon = 0; } expon |= sign; fMant = ldexp (fMant,32); fsMant = floor (fMant); hiMant = FloatToUnsigned (fsMant); fMant = ldexp (fMant-fsMant,32); fsMant = floor (fMant); loMant = FloatToUnsigned (fsMant); } } bytes[0] = expon >> 8; bytes[1] = expon; bytes[2] = hiMant >> 24; bytes[3] = hiMant >> 16; bytes[4] = hiMant >> 8; bytes[5] = hiMant; bytes[6] = loMant >> 24; bytes[7] = loMant >> 16; bytes[8] = loMant >> 8; bytes[9] = loMant; } /*--------------------------------------------------------------------------- | FUNCTION convertFromIeeeExtended ---------------------------------------------------------------------------*/ double convertFromIeeeExtended (unsigned char *bytes) { int expon; double f; unsigned int hiMant; unsigned int loMant; expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); hiMant = ((unsigned int)(bytes[2] & 0xFF) << 24) | ((unsigned int)(bytes[3] & 0xFF) << 16) | ((unsigned int)(bytes[4] & 0xFF) << 8) | ((unsigned int)(bytes[5] & 0xFF)); loMant = ((unsigned int)(bytes[6] & 0xFF) << 24) | ((unsigned int)(bytes[7] & 0xFF) << 16) | ((unsigned int)(bytes[8] & 0xFF) << 8) | ((unsigned int)(bytes[9] & 0xFF)); if (expon == 0 && hiMant == 0 && loMant == 0) { f = 0; } else { if (expon == 0x7FFF) { // Infinity or NaN f = HUGE_VAL; } else { expon -= 16383; f = ldexp (UnsignedToFloat (hiMant),expon-=31); f += ldexp (UnsignedToFloat (loMant),expon-=32); } } if (bytes[0] & 0x80) return -f; else return f; } /***************************************************************************/