shithub: riscv

Download patch

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;