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
4.3 KiB
Plaintext
110 lines
4.3 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:: padding
|
|
Controls the zero-padding added to either end of the source buffer or segment. Possible values are 0 (no padding), 1 (default, half the window size), or 2 (window size - hop size). Padding ensures that all input samples are completely analysed: with no padding, the first analysis window starts at time 0, and the samples at either end will be tapered by the STFT windowing function. Mode 1 has the effect of centering the first sample in the analysis window and ensuring that the very start and end of the segment are accounted for in the analysis. Mode 2 can be useful when the overlap factor (window size / hop size) is greater than 2, to ensure that the input samples at either end of the segment are covered by the same number of analysis frames as the rest of the analysed material.
|
|
|
|
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;
|
|
}
|
|
)
|
|
|
|
{ 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)
|
|
});
|
|
)
|
|
::
|