audio/pcmconv: implement filter coefficient interpolation, cleanup

This commit is contained in:
cinap_lenrek 2012-12-12 15:46:12 +01:00
parent 2823498ac3
commit 985df234d6

View file

@ -21,8 +21,11 @@ struct Chan
ulong ; /* output step */
ulong ; /* filter step */
ulong le; /* filter end */
ulong u; /* unity scale */
int *h; /* filter coefficients */
int *; /* coefficient deltas for interpolation */
int u; /* unity scale */
int wx; /* extra samples */
int ix; /* buffer index */
@ -32,7 +35,7 @@ struct Chan
enum {
Nl = 8,
= 8, /* for coefficient interpolation, not implenented */
= 8,
Np = Nl+,
L = 1<<Np,
@ -44,10 +47,15 @@ enum {
void
chaninit(Chan *c, int irate, int orate, int count)
{
static int h[] = {
#include "fir.h"
};
static int [nelem(h)], init = 0;
int n;
c->ρ = ((uvlong)orate<<Np)/irate;
if(0 && c->ρ == One)
if(c->ρ == One)
return;
c->u = 13128; /* unity scale factor for fir */
c-> = ((uvlong)irate<<Np)/orate;
c-> = L;
if(c->ρ < One){
@ -56,6 +64,15 @@ chaninit(Chan *c, int irate, int orate, int count)
c-> *= c->ρ;
c-> >>= Np;
}
c->le = nelem(h)<<;
c->h = h;
if(!init){
init = 1;
for(n=0; n<nelem()-1; n++)
[n] = h[n+1] - h[n];
}
c-> = ;
c->u = 13128; /* unity scale factor for fir */
c->wx = 2*Nz*irate / orate;
c->ix = c->wx;
c->t = c->ix<<Np;
@ -66,32 +83,46 @@ chaninit(Chan *c, int irate, int orate, int count)
int
filter(Chan *c)
{
ulong l, n, p;
ulong l, , le, p, i;
int *x, *h, *, a;
vlong v;
static int h[] = {
#include "fir.h"
};
v = 0;
h = c->h;
= c->;
= c->;
le = c->le;
/* left side */
x = &c->x[c->t>>Np];
p = c->t & ((1<<Np)-1);
l = c->ρ < One ? (c->ρ * p)>>Np : p;
for(n = c->t>>Np; l < nelem(h)<<; l += c->)
v += (vlong)c->x[--n] * h[l>>];
while(l < le){
i = l >> ;
a = l & ((1<<)-1);
l += ;
a *= [i];
a >>= ;
a += h[i];
v += (vlong)*(--x) * a;
}
/* right side */
x = &c->x[c->t>>Np];
p = (One - p) & ((1<<Np)-1);
l = c->ρ < One ? (c->ρ * p)>>Np : p;
n = c->t>>Np;
if(p == 0){
/* skip h[0] as it was already been summed above if p == 0 */
if(p == 0) /* skip h[0] as it was already been summed above if p == 0 */
l += c->;
n++;
while(l < le){
i = l >> ;
a = l & ((1<<)-1);
l += ;
a *= [i];
a >>= ;
a += h[i];
v += (vlong)*x++ * a;
}
for(; l < nelem(h)<<; l += c->)
v += (vlong)c->x[n++] * h[l>>];
/* scale */
v >>= 2;
@ -151,8 +182,11 @@ resample(Chan *c, int *x, int *y, ulong count)
n = c->t >> Np;
n -= c->wx;
e -= c->wx;
while(e < i)
c->x[n++] = c->x[e++];
i -= e;
if(i > 0){
memmove(c->x + n, c->x + e, i*sizeof(int));
n += i;
}
c->ix = n;
}
} while(count > 0);