Question

Anyone has an idea for automatic phase and frequency alignment?

To explain: assume, you have an Impulse

in = Impulse.ar(Rand(2, 5), Rand(0, 1));

now I'd like to manipulate the frequency of another Impulse such that it adapts its phase and frequency to match the input. Any suggestions, even for a google search are highly appreciated.

[question asked on behalf of a colleague]

Was it helpful?

Solution

I don't agree that this, as frame is a tough problem. Impulses are simple to track - that's why, for example, old rotary dial phones used pulse trains.

Here's some code that generates an impulse at a random frequency, then resynthesises another impulse at the same frequency. It also outputs a pitch estimate.

(
var left, right, master, slave, periodestimatebus, secretfrequency;
s = Server.default;
left = Bus.new(\audio, 0,1);
right = Bus.new(\audio, 1,1);
periodestimatebus = Bus.control(s,1);
//choose our secret frequency here for later comparison:
secretfrequency = rrand(2.0,5.0);

//generate impulse with secret frequency at some arbitrary phase
master = {Impulse.ar(secretfrequency, Rand(0, 1));}.play(s, left);

slave = {
    var masterin, clockcount, clockoffset, syncedclock, periodestimate, tracking;
    masterin = In.ar(left);
    //This 1 Hz LFSaw is the "clock" against which we measure stuff
    clockcount = LFSaw.ar(1, 0, 0.5, 0.5);
    clockoffset = Latch.ar(clockcount, Delay1.ar(masterin));
    syncedclock = (clockcount - clockoffset).frac;
    //syncedclock is a version of the clock hard-reset (one sample after) every impulse trigger
    periodestimate = Latch.ar(syncedclock, masterin);
    //sanity-check our f impulse
    Out.kr(periodestimatebus, periodestimate);
    //there is no phase estimate per se - what would we measure it against? -
    //but we can resynthesise a new impulse up to a 1 sample delay from the matched clock.
    tracking = (Slope.ar(syncedclock)>0);
}.play(master, right, 0, addAction: \addAfter);

//Let's see how we performed
{
    periodestimatebus.get({|periodestimate|
        ["actual/estimated frequency", secretfrequency, periodestimate.reciprocal].postln;
    });
}.defer(1);
)

Notes to this code:

The periodestimate is generated by tricksy use of Delay1 to make sure that it samples the value of the clock just before it is reset. As such it is off by one sample.

The current implementation will produce a good period estimate with varying frequencies, down to 1Hz at least. Any lower and you'd need to change the clockcount clock to have a different frequency and tweak the arithmetic.

Many improvements are possible. For example, if you wish to track varying frequencies you might want to tweak it a little bit so that the resynthesized signal does not click too often as it underestimates the signal.

OTHER TIPS

This is a tough problem, as you are dealing with a noisy source with a low frequency. If this were a sine wave I'd recommend a FFT, but FFTs don't do very well with noisy sources and low frequencies. It's still worth a shot. FFTs can match phase too. I believe you can use pitch.ar to help find the frequency.

The Chrip-Z algorithm is something you could use instead of the FFT -http://www.embedded.com/design/configurable-systems/4006427/A-DSP-algorithm-for-frequency-analysis http://en.wikipedia.org/wiki/Bluestein%27s_FFT_algorithm

Another thing you could try is to use a neural net to try and guess it's way to the right information. You could use active training to help it achieve this goal. There is a very general discussion of this on SO: Pitch detection using neural networks

One method some folks are coming around to is simulating the neurons of Cochlea to detect pitch.

You may want to read up on Phase-locked loops: http://en.wikipedia.org/wiki/Phase-locked_loop

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top