audio/pcmconv: implement filter coefficient interpolation, cleanup
This commit is contained in:
parent
2823498ac3
commit
985df234d6
1 changed files with 53 additions and 19 deletions
|
@ -21,8 +21,11 @@ struct Chan
|
||||||
|
|
||||||
ulong tΔ; /* output step */
|
ulong tΔ; /* output step */
|
||||||
ulong lΔ; /* filter step */
|
ulong lΔ; /* filter step */
|
||||||
|
ulong le; /* filter end */
|
||||||
|
|
||||||
ulong u; /* unity scale */
|
int *h; /* filter coefficients */
|
||||||
|
int *hΔ; /* coefficient deltas for interpolation */
|
||||||
|
int u; /* unity scale */
|
||||||
|
|
||||||
int wx; /* extra samples */
|
int wx; /* extra samples */
|
||||||
int ix; /* buffer index */
|
int ix; /* buffer index */
|
||||||
|
@ -32,7 +35,7 @@ struct Chan
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Nl = 8,
|
Nl = 8,
|
||||||
Nη = 8, /* for coefficient interpolation, not implenented */
|
Nη = 8,
|
||||||
Np = Nl+Nη,
|
Np = Nl+Nη,
|
||||||
|
|
||||||
L = 1<<Np,
|
L = 1<<Np,
|
||||||
|
@ -44,10 +47,15 @@ enum {
|
||||||
void
|
void
|
||||||
chaninit(Chan *c, int irate, int orate, int count)
|
chaninit(Chan *c, int irate, int orate, int count)
|
||||||
{
|
{
|
||||||
|
static int h[] = {
|
||||||
|
#include "fir.h"
|
||||||
|
};
|
||||||
|
static int hΔ[nelem(h)], init = 0;
|
||||||
|
int n;
|
||||||
|
|
||||||
c->ρ = ((uvlong)orate<<Np)/irate;
|
c->ρ = ((uvlong)orate<<Np)/irate;
|
||||||
if(0 && c->ρ == One)
|
if(c->ρ == One)
|
||||||
return;
|
return;
|
||||||
c->u = 13128; /* unity scale factor for fir */
|
|
||||||
c->tΔ = ((uvlong)irate<<Np)/orate;
|
c->tΔ = ((uvlong)irate<<Np)/orate;
|
||||||
c->lΔ = L;
|
c->lΔ = L;
|
||||||
if(c->ρ < One){
|
if(c->ρ < One){
|
||||||
|
@ -56,6 +64,15 @@ chaninit(Chan *c, int irate, int orate, int count)
|
||||||
c->lΔ *= c->ρ;
|
c->lΔ *= c->ρ;
|
||||||
c->lΔ >>= Np;
|
c->lΔ >>= 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->u = 13128; /* unity scale factor for fir */
|
||||||
c->wx = 2*Nz*irate / orate;
|
c->wx = 2*Nz*irate / orate;
|
||||||
c->ix = c->wx;
|
c->ix = c->wx;
|
||||||
c->t = c->ix<<Np;
|
c->t = c->ix<<Np;
|
||||||
|
@ -66,32 +83,46 @@ chaninit(Chan *c, int irate, int orate, int count)
|
||||||
int
|
int
|
||||||
filter(Chan *c)
|
filter(Chan *c)
|
||||||
{
|
{
|
||||||
ulong l, n, p;
|
ulong l, lΔ, le, p, i;
|
||||||
|
int *x, *h, *hΔ, a;
|
||||||
vlong v;
|
vlong v;
|
||||||
|
|
||||||
static int h[] = {
|
|
||||||
#include "fir.h"
|
|
||||||
};
|
|
||||||
|
|
||||||
v = 0;
|
v = 0;
|
||||||
|
|
||||||
|
h = c->h;
|
||||||
|
hΔ = c->hΔ;
|
||||||
|
lΔ = c->lΔ;
|
||||||
|
le = c->le;
|
||||||
|
|
||||||
/* left side */
|
/* left side */
|
||||||
|
x = &c->x[c->t>>Np];
|
||||||
p = c->t & ((1<<Np)-1);
|
p = c->t & ((1<<Np)-1);
|
||||||
l = c->ρ < One ? (c->ρ * p)>>Np : p;
|
l = c->ρ < One ? (c->ρ * p)>>Np : p;
|
||||||
for(n = c->t>>Np; l < nelem(h)<<Nη; l += c->lΔ)
|
while(l < le){
|
||||||
v += (vlong)c->x[--n] * h[l>>Nη];
|
i = l >> Nη;
|
||||||
|
a = l & ((1<<Nη)-1);
|
||||||
|
l += lΔ;
|
||||||
|
a *= hΔ[i];
|
||||||
|
a >>= Nη;
|
||||||
|
a += h[i];
|
||||||
|
v += (vlong)*(--x) * a;
|
||||||
|
}
|
||||||
|
|
||||||
/* right side */
|
/* right side */
|
||||||
|
x = &c->x[c->t>>Np];
|
||||||
p = (One - p) & ((1<<Np)-1);
|
p = (One - p) & ((1<<Np)-1);
|
||||||
l = c->ρ < One ? (c->ρ * p)>>Np : p;
|
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->lΔ;
|
l += c->lΔ;
|
||||||
n++;
|
while(l < le){
|
||||||
|
i = l >> Nη;
|
||||||
|
a = l & ((1<<Nη)-1);
|
||||||
|
l += lΔ;
|
||||||
|
a *= hΔ[i];
|
||||||
|
a >>= Nη;
|
||||||
|
a += h[i];
|
||||||
|
v += (vlong)*x++ * a;
|
||||||
}
|
}
|
||||||
for(; l < nelem(h)<<Nη; l += c->lΔ)
|
|
||||||
v += (vlong)c->x[n++] * h[l>>Nη];
|
|
||||||
|
|
||||||
/* scale */
|
/* scale */
|
||||||
v >>= 2;
|
v >>= 2;
|
||||||
|
@ -151,8 +182,11 @@ resample(Chan *c, int *x, int *y, ulong count)
|
||||||
n = c->t >> Np;
|
n = c->t >> Np;
|
||||||
n -= c->wx;
|
n -= c->wx;
|
||||||
e -= c->wx;
|
e -= c->wx;
|
||||||
while(e < i)
|
i -= e;
|
||||||
c->x[n++] = c->x[e++];
|
if(i > 0){
|
||||||
|
memmove(c->x + n, c->x + e, i*sizeof(int));
|
||||||
|
n += i;
|
||||||
|
}
|
||||||
c->ix = n;
|
c->ix = n;
|
||||||
}
|
}
|
||||||
} while(count > 0);
|
} while(count > 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue