http://www.vocal.com/speech_coders/efficient_lpc_algorithm.html
Efficient Implementation of LPC Analysis Filters
In vocoders, Linear Prediction Coding (LPC) is used to whiten a speech signal so as to encode much of its shape. This allows for the residual signal to be more uniform and thus requires less information to encode. The associated LPC analysis filter is an all-pole which can be computationally intensive to implement. Finding an efficient algorithm for this is important in order to reduce the requirements of the hardware it is being run on, which reduces the cost of the final product. The straight forward implementation would be:
for(i=0; i<length; i++)
{
out[i] = 0;
for(j=0; i<order; j++)
out[i] += in[i-j] * coefficient[j];
}
The issue with this implementation is that it can create a bottleneck
in memory as we are trying to read the input array in a way that jumps
around. This can cause large sections of the input array to be
removed from memory when in fact it will be needed again during the
computation of the next element of the "out" array. A
solution to this is to create a state array which will hold the
necessary previous elements of the "in" array. One
implementation of this is:
for(i=0; i<length; i++)
{
out[i] = 0;
for(j=1; i<order; j++)
{
state[j-1] = state[j];
out[i] += in[j-1] * coefficient[order - j];
}
state[order-1] = in[i];
out[i] += state[order-1] * coefficient[0];
}
This removes the bottleneck with the in array, as it is being accessed
in order, which will help with memory control. The problem with this
implementation is that we need to copy the state array at each
iteration. This can be overcome by using a circular filter where we
keep track of where we start in the state array at each iteration.
Then, when we reach the end of state in the middle of computing
"out", we wrap back to the beginning of state. This can be
implemented as:
k=0;
for(i=0; i<length; i++)
{
out[i] = 0;
for(j=1; i<order; j++)
{
out[i] += state[k] * coefficient[j];
k++;
if(k==order) k=0;
}
out[i] += in[i] * coefficient[0];
state[k] = in[i];
}
This incorporates the idea of the state array while not requiring that
we copy the entire array with each iteration. This can be improved
even further by removing the "if" statement. Conditional
statements such as this can slow down the processor because most of
the time it will need to discard the command to set k=0
,
which it will have preloaded into its queue. If we know what order is
ahead of time, we can define a function which will perform the
conditional on a binary level. This will remove the issue of
adjusting the operations at the conditional. For example if order is
a power of 2, we can take the function to be bitwise anding with
order-1. For other values of order, there are other fast computations
that can be used as replacements for the "if" statement.
home | contact us | request quotation
© Copyright 2012, VOCAL Technologies, Ltd. All rights reserved. Rev. 2.29e.
© Copyright 2012, VOCAL Technologies, Ltd. All rights reserved. Rev. 2.29e.
No hay comentarios:
Publicar un comentario