ref: e47668b4c47700936da972a50746970ef2109243
parent: 317d4dab26c4d2d4eeb143aa894731092e174368
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Dec 11 15:42:33 EST 2012
audio/pcmconv: disable floating point exceptions for data conversion for the float to integer conversion, disable exceptions. also clamp the values. -- cinap
--- a/sys/src/cmd/audio/pcmconv/pcmconv.c
+++ b/sys/src/cmd/audio/pcmconv/pcmconv.c
@@ -214,12 +214,32 @@
void
ficonv(int *dst, uchar *src, int bits, int skip, int count)
{- while(count--){- if(bits == 32)
- *dst++ = *((float*)src) * 2147483647.f;
- else
- *dst++ = *((double*)src) * 2147483647.f;
- src += skip;
+ if(bits == 32){+ while(count--){+ float f;
+
+ f = *((float*)src);
+ if(f > 1.0)
+ *dst++ = 0x7fffffff;
+ else if(f < -1.0)
+ *dst++ = -0x80000000;
+ else
+ *dst++ = f*2147483647.f;
+ src += skip;
+ }
+ } else {+ while(count--){+ float d;
+
+ d = *((float*)src);
+ if(d > 1.0)
+ *dst++ = 0x7fffffff;
+ else if(d < -1.0)
+ *dst++ = -0x80000000;
+ else
+ *dst++ = d*2147483647.f;
+ src += skip;
+ }
}
}
@@ -275,12 +295,16 @@
void
foconv(int *src, uchar *dst, int bits, int skip, int count)
{- while(count--){- if(bits == 32)
+ if(bits == 32){+ while(count--){*((float*)dst) = *src++ / 2147483647.f;
- else
+ dst += skip;
+ }
+ } else {+ while(count--){*((double*)dst) = *src++ / 2147483647.f;
- dst += skip;
+ dst += skip;
+ }
}
}
@@ -408,6 +432,9 @@
case 'u': oconv = uoconv; break;
case 'f': oconv = foconv; break;
}
+
+ if(i.fmt == 'f' || o.fmt == 'f')
+ setfcr(getfcr() & ~(FPINVAL|FPOVFL));
n = (sizeof(ibuf)-i.framesz)/i.framesz;
r = n*i.framesz;
--
⑨