You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.6 KiB
Plaintext

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)
});
)
::