TITLE:: FluidBufSTFT summary:: Perform a Short-Time Fourier Transform on one channel of a buffer categories:: FluidCorpusManipulation related:: Classes/Buffer DESCRIPTION:: Performs either a forward or inverse Short-Time Fourier Transform (STFT) on a single channel source buffer~. In the forward case, resulting magnitudes and phases can be written to output buffers. In the inverse case, these buffers can be used to reconstruct the original source into a new buffer. The magntude and phase buffers are laid out as (number of hops, number of bins). The number of hops is a function of the source length and the hop size. The number of bins is (1 + (fft size / 2)). The object is restricted to analysing a single source channel, because the channel counts of the magntude and phase buffers would quickly get out of hand otherwise. 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 use for the forward STFT ARGUMENT:: startFrame The starting point for analysis in the source (in samples) ARGUMENT:: numFrames The duration (in samples) to analyse ARGUMENT:: startChan The channel to analyse ARGUMENT:: magnitude The link::Classes/Buffer:: to write magnitudes to in the forward case, or read from in the inverse case. This is optional for the forward transform, mandatory for the inverse. ARGUMENT:: phase The link::Classes/Buffer:: to write phases to in the forward case, or read from in the inverse case. This is optional for the forward transform, mandatory for the inverse. ARGUMENT:: resynthesis The link::Classes/Buffer:: to write re-synthesised data to in the inverse case. Ignored for the forward transform. Mandatory in the inverse case. ARGUMENT:: inverse When set to 1, an inverse STFT is performed, and the resynthesised data is written to the resynthesis buffer using overlap-add. ARGUMENT:: windowSize The number of source samples that are analysed at once. ARGUMENT:: hopSize How many samples there are in-between analysis windows. The -1 default value will default to half of windowSize (overlap of 2). ARGUMENT:: fftSize The FFT/IFFT size. It should be at least 4 samples long, at least the size of the window, and a power of 2. Making it larger allows an oversampling of the spectral precision. The -1 default value will use the next power of 2 equal or above the windowSize. For this object it is effectively capped at 65536. ARGUMENT:: freeWhenDone Free the server instance when processing complete. Default true ARGUMENT:: action Runs when processing is complete INSTANCEMETHODS:: EXAMPLES:: code:: s.reboot ( b = Buffer.read(s,File.realpath(FluidBufSTFT.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Nicol-LoopE-M.wav"); m = Buffer.new; p = Buffer.new; r = Buffer.new; ) ( fork{ FluidBufSTFT.process(s,source:b,magnitude:m,phase:p).wait; FluidBufSTFT.process(s,magnitude:m,phase:p,resynthesis:r,inverse:1).wait; "Done".postln; } ) FluidBufSTFT.process(s,source:b,magnitude:m,phase:p) m.getn(4444,10,{|x|x.postln;}) { PlayBuf.ar(1,r); }.play //nullsum { PlayBuf.ar(1,r) - PlayBuf(1,b); }.play //draw the magnitudes as a greyscale spectrogram // make the image i = Image.new(m.numFrames, m.numChannels) //retreive the image and assign to pixels ( m.loadToFloatArray(action: {|x| var mod = m.numChannels; { x.do{ |val, index| i.setColor(Color.gray(val), index.div(mod), mod - 1 - index.mod(mod)); }; i.plot("spectrogram", showInfo: false); }.fork(AppClock) }); ) ::