Discussion:
[Freetel-codec2] Possible bug in lpc.c inverse_filter
Steve
2015-10-29 20:00:07 UTC
Permalink
Problem Description:

In codec2.c we have a function called codec2_encode_700b() and an
instruction:

inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*N, bpf_out, BPF_N);

BPF_N is 101, 4 * N = 320 (which could be M instead)

The number of coeficients of the BPF filter is 101.

In lpc.c we have the location of the inverse_filter function.

Since there are 101 coeficients, you can address these as 0..100 in an
array.
This function however references 0..101 as you can see the "j" loop goes
from
0 to "order" which is 101.

I believe this function is falling out of the coeficient array when j = 101.

Solution:

Change the "<=" in the "j" loop to "<" on line #209

http://sourceforge.net/p/freetel/code/HEAD/tree/codec2-dev/src/lpc.c#l209

Reference Code:

void inverse_filter(
float Sn[], /* Nsam input samples */
float a[], /* LPCs for this frame of samples */
int Nsam, /* number of samples */
float res[], /* Nsam residual samples */
int order /* order of LPC */
)
{
int i,j; /* loop variables */

for(i=0; i<Nsam; i++) {
res[i] = 0.0;
for(j=0; j<=order; j++)
res[i] += Sn[i-j]*a[j]; <---Note a[j] can be a[0]..a[101]
}
}
David Rowe
2015-10-29 20:42:12 UTC
Permalink
Nice catch Steve, thanks.

The inverse filter function is a part of a library of linear prediction
coding (LPC) functions. The convention for LPC is to specify the order
p which ends up being a filter of length p+1.

So I'll just change the call to BPF_N-1.

Cheers,

David
Post by Steve
In codec2.c we have a function called codec2_encode_700b() and an
inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*N, bpf_out, BPF_N);
BPF_N is 101, 4 * N = 320 (which could be M instead)
The number of coeficients of the BPF filter is 101.
In lpc.c we have the location of the inverse_filter function.
Since there are 101 coeficients, you can address these as 0..100 in an
array.
This function however references 0..101 as you can see the "j" loop goes
from
0 to "order" which is 101.
I believe this function is falling out of the coeficient array when j = 101.
Change the "<=" in the "j" loop to "<" on line #209
http://sourceforge.net/p/freetel/code/HEAD/tree/codec2-dev/src/lpc.c#l209
void inverse_filter(
float Sn[], /* Nsam input samples */
float a[], /* LPCs for this frame of samples */
int Nsam, /* number of samples */
float res[], /* Nsam residual samples */
int order /* order of LPC */
)
{
int i,j; /* loop variables */
for(i=0; i<Nsam; i++) {
res[i] = 0.0;
for(j=0; j<=order; j++)
res[i] += Sn[i-j]*a[j]; <---Note a[j] can be a[0]..a[101]
}
}
------------------------------------------------------------------------------
_______________________________________________
Freetel-codec2 mailing list
https://lists.sourceforge.net/lists/listinfo/freetel-codec2
------------------------------------------------------------------------------
Loading...