frac32buffer.bipolar input signal. should be dc-free, if you're not sure, put a highpass in front of it

int32 number of samples at s-rate sample rate

bool32.pulse trig

frac32.u.map tolerance for the mean value part, best set to intermediate values

spinner Maximum period allowed. Used to discard false readings

spinner Minimum period allowed. Used to discard false readings

Declaration

```
uint32_t count = 0; // sample counter
uint32_t output = 0; // output reading. The period is stored here
int64_t integral = 0; // integral of the signal starting from 0-crossing
int32_t dx = 0; // derivative at zero crossing
int64_t ramp = 0; //"tolerance" ramp
bool sign_old = 0; // sign of previous sample
bool sign = 0; // sign of current sample
int32_t in_old; // old input
```

Control Rate

```
outlet_smp = output; // output the reading
outlet_trig = 0;
```

Audio Rate

```
count++; // increase the counter by 1
sign = inlet_in > 0 ? 1 : 0; // calculate the sign of curent input
integral += inlet_in; // integrate the input
ramp += ___SMMUL(
dx, param_tol
<< 2); // integrate the ramp, using the derivative at zero crossing
// too early
bool trig = (count > attr_min) && ((ramp > 0) ? (integral < ramp ? 1 : 0)
: (integral > ramp ? 0 : 1));
// this condition serves to filter out meaningless zero crossings:
// if count<attr_min it means it's too early to provide a reading (maybe there's
// some noise in the signal) the second condition serves to test if the mean
// value of the signal is sufficiently close to 0 let's be honest: we'll never be
// so lucky to get it exactly to 0, so we'll settle at a sufficiently small value
// how small? it depends on how steep was the signal at zero crossing and on how
// happy we are with approximate readings
if (sign != sign_old) // a zero crossing has occurred
{
if (trig) // if the "condition zero" i've explained before is met, we have a
// readout!
{
output = count; // readout
count = 0; // resetting the counter
integral = 0; // resetting the integrator
ramp = 0; // resetting the ramp integrator
dx = inlet_in - in_old; // calculating a new derivative at 0x
outlet_trig = 1 << 27;
}
if (count > attr_max) // the reading is taking too long. I'll start counting
// from here without passing the readout.
{
count = 0; // resetting the counter
integral = 0; // resetting the integrator
ramp = 0; // resetting the ramp integrator
dx = inlet_in - in_old; // calculating a new derivative at 0x
}
}
sign_old = sign;
in_old = inlet_in;
```