summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-12-11 20:42:33 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2012-12-11 20:42:33 +0100
commit45a5074b10266b82a03c9fd7a636672c34eb1f39 (patch)
tree8fb9085841aa1dce8e9d9c9d2a49b56f316698d7
parent0903d01134a93869bea5f80129e99f872c00712d (diff)
downloadplan9front-45a5074b10266b82a03c9fd7a636672c34eb1f39.tar.xz
audio/pcmconv: disable floating point exceptions for data conversion
for the float to integer conversion, disable exceptions. also clamp the values. -- cinap
-rw-r--r--sys/src/cmd/audio/pcmconv/pcmconv.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/sys/src/cmd/audio/pcmconv/pcmconv.c b/sys/src/cmd/audio/pcmconv/pcmconv.c
index b40b8e562..188dd93c7 100644
--- a/sys/src/cmd/audio/pcmconv/pcmconv.c
+++ b/sys/src/cmd/audio/pcmconv/pcmconv.c
@@ -214,12 +214,32 @@ uiconv(int *dst, uchar *src, int bits, int skip, int count)
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 @@ uoconv(int *src, uchar *dst, int bits, int skip, int count)
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;
+ }
}
}
@@ -409,6 +433,9 @@ main(int argc, char *argv[])
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;
m = 3+(n*o.rate)/i.rate;