I was using this code to get the moving average of a sinusoidal Realtime wave with a constant frequency. (test_ sin being a sin wave with a constant frequency). I was sampling 100 samples as it can be seen in LENGTH_X = 100 and Buffer_X[100].
static double test_sin = 0;
static double sum_x = 0 , filter_out_X = 0 ;
static int LENGTH_X = 100 , counter_filter_X = 0 ;
static double Buffer_X[100]= {0} ;
.
.
.
sum_x = sum_x + test_sin - Buffer_X\[counter_filter_X\];
filter_out_X = sum_x / LENGTH_X ;
Buffer_X\[counter_filter_X\] = (test_sin);
counter_filter_X = counter_filter_X+1 ;
if (counter_filter_X == LENGTH_X)
{
counter_filter_X = 0 ;
}
Basically i followed this reference to make the algorithm here on Youtube: efficient Moving Average Filter
The question i want to ask is how can I alter this code such that i can change the samples.
My sin wave has a variable frequency so i want to keep the LENGTH_X and BUffer_X[] variable or changing as well not just 100 samples. i already know the samples how much to keep.
Once I set Length_X =100 and Buffer_X[100]= {0} it gets stuck to 100 samples even if later i try to re initialize it,it does not re initialize as well.
I tried simple things like initializing in a different manner:
if(freq>1000)
{
static int LENGTH_X = 100 , counter_filter_X = 0 ;
static double Buffer_X[100]= {0} ;
}
else
{
static int LENGTH_X = 10 , counter_filter_X = 0 ;
static double Buffer_X[10]= {0} ;
}
The posted code for changing number of samples won't work. The variables defined inside the if-else
part will not be accessible after the if-else
.
If supported on your system you could use variable length arrays and memset
. Like:
int LENGTH_X;
int counter_filter_X = 0;
if(freq>1000)
{
LENGTH_X = 100;
}
else
{
LENGTH_X = 10;
}
double Buffer_X[LENGTH_X]; // variable length array
memset(Buffer_X, 0, LENGTH_X * sizeof Buffer_X[0]); // zero initialize
Or you can go for dynamic allocated memory. Like
int LENGTH_X;
int counter_filter_X = 0;
if(freq>1000)
{
LENGTH_X = 100;
}
else
{
LENGTH_X = 10;
}
double* Buffer_X = calloc(LENGTH_X, sizeof Buffer_X[0]); // dynamic zero-initialized memory
That said I would consider if there is a reason for changing array size at run time. If you know a maximum for LENGTH_X
just make the array that maximum size and only use the part of the array you currently want. Re-initializing can be done using memset
as shown above.
Maybe your code could look like:
#define MAX_LENGTH 1000
...
...
double test_sin = 0;
double sum_x = 0;
double filter_out_X = 0 ;
int LENGTH_X = 100;
int counter_filter_X = 0;
double Buffer_X[MAX_LENGTH]= {0} ;
while(keep_running)
{
if (change_length)
{
sum_x = 0;
counter_filter_X = 0;
if(freq>1000)
{
LENGTH_X = 100;
}
else
{
LENGTH_X = 10;
}
memset(Buffer_X, 0, LENGTH_X * sizeof Buffer_X[0]);
}
test_sin = get_sample();
sum_x = sum_x + test_sin - Buffer_X[counter_filter_X];
filter_out_X = sum_x / LENGTH_X ;
Buffer_X[counter_filter_X] = test_sin;
counter_filter_X = counter_filter_X+1 ;
if (counter_filter_X == LENGTH_X)
{
counter_filter_X = 0 ;
}
...
...
freq = ...;
change_length = ...;
}
Here you'll have add some code for updating freq
and change_length