git: 9front

Download patch

ref: adf78f131d45c7d031815330f4e1801efb238274
parent: 63c83c7763ab102729d6de9e07dff225c5dfc144
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Dec 12 14:04:57 EST 2012

audio/pcmconv: cleanup

--- a/sys/src/cmd/audio/pcmconv/pcmconv.c
+++ b/sys/src/cmd/audio/pcmconv/pcmconv.c
@@ -23,9 +23,9 @@
 	ulong	lΔ;	/* filter step */
 	ulong	le;	/* filter end */
 
+	int	u;	/* unity scale */
 	int	*h;	/* filter coefficients */
 	int	*hΔ;	/* coefficient deltas for interpolation */
-	int	u;	/* unity scale */
 
 	int	wx;	/* extra samples */
 	int	ix;	/* buffer index */
@@ -34,17 +34,13 @@
 };
 
 enum {
-	Nl	= 8,
-	Nη	= 8,
-	Np	= Nl+Nη,
-
-	L	= 1<<Np,
-	Nz	= 13,
-
+	Nl	= 8,		/* 2^Nl samples per zero crossing in fir */
+	Nη	= 8,		/* phase bits for filter interpolation */
+	Np	= Nl+Nη,	/* phase bits (fract of fixed point) */
 	One	= 1<<Np,
 };
 
-void
+int
 chaninit(Chan *c, int irate, int orate, int count)
 {
 	static int h[] = {
@@ -55,29 +51,35 @@
 
 	c->ρ = ((uvlong)orate<<Np)/irate;
 	if(c->ρ == One)
-		return;
+		goto Done;
+
 	c->tΔ = ((uvlong)irate<<Np)/orate;
-	c->lΔ = L;
+	c->lΔ = 1<<(Nl+Nη);
+	c->le = nelem(h)<<Nη;
+	c->wx = 1 + (c->le / c->lΔ);
+	c->u = 13128;	/* unity scale factor for fir */
 	if(c->ρ < One){
 		c->u *= c->ρ;
 		c->u >>= Np;
 		c->lΔ *= c->ρ;
 		c->lΔ >>= Np;
+		c->wx *= c->tΔ;
+		c->wx >>= Np;
 	}
-	c->le = nelem(h)<<Nη;
-	c->h = h;
 	if(!init){
 		init = 1;
 		for(n=0; n<nelem(hΔ)-1; n++)
 			hΔ[n] = h[n+1] - h[n];
 	}
+	c->h = h;
 	c->hΔ = hΔ;
-	c->u = 13128;	/* unity scale factor for fir */
-	c->wx = 2*Nz*irate / orate;
 	c->ix = c->wx;
 	c->t = c->ix<<Np;
 	c->nx = c->wx*2 + count;
 	c->x = sbrk(sizeof(c->x[0]) * c->nx);
+	count += c->nx; /* account for buffer accumulation */
+Done:
+	return ((uvlong)count * c->ρ) >> Np;
 }
 
 int
@@ -418,7 +420,7 @@
 	int *out, *in;
 	Chan ch[8];
 	Desc i, o;
-	int k, r, n, m;
+	int k, n, m, nin, nout;
 	vlong l;
 
 	void (*oconv)(int *, uchar *, int, int, int) = nil;
@@ -473,21 +475,22 @@
 	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;
-	in = sbrk(sizeof(int) * n);
-	out = sbrk(sizeof(int) * m);
-	obuf = sbrk(o.framesz * m);
+	nin = (sizeof(ibuf)-i.framesz)/i.framesz;
+	in = sbrk(sizeof(int) * nin);
 
+	nout = 0;
 	memset(ch, 0, sizeof(ch));
 	for(k=0; k < i.channels; k++)
-		chaninit(&ch[k], i.rate, o.rate, n);
+		nout = chaninit(&ch[k], i.rate, o.rate, nin);
 
+	out = sbrk(sizeof(int) * nout);
+	obuf = sbrk(o.framesz * nout);
+
 	for(;;){
-		if(l >= 0 && l < r)
-			r = l;
-		n = cread(0, ibuf, r, i.framesz);
+		n = nin * i.framesz;
+		if(l >= 0 && l < n)
+			n = l;
+		n = cread(0, ibuf, n, i.framesz);
 		if(n < 0)
 			sysfatal("read: %r");
 		if(l > 0)
--