TITLE:: FluidBufFlatten summary:: Flatten a multichannel buffer on the server categories:: Libraries>FluidCorpusManipulation related:: Classes/Buffer, Classes/FluidBufCompose, Classes/FluidBufSelect, Classes/FluidBufSelectEvery DESCRIPTION:: Flatten a multichannel link::Classes/Buffer:: to a single channel. This can be useful for constructing n-dimensional data points for use with link::Classes/FluidDataSet:: The code::axis:: determines how the flattening is arranged. The default value, 1, flattens channel-wise, such that (if we imagine channels are rows, time positions are columns): table:: ## a 1 || a 2 || a 3 ## b 1 || b 2 || b 3 ## c 1 || c 2 || c 3 :: becomes table:: ## a 1 || b 1 || c 1 || a 2 || b 2 || c 2 || a 3 || b 3 || c 3 :: whereas with code::axis = 0:: we get table:: ## a 1 || a 2 || a 3 || b 1 || b 2 || b 3 || c 1 || c 2 || c 3 :: CLASSMETHODS:: private::new1 METHOD:: process, processBlocking Run the process on the given sever, and perfrom code::action:: when done ARGUMENT:: server The link::Classes/Server:: on which to run ARGUMENT:: source The link::Classes/Buffer:: to flatten ARGUMENT:: startFrame Where in the source should the flattening process start, in samples. ARGUMENT:: numFrames How many frames should be processed. ARGUMENT:: startChan For multichannel source buffers, which channel to start processing at. ARGUMENT:: numChans For multichannel source buffers, how many channels should be processed. ARGUMENT:: destination The link::Classes/Buffer:: to write the flattened data to ARGUMENT:: axis Whether to group points channel-wise or frame-wise ARGUMENT:: freeWhenDone Free the server instance when processing complete. Default true ARGUMENT:: action Runs when processing is complete EXAMPLES:: code:: //FluidBufPitch is useful to illustrate the effect of this, because the pitch and confidence values are easily distinguishable ( ~path = FluidFilesPath(); ~randomsoundfile = SoundFile.collect(~path +/+ '*').choose; b = Buffer.read(s,~randomsoundfile.path,action:{"Sound Loaded".postln}); ~pitchdata = Buffer.new; ~flatdata = Buffer.new; ) //Pitch analysis, writes pitches as frequencies to chan 0, confidences [0-1] to chan 1 FluidBufPitch.process(s,b,numFrames:512 * 10,numChans:1,features:~pitchdata,action:{"Pitch Analysis Done".postln}); // Flatten and print the flat buffer. We expect to see larger numbers (20-2000) interleaved with smaller (0-1) ( FluidBufFlatten.process(s,~pitchdata, destination: ~flatdata, axis:1, action:{ ~flatdata.loadToFloatArray(action:{ |a| a.postln; }) }) ) //changing the axis, we see all large numbers first ( FluidBufFlatten.process(s,~pitchdata, destination:~flatdata, axis:0, action:{ ~flatdata.loadToFloatArray(action:{ |a| a.postln; }) }) ) //adding the source range make this processor very powerful, but can be quite confusing //here we take only one frame starting at the second one (0-counting) ( FluidBufFlatten.process(s,~pitchdata,startFrame: 1,numFrames: 1, destination:~flatdata, action:{ ~flatdata.loadToFloatArray(action:{ |a| a.postln; }) }) ) //and here we take only the confidences ( FluidBufFlatten.process(s,~pitchdata, startChan: 1, destination:~flatdata, action:{ ~flatdata.loadToFloatArray(action:{ |a| a.postln; }) }) ) ::