X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=fltpoint.c;h=2205a79f4c0d8d5a30d20216b8f08d17d84c7808;hp=1de5d0ac42a3cd5d53aae63beabf0e1eec17e9e8;hb=c59f7a33730dacf753e066a4002e2f749051a137;hpb=3b063cd8b11b5e868efec02f9e281a1e04f2707b diff --git a/fltpoint.c b/fltpoint.c index 1de5d0a..2205a79 100644 --- a/fltpoint.c +++ b/fltpoint.c @@ -2,7 +2,7 @@ // Floating point to IEEE-754 conversion routines // // by James Hammons -// (C) 2018 Underground Software +// (C) 2019 Underground Software // // Since there are no guarantees vis-a-vis floating point numbers in C, we have // to utilize routines like the following in order to guarantee that the thing @@ -14,6 +14,8 @@ #include "fltpoint.h" #include #include +#include +#include "error.h" // // Check for IEEE-754 conformance (C99 compilers should be OK here) @@ -72,7 +74,7 @@ uint32_t FloatToIEEE754(float f) // [+0.5, +1)) and base-2 exponent // d = mantissa * (2 ^ exponent) *exactly* for FLT_RADIX=2 // Also, since we want the mantissa to be non-inverted (2's complemented), - // we make sure to pass in a positive number (floats/doubles are not 2's + // we make sure to pass in a positive number (floats/doubles are *not* 2's // complemented) as we already captured the sign bit above. int32_t exponent; float mantissa = frexpf((f < 0 ? -f : f), &exponent); @@ -111,7 +113,7 @@ uint64_t DoubleToIEEE754(double d) // and base-2 exponent // d = mantissa * (2 ^ exponent) *exactly* for FLT_RADIX=2 // Also, since we want the mantissa to be non-inverted (2's complemented), - // we make sure to pass in a positive number (floats/doubles are not 2's + // we make sure to pass in a positive number (floats/doubles are *not* 2's // complemented) as we already captured the sign bit above. double mantissa = frexp((d < 0 ? -d : d), &exponent); @@ -169,3 +171,46 @@ void DoubleToExtended(double d, uint8_t out[]) out[11] = intMant & 0xFF; } + +// +// Convert a double to a DSP56001 style fixed point float. +// Seems to be 23 bits of float value with 1 bit (MSB) for the sign. +// +uint32_t DoubleToDSPFloat(double d) +{ + if (d >= 1) + { + warn("DSP value clamped to +1."); + return 0x7FFFFF; + } + else if (d <= -1) + { + warn("DSP value clamped to -1."); + return 0x800000; + } + + return trunc(round(ldexp(d, 23))); +} + + +// +// Convert a host native floating point number to a fixed point number. +// +uint64_t DoubleToFixedPoint(double d, int intBits, int fracBits) +{ + uint8_t signBit = (signbit(d) ? 1 : 0); + + // Ensure what we're working on is positive... + if (d < 0) + d *= -1; + + double scaleFactor = (double)(1 << fracBits); + uint64_t result = (uint64_t)(d * scaleFactor); + + // Invert the result, if necessary + if (signBit == 1) + result = (result = 0xFFFFFFFFFFFFFFFFLL) + 1; + + return result; +} +