Help with implementing unusual autocorrelation

Hi,

I’m interested in implementing a new(ish) pitch tracking algorithm called “Bitstream Autocorrelation”. There’s a C++ library available so I could do it as a plugin, but the algorithm is relatively simple so I’m interested in whether it could work in pure SCLang too.

I’ll try to give a brief explanation:

  1. Take an input signal and call .sign on it. This turns anything positive into a 1 and anything negative into a -1
  2. Record that signal into a buffer (the size of the buffer determines the lowest frequency that it’s possible to detect, at a cost of increased latency)
  3. Compare the .sign of the incoming signal with what’s stored in the buffer using a sliding window. Instead of a traditional autocorrelation though (which uses multiply and sum), instead we compare them with .bitXor. With this, an exact match between two square wave patterms would result in a value of all 0s for the window.
  4. Count the total 0s and 1s for each sliding window from the step above. A low value (around 0) indicates the starting point of a new period so we require some kind of thresholding in this step.
  5. The distance between these valleys give an indication of the pitch.

There’s a Python 2 implementation here and the actual algorithm is maybe 20 lines or so.

I’m still not great at writing my own synths but this is what I tried so far:

({
	var freq, hasFreq;
	~sig = SinOsc.ar(430) + SinOsc.ar(LFTri.ar(4, mul: 50, add: 440));
	~delayed = DelayN.ar(~sig, 1, 1);
	~xors = (~sig.sign).bitXor((~delayed.sign));
	
	#freq, hasFreq = Pitch.kr(~xors);
	freq.poll;
	SinOsc.ar(freq);
}.play)

My issue is that the DelayN stops working after filling up once. I think I need something else to make a continuous sliding window.

Any advice would be appreciated, even if it’s that I should write it as a plugin instead.

1 Like