Skip to content

Chaos Attractor

Tier: Algorithms | ComponentType: 20 | Params: 2

Modulation source using four strange attractors (Lorenz, Rossler, Henon, Thomas) integrated at controllable rate, outputting normalized 3D coordinates for modulation and visualization.

Overview

ChaosAttractor implements four classical strange attractor systems as modulation sources. Rather than processing audio directly, it generates three continuously evolving control signals (\(x\), \(y\), \(z\)) by numerically integrating the attractor's differential equations at a rate controlled by the Rate parameter.

The Lorenz system produces the iconic butterfly-shaped trajectory with chaotic switching between two lobes. Rossler generates a simpler spiral with periodic bursts into a third dimension. Henon is a discrete 2D map (no \(z\) output) with fractal structure. Thomas is a cyclically symmetric system with a slowly dissipating, intricately folded trajectory.

Each attractor's raw state variables occupy different numerical ranges. A per-type normalization stage maps them into the \([-1, 1]\) range for uniform use as modulation sources. A 128-point trajectory history is maintained at decimated rate for 2D visualization of the attractor's phase portrait.

In chain mode, the attractor modulates input amplitude: input * (0.5 + 0.5 * normX), giving amplitude modulation driven by chaotic dynamics.

File Locations

Path
Header Sources/FolioDSP/include/FolioDSP/Algorithms/ChaosAttractor.h
Implementation Sources/FolioDSP/src/Algorithms/ChaosAttractor.cpp
Tests Tests/FolioDSPTests/ChaosAttractorTests.swift
Bridge Sources/FolioDSPBridge/src/FolioDSPBridge.mm (ChaosAttractorBridge)

Parameters

Index Name Description Min Max Default Min Default Max Default Unit
0 Rate Integration speed 0.01 20000.0 0.1 50.0 1.0 Hz
1 Type Attractor type (0=Lorenz, 1=Rossler, 2=Henon, 3=Thomas) 0.0 3.0 0.0 3.0 0.0

Processing Algorithm

The process() function executes these steps on every call:

1. Load Parameters

Rate is loaded atomically. The integration time step is computed from rate and sample rate:

\[dt = \frac{\text{rate}_{\text{Hz}}}{f_s}\]

2. Integrate Attractor Equations

The appropriate system is stepped forward by \(dt\). Each system uses Euler integration (\(x \mathrel{+}= dx \cdot dt\)) except Henon, which is a discrete map.

Lorenz (\(\sigma = 10\), \(\rho = 28\), \(\beta = 8/3\)):

\[\frac{dx}{dt} = \sigma(y - x)\]
\[\frac{dy}{dt} = x(\rho - z) - y\]
\[\frac{dz}{dt} = xy - \beta z\]

Rossler (\(a = 0.2\), \(b = 0.2\), \(c = 5.7\)):

\[\frac{dx}{dt} = -(y + z)\]
\[\frac{dy}{dt} = x + ay\]
\[\frac{dz}{dt} = b + z(x - c)\]

Henon (\(a = 1.4\), \(b = 0.3\)) -- discrete map, no \(dt\):

\[x_{n+1} = 1 - a \cdot x_n^2 + y_n\]
\[y_{n+1} = b \cdot x_n\]

Thomas (\(b \approx 0.208186\)):

\[\frac{dx}{dt} = \sin(y) - bx\]
\[\frac{dy}{dt} = \sin(z) - by\]
\[\frac{dz}{dt} = \sin(x) - bz\]

3. Safety Clamp

Raw state variables are clamped to prevent divergence to infinity:

\[x, y, z \in [-100, 100] \quad \text{(Lorenz, Rossler, Thomas)}\]
\[x, y \in [-10, 10] \quad \text{(Henon)}\]

4. Normalization

Each attractor type has different characteristic ranges. The raw values are divided by per-type scale factors and clamped to \([-1, 1]\):

Type \(x\) scale \(y\) scale \(z\) mapping
Lorenz 20 25 \((z - 25) / 25\)
Rossler 12 10 \((z - 12.5) / 12.5\)
Henon 1.3 0.4 \(z = 0\) (2D)
Thomas 5 5 \(z / 5\)
\[x_{\text{norm}} = \text{clamp}\!\left(\frac{x_{\text{raw}}}{\text{scale}_x},\ -1,\ 1\right)\]

5. Trajectory History

A 128-point ring buffer records the normalized \((x, y, z)\) triple every 64 samples for phase portrait visualization.

6. Snapshot Emission

At display rate (~60 fps), a snapshot containing normalized coordinates, attractor type, rate, and the full 128-point trajectory history is written to the snapshot slot.

Core Equations

Lorenz:

\[\dot{x} = \sigma(y - x), \quad \dot{y} = x(\rho - z) - y, \quad \dot{z} = xy - \beta z\]

Rossler:

\[\dot{x} = -(y + z), \quad \dot{y} = x + ay, \quad \dot{z} = b + z(x - c)\]

Henon:

\[x_{n+1} = 1 - ax_n^2 + y_n, \quad y_{n+1} = bx_n\]

Thomas:

\[\dot{x} = \sin(y) - bx, \quad \dot{y} = \sin(z) - by, \quad \dot{z} = \sin(x) - bz\]

Snapshot Fields

Field Type Range Unit Description
X Float -1 to 1 Normalized x coordinate
Y Float -1 to 1 Normalized y coordinate
Z Float -1 to 1 Normalized z coordinate
Type Uint8 0--3 Current attractor type
Rate Float 0.01--20000 Hz Current integration rate

Implementation Notes

  • No process(float) signature -- ChaosAttractor is a modulation source with a void process() method. The normalized \(x\), \(y\), \(z\) values are accessed via getter methods.
  • Double precision for raw state variables (rawX_, rawY_, rawZ_) to maintain numerical stability during integration over long periods.
  • Euler integration is used for all continuous systems. This is adequate because the integration rate is typically much higher than the attractor's characteristic frequencies, and the safety clamp prevents runaway.
  • Type change resets state -- calling setType() resets the attractor to its initial conditions near the attractor basin, ensuring it converges to the characteristic trajectory.
  • Trajectory history uses a separate decimation counter (historyInterval_ = 64) independent of snapshot rate, providing consistent visualization density regardless of display rate.
  • All parameters use std::atomic<float> for lock-free thread safety.
  • Snapshot emission is decimated to ~60 fps (every 735 samples at 44.1 kHz).

Equation Summary

dx = sigma(y-x); dy = x(rho-z)-y; dz = xy-beta*z