TITLE:: FluidBufLoudness SUMMARY:: A Selection of Pitch Descriptors on a Buffer CATEGORIES:: Libraries>FluidDecomposition RELATED:: Guides/FluCoMa, Guides/FluidDecomposition, Classes/SpecCentroid, Classes/SpecFlatness, Classes/SpecCentroid, Classes/SpecPcile DESCRIPTION:: This class implements three popular pitch descriptors, computed as frequency and the confidence in its value. It is part of the Fluid Decomposition Toolkit of the FluCoMa project.FOOTNOTE:: This was made possible thanks to the FluCoMa project ( http://www.flucoma.org/ ) funded by the European Research Council ( https://erc.europa.eu/ ) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899).:: The process will return a multichannel buffer with two channels per input channel, one for pitch and one for the pitch tracking confidence. Each sample represents a value, which is every hopSize. Its sampling rate is sourceSR / hopSize. CLASSMETHODS:: METHOD:: process This is the method that calls for the pitch descriptor to be calculated on a given source buffer. ARGUMENT:: server The server on which the buffers to be processed are allocated. ARGUMENT:: source The index of the buffer to use as the source material to be pitch-tracked. The different channels of multichannel buffers will be processing sequentially. ARGUMENT:: startFrame Where in the srcBuf should the process start, in sample. ARGUMENT:: numFrames How many frames should be processed. ARGUMENT:: startChan For multichannel srcBuf, which channel should be processed first. ARGUMENT:: numChans For multichannel srcBuf, how many channel should be processed. ARGUMENT:: features The destination buffer for the pitch descriptors. ARGUMENT:: kWeighting (describe argument here) ARGUMENT:: truePeak (describe argument here) ARGUMENT:: winSize (describe argument here) ARGUMENT:: hopSize (describe argument here) ARGUMENT:: action A Function to be evaluated once the offline process has finished and all Buffer's instance variables have been updated on the client side. The function will be passed [features] as an argument. RETURNS:: Nothing, as the destination buffer is declared in the function call. EXAMPLES:: code:: // create a buffer with a short clicking sinusoidal burst (220Hz) starting at frame 8192 for 1024 frames ( b = Buffer.sendCollection(s, (Array.fill(8192,{0}) ++ (Signal.sineFill(1203,[0,0,0,0,0,1],[0,0,0,0,0,0.5pi]).takeThese({|x,i|i>1023})) ++ Array.fill(8192,{0}))); c = Buffer.new(s); ) // listen to the source and look at the buffer b.play; b.plot; d = Buffer.alloc(s,44100) // run the process with basic parameters ( Routine{ t = Main.elapsedTime; FluidBufLoudness.process(s, d, features: c); (Main.elapsedTime - t).postln; }.play ) // look at the analysis c.plot(minval:-130, maxval:6) // plot with a different range to appreciate the confidence: c.plot // The values are interleaved [pitch,confidence] in the buffer as they are on 2 channels: to get to the right frame, divide the SR of the input by the hopesize, then multiply by 2 because of the channel interleaving // here we are querying from one frame before (the signal starts at 8192, which is frame 16 (8192/512), therefore starting the query at frame 15, which is index 30. c.getn(30,10,{|x|x.postln}) // observe that the first frame is silent, as expected. The next frame's confidence is low-ish, because the window is half full (window of 1024, overlap of 512). Then a full window is analysed, with strong confidence. Then another half full window, then silence, as expected. :: STRONG::A stereo buffer example.:: CODE:: // load two very different files ( b = Buffer.read(s,File.realpath(FluidBufLoudness.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-SA-UprightPianoPedalWide.wav"); c = Buffer.read(s,File.realpath(FluidBufLoudness.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-AaS-AcousticStrums-M.wav"); ) // composite one on left one on right as test signals FluidBufCompose.process(s, c, numFrames:b.numFrames, startFrame:555000,destStartChan:1, destination:b) b.play // create a buffer as destinations c = Buffer.new(s); //run the process on them ( Routine{ t = Main.elapsedTime; FluidBufLoudness.process(s, b, features: c, winSize: 17640, hopSize:4410); (Main.elapsedTime - t).postln; }.play ) // look at the buffer: [pitch,confidence] for left then [pitch,confidence] for right c.plot(minval:-130, maxval:6) ::