Signal Averaging P5JS

So I was writing the signal averaging code on a random generated data.

Steps I did -

  1. Generating a signal to simulated Real time data
  2. Signal = random data (-10,10) + periodic data (50,100 ) after every 100 tx
  3. Taking sample of 100 points and averaging with live data

What I think I am doing incorrectly is -

  1. Averaging sample incorrectly

Can you please look into the code?

Here is the live version - https://editor.p5js.org/black/sketches/CKhVPepqn

let signal = [];
let prev = [];
let curr = [];
let sum = [];
let counter = 0;
let tx = 0;
let sampleSize = 200;

function setup() {
  createCanvas(400, 400);
  for(let i=0;i<sampleSize;i++){
    prev.push(0);
  }
}

function draw() {
  background(220);

  translate(0,height);
  scale(1,-1);
  
  // signal
  if (signal.length < 400) signal.push(random(-10, 10)+(tx<100?random(50,100):0));
  else signal.shift();
  
  if(tx<100)tx++;
  else tx =0;

  // signal plot
  stroke(0);
  noFill();
  beginShape();
  for (let i = 0; i < signal.length; i++) {
    vertex(i, signal[i]);
  }
  endShape();
  
  prev[counter]=(prev[counter]+signal[counter])/2;
   
  if(counter<sampleSize)counter++;
  else counter=0;
  
  stroke(255,0,0);
  beginShape();
  for(let i=0;i<prev.length;i++){
      vertex(i, prev[i]+200);
  } 
  endShape();
}

Were you able to resolve this?

As there are many ways to do averaging, and many potential results, what I’m not understanding is what you mean by “incorrectly”: What is your code currently doing, and what do you want it to be doing instead? How do you know it is wrong, and how will you know when it is working?

1 Like

Hey jeremydouglass thank for responding…

Let me explain you what I think I am doing incorrectly -

let say you have arrays of same size … a1=[ …], a2=[ …], a3=[ …], a4=[ …], a5=[ …] … aN=[ …]

this is correct
Aavg = [] = (a1+a2+a3+a4+a5…aN)/N = ( [a1x1+a2x1+a3x1…], [aNx1, a1x2+a2x2+a3x2+…aNx2 ], … );
but for this you need to know all arrays beforehand …

To do real time signal averaging which I am doing is -
((a1+a2)/2+a3)/2 …and so on…

why? because in real time you don’t know next sample so you have to average current and pevious sample… then average it with next sample…

And this is what I think I am doing wrong.

One approach: You’ll still need a window of samples, a0 to aN. It is just a rolling window. The bigger the window, the smoother the result. A window size of 2 is really jumpy. A window size of 100 might be too smooth.

If you want to use the previous average value as a smoothing effect on the output, do that in output only, then throw it away – do not roll it into the next average calculation, just use the window.

let avg = myavg(signalBuffer); // don't use prevavg in this calc
let smoothamt = 0.2
let smoothavg = lerp(avg, prevavg, smoothamt);
// ... display with smoothavg
prevavg = avg; // save for next loop

Now avg is a real value on real data. If you compound avg it becomes an artifact.

1 Like