ref: 45a5074b10266b82a03c9fd7a636672c34eb1f39
parent: 0903d01134a93869bea5f80129e99f872c00712d
author: cinap_lenrek <[email protected]>
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;