git: 9front

Download patch

ref: 16b4df4c6d0e521ab3deed40d814b2b8f61cf504
parent: adf78f131d45c7d031815330f4e1801efb238274
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Thu Dec 13 04:39:15 EST 2012

audio/pcmconv: dithering

--- a/sys/src/cmd/audio/pcmconv/pcmconv.c
+++ b/sys/src/cmd/audio/pcmconv/pcmconv.c
@@ -141,7 +141,7 @@
 }
 
 int*
-resample(Chan *c, int *x, int *y, ulong count)
+resample(Chan *c, int *x, int *y, int count)
 {
 	ulong e;
 	int i, n;
@@ -197,6 +197,20 @@
 }
 
 void
+dither(int *y, int ibits, int obits, int count)
+{
+	static ulong prnd;
+
+	if(ibits >= 32 || obits >= ibits)
+		return;
+
+	while(count--){
+		prnd = (prnd*0x19660dL + 0x3c6ef35fL) & 0xffffffffL;
+		*y++ += ((int)prnd) >> ibits;
+	}
+}
+
+void
 siconv(int *dst, uchar *src, int bits, int skip, int count)
 {
 	int i, v, s, b;
@@ -497,6 +511,7 @@
 			l -= n;
 		n /= i.framesz;
 		(*iconv)(in, ibuf, i.bits, i.framesz, n);
+		dither(in, i.bits, o.bits, n);
 		m = resample(&ch[0], in, out, n) - out;
 		if(m < 1){
 			if(n == 0)
@@ -506,6 +521,7 @@
 		if(i.channels == o.channels){
 			for(k=1; k<i.channels; k++){
 				(*iconv)(in, ibuf + k*((i.bits+7)/8), i.bits, i.framesz, n);
+				dither(in, i.bits, o.bits, n);
 				resample(&ch[k], in, out, n);
 				if(m > 0)
 					(*oconv)(out, obuf + k*((o.bits+7)/8), o.bits, o.framesz, m);
--