Jitter
- API Reference jitter function, Modulation module
- fn-vis: useful for seeing output values
Jitter is the random modulation of a value. It is usually bipolar, meaning that it might shift a value upwards or downwards.
On a normalised scale of 0..1 scale, let's say we want to apply jitter of 10% to a value of 0.5. If the jitter was to be absolute, that yields a potential new value of 0.4 - 0.6. An algorithm for this is:
// repl-pad
import { clamp } from 'https://unpkg.com/ixfx/dist/bundle.js';
const jitter = (value, jitter) => {
// Double jitter in order to +- and apply random
const j = jitter * 2 * Math.random();
// Offset value, add j and clamp to 0-1
return clamp(value - jitter + j);
}
// Jitter a value of 50% by 10%
// Yields a range of 0.4-0.6
jitter(0.5, 0.1);
Another option is to jitter by a relative amount, with respect to the input value. In that case, jittering 0.5 by 10% yields a range of 0.45 - 0.55, because 10% of 0.5 is 0.05. Thus for a given jitter amount, a larger input value will jitter more wildly than a smaller value, creating a sense of instability.
ixfx provides both of these approaches with jitter
.
// repl-pad
import { jitter } from 'https://unpkg.com/ixfx/dist/modulation.js';
// Absolute jitter 0.5 by 10%
jitter({ absolute: 0.1 })(0.1); // number 0.4-0.6
// Relative jitter 0.5 by 10%
jitter({ relative: 0.1 })(0.5); // number 0.45-0.55
Remember that jitter
returns a function (which is why there's the double parenthesis in the example above). This is so the same jitter options can be reused without scattering them all over the place.
// One-time setup
const jitterFn = jitter({ absolute: 0.1 });
// Re-use the function when you like
jitterFn(100); // Jitter 100 by an absolute 10%;
jitterFn(50); // Jitter 50 by an absolute 10%
Try adjusting the value-to-jitter and jitter amount:
By default jitter
uses Math.random
, but you could just as well plug in a weighted
, or gaussian
random number generator.
import { jitter } from 'https://unpkg.com/ixfx/dist/modulation.js';
import { gaussian } from 'https://unpkg.com/ixfx/dist/random.js';
// Note we pass in as a function, so no () after gaussian
const jitterFn = jitter({ absolute:0.2, source: gaussian });
In the plot below, notice how jitter is more likely to be close to the original value, instead of being evenly distributed across the whole specified jitter range. A more organic outcome?