Audio Architecture

1. Overview

Oh My Ondas is a 4-source, 4-channel mixer with per-channel FX processing. The four sources — microphone, sampler, synthesizer, and internet radio — each feed into a dedicated mixer channel with independent gain, 3-band EQ, and a full FX chain (delay, glitch, grain). All channels merge through a master EQ, master FX stage, and master gain before reaching the audio output and analyser.

2. Signal Flow

Each source follows an identical path through its channel strip. The per-channel FX sit between the channel EQ and the master bus, allowing independent effects processing without affecting other sources.

Per-channel path (x4: mic, samples, synth, radio):
Source Channel Gain Channel EQ (Lo/Mid/Hi) Channel FX (Delay/Glitch/Grain) Master EQ
Master bus:
Master EQ Master FX (Delay/Glitch/Grain) Master Gain Analyser Audio Output

3. Per-Channel FX

The ChannelFX class provides three effect types per instance. Five instances are created: one per channel (mic, samples, synth, radio) and one master.

Delay

Variable-time delay (0–2s) with feedback loop and dry/wet crossfade. At 100% mix, the dry signal is attenuated to 50% rather than muted, preserving transient definition.

Glitch

Probability-based slice effects running on a 100ms check interval. Three modes: stutter (rapid volume chops), reverse (feedback burst simulating reversal), and jump (random amplitude spikes).

Grain

Simplified granular texture using the delay line. Grain density maps to delay feedback, grain size maps to delay time. Freeze mode sets feedback to 0.98 for near-infinite sustain of the delay buffer.

Routing via MangleEngine

The MangleEngine acts as a routing manager. Its currentRoute property (default: 'master') determines which ChannelFX instance receives effect parameter changes. Direct per-channel control is available via setChannelDelayMix(channelName, percent) and similar methods.

4. Soundscape Analysis

The SoundscapeAnalyzer taps a high-resolution AnalyserNode (FFT size 2048) into the mic channel gain node in parallel. The tap is non-destructive — it doesn't alter the mic audio path.

Analysis Pipeline

Metrics

Classification

AI Integration

When generateFull() runs, it calls listenToEnvironment(2000) first. If the soundscape has meaningful amplitude (> 0.05), the classification overrides GPS-based vibe selection: rhythmic→urban, tonal→nature, ambient→calm, noisy/chaotic→chaos. Transient density and brightness also adjust the density and complexity parameters (+15 and +10 respectively). Dominant frequencies below 10Hz are used as tempo hints.

5. Creative Source Roles

The SourceRoleManager breaks from the assumption that samples = drums, radio = plays straight, synth = notes. Any source can serve any of four roles:

Role Distribution by Vibe

Strategy Pattern

Each role+source combination has a strategy function that configures the track. Examples:

Modulation Routing

Modulation-role tracks set up real-time parameter routes. Each sequencer tick, processModulation() reads the source channel's RMS amplitude and maps it (scaled) to a target channel's FX parameter. For example: mic amplitude → synth delay mix.

6. P-Lock Integration

Per-step parameter locks now include an fxRoute field that determines which channel's FX receives the P-Lock values. The resolution order is:

This allows a single pattern to apply delay to the radio channel on step 3, grain to the synth on step 7, and leave all other steps targeting master — per-step, per-channel FX automation.

7. File Reference

FileResponsibility
audio-engine.jsAudioContext, channel routing, gain, EQ, metering, per-channel FX wiring
channel-fx.jsChannelFX class: delay, glitch, grain per instance
mangle.jsMangleEngine: FX routing manager, delegates to ChannelFX instances
soundscape-analyzer.jsSoundscapeAnalyzer: mic spectral analysis, classification
source-roles.jsSourceRoleManager: creative role assignment, modulation routing
sequencer.jsStep sequencer, P-Locks with per-channel FX targeting, trig conditions
scenes.jsScene save/recall/morph with per-channel FX and role state
ai-composer.jsAI composition engine: soundscape-aware, role-based track assignment
mic-input.jsMicrophone input management
sampler.js8-pad sampler with kit loading and capture
synth.js2-oscillator subtractive synth with ADSR, filter, LFO
radio.jsInternet radio streaming and capture
recorder.jsAudio recording to file
arrangement.jsMulti-scene arrangement timeline
gps.jsGPS positioning and location tracking
landmark.jsGPS-tagged sonic snapshots
journey.jsGPS-tracked walking sessions
app.jsUI controller, event binding, initialization