Count samples between zero crossings


#1

I'm trying to make a sample counter (k-rate) that counts how many non-zero samples occured since the last zero-crossing.
What I have so far in <code.krate> is:

if (inlet_in<=0 and xflag == 1){
outlet_o = 281474976710656/counter*(1<<21);
counter=1;
xflag=0;
}
if(inlet_in>0 and xflag == 0){
outlet_o = 281474976710656/counter*(1<<21);
counter=1;
xflag=1;
}
counter++;

ultimately, I would want it to output a frequency from the wavelength. hence the division by counter*(1<<21), but that's no where near the right way to do it, apparently...
How do I correctly scale the counter value so that it outputs as a value between -64 and 64 from the object, representing the frequency?
thanks


#2

you would need s-rate for this, not k-rate.


#3

maybe the word "samples" was misleading, I mean the 3kHz k-rate values
But I believe the question remains the same in both cases...


#4

what is this? how are you calculating it?

is this not the same as

 (281474976710656/counter) << 21

which is easier to read smile
(id assume the compiler is smart enough to make it this anyway)


#5

To be honest, I have no idea what 281474976710656 is exactly, just that it represents '64' somehow... smile
script/oneliner_k with the following:
outlet_out=281474976710656/inlet_in;
is what I used in that Euclidean patterns patch, as per Johannes' suggestion, and it amounts to 64/inlet_in.


#6

Not sure what you want exactly, but I think it should be 3000/counter if you want the frequency.
The inlet should be something that detects zero-crossings.
(Then for frequency to midi or -64,64 range it would be useful to have an object : there is a MTOF function, but not yet a FTOM )


#7

errm, something seems wrong that is 64 << 42 ... where as normally we would use 64 << 21
(moral of story.. never use literals like this... always use the calculation form ( e.g. 64 << 21) so its clear what they are...
there is no efficiency gain, as compiler will optimise constant calculations anyway)


#8

Hey thetechnobear,
so then how do I use it to map to a value between, say 3000 and 2, so that I get
something between -64 and 63 coming out of a frac32 outlet?
thanks!


#9

bipolar << 21 and unipolar << 20

I always have to re-check this myself ... and here is my tip of the day smile

go check midi/in/keyb.axo in the k-rate code

outlet_note= _note<<21;
outlet_gate= _gate;
outlet_gate2= _gate2;
_gate2 = _gate;
outlet_velocity= _velo<<20;
outlet_releaseVelocity= _rvelo<<20;

easy to remember from here, since we know velocity is 0..127 and is unipolar output.

note number we know is bipolar output in axoloti... but we know its unipolar in midi... but we can see this is taken care of in the midihandler()

_note = data1-64;

so we can see here, that the k-rate handler is actually getting -64 to 67, as we would expect for a bipolar input.

I use this as example, since we all know midi really well, so its really easy to see how Axoloti maps integers into the unipolar/bipolar float representation..

so back to your Q, you just need to scale your 'result' to -64 to 64 then shift it...

the next important part, is how is frequency represented as its obviously scaled,
well if we look at osc/sine lin ... we can see it goes zero to 24kHz (due to Nyquist based on 48k)
so thats you scaling for your output. very easy because frequency is linear.

important note: I used sine lin, as its frequency... most oscillators/lfos are pitch, which has completely different scaling
and you have to be more careful when your doing pitch as this is non-linear.