Back to projects
Chladni logo

Chladni

Real-time visualizer of vibration patterns generated by acoustic frequencies.

WebAudio API Canvas Physics

I have designed this system to explore the visual representation of acoustic frequencies in real time. The motivation behind this development is to provide a high-performance, zero-perceptible-latency environment where the mathematical theory of Chladni patterns can be rendered directly in the browser, democratizing access to research and audio-visual contemplation tools.

Utility and Operating Flow

This engine solves the problem of abstract sound visualization. Typically, understanding how frequencies interact in a physical medium requires metal plates and high-fidelity transducers. I have digitized and optimized this phenomenon, offering an infinite mathematical surface.

For the user, the system presents a minimalist workflow:

  1. Signal Capture or Generation: The user can inject audio from a physical microphone (evaluating their acoustic environment) or use the internal “Sound Check,” which generates pure tones of specific frequencies (e.g., 432Hz, 528Hz) and colored noise buffers (White, Pink, Brown).
  2. Spectral Analysis: The internal engine fragments the captured audio signal into low and high-frequency bands.
  3. Mathematical Translation: The intensities of the low and high frequencies are mapped in real time to the variables m and n of the Chladni wave equation.
  4. Visual Representation: Tens of thousands of particles react stochastically to the equation values on an infinite on-screen canvas. The zones of lower amplitude attract particles (nodes), while the zones of higher amplitude repel them (antinodes), drawing the characteristic geometric pattern of standing waves.

The value of this tool is split into two facets: an analytical one, as a visual sound study tool for engineers and designers; and a contemplative one, acting as a frequency visualizer for meditation under an aesthetic approach inspired by modern music players.

Deep Architectural Analysis

At the engineering level, I have opted for an architecture that prioritizes performance in the paint cycle and a clear separation of responsibilities, completely avoiding the overhead of heavy reactive frameworks (like React or Vue).

Structural Patterns

The project follows a modular approach similar to a simplified “Ports and Adapters Architecture.” The business rules (particle physics, FFT analysis) are isolated from the user interface. Astro is used primarily as a static site generator and router, providing a lightweight base. All client-side interactivity is delegated to native Web Components or directly injected scripts, supported by an external atomic state management.

graph TD;
    subgraph UI Layer
        A[ControlBar Component]
        B[Welcome/Canvas View]
    end

    subgraph State Management
        C[nanostores]
        C1(audioMode)
        C2(simulation parameters m/n)
        C3(appearance)
    end

    subgraph Domain logic
        D[AudioEngine]
        E[ChladniEngine]
    end

    A <-->|Subscribe/Publish| C
    B <-->|Subscribe/Publish| C

    D -->|FFT Analysis updates m/n| C
    C -->|m/n & params sync| E

    E -->|Render Frame| F[HTML5 Canvas]

Data Modeling and Engine Logic

I have divided the heavy logic into two main entities running on the client:

  1. AudioEngine: Responsible for the Web Audio Context (AudioContext). It manages the lifecycle of oscillators (OscillatorNode), gain nodes, and Fast Fourier Transform analysis (AnalyserNode). I have optimized this module by pre-calculating the static indices for the frequency bands (Low: ~100-600Hz, High: ~600-3000Hz) in its initialization phase. During the update cycle (getAnalysis()), it extracts the average energy of these bands, and through linear interpolation (Lerp), it smooths the transitions of the variables m and n, ensuring a fluid mutation of the visuals during sudden noise changes. Additionally, it caches the generated noise buffers to mitigate expensive recalculations and excessive memory usage.

  2. ChladniEngine: Represents the physics and rendering engine on the Canvas. It accepts an HTMLCanvasElement and manages the positions of thousands of particles using a single flat Float32Array, avoiding the creation and Garbage Collection of thousands of individual objects. During its update() method, the Chladni plate formula is computed for each particle: $$ Amp = |\cos(n\pi x)\cos(m\pi y) - \cos(m\pi x)\cos(n\pi y)| $$ To maximize performance, I have hoisted the wave function constants (products of n, m, PI, and the zoom factor) out of the high-frequency loop. I implemented an “infinite plane” logic: instead of wrapping coordinates in rigid boundaries, particles wrap around the screen edges. The zoom parameter mathematically scales the input coordinates to the wave function, altering the pattern density without losing fidelity or generating visual artifacts, and using the entire width and height of the viewport asymmetrically to ensure that the pattern fills the available space.

Technology Stack

TechnologyArchitectural RoleDesign Justification
AstroCore Framework / PWAStructures the project, optimizing CSS and initial HTML delivery. It allows converting the application into a PWA (with @vite-pwa/astro) easily and without blocking rendering dependencies.
Vanilla TypeScriptBusiness LogicIntentional absence of reactive UI frameworks to ensure maximum CPU resource allocation for particle mathematical processing in ChladniEngine.
nanostoresState ManagementProvides independent and connectable state atoms. Effectively decouples UI components from ChladniEngine and AudioEngine.
HTML5 Canvas (2D)Presentation LayerDirect pixel/rectangle writing via native API through a requestAnimationFrame loop.
Web Audio APISensorial Layer / DSPLow-latency access to physical microphone hardware and capability of digital signal synthesis (oscillators, noise buffer generation) internally on the browser’s main thread.
Tailwind CSS v4Styling LayerCSS utilities management to ensure a strict glassmorphism aesthetic and use of color variables such as Zinc-950 for the background.

In conclusion, this design couples spectral analysis algorithms directly with wave algebra on a linear memory renderer. The use of typed arrays and the avoidance of the Virtual DOM ensure stable 60 FPS update cycles, regardless of whether the engine processes cached brown noise or the analog signal of the environment through the Web Audio API, establishing a highly stress-tolerant computational platform on the client.