FrameCompare calculates spectral MSE distance of two fft chains


FrameCompare.kr(buffer1, buffer2, wAmount)


Given two FFT chains, this UGen calculates the MSE between the magnitudes of these two inputs and provides a continuous analytic similarity rating (lower the value, more similar the inputs). In it's current state, only hanning window should be used (wintype: 1).


buffer1 - FFT chain1

buffer2 - FFT chain2

wAmount - Influence of the weight matrix (should be between 0 and 1). Weight matrix helps to minimize errors on regions with more energy. Default: 0.5


s.boot;


(

SynthDef(\f_compare, 

{

arg nFreq1 = 220, nQ1 = 0.01, mul = 1, nFreq2 = 2000, nQ2 = 0.01, t_finTrig;

var in1 = BPF.ar(WhiteNoise.ar(mul), nFreq1, nQ1);

var in2 = BPF.ar(WhiteNoise.ar(mul), nFreq2, nQ2);

var chain1 = FFT(LocalBuf(2048), in1, wintype: 1);

var chain2 = FFT(LocalBuf(2048), in2, wintype: 1);

var fc = FrameCompare.kr(chain1, chain2, 0.5);

SendReply.kr(t_finTrig, 'fc_result', [fc]);

FreeSelf.kr(t_finTrig);

Out.ar(0, [in1, in2]);

}).memStore;


r = 

OSCresponderNode(nil, 'fc_result',

{|t, r, msg, other|

"FrameCompare result: %".format(msg[3]).postln;

});

)


r.add;

a = Synth(\f_compare);

//wait for a few seconds

a.set(\t_finTrig, 1);


a = Synth(\f_compare, [\nFreq2, 4000, \nQ2, 0.01]);

//wait for a few seconds

a.set(\t_finTrig, 1);


a = Synth(\f_compare, [\nFreq2, 220, \nQ2, 0.5]);

//wait for a few seconds

a.set(\t_finTrig, 1);


//same args for noise filters

a = Synth(\f_compare, [\nFreq2, 220, \nQ2, 0.01]);

//wait for a few seconds

a.set(\t_finTrig, 1); //most similar


r.remove;

a = nil;