Zero crossings from a 1D signal I'm trying to get the peaks/zero crossings from a basic 1D signal and am not sure if my naive/basic approach is correct:

float[] signal = {168.02423,167.11852,167.50813,166.8597,166.05814,165.11226,164.18024,162.52278,159.26706,154.01059,151.02512,145.88942,139.96555,131.64963,128.41841,125.55873,123.26397,121.80526,120.997765,120.13878,120.15161,120.45633,121.23436,120.788994,120.17174,119.775856,119.009384,117.477,115.0316,108.588875,100.850945,88.417404,82.39221,74.47572,68.39083,60.352554,57.09356,54.930645,54.195927,53.56418,53.094868,53.119434,53.129646,53.692352,53.817867,54.48929,55.07399,56.200096,56.464325,56.61977,56.26392,55.87918,55.708,56.005222,56.370075,57.943306,60.338276,66.09525,71.971245,83.3894,93.25841,106.6345,111.20811,114.71198,117.44606,120.572174,122.55059,125.76803,130.27737,136.78697,139.3824,141.46649,143.04817,146.876,153.58531,163.69055,167.01625,169.79066,171.79346,172.96455,174.65863,174.15462,169.83751,160.82489,157.3805,154.58945,152.88863,151.37778,149.86177,148.10445,146.99503,143.16574,136.07457,123.7554,116.98741,107.79893,101.15501,92.90702,89.435356,86.62778,84.60331,82.44227,81.345985,80.086426,78.7316,75.1582,70.30843,62.90986,60.226223,57.940796,56.880646,55.95489,55.675377,55.12072,54.582558,53.560856,53.353596,53.047993,52.981926,52.87674,53.188942,53.541054,53.332302,52.96336,52.367634,53.034874,54.12153,54.88389,57.317207,60.54665,66.118195,70.391785,77.9589,84.03312,93.41969,99.085686,105.99711,109.171776,112.26317,114.13363,116.024254,117.41363,118.9697,120.61764,121.154816,121.67257,121.55961,121.32448,120.59877,120.989365,121.22733,121.907104,122.72483,123.732155,124.994804,126.84889,129.00806,134.3398,141.73413,152.50774,156.32497,159.0031,160.628,161.92178,163.19771,164.65904,166.22505,167.14778,167.68938,168.30038,168.64857,169.15517,168.63728,168.94241};
int sl = signal.length;

void setup(){
  size(400,400);
  noFill();
  smooth();

  float[] sorted = new float[sl];
  arrayCopy(signal,sorted);
  Arrays.sort(sorted);
  float min = sorted[0];
  float max = sorted[sl-1];

  background(255);
  boolean wasPlus = true,isPlus = false;
  for(int i = 0 ; i &lt; sl; i++){
    //plotting
    float x = map(i,0,sl,1,width-1);
    float y = map(signal[i],min,max,height,0);
    stroke(0);
    line(x,height,x,y);
    //zerox
    float c = signal[i];//current
    float p = signal[i &lt; 1 ? sl-1 : i-1];//previous
    isPlus = (c-p) &gt; 0;
    if(isPlus != wasPlus) {
      stroke(192,0,0);
      ellipse(x,y,5,5);
      wasPlus = isPlus;
    }
  }
}


Results:



It looks like I'm close, but I was hoping I can get one circle at a peak, not several. Any hints/tips?
Well, fine for good signals. Good signals means low noise level, absense of features like very slow volume change rates, etc.
Otherwise, you need things like FIR filter(s) to average and diffifentiate signal and use an interpolation to increase precision of the detection.