From b2338ed9d9414345de1e57447decc52ad010e432 Mon Sep 17 00:00:00 2001 From: Gerard Date: Fri, 12 Jun 2020 17:57:52 +0100 Subject: [PATCH] FluidNormalize: review example --- .../HelpSource/Classes/FluidNormalize.schelp | 79 +++++++++---------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidNormalize.schelp b/release-packaging/HelpSource/Classes/FluidNormalize.schelp index 8fd2694..a28d6c2 100644 --- a/release-packaging/HelpSource/Classes/FluidNormalize.schelp +++ b/release-packaging/HelpSource/Classes/FluidNormalize.schelp @@ -68,66 +68,59 @@ s.boot; ~audiofile = File.realpath(FluidBufPitch.class.filenameSymbol).dirname +/+ "../AudioFiles/Tremblay-ASWINE-ScratchySynth-M.wav"; ~raw = FluidDataSet(s,\norm_help_raw); ~norm = FluidDataSet(s,\norm_help_normd); -~audio = Buffer.read(s,~audiofile); ~pitch_feature = Buffer.new(s); -~stats = Buffer.new(s); -~datapoint = Buffer.alloc(s,2); +~stats = Buffer.alloc(s, 7, 2); ~normalizer = FluidNormalize(s); ) -// Do a pitch analysis on the audio, which gives us pitch and pitch confidence (so a 2D datum) +// Load audio and run a pitch analysis, which gives us pitch and pitch confidence (so a 2D datum) +( +~audio = Buffer.read(s,~audiofile); +FluidBufPitch.process(s,~audio, features: ~pitch_feature); +) + // Divide the time series in to 10, and take the mean of each segment and add this as a point to // the 'raw' FluidDataSet ( -~raw.clear; -~norm.clear; -FluidBufPitch.process(s,~audio,features:~pitch_feature,action:{ - "Pitch analysis.complete. Doing stats".postln; - fork{ - var chunkLen = (~pitch_feature.numFrames / 10).asInteger; - 10.do{ |i| - s.sync; FluidBufStats.process(s,~pitch_feature,startFrame:i*chunkLen,numFrames:chunkLen,stats:~stats, action:{ - ~stats.loadToFloatArray(action:{ |statsdata| - [statsdata[0],statsdata[1]].postln; - ~datapoint.setn(0,[statsdata[0],statsdata[1]]); - s.sync; - ("Adding point" ++ i).postln; - ~raw.addPoint(i,~datapoint); - }) - }); - if(i == 9) {"Analysis done, dataset ready".postln} - } - } -}); +{ + var trig = LocalIn.kr(1, 1); + var buf = LocalBuf(2, 1); + var count = PulseCount.kr(trig) - 1; + var chunkLen = (~pitch_feature.numFrames / 10).asInteger; + var stats = FluidBufStats.kr( + source: ~pitch_feature, startFrame: count * chunkLen, + numFrames: chunkLen, stats: ~stats, trig: trig + ); + var rd = BufRd.kr(2, ~stats, DC.kr(0), 0, 1);// pick only mean pitch and confidence + var wr1 = BufWr.kr(rd[0], buf, DC.kr(0)); + var wr2 = BufWr.kr(rd[1], buf, DC.kr(1)); + var dsWr = FluidDataSetWr.kr(\norm_help_raw, buf: buf, trig: Done.kr(stats)); + LocalOut.kr( Done.kr(dsWr)); + FreeSelf.kr(count - 9); +}.play; ) -//Fit the FluidNormalizer to the raw data, and then apply the scaling out of place into -//our second FluidDataSet, so we can compare. -//Download the dataset contents into arrays for plotting + +// Normalize and load to language-side array ( -~normalizer.fit(~raw); -~normalizer.transform(~raw,~norm); ~rawarray = Array.new(10); ~normedarray= Array.new(10); -fork{ - 10.do{|i| - ~raw.getPoint(i,~datapoint,{ - ~datapoint.loadToFloatArray(action:{|a| ~rawarray.add(Array.newFrom(a))}) - }); - s.sync; - ~norm.getPoint(i,~datapoint,{ - - ~datapoint.loadToFloatArray(action:{|a| ~normedarray.add(Array.newFrom(a))}) - }); - s.sync; - if(i==9){"Data downloaded".postln}; - } -} +~normalizer.fitTransform(~raw,~norm, { + ~raw.dump{|x| 10.do{|i| + ~rawarray.add(x["data"][i.asString]) + }}; + ~norm.dump{|x| 10.do{|i| + ~normedarray.add(x["data"][i.asString]) + }}; +}); ) + //Plot side by side. Before normalization the two dimensions have radically different scales //which can be unhelpful in many cases + ( ~rawarray.flatten(1).unlace.plot("Unnormalized",Rect(0,0,400,400),minval:0,maxval:[5000,1]).plotMode=\bars; ~plot2 = ~normedarray.flatten(1).unlace.plot("Normalized",Rect(410,0,400,400)).plotMode=\bars; ) + ::