BufAudioTransport now has A-B based Arguments

nix
Ted Moore 4 years ago
parent 6d796b6329
commit 6cd431622e

@ -4,29 +4,29 @@ FluidBufAudioTransport : FluidBufProcessor {
^\FluidBufAudioTransp ^\FluidBufAudioTransp
} }
*kr { |source1, startFrame1 = 0, numFrames1 = -1, startChan1 = 0, numChans1 = -1, source2, startFrame2 = 0, numFrames2 = -1, startChan2 = 0, numChans2 = -1, destination, interpolation = 0.0, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1, blocking = 0| *kr { |sourceA, startFrameA = 0, numFramesA = -1, startChanA = 0, numChansA = -1, sourceB, startFrameB = 0, numFramesB = -1, startChanB = 0, numChansB = -1, destination, interpolation = 0.0, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1, blocking = 0|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source1.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw}; sourceA.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw};
source2.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw}; sourceB.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw};
source1 = source1.asUGenInput; sourceA = sourceA.asUGenInput;
source2 = source2.asUGenInput; sourceB = sourceB.asUGenInput;
destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw}; destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw};
destination = destination.asUGenInput; destination = destination.asUGenInput;
^FluidProxyUgen.kr(this.objectClassName++\Trigger,-1, source1, startFrame1, numFrames1, startChan1, numChans1, source2, startFrame1, numFrames1, startChan2, numChans2, destination, interpolation, windowSize, hopSize, fftSize, maxFFTSize, trig, blocking); ^FluidProxyUgen.kr(this.objectClassName++\Trigger,-1, sourceA, startFrameA, numFramesA, startChanA, numChansA, sourceB, startFrameA, numFramesA, startChanB, numChansB, destination, interpolation, windowSize, hopSize, fftSize, maxFFTSize, trig, blocking);
} }
*process { |server, source1, startFrame1 = 0, numFrames1 = -1, startChan1 = 0, numChans1 = -1, source2, startFrame2 = 0, numFrames2 = -1, startChan2 = 0, numChans2 = -1, destination, interpolation=0.0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action| *process { |server, sourceA, startFrameA = 0, numFramesA = -1, startChanA = 0, numChansA = -1, sourceB, startFrameB = 0, numFramesB = -1, startChanB = 0, numChansB = -1, destination, interpolation=0.0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source1.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw}; sourceA.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw};
source2.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw}; sourceB.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw};
source1 = source1.asUGenInput; sourceA = sourceA.asUGenInput;
source2 = source2.asUGenInput; sourceB = sourceB.asUGenInput;
destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw}; destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw};
destination = destination.asUGenInput; destination = destination.asUGenInput;
@ -34,17 +34,17 @@ FluidBufAudioTransport : FluidBufProcessor {
^this.new( ^this.new(
server, nil, [destination] server, nil, [destination]
).processList( ).processList(
[source1, startFrame1, numFrames1, startChan1, numChans1, source2, startFrame2, numFrames2, startChan2, numChans2, destination, interpolation, windowSize, hopSize, fftSize,maxFFTSize,0], freeWhenDone, action [sourceA, startFrameA, numFramesA, startChanA, numChansA, sourceB, startFrameB, numFramesB, startChanB, numChansB, destination, interpolation, windowSize, hopSize, fftSize,maxFFTSize,0], freeWhenDone, action
) )
} }
*processBlocking { |server, source1, startFrame1 = 0, numFrames1 = -1, startChan1 = 0, numChans1 = -1, source2, startFrame2 = 0, numFrames2 = -1, startChan2 = 0, numChans2 = -1, destination, interpolation=0.0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action| *processBlocking { |server, sourceA, startFrameA = 0, numFramesA = -1, startChanA = 0, numChansA = -1, sourceB, startFrameB = 0, numFramesB = -1, startChanB = 0, numChansB = -1, destination, interpolation=0.0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source1.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw}; sourceA.isNil.if {"FluidAudioTransport: Invalid source 1 buffer".throw};
source2.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw}; sourceB.isNil.if {"FluidAudioTransport: Invalid source 2 buffer".throw};
source1 = source1.asUGenInput; sourceA = sourceA.asUGenInput;
source2 = source2.asUGenInput; sourceB = sourceB.asUGenInput;
destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw}; destination.isNil.if {"FluidAudioTransport: Invalid destination buffer".throw};
destination = destination.asUGenInput; destination = destination.asUGenInput;
@ -52,7 +52,7 @@ FluidBufAudioTransport : FluidBufProcessor {
^this.new( ^this.new(
server, nil, [destination] server, nil, [destination]
).processList( ).processList(
[source1, startFrame1, numFrames1, startChan1, numChans1, source2, startFrame2, numFrames2, startChan2, numChans2, destination, interpolation, windowSize, hopSize, fftSize,maxFFTSize,1], freeWhenDone, action [sourceA, startFrameA, numFramesA, startChanA, numChansA, sourceB, startFrameB, numFramesB, startChanB, numChansB, destination, interpolation, windowSize, hopSize, fftSize,maxFFTSize,1], freeWhenDone, action
) )
} }
} }

@ -1,77 +1,310 @@
TITLE:: FluidBufAudioTransport TITLE:: FluidBufAudioTransport
summary:: Interpolate between buffers SUMMARY:: Interpolate between buffers
categories:: Libraries>FluidCorpusManipulation CATEGORIES:: Libraries>FluidCorpusManipulation
related:: Classes/FluidAudioTransport RELATED:: Classes/FluidAudioTransport
DESCRIPTION:: DESCRIPTION::
Interpolates between the spectra of two sounds using the Optimal Transport algorithm
See
Henderson and Solomonm (2019) AUDIO TRANSPORT: A GENERALIZED PORTAMENTO VIA OPTIMAL TRANSPORT, DaFx Interpolates between the spectra of two sounds using the Optimal Transport algorithm
See Henderson and Solomonm (2019) AUDIO TRANSPORT: A GENERALIZED PORTAMENTO VIA OPTIMAL TRANSPORT, DaFx
CLASSMETHODS:: CLASSMETHODS::
METHOD:: process, processBlocking METHOD:: process, processBlocking
Process two audio link::Classes/Buffer:: Processs the source LINK::Classes/Buffer:: on the LINK::Classes/Server::. CODE::processBlocking:: will execute directly in the server command FIFO, whereas CODE::process:: will delegate to a separate worker thread. The latter is generally only worthwhile for longer-running jobs where you don't wish to tie up the server.
ARGUMENT:: server ARGUMENT:: server
The server the process runs on The LINK::Classes/Server:: on which the buffers to be processed are allocated.
ARGUMENT:: sourceA
The first source buffer
ARGUMENT:: startFrameA
offset into the first source buffer (samples)
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numFramesA
number of samples to use from first source buffer
ARGUMENT:: startChanA
starting channel of first source buffer
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numChansA
number of channels to process in first source buffer
ARGUMENT:: sourceB
the second source buffer
ARGUMENT:: startFrameB
offset into the second source buffer (samples)
ARGUMENT:: source1 STRONG::Constraints::
The first source buffer
ARGUMENT:: startFrame1 LIST::
offset into the first source buffer (samples) ##
Minimum: 0
ARGUMENT:: numFrames1 ::
number of samples to use from first source buffer
ARGUMENT:: startChan1 ARGUMENT:: numFramesB
starting channel of first source buffer
ARGUMENT:: numChans1
number of channels to process in first source buffer number of samples to process from second buffer
ARGUMENT:: source2
the second source buffer
ARGUMENT:: startFrame2 ARGUMENT:: startChanB
offset into the second source buffer (samples)
ARGUMENT:: numFrames2
number of samples to process from second buffer starting channel for second buffer
ARGUMENT:: startChan2 STRONG::Constraints::
starting channel for second buffer
LIST::
##
Minimum: 0
::
ARGUMENT:: numChansB
number of channels to process in second buffer
ARGUMENT:: numChans2
number of channels to process in second buffer
ARGUMENT:: destination ARGUMENT:: destination
buffer for interpolated audio
buffer for interpolated audio
ARGUMENT:: interpolation ARGUMENT:: interpolation
The amount to interpolate between A and B (0-1, 0 = A, 1 = B)
The amount to interpolate between A and B (0-1, 0 = A, 1 = B)
STRONG::Constraints::
LIST::
##
Minimum: 0.0
##
Maximum: 1.0
::
ARGUMENT:: windowSize ARGUMENT:: windowSize
The window size. As spectral differencing relies on spectral frames, we need to decide what precision we give it spectrally and temporally, in line with Gabor Uncertainty principles. http://www.subsurfwiki.org/wiki/Gabor_uncertainty
The window size. As spectral differencing relies on spectral frames, we need to decide what precision we give it spectrally and temporally, in line with Gabor Uncertainty principles. LINK::http://www.subsurfwiki.org/wiki/Gabor_uncertainty::
ARGUMENT:: hopSize ARGUMENT:: hopSize
The window hop size. As sinusoidal estimation relies on spectral frames, we need to move the window forward. It can be any size but low overlap will create audible artefacts. The -1 default value will default to half of windowSize (overlap of 2).
The window hop size. As sinusoidal estimation relies on spectral frames, we need to move the window forward. It can be any size but low overlap will create audible artefacts. The -1 default value will default to half of windowSize (overlap of 2).
ARGUMENT:: fftSize ARGUMENT:: fftSize
The inner 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 highest of windowSize and (bandwidth - 1) * 2.
The inner 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 highest of windowSize and (bandwidth - 1) * 2.
ARGUMENT:: freeWhenDone ARGUMENT:: freeWhenDone
Free the server instance when processing complete. Default true Free the server instance when processing complete. Default CODE::true::
ARGUMENT:: action 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 [destination] as an argument. 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 CODE::[features]:: as an argument.
RETURNS:: An instance of the processor
METHOD:: kr
Trigger the equivalent behaviour to CODE::processBlocking / process:: from a LINK::Classes/Synth::. Can be useful for expressing a sequence of buffer and data processing jobs to execute. Note that the work still executes on the server command FIFO (not the audio thread), and it is the caller's responsibility to manage the sequencing, using the CODE::done:: status of the various UGens.
ARGUMENT:: sourceA
The first source buffer
ARGUMENT:: startFrameA
offset into the first source buffer (samples)
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numFramesA
number of samples to use from first source buffer
ARGUMENT:: startChanA
starting channel of first source buffer
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numChansA
number of channels to process in first source buffer
ARGUMENT:: sourceB
the second source buffer
ARGUMENT:: startFrameB
offset into the second source buffer (samples)
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numFramesB
number of samples to process from second buffer
ARGUMENT:: startChanB
starting channel for second buffer
STRONG::Constraints::
LIST::
##
Minimum: 0
::
ARGUMENT:: numChansB
number of channels to process in second buffer
ARGUMENT:: destination
buffer for interpolated audio
ARGUMENT:: interpolation
The amount to interpolate between A and B (0-1, 0 = A, 1 = B)
STRONG::Constraints::
LIST::
##
Minimum: 0.0
##
Maximum: 1.0
::
ARGUMENT:: windowSize
The window size. As spectral differencing relies on spectral frames, we need to decide what precision we give it spectrally and temporally, in line with Gabor Uncertainty principles. LINK::http://www.subsurfwiki.org/wiki/Gabor_uncertainty::
ARGUMENT:: hopSize
The window hop size. As sinusoidal estimation relies on spectral frames, we need to move the window forward. It can be any size but low overlap will create audible artefacts. The -1 default value will default to half of windowSize (overlap of 2).
ARGUMENT:: fftSize
The inner 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 highest of windowSize and (bandwidth - 1) * 2.
ARGUMENT:: trig
A CODE::kr:: signal that will trigger execution
ARGUMENT:: blocking
Whether to execute this process directly on the server command FIFO or delegate to a worker thread. See CODE::processBlocking/process:: for caveats.
INSTANCEMETHODS:: INSTANCEMETHODS::
METHOD:: kr
Returns a UGen that reports the progress of the running task when executing in a worker thread. Calling code::scope:: with this can be used for a convinient progress monitor
private:: synth, server METHOD:: cancel
Cancels non-blocking processing
METHOD:: wait
When called in the context of a LINK::Classes/Routine:: (it won't work otherwise), will block execution until the processor has finished. This can be convinient for writing sequences of processes more linearly than using lots of nested actions.
EXAMPLES:: EXAMPLES::
code:: code::

Loading…
Cancel
Save