diff --git a/release-packaging/HelpSource/Classes/FluidMFCC.schelp b/release-packaging/HelpSource/Classes/FluidMFCC.schelp index 8bedc57..0f877ee 100644 --- a/release-packaging/HelpSource/Classes/FluidMFCC.schelp +++ b/release-packaging/HelpSource/Classes/FluidMFCC.schelp @@ -50,24 +50,27 @@ RETURNS:: EXAMPLES:: code:: -//create a monitoring bus for the descriptors -b = Bus.new(\control,0,13); - //create a monitoring window for the values ( +b = Bus.new(\control,0,13); w = Window("MFCCs Monitor", Rect(10, 10, 420, 320)).front; a = MultiSliderView(w,Rect(10, 10, 400, 300)).elasticMode_(1).isFilled_(1); +a.reference_(Array.fill(13,{0.5})); //make a center line to show 0 ) //run the window updating routine. ( + +~winRange = 500; + r = Routine { { b.get({ arg val; { if(w.isClosed.not) { - a.value = val; + //val.postln; + a.value = val.linlin(~winRange.neg,~winRange,0,1); } }.defer }); @@ -78,8 +81,8 @@ r = Routine { //play a simple sound to observe the values ( -x = {arg type = 0; - var source = Select.ar(type,[SinOsc.ar(220),Saw.ar(220),Pulse.ar(220)]) * LFTri.kr(0.1).exprange(0.01,0.1); +x = {arg type = 0; + var source = Select.ar(type,[SinOsc.ar(220),Saw.ar(220),Pulse.ar(220)]) * LFTri.kr(0.1).exprange(0.01,0.1); Out.kr(b,FluidMFCC.kr(source,maxNumCoeffs:13)); source.dup; }.play; @@ -87,19 +90,20 @@ x = {arg type = 0; // change the wave types, observe the amplitude invariance of the descriptors, apart from the leftmost coefficient x.set(\type, 1) +~winRange = 100; //adjust the range above and below 0 to zoom in or out on the MFCC x.set(\type, 2) x.set(\type, 0) // free this source x.free // load a more exciting one -c = Buffer.read(s,File.realpath(FluidMelBands.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-AaS-SynthTwoVoices-M.wav"); +c = Buffer.read(s,File.realpath(FluidMFCC.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-AaS-SynthTwoVoices-M.wav"); // analyse with parameters to be changed ( -x = {arg bands = 40, low = 20, high = 20000; +x = {arg bands = 40, low = 20, high = 20000; var source = PlayBuf.ar(1,c,loop:1); - Out.kr(b,FluidMelBands.kr(source, bands, low, high, 40) / 10); + Out.kr(b,FluidMFCC.kr(source, 13, bands, low, high, 13) / 10); source.dup; }.play; ) @@ -111,7 +115,7 @@ x.set(\bands,20) x.set(\bands,40) // focus all the bands on a mid range -x.set(\low,320, \high, 8000) +x.set(\low,320, \high, 800) // focusing on the low end shows the fft resolution issue. One could restart the analysis with a larger fft to show more precision x.set(\low,20, \high, 160) @@ -126,5 +130,153 @@ x.free;b.free;c.free;r.stop; STRONG::A musical example:: CODE:: -// todo: port the Max one +//program that freezes mfcc spectra, then looks for matches between two frozen spectra +( +SynthDef("MFCCJamz", {arg freq=220, source = 0, buffer, mfccBus, distBus, t_freeze0=0, t_freeze1=0, onsetsOn0=0, onsetsOn1=0; + var sound, mfcc, mfccFreeze0, mfccFreeze1, dist0, dist1, closest, slice; + + sound = SelectX.ar(source, [ + SinOsc.ar(freq, 0, 0.1), + LFTri.ar(freq, 0, 0.1), + LFSaw.ar(freq, 0, 0.1), + Pulse.ar(freq, 0.5, 0.1), + WhiteNoise.ar(0.1), + PinkNoise.ar(0.1), + PlayBuf.ar(1, buffer, 1, loop:1) + ]); + + slice = FluidOnsetSlice.ar(sound); //onset detection for mfcc freeze on onset + + mfcc = FluidMFCC.kr(sound,maxNumCoeffs:13); + mfccFreeze0 = Latch.kr(mfcc, t_freeze0+(slice*onsetsOn0)); + mfccFreeze1 = Latch.kr(mfcc, t_freeze1+(slice*onsetsOn1)); + + Out.kr(mfccBus,mfcc.addAll(mfccFreeze0).addAll(mfccFreeze1)); + + //distance calculations + + dist0 = Mix((mfcc.copyRange(1,12) - mfccFreeze0.copyRange(1,12)).squared).sqrt; + dist1 = Mix((mfcc.copyRange(1,12) - mfccFreeze1.copyRange(1,12)).squared).sqrt; + + Out.kr(distBus, [dist0, dist1]); + + //sends a trigger when the item with a closer euclidean distance changes + SendTrig.kr(Trig1.kr(dist1-dist0, 0.001)+Trig1.kr(dist0-dist1, 0.001), 0, dist1