|
|
TITLE:: FluidAmpSlice
|
|
|
SUMMARY:: Amplitude-based Detrending Slicer
|
|
|
CATEGORIES:: Libraries>FluidDecomposition
|
|
|
RELATED:: Guides/FluCoMa, Guides/FluidDecomposition
|
|
|
|
|
|
DESCRIPTION::
|
|
|
This class implements an amplitude-based slicer, with various customisable options and conditions to detect relative amplitude changes as onsets. It is part of the LINK:: Guides/FluidDecomposition:: of LINK:: Guides/FluCoMa::. For more explanations, learning material, and discussions on its musicianly uses, visit http://www.flucoma.org/
|
|
|
|
|
|
FluidAmpSlice is based on two envelop followers on a highpassed version of the signal: one slow that gives the trend, and one fast. Each have features that will interact. The example code below is unfolding the various possibilites in order of complexity.
|
|
|
|
|
|
The process will return an audio steam with sample-long impulses at estimated starting points of the different slices.
|
|
|
|
|
|
CLASSMETHODS::
|
|
|
|
|
|
METHOD:: ar
|
|
|
The audio rate version of the object.
|
|
|
|
|
|
ARGUMENT:: in
|
|
|
The audio to be processed.
|
|
|
|
|
|
ARGUMENT:: fastRampUp
|
|
|
The number of samples the fast envelope follower will take to reach the next value when raising. Typically, this will be faster than slowRampUp.
|
|
|
|
|
|
ARGUMENT:: fastRampDown
|
|
|
The number of samples the fast envelope follower will take to reach the next value when falling. Typically, this will be faster than slowRampDown.
|
|
|
|
|
|
ARGUMENT:: slowRampUp
|
|
|
The number of samples the absolute envelope follower will take to reach the next value when raising.
|
|
|
|
|
|
ARGUMENT:: slowRampDown
|
|
|
The number of samples the absolute envelope follower will take to reach the next value when falling.
|
|
|
|
|
|
ARGUMENT:: onThreshold
|
|
|
The threshold in dB of the relative envelope follower to trigger an onset, aka to go ON when in OFF state. It is computed on the difference between the two envelope followers.
|
|
|
|
|
|
ARGUMENT:: offThreshold
|
|
|
The threshold in dB of the relative envelope follower to reset, aka to allow the differential envelop to trigger again.
|
|
|
|
|
|
ARGUMENT:: floor
|
|
|
The level in dB the slowRamp needs to be above to consider a detected difference valid, allowing to ignore the slices in the noise floor.
|
|
|
|
|
|
ARGUMENT:: minSliceLength
|
|
|
The length in samples that the Slice will stay ON. Changes of states during that period will be ignored.
|
|
|
|
|
|
ARGUMENT:: highPassFreq
|
|
|
The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. A frequency of 0 bypasses the filter.
|
|
|
|
|
|
RETURNS::
|
|
|
An audio stream with square envelopes around the slices. The latency between the input and the output is dependant on the relation between the two envelope followers.
|
|
|
|
|
|
EXAMPLES::
|
|
|
|
|
|
code::
|
|
|
// detrending explained
|
|
|
// Our source here is a sinewave that does not go to silence and has sharp-ish amplitude bumps as onsets we try to track
|
|
|
(
|
|
|
{var env, source = SinOsc.ar(320,0,LFSaw.ar(20, 0, -0.4, 0.6));
|
|
|
env = FluidAmpSlice.ar(source,fastRampUp: 5,fastRampDown: 50,slowRampUp: 220,slowRampDown: 220, onThreshold: 10, offThreshold: 10,floor: -60);
|
|
|
[source, env]
|
|
|
}.plot(0.08);
|
|
|
)
|
|
|
//beware of double trigger at the begining of the 2nd cycle above). A solution: Schmidth triggers
|
|
|
(
|
|
|
{var env, source = SinOsc.ar(320,0,LFSaw.ar(20, 0, -0.4, 0.6));
|
|
|
env = FluidAmpSlice.ar(source,fastRampUp: 5,fastRampDown: 50,slowRampUp: 220,slowRampDown: 220, onThreshold: 10, offThreshold: 7,floor: -60);
|
|
|
[source, env]
|
|
|
}.plot(0.08);
|
|
|
)
|
|
|
// another solution: minslicelength
|
|
|
(
|
|
|
{var env, source = SinOsc.ar(320,0,LFSaw.ar(20, 0, -0.4, 0.6));
|
|
|
env = FluidAmpSlice.ar(source,fastRampUp: 5,fastRampDown: 50,slowRampUp: 220,slowRampDown: 220, onThreshold: 10, offThreshold: 7,floor: -60, minSliceLength: 220);
|
|
|
[source, env]
|
|
|
}.plot(0.08);
|
|
|
)
|
|
|
//quick drum onsets
|
|
|
//load a buffer
|
|
|
b = Buffer.read(s,File.realpath(FluidAmpSlice.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Nicol-LoopE-M.wav");
|
|
|
(
|
|
|
{var env, source = PlayBuf.ar(1,b);
|
|
|
env = FluidAmpSlice.ar(source,fastRampUp: 10,fastRampDown: 2205,slowRampUp: 4410,slowRampDown: 4410,onThreshold: 10,offThreshold: 5,floor: -40,minSliceLength: 4410,highPassFreq: 20);
|
|
|
[source, env]
|
|
|
}.play;
|
|
|
)
|
|
|
::
|