Sorry about not adding code for the potential trouble section lol.
// Adapting coefficiants
int i,j;
fract32 temp;
fract32 MU = float_to_fr32(ANC_MU); // step size
static fract32 state[2][ANC_FILTER_ORDER]; // temp delay buffer
static fract32 wvector[2]; // adaptive coeffs
for(i = 0; i < ANC_SAMPLE_SIZE)
{
/* Sine coeffs */
memmove(&state[0][1], &state[0][0], sizeof(fract32) *
ANC_FILTER_ORDER-1); // shift left
state[0][0] = sample; // Add new value to beginning
for(i = 0; i < ANC_FILTER_ORDER; i++)
{
temp = mult_fr1x32x32(reference->w[i],desired);
wvector[0][i] = add_fr1x32(wvector[0][i], mult_fr1x32x32(temp,
MU));
}
/* Cosine coeffs */
memmove(&state[1][1], &state[1][0], sizeof(fract32) *
ANC_FILTER_ORDER-1); // shift left
state[1][0] = sample; // Add new value to beginning
for(i = 0; i < ANC_FILTER_ORDER; i++)
{
temp = mult_fr1x32x32(reference->w[i],desired);
wvector[1][i] = add_fr1x32(wvector[1][i], mult_fr1x32x32(temp,
MU));
}
}
I Have circular buffer implementation to achieve this but this is
essentially whats happening.
---------------------------------------
Posted through http://www.DSPRelated.com
Reply by Steve Pope●November 6, 20152015-11-06
lightbearer <110036@DSPRelated> wrote:
>However, when i start to input the signals in their full periods, my
>adaptive coefficients (fract32) starts to saturate and the filter starts
>to misbehave.
[snip]
>Here's some pseudo code as to what's going on in active mode.
>[snip]
> // Finally, Adapt coefficiants
You did not give any pseudo-code for your "adapt coefficients"
block, even though this is likely where your problem is.
I have not implemented an adaptive notch, but colleagues tell
me it is pretty routine... however, in my experience "adaptive
anything" is at least potentially far from routine...
My only advice is to perfect the algorithm first in high precision before
moving to target precisions (in your case, fract32).
Good luck
Steve
Reply by lightbearer●November 5, 20152015-11-05
I've been coding up a working MATLAB simulation on a Blackfin 533 using
the 32 bit fractional data type (fract32). I have used FIR filters to
implement convolution to get outputs from different filter stages. I'm
using look up tables created from MATLAB to simulate the algorithm
internally on the processor. The LUTs consist of secondary path filtered
white noise and a 30Hz sine wave also filtered through the same impulse
response as the white noise. I run the system identification mode for 5
seconds and switch to active mode filtering.
During development, I've been using only a fraction of the look up
tables(which doesn't contain the full period of the sine wave) which fills
a buffer of 512 bytes. This was the case for both the filtered 30Hz input
signal as well as the reference sine/cosine waves. This works as I can
verify this by plotting the signals on every iteration.
However, when i start to input the signals in their full periods, my
adaptive coefficients (fract32) starts to saturate and the filter starts
to misbehave. I've been reading up on scaling at different filter nodes
but to no avail.
Any help on this will be greatly appreciated.
Here's some pseudo code as to what's going on in active mode.
#define ANC_SAMPLE_FREQ_HZ 48000
#define ANC_SAMPLE_SIZE 512
#define ANC_FILTER_ORDER 128.
#define ANC_MU 0.00021
#define TEST_FREQ 30.0
/* temp buffers */
static fract32 references[2][ANC_SAMPLE_SIZE];
static fract32 weightedreference[2][ANC_SAMPLE_SIZE];
static fract32 filteredreference[2][ANC_SAMPLE_SIZE];
static fract32 filteredOut[ANC_SAMPLE_SIZE];
static fract32 desiredResponse[ANC_SAMPLE_SIZE];
// output buffer
static fract32 _output[ANC_SAMPLE_SIZE];
/* FIR filters that are initialized at startup before DMA fires */
static fir_state_fr32 weightFilter[2]; // Adaptive filters
static fir_state_fr32 secondaryFilter[2]; // Secondary path filtering for
reference waves
static fir_state_fr32 secondarypath; // Secondary path filtering for
the output
for(n = 0; n < ANC_SAMPLE_SIZE; n++)
{
references[0][n] = generate_SINE(TEST_FREQ); // Sin
references[1][n] = generate_COSINE(TEST_FREQ ; // Cos
}
// Weighted Sine reference
fir_fr32(references[0], weightedreference[0],
ANC_SAMPLE_SIZE,
&weightFilter[0]);
// Weighted Cosine reference
fir_fr32(references[1], weightedreference[1],
ANC_SAMPLE_SIZE,
&weightFilter[1]);
// Secondary path filtered sine reference
fir_fr32(references[0], filteredreference[0],
ANC_SAMPLE_SIZE,
&secondaryFilter[0]);
// Secondary path filtered cosine reference
fir_fr32(references[1], filteredreference[1],
ANC_SAMPLE_SIZE,
&secondaryFilter[0]);
// Compute output
for(n = 0; n < ANC_SAMPLE_SIZE; n++)
{
sData->outputvector[n] = add_fr1x32(weightedreference[0][n],
weightedreference[1][n]);
}
// Secondary path filtered controller output
fir_fr32(_output, filteredOut, ANC_SAMPLE_SIZE,
&secondarypath);
// Compute noise estimate
for(n = 0; n < ANC_SAMPLE_SIZE; n++)
{
debug = generate_debugInput(); // get filtered 30Hz input from LUT
desiredResponse[n] = sub_fr1x32(debug, filteredOut[n]);
}
// Finally, Adapt coefficiants
---------------------------------------
Posted through http://www.DSPRelated.com