motion.lib

Motion library. Its official prefix is mo.

This library provides helpers for motion and orientation processing: shock detection, inclination and gravity projection, acceleration and gyroscope envelopes, orientation weighting toward the device axes, and utilities for normalized motion streams.

Usage:

mo = library("motion.lib");
process = mo.shockTrigger(50, 0.75, 75, accX);

All motion axes are expected to be normalized to [-1, 1] (e.g., gravity ~= 1 g). Functions return signals in [0, 1] unless documented otherwise. Time parameters are in milliseconds unless noted. Some helpers (e.g., projectedGravity) allow an optional dead-zone offset: low magnitudes are zeroed, and the remaining span is rescaled to preserve the 0..1 range.

Typical use-cases:

  • Map shocks to drum triggers or one-shot events.
  • Derive smooth inclination or projected-gravity controls for fades/pans.
  • Track acceleration/gyro envelopes to drive dynamics (filters, gains, FX sends).
  • Weight device orientation toward axes for spatial routing or mode selection.
  • Normalize motion streams with dead-zones to reduce jitter or false positives.

The Motion library is organized into 7 sections:

References

Shock Detection


(mo.)shockTrigger

Debounced shock trigger from an accelerometer axis.

Usage

shockTrigger(hpHz, threshold, debounceMs, sig) : _

Where:

  • hpHz: high-pass frequency (Hz) used to isolate shocks ( > 0 )
  • threshold: trigger threshold applied after high-pass (normalized g units)
  • debounceMs: time in milliseconds to hold the trigger high (>= 0)
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Output is a gate in [0, 1].

Example

mo = library("motion.lib");
process = mo.shockTrigger(50, 0.75, 75, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
shockTrigger_test = mo.shockTrigger(50, 0.5, 50, os.pulsetrain(2, 0.5));

Inclination and Gravity Projection


(mo.)inclinometer

Low-pass inclinometer for a single axis.

Usage

inclinometer(lpHz, sig) : _

Where:

  • lpHz: low-pass frequency (Hz) ( > 0 )
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Output is clamped to [0, 1] with negative values removed.

Example

mo = library("motion.lib");
process = mo.inclinometer(1.5, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
inclinometer_test = mo.inclinometer(2, os.sawtooth(1));

(mo.)inclineBalance

Balance between positive and negative inclination on the same axis.

Usage

inclineBalance(lpHz, posSig, negSig) : _

Where:

  • lpHz: low-pass frequency (Hz) ( > 0 )
  • posSig: positive-facing accelerometer axis signal (normalized, typically [-1, 1])
  • negSig: negative-facing accelerometer axis signal (normalized, typically [-1, 1])

Output maps posSig -> 1 and negSig -> 0 with smoothing and clamping.

Example

mo = library("motion.lib");
process = mo.inclineBalance(1.5, accPosX, accNegX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
inclineBalance_test =
  mo.inclineBalance(1.5, os.sawtooth(0.2) * 0.5 + 0.5, os.sawtooth(0.2) * (-0.5));

(mo.)inclineSymmetric

Symmetric gravity comparison (0->1->0) from positive and negative axes.

Usage

inclineSymmetric(lpHz, posSig, negSig) : _

Where:

  • lpHz: low-pass frequency (Hz) ( > 0 )
  • posSig: positive-facing accelerometer axis signal (normalized, typically [-1, 1])
  • negSig: negative-facing accelerometer axis signal (normalized, typically [-1, 1])

Output peaks at 1 near either pole and returns to 0 near the midpoint.

Example

mo = library("motion.lib");
process = mo.inclineSymmetric(1.5, accPosX, accNegX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
inclineSymmetric_test =
  mo.inclineSymmetric(1.5, os.triangle(0.3) * 0.5 + 0.5, os.triangle(0.3) * (-0.5));

(mo.)projectedGravity

Projects an axis onto gravity with optional dead-zone offset.

Usage

projectedGravity(lpHz, offset, sig) : _

Where:

  • lpHz: low-pass frequency (Hz) ( > 0 )
  • offset: dead-zone offset applied after projection (0..0.33). Magnitudes below offset clamp to 0, and the remaining range is rescaled to keep the output in [0, 1].
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Output is normalized to [0, 1] with an optional dead zone near 0.

Example

mo = library("motion.lib");
process = mo.projectedGravity(1.5, 0.08, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
projectedGravity_test = mo.projectedGravity(2, 0.05, os.triangle(0.1));

Envelopes Helpers


(mo.)motionEnvelope

Base thresholded AR envelope used by the accelerometer and gyroscope helpers.

Usage

motionEnvelope(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: input signal (normalized)

Signal is offset by thr, floored at 0, scaled by gain, clamped to [0, 1], then fed to an attack/release follower (an.amp_follower_ar).

Example

mo = library("motion.lib");
process = mo.motionEnvelope(0.05, 1.25, 15, 25, accX);

(mo.)envelopeAbs

Envelope on the absolute value of a signal (responds to both polarities).

Usage

envelopeAbs(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr, gain, envUpMs, envDownMs: passed to motionEnvelope
  • sig: input signal

Absolute value is taken before envelope detection.


(mo.)envelopePos

Envelope for the positive portion of a signal.

Usage

envelopePos(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr, gain, envUpMs, envDownMs: passed to motionEnvelope
  • sig: input signal

Negative values are ignored by the thresholding stage.


(mo.)envelopeNeg

Envelope for the negative portion of a signal (by flipping its polarity first).

Usage

envelopeNeg(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr, gain, envUpMs, envDownMs: passed to motionEnvelope
  • sig: input signal

The signal is negated before the shared positive-only detector.


(mo.)pita3

3D magnitude helper sqrt(x^2 + y^2 + z^2) used for total envelopes.

Usage

pita3(x, y, z) : _

Where:

  • x: first axis or signal component
  • y: second axis or signal component
  • z: third axis or signal component

(mo.)totalEnvelope

Magnitude-based envelope across three axes.

Usage

totalEnvelope(thr, gain, envUpMs, envDownMs, x, y, z) : _

Where:

  • thr: threshold passed to motionEnvelope
  • gain: gain passed to motionEnvelope
  • envUpMs: attack time in milliseconds passed to motionEnvelope
  • envDownMs: release time in milliseconds passed to motionEnvelope
  • x: normalized X-axis signal
  • y: normalized Y-axis signal
  • z: normalized Z-axis signal

The three-axis magnitude is computed with pita3 before applying motionEnvelope.

Acceleration Envelopes


(mo.)accelEnvelopeAbs

Envelope follower on the absolute value of an accelerometer axis.

Usage

accelEnvelopeAbs(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.accelEnvelopeAbs(0.1, 1.2, 10, 12, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
accelEnvelopeAbs_test =
  mo.accelEnvelopeAbs(0.1, 1.2, 10, 12, os.sawtooth(0.5));

(mo.)accelEnvelopePos

Envelope follower for positive acceleration on one axis.

Usage

accelEnvelopePos(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Negative values are ignored; output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.accelEnvelopePos(0.05, 1.35, 10, 10, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
accelEnvelopePos_test =
  mo.accelEnvelopePos(0.05, 1.35, 10, 10, os.triangle(2) * 0.8);

(mo.)accelEnvelopeNeg

Envelope follower for negative acceleration on one axis.

Usage

accelEnvelopeNeg(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: accelerometer axis signal (normalized, typically [-1, 1])

Positive values are ignored; output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.accelEnvelopeNeg(0.05, 1.35, 10, 10, accX);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
accelEnvelopeNeg_test =
  mo.accelEnvelopeNeg(0.05, 1.35, 10, 10, os.triangle(2) * (-0.8));

(mo.)totalAccel

Total acceleration magnitude with thresholding and envelope.

Usage

totalAccel(thr, gain, envUpMs, envDownMs, ax, ay, az) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • ax: accelerometer X axis (normalized, typically [-1, 1])
  • ay: accelerometer Y axis (normalized, typically [-1, 1])
  • az: accelerometer Z axis (normalized, typically [-1, 1])

Output magnitude is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.totalAccel(0.1, 1.35, 10, 10, ax, ay, az);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
totalAccel_test =
  mo.totalAccel(0.05, 1.2, 8, 12,
    os.sawtooth(0.2) * 0.2,
    os.triangle(0.15) * 0.1,
    os.sawtooth(0.12) * 0.3);

Gyroscope Envelopes


(mo.)gyroEnvelopeAbs

Envelope follower on the absolute value of a gyroscope axis.

Usage

gyroEnvelopeAbs(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: gyroscope axis signal (normalized rad/s range)

Output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.gyroEnvelopeAbs(0.01, 0.8, 50, 50, gx);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
gyroEnvelopeAbs_test =
  mo.gyroEnvelopeAbs(0.02, 0.9, 25, 30, os.sawtooth(0.5) * 0.2);

(mo.)gyroEnvelopePos

Envelope follower for positive gyroscope rotation on one axis.

Usage

gyroEnvelopePos(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: gyroscope axis signal (normalized rad/s range)

Negative values are ignored; output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.gyroEnvelopePos(0.01, 0.8, 50, 50, gx);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
gyroEnvelopePos_test =
  mo.gyroEnvelopePos(0.02, 0.9, 25, 30, os.triangle(3) * 0.8);

(mo.)gyroEnvelopeNeg

Envelope follower for negative gyroscope rotation on one axis.

Usage

gyroEnvelopeNeg(thr, gain, envUpMs, envDownMs, sig) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • sig: gyroscope axis signal (normalized rad/s range)

Positive values are ignored; output envelope is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.gyroEnvelopeNeg(0.01, 0.8, 50, 50, gx);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
gyroEnvelopeNeg_test =
  mo.gyroEnvelopeNeg(0.02, 0.9, 25, 30, os.triangle(3) * (-0.8));

(mo.)totalGyro

Total gyroscope magnitude with thresholding and envelope.

Usage

totalGyro(thr, gain, envUpMs, envDownMs, gx, gy, gz) : _

Where:

  • thr: threshold subtracted before detection (normalized)
  • gain: linear gain applied after thresholding
  • envUpMs: attack time in milliseconds (>= 0)
  • envDownMs: release time in milliseconds (>= 0)
  • gx: gyroscope X axis (normalized rad/s range)
  • gy: gyroscope Y axis (normalized rad/s range)
  • gz: gyroscope Z axis (normalized rad/s range)

Output magnitude is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.totalGyro(0.01, 0.8, 50, 50, gx, gy, gz);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
totalGyro_test =
  mo.totalGyro(0.02, 0.9, 25, 30,
    os.sawtooth(0.2) * 0.2,
    os.triangle(0.15) * 0.1,
    os.sawtooth(0.12) * 0.3);

Orientation Weighting


(mo.)orientationWeight

Weighting of a 3D vector toward a target axis with shape and smoothing.

Usage

orientationWeight(targetX, targetY, targetZ, shape, xs, ys, zs, smoothMs) : _

Where:

  • targetX: target X coordinate (-1..1)
  • targetY: target Y coordinate (-1..1)
  • targetZ: target Z coordinate (-1..1)
  • shape: scaling applied to the distance (>= 0, larger tightens the lobe)
  • xs: current X coordinate (normalized)
  • ys: current Y coordinate (normalized)
  • zs: current Z coordinate (normalized)
  • smoothMs: smoothing time in milliseconds (>= 0)

Output weight is clamped to [0, 1].

Example

mo = library("motion.lib");
process = mo.orientationWeight(0, 1, 0, 1, x, y, z, 10);

Test

mo = library("motion.lib");
orientationWeight_test =
  mo.orientationWeight(0, 1, 0, 1, 0, 1, 0, 10);

(mo.)orientation6

Weights toward the six device axes (Cour/stage left -X, Rear -Y, Jardin/stage right +X, Front +Y, Down -Z, Up +Z).

Usage

orientation6(xs, ys, zs,
             shapeCour, shapeRear, shapeJardin, shapeFront, shapeDown, shapeUp,
             smoothMs) : _

Where:

  • xs: current X coordinate (normalized)
  • ys: current Y coordinate (normalized)
  • zs: current Z coordinate (normalized)
  • shapeCour: shape for Cour (-X)
  • shapeRear: shape for Rear (-Y)
  • shapeJardin: shape for Jardin (+X)
  • shapeFront: shape for Front (+Y)
  • shapeDown: shape for Down (-Z)
  • shapeUp: shape for Up (+Z)
  • smoothMs: smoothing time in milliseconds (>= 0)

Output is six weights (Cour, Rear, Jardin, Front, Down, Up), each in [0, 1].

Example

mo = library("motion.lib");
process = mo.orientation6(x, y, z, 1, 1, 1, 1, 1, 1, 10);

Test

mo = library("motion.lib");
os = library("oscillators.lib");
orientation6_test =
  mo.orientation6(
    os.triangle(0.05),
    os.sawtooth(0.08),
    os.triangle(0.03),
    1, 1, 1, 1, 1, 1,
    10);

Utility Scaling


(mo.)scale

Normalized scaler with input dead-zone and bounded output range.

Usage

scale(ilow, ihigh, olow, ohigh) : _

Where:

  • ilow: minimum input value before scaling starts (0..1)
  • ihigh: maximum input value before clamping (must be > ilow)
  • olow: minimum output value
  • ohigh: maximum output value

Inputs below ilow clamp to olow; above ihigh clamp to ohigh.

Example

mo = library("motion.lib");
process = _ : mo.scale(0.2, 0.8, 100, 20000) : _;

Test

mo = library("motion.lib");
os = library("oscillators.lib");
scale_test = (os.sawtooth(2) * 0.5 + 0.5) : mo.scale(0.2, 0.8, 0, 1);