# Tested with human voice

Testing showed that for human voice, the frequency domain onsets and pitch tracking were more accurate and faster than the time domain, which is good to know.

Once the frequency is detected, it needs to be mapped to a scale degree. I’ve added this functionality to the Tuning Lib quark. While doing this, I could the help file was confusing and badly laid out and some of the names of flags on the quantisations were not helpful, so I fixed the helpfile, documented the new method, renamed some of the flags (the old ones still work). And then I found it wasn’t handling octaves correctly – it assumed the octave ratio is always 2, which is not true for Bohlen Pierce scales, or some scales derived by Dissonance Curve. So this was good because that bug is not fixed after a mere 8 years of lurking there. HOWEVER, the more I think about it, the less I think this belongs in Key….

Pitch detecting is flaky as hell, but onsets are solid, which is going to make the creation of melodic loops difficult, unless they actually just record the tuba and do stuff with it.

This is the code that’s working with my voice:

 (

 s.waitForBoot({ s.meter; SynthDef(\domifare_input, { arg gate=0, in=0; var input, env, fft_pitch, onset, chain, hasfreq; input = SoundIn.ar(in, 1); env = EnvGen.kr(Env.asr, gate, doneAction:2); chain = FFT(LocalBuf(2048), input); onset = Onsets.kr(chain, odftype:\phase);//odftype:\wphase); #fft_pitch, hasfreq = Pitch.kr(input); //send pitch SendTrig.kr(hasfreq, 2, fft_pitch); // send onsets SendTrig.kr(onset, 4, 1); //sin = SinOsc.ar(xings/2); //Out.ar(out, sin); // audio routing //Out.ar(out, input); }).add; k = Key(Scale.major); // A maj //k.change(6); // C maj - changing to c maj puts degree[0] to 6! b = [\Do, \Re, \Mi, \Fa, \So, \La, \Si]; (scale:k.scale, note:k.scale.degrees[0]).play; OSCdef(\domifare_in, {|msg, time, addr, recvPort| var tag, node, id, value; #tag, node, id, value = msg; case { id == 2 } { //value.postln; //c = k.freqToDegree(value.asFloat).postln; //b[c.asInt].postln; b[k.freqToDegree(value.asFloat)].postln; } { id == 4 } { "4 freq dom onset".postln; } }, '/tr', s.addr); s.sync; a = Synth(\domifare_input, [\in, 0 , \out, 3, \rmswindow, 50, \gate, 1, \thresh, 0.01]); 

}) )