Building mod Apps with AI Assistants
This guide helps AI assistants (LLMs) effectively build audio applications using mod. If you're an AI helping a user build a mod app, this page provides everything you need.
Quick Start
mod is a React library for building modular audio applications using the Web Audio API. Components represent audio modules that you connect together like a modular synthesizer.
Basic Template
import { AudioProvider, ToneGenerator, Monitor, useModStream } from '@mode-7/mod';
function App() {
const audio = useModStream();
return (
<AudioProvider>
<ToneGenerator output={audio} frequency={440} type="sine" gain={0.5} />
<Monitor input={audio} />
</AudioProvider>
);
}Essential Rules
- Always wrap in AudioProvider - All mod components must be inside
<AudioProvider> - Use useModStream for connections - Create refs with
const ref = useModStream() - Every chain needs Monitor - Audio won't play without
<Monitor input={ref} /> - Import from @mode-7/mod - All components come from this package
- Sources → Processors → Monitor - Signal flows through connected refs
Component Categories
Sources (Audio Generators)
Generate or input audio signals. Have output prop only.
| Component | Purpose | Key Props |
|---|---|---|
| ToneGenerator | Pure tones | frequency, type (sine/square/sawtooth/triangle), gain |
| NoiseGenerator | Noise | type (white/pink/brown), gain |
| Microphone | Mic input | gain |
| MP3Deck | Audio files | src, loop, gain |
| StreamingAudioDeck | Streaming audio | url, loop, gain |
CV Generators (Modulation)
Generate control voltage signals. Have output prop, connect to cvInput of processors.
| Component | Purpose | Key Props |
|---|---|---|
| LFO | Cyclic modulation | rate (Hz), waveform, depth |
| ADSR | Envelopes | attack, decay, sustain, release |
| Sequencer | Step patterns | steps (array), bpm |
| Clock | Tempo sync | bpm |
Processors (Effects)
Transform audio. Have input and output props. Can have cvInput for modulation.
| Component | Purpose | Key Props |
|---|---|---|
| Filter | Frequency filtering | type, frequency, Q, cvInput, cvTarget, cvAmount |
| Delay | Echo | delayTime, feedback, mix |
| Reverb | Spatial reverb | roomSize, damping, mix |
| Distortion | Distortion/overdrive | drive, type |
| Compressor | Dynamics | threshold, ratio, attack, release |
| Tremolo | Amplitude modulation | rate, depth |
| Chorus | Chorus | rate, depth, delay |
| Phaser | Phase shifting | rate, depth, stages |
| Flanger | Flanging | rate, depth, feedback |
| Panner | Stereo panning | pan (-1 to 1) |
| EQ | Equalization | lowGain, midGain, highGain |
| BitCrusher | Lo-fi degradation | bits, sampleRate |
| Limiter | Peak limiting | threshold |
| Gate | Noise gate | threshold |
| AutoWah | Auto-wah | baseFrequency, sensitivity |
| RingModulator | Ring modulation | frequency |
| VCA | Voltage controlled amp | gain, cv, cvAmount |
Mixers
Combine multiple signals. Have multiple inputs, one output.
| Component | Purpose | Key Props |
|---|---|---|
| Mixer | Mix N channels | inputs (array of refs) |
| CrossFade | Blend two sources | inputs ([ref, ref]), mix (0-1), mode |
Output
Send to speakers. Have input prop only.
| Component | Purpose | Key Props |
|---|---|---|
| Monitor | Output to speakers | gain, mute |
Visualizations
Observe audio without affecting it. Have input prop.
| Component | Purpose | Render Props |
|---|---|---|
| Oscilloscope | Waveform | dataArray, bufferLength |
| SpectrumAnalyzer | Frequency spectrum | dataArray, bufferLength |
| LevelMeter | Audio levels | level, peak, isClipping |
ModUI Components
Pre-styled UI controls for audio apps. All imported from @mode-7/mod.
Slider
Range slider with optional +/- buttons.
Props:
value: number(required) - Current valueonChange: (value: number) => void(required) - Change handlermin: number- Minimum value (default: 0)max: number- Maximum value (default: 100)step: number- Step increment (default: 1)label: string- Label textunit: string- Unit suffix (e.g., "Hz", "%")formatValue: (value: number) => string- Custom formattershowButtons: boolean- Show +/- buttons (default: true)disabled: boolean- Disable slider (default: false)
Example:
import { Slider } from '@mode-7/mod';
<Slider
value={frequency}
onChange={setFrequency}
min={20}
max={2000}
label="Frequency"
unit=" Hz"
/>Knob
Rotary knob control.
Props:
value: number(required) - Current valueonChange: (value: number) => void(required) - Change handlermin: number- Minimum value (default: 0)max: number- Maximum value (default: 100)step: number- Step increment (default: 1)label: string- Label textsize: number- Knob size in pixels (default: 64)sensitivity: number- Drag sensitivity (default: 1)formatValue: (value: number) => string- Custom formatterdisabled: boolean- Disable knob (default: false)
Example:
import { Knob } from '@mode-7/mod';
<Knob
value={cutoff}
onChange={setCutoff}
min={20}
max={20000}
label="Cutoff"
size={72}
/>Button
Styled button component.
Props:
onClick: () => void- Click handleractive: boolean- Active/pressed statedisabled: boolean- Disable buttonchildren: ReactNode- Button contentclassName: string- Additional classes
Example:
import { Button } from '@mode-7/mod';
<Button onClick={handlePlay} active={isPlaying}>
{isPlaying ? 'Stop' : 'Play'}
</Button>Select
Dropdown select component.
Props:
value: string(required) - Current valueonChange: (value: string) => void(required) - Change handleroptions: Array<{value: string, label: string}>(required) - Optionslabel: string- Label textdisabled: boolean- Disable select
Example:
import { Select } from '@mode-7/mod';
<Select
value={waveform}
onChange={setWaveform}
label="Waveform"
options={[
{ value: 'sine', label: 'Sine' },
{ value: 'square', label: 'Square' },
{ value: 'sawtooth', label: 'Sawtooth' }
]}
/>XYPad
2D touchpad control for controlling two parameters simultaneously.
Props:
x: number(required) - X value (0-1)y: number(required) - Y value (0-1)onXChange: (value: number) => void(required) - X change handleronYChange: (value: number) => void(required) - Y change handlerwidth: number- Pad width (default: 200)height: number- Pad height (default: 200)xLabel: string- X axis labelyLabel: string- Y axis labeldisabled: boolean- Disable pad
Example:
import { XYPad } from '@mode-7/mod';
<XYPad
x={xPos}
y={yPos}
onXChange={setXPos}
onYChange={setYPos}
xLabel="Cutoff"
yLabel="Resonance"
width={250}
height={250}
/>FilePicker
File input component.
Props:
onFileSelect: (file: File) => void(required) - File selection handleraccept: string- Accepted file types (e.g., "audio/*")label: string- Label textbuttonText: string- Button text (default: "Choose File")
Example:
import { FilePicker } from '@mode-7/mod';
<FilePicker
onFileSelect={(file) => loadAudioFile(file)}
accept="audio/*"
label="Load Audio"
/>TextInput
Text input component.
Props:
value: string(required) - Current valueonChange: (value: string) => void(required) - Change handlerlabel: string- Label textplaceholder: string- Placeholder textdisabled: boolean- Disable inputtype: string- Input type (default: "text")
Example:
import { TextInput } from '@mode-7/mod';
<TextInput
value={projectName}
onChange={setProjectName}
label="Project Name"
placeholder="Enter name..."
/>ProgressBar
Progress indicator component.
Props:
value: number(required) - Progress value (0-100)label: string- Label textshowValue: boolean- Show value text (default: true)indeterminate: boolean- Show indeterminate animation
Example:
import { ProgressBar } from '@mode-7/mod';
<ProgressBar
value={loadProgress}
label="Loading..."
showValue={true}
/>OscilloscopeCanvas
Pre-built canvas oscilloscope visualization.
Props:
dataArray: Uint8Array(required) - Waveform data from Oscilloscope componentbufferLength: number(required) - Buffer length from Oscilloscope componentwidth: number- Canvas width (default: 300)height: number- Canvas height (default: 150)strokeColor: string- Line color (default: "#4CAF50")backgroundColor: string- Background color (default: "#1a1a1a")
Example:
import { Oscilloscope, OscilloscopeCanvas } from '@mode-7/mod';
<Oscilloscope input={audioRef}>
{({ dataArray, bufferLength }) => (
<OscilloscopeCanvas
dataArray={dataArray}
bufferLength={bufferLength}
width={400}
height={200}
strokeColor="#00ff00"
/>
)}
</Oscilloscope>SpectrumAnalyzerCanvas
Pre-built canvas spectrum analyzer visualization.
Props:
dataArray: Uint8Array(required) - Frequency data from SpectrumAnalyzer componentbufferLength: number(required) - Buffer length from SpectrumAnalyzer componentwidth: number- Canvas width (default: 300)height: number- Canvas height (default: 150)barColor: string- Bar color (default: "#4CAF50")backgroundColor: string- Background color (default: "#1a1a1a")barGap: number- Gap between bars (default: 2)
Example:
import { SpectrumAnalyzer, SpectrumAnalyzerCanvas } from '@mode-7/mod';
<SpectrumAnalyzer input={audioRef}>
{({ dataArray, bufferLength }) => (
<SpectrumAnalyzerCanvas
dataArray={dataArray}
bufferLength={bufferLength}
width={400}
height={200}
barColor="#ff9800"
/>
)}
</SpectrumAnalyzer>LevelMeterCanvas
Pre-built canvas level meter visualization.
Props:
level: number(required) - Current level (0-1) from LevelMeter componentpeak: number(required) - Peak level (0-1) from LevelMeter componentisClipping: boolean(required) - Clipping indicator from LevelMeter componentwidth: number- Meter width (default: 20)height: number- Meter height (default: 150)orientation: 'vertical' | 'horizontal'- Meter orientation (default: 'vertical')normalColor: string- Normal level color (default: "#4CAF50")warningColor: string- Warning level color (default: "#FF9800")clipColor: string- Clipping color (default: "#F44336")
Example:
import { LevelMeter, LevelMeterCanvas } from '@mode-7/mod';
<LevelMeter input={audioRef}>
{({ level, peak, isClipping }) => (
<LevelMeterCanvas
level={level}
peak={peak}
isClipping={isClipping}
width={30}
height={200}
/>
)}
</LevelMeter>Common Patterns
1. Basic Signal Chain
const signal = useModStream();
<ToneGenerator output={signal} frequency={440} />
<Monitor input={signal} />2. Source → Effect → Output
const dry = useModStream();
const wet = useModStream();
<ToneGenerator output={dry} />
<Filter input={dry} output={wet} frequency={1000} Q={5} />
<Monitor input={wet} />3. Multiple Effects Chain
const source = useModStream();
const filtered = useModStream();
const delayed = useModStream();
const reverbed = useModStream();
<NoiseGenerator output={source} />
<Filter input={source} output={filtered} />
<Delay input={filtered} output={delayed} />
<Reverb input={delayed} output={reverbed} />
<Monitor input={reverbed} />4. Mixing Multiple Sources
const tone1 = useModStream();
const tone2 = useModStream();
const mixed = useModStream();
<ToneGenerator output={tone1} frequency={220} />
<ToneGenerator output={tone2} frequency={440} />
<Mixer inputs={[tone1, tone2]} output={mixed} />
<Monitor input={mixed} />5. CV Modulation (LFO → Filter)
const audio = useModStream();
const lfo = useModStream();
const filtered = useModStream();
<ToneGenerator output={audio} frequency={220} />
<LFO output={lfo} rate={2} waveform="sine" />
<Filter
input={audio}
output={filtered}
frequency={1000}
cvInput={lfo}
cvTarget="frequency"
cvAmount={5000}
/>
<Monitor input={filtered} />6. Envelope-Controlled Filter
const audio = useModStream();
const env = useModStream();
const filtered = useModStream();
<NoiseGenerator output={audio} />
<ADSR output={env} attack={0.01} decay={0.2} sustain={0.3} release={0.5}>
{({ trigger }) => <button onClick={trigger}>Trigger</button>}
</ADSR>
<Filter
input={audio}
output={filtered}
cvInput={env}
cvTarget="frequency"
cvAmount={8000}
/>
<Monitor input={filtered} />7. Crossfade Between Sources
const sourceA = useModStream();
const sourceB = useModStream();
const output = useModStream();
<ToneGenerator output={sourceA} frequency={220} />
<NoiseGenerator output={sourceB} type="white" />
<CrossFade inputs={[sourceA, sourceB]} output={output} mix={0.5} />
<Monitor input={output} />8. With UI Controls (Render Props)
const audio = useModStream();
<ToneGenerator output={audio}>
{({ frequency, setFrequency, type, setType, gain, setGain }) => (
<div>
<Slider value={frequency} onChange={setFrequency} min={20} max={2000} label="Frequency" />
<Select
value={type}
onChange={setType}
options={[
{ value: 'sine', label: 'Sine' },
{ value: 'square', label: 'Square' },
{ value: 'sawtooth', label: 'Sawtooth' },
{ value: 'triangle', label: 'Triangle' },
]}
/>
<Slider value={gain} onChange={setGain} min={0} max={1} step={0.01} label="Gain" />
</div>
)}
</ToneGenerator>
<Monitor input={audio} />9. With Visualization
const audio = useModStream();
<ToneGenerator output={audio} />
<Oscilloscope input={audio}>
{({ dataArray, bufferLength }) => (
<OscilloscopeCanvas dataArray={dataArray} bufferLength={bufferLength} height={150} />
)}
</Oscilloscope>
<Monitor input={audio} />10. Controlled Props Pattern
const [frequency, setFrequency] = useState(440);
const [gain, setGain] = useState(0.5);
const audio = useModStream();
<ToneGenerator
output={audio}
frequency={frequency}
onFrequencyChange={setFrequency}
gain={gain}
onGainChange={setGain}
/>Component Usage Patterns
mod components support three patterns:
1. Render Props (Most Common)
<ToneGenerator output={ref}>
{({ frequency, setFrequency, gain, setGain }) => (
<div>
<input value={frequency} onChange={e => setFrequency(+e.target.value)} />
</div>
)}
</ToneGenerator>2. Controlled Props
const [freq, setFreq] = useState(440);
<ToneGenerator output={ref} frequency={freq} onFrequencyChange={setFreq} />3. Imperative Refs
const toneRef = useRef<ToneGeneratorHandle>(null);
useEffect(() => {
toneRef.current?.setFrequency(880);
}, []);
<ToneGenerator ref={toneRef} output={ref} />CV Modulation
Connect CV generators to processors using cvInput, cvTarget, and cvAmount:
<LFO output={lfoRef} rate={5} />
<Filter
input={audioRef}
output={outRef}
frequency={1000} // Base frequency
cvInput={lfoRef} // CV source
cvTarget="frequency" // What to modulate
cvAmount={3000} // Modulation depth (±3000Hz)
/>Common cvTargets:
- Filter:
frequency,Q - Processors: Check component docs for available targets
Signal Flow Rules
- Sources have
outputonly - Processors have
inputANDoutput - Mixers have
inputs(array) ANDoutput - Monitor has
inputonly - CV generators have
output, connect tocvInputprops - Visualizations have
input, don't affect audio
Complete Example: Simple Synthesizer
import {
AudioProvider,
ToneGenerator,
Filter,
ADSR,
Monitor,
useModStream,
Slider,
Select,
Button
} from '@mode-7/mod';
import { useState } from 'react';
function Synth() {
const osc = useModStream();
const env = useModStream();
const filtered = useModStream();
const [frequency, setFrequency] = useState(440);
return (
<AudioProvider>
<h1>Simple Synth</h1>
{/* Oscillator */}
<ToneGenerator output={osc} frequency={frequency}>
{({ type, setType, gain, setGain }) => (
<div>
<Slider
value={frequency}
onChange={setFrequency}
min={20}
max={2000}
label="Frequency"
/>
<Select
value={type}
onChange={setType}
options={[
{ value: 'sine', label: 'Sine' },
{ value: 'square', label: 'Square' },
{ value: 'sawtooth', label: 'Sawtooth' },
]}
/>
<Slider value={gain} onChange={setGain} min={0} max={1} label="Level" />
</div>
)}
</ToneGenerator>
{/* Envelope */}
<ADSR output={env}>
{({ attack, setAttack, decay, setDecay, sustain, setSustain, release, setRelease, trigger }) => (
<div>
<h3>Envelope</h3>
<Button onClick={trigger}>Trigger</Button>
<Slider value={attack} onChange={setAttack} min={0.001} max={2} label="Attack" />
<Slider value={decay} onChange={setDecay} min={0.001} max={2} label="Decay" />
<Slider value={sustain} onChange={setSustain} min={0} max={1} label="Sustain" />
<Slider value={release} onChange={setRelease} min={0.001} max={5} label="Release" />
</div>
)}
</ADSR>
{/* Filter with envelope modulation */}
<Filter
input={osc}
output={filtered}
cvInput={env}
cvTarget="frequency"
cvAmount={8000}
>
{({ frequency, setFrequency, Q, setQ }) => (
<div>
<h3>Filter</h3>
<Slider value={frequency} onChange={setFrequency} min={20} max={20000} label="Cutoff" />
<Slider value={Q} onChange={setQ} min={0.1} max={30} label="Resonance" />
</div>
)}
</Filter>
{/* Output */}
<Monitor input={filtered}>
{({ gain, setGain, isMuted, setMuted }) => (
<div>
<Slider value={gain} onChange={setGain} min={0} max={1} label="Master" />
<Button active={isMuted} onClick={() => setMuted(!isMuted)}>
{isMuted ? 'Unmute' : 'Mute'}
</Button>
</div>
)}
</Monitor>
</AudioProvider>
);
}Troubleshooting
No Audio Output
- ✅ Check AudioProvider wraps all components
- ✅ Check Monitor is connected
- ✅ Check browser autoplay policy (user must interact first)
- ✅ Check volume/gain settings
TypeScript Errors
- ✅ Import types:
import type { ModStreamRef } from '@mode-7/mod' - ✅ Use component-specific Handle types for refs
Connection Errors
- ✅ Sources connect to
inputprops - ✅ Processors output to other processors'
input - ✅ Always end with Monitor
- ✅ CV generators connect to
cvInput, notinput
Documentation Links
- Getting Started: /guide/getting-started
- Architecture: /guide/architecture
- Audio Context: /guide/audio-context
- Connecting Modules: /guide/connecting-modules
- CV Modulation: /guide/cv-modulation
- API Reference: /api/overview
- Examples: /guide/examples/simple-synth
Quick Reference Card
// Install
npm install @mode-7/mod
// Import
import {
AudioProvider,
ToneGenerator,
Filter,
Monitor,
useModStream
} from '@mode-7/mod';
// Create connections
const ref = useModStream();
// Basic structure
<AudioProvider>
<Source output={ref1} />
<Processor input={ref1} output={ref2} />
<Monitor input={ref2} />
</AudioProvider>
// Modulation
<CVGenerator output={cvRef} />
<Processor cvInput={cvRef} cvTarget="paramName" cvAmount={100} />Detailed Component API
ToneGenerator - Audio Oscillator
Generates pure tones at specified frequencies with multiple waveforms.
Props:
output: ModStreamRef(required) - Output stream referencefrequency: number- Frequency in Hz (default: 440)onFrequencyChange: (freq: number) => void- Frequency change callbackgain: number- Gain level 0-1 (default: 0.3)onGainChange: (gain: number) => void- Gain change callbackwaveform: 'sine' | 'square' | 'sawtooth' | 'triangle'- Waveform type (default: 'square')onWaveformChange: (waveform: OscillatorType) => void- Waveform change callbackcv: ModStreamRef- CV input for frequency modulationcvAmount: number- CV modulation depth (default: 100)label: string- Component label (default: 'tone-generator')
Render Props:
{({ frequency, setFrequency, gain, setGain, waveform, setWaveform, isActive }) => ReactNode}Example - With UI:
const tone = useModStream();
<ToneGenerator output={tone}>
{({ frequency, setFrequency, waveform, setWaveform }) => (
<div>
<Slider value={frequency} onChange={setFrequency} min={20} max={2000} label="Freq" />
<Select
value={waveform}
onChange={setWaveform}
options={[
{ value: 'sine', label: 'Sine' },
{ value: 'square', label: 'Square' }
]}
/>
</div>
)}
</ToneGenerator>Filter - Frequency Filter
Filters audio frequencies with multiple filter types and CV modulation support.
Props:
input: ModStreamRef(required) - Input streamoutput: ModStreamRef(required) - Output streamfrequency: number- Cutoff frequency in Hz (default: 1000)onFrequencyChange: (freq: number) => void- Frequency change callbackQ: number- Resonance/Q factor (default: 1)onQChange: (q: number) => void- Q change callbacktype: 'lowpass' | 'highpass' | 'bandpass' | 'notch' | 'allpass' | 'lowshelf' | 'highshelf' | 'peaking'- Filter type (default: 'lowpass')onTypeChange: (type: BiquadFilterType) => void- Type change callbackcvInput: ModStreamRef- CV modulation inputcvTarget: 'frequency' | 'Q'- Which parameter to modulatecvAmount: number- Modulation depth (default: 1000)label: string- Component label
Render Props:
{({ frequency, setFrequency, Q, setQ, type, setType }) => ReactNode}Example - CV Modulated Filter:
const audio = useModStream();
const lfo = useModStream();
const filtered = useModStream();
<NoiseGenerator output={audio} />
<LFO output={lfo} rate={3} waveform="sine" />
<Filter
input={audio}
output={filtered}
frequency={1000}
Q={5}
type="lowpass"
cvInput={lfo}
cvTarget="frequency"
cvAmount={5000} // ±5000Hz modulation
/>
<Monitor input={filtered} />LFO - Low Frequency Oscillator
Generates control voltage signals for modulation.
Props:
output: ModStreamRef(required) - CV output streamrate: number- Frequency in Hz (default: 1)onRateChange: (rate: number) => void- Rate change callbackwaveform: 'sine' | 'square' | 'sawtooth' | 'triangle'- Waveform (default: 'sine')onWaveformChange: (waveform: OscillatorType) => void- Waveform change callbackdepth: number- Modulation depth 0-1 (default: 1)onDepthChange: (depth: number) => void- Depth change callbacklabel: string- Component label
Render Props:
{({ rate, setRate, waveform, setWaveform, depth, setDepth }) => ReactNode}ADSR - Envelope Generator
Attack-Decay-Sustain-Release envelope generator for controlling parameters over time.
Props:
output: ModStreamRef(required) - CV output streamattack: number- Attack time in seconds (default: 0.1)onAttackChange: (attack: number) => void- Attack change callbackdecay: number- Decay time in seconds (default: 0.1)onDecayChange: (decay: number) => void- Decay change callbacksustain: number- Sustain level 0-1 (default: 0.7)onSustainChange: (sustain: number) => void- Sustain change callbackrelease: number- Release time in seconds (default: 0.3)onReleaseChange: (release: number) => void- Release change callbacklabel: string- Component label
Render Props:
{({
attack, setAttack,
decay, setDecay,
sustain, setSustain,
release, setRelease,
trigger: () => void // Function to trigger the envelope
}) => ReactNode}Example - Envelope-Controlled VCA:
const audio = useModStream();
const env = useModStream();
const output = useModStream();
<NoiseGenerator output={audio} />
<ADSR output={env} attack={0.01} decay={0.2} sustain={0.3} release={0.5}>
{({ trigger }) => <Button onClick={trigger}>Trigger</Button>}
</ADSR>
<VCA input={audio} output={output} cvInput={env} cvAmount={1} />
<Monitor input={output} />Delay - Echo Effect
Creates echo/delay effects with feedback control.
Props:
input: ModStreamRef(required) - Input streamoutput: ModStreamRef(required) - Output streamdelayTime: number- Delay time in seconds (default: 0.3)onDelayTimeChange: (time: number) => void- Delay time change callbackfeedback: number- Feedback amount 0-0.9 (default: 0.5)onFeedbackChange: (feedback: number) => void- Feedback change callbackmix: number- Dry/wet mix 0-1 (default: 0.5)onMixChange: (mix: number) => void- Mix change callbacklabel: string- Component label
Render Props:
{({ delayTime, setDelayTime, feedback, setFeedback, mix, setMix }) => ReactNode}Reverb - Reverberation Effect
Adds spatial reverb to audio signals.
Props:
input: ModStreamRef(required) - Input streamoutput: ModStreamRef(required) - Output streamroomSize: number- Room size 0-1 (default: 0.5)onRoomSizeChange: (size: number) => void- Room size change callbackdamping: number- High frequency damping 0-1 (default: 0.5)onDampingChange: (damping: number) => void- Damping change callbackmix: number- Dry/wet mix 0-1 (default: 0.3)onMixChange: (mix: number) => void- Mix change callbacklabel: string- Component label
Render Props:
{({ roomSize, setRoomSize, damping, setDamping, mix, setMix }) => ReactNode}Mixer - Audio Mixer
Combines multiple audio signals into one output.
Props:
inputs: ModStreamRef[](required) - Array of input streams to mixoutput: ModStreamRef(required) - Mixed output streamgains: number[]- Individual gain levels for each input (0-1)onGainsChange: (gains: number[]) => void- Gains change callbacklabel: string- Component label
Render Props:
{({ gains, setGains, setGain: (index: number, gain: number) => void }) => ReactNode}Example - Mixing Three Sources:
const osc1 = useModStream();
const osc2 = useModStream();
const noise = useModStream();
const mixed = useModStream();
<ToneGenerator output={osc1} frequency={220} />
<ToneGenerator output={osc2} frequency={330} />
<NoiseGenerator output={noise} type="white" />
<Mixer inputs={[osc1, osc2, noise]} output={mixed}>
{({ gains, setGain }) => (
<div>
<Slider value={gains[0]} onChange={(v) => setGain(0, v)} label="Osc 1" />
<Slider value={gains[1]} onChange={(v) => setGain(1, v)} label="Osc 2" />
<Slider value={gains[2]} onChange={(v) => setGain(2, v)} label="Noise" />
</div>
)}
</Mixer>
<Monitor input={mixed} />NoiseGenerator - Noise Source
Generates different types of noise (white, pink, brown).
Props:
output: ModStreamRef(required) - Output streamtype: 'white' | 'pink' | 'brown'- Noise type (default: 'white')onTypeChange: (type: NoiseType) => void- Type change callbackgain: number- Gain level 0-1 (default: 0.3)onGainChange: (gain: number) => void- Gain change callbacklabel: string- Component label
Render Props:
{({ type, setType, gain, setGain }) => ReactNode}MP3Deck - Audio File Player
Plays audio files (MP3, WAV, etc.).
Props:
output: ModStreamRef(required) - Output streamsrc: string- Audio file URL (default: '')onSrcChange: (src: string) => void- Source change callbackloop: boolean- Loop playback (default: false)onLoopChange: (loop: boolean) => void- Loop change callbackgain: number- Gain level 0-1 (default: 1)onGainChange: (gain: number) => void- Gain change callbackautoplay: boolean- Auto-play when loaded (default: false)label: string- Component label
Render Props:
{({
src, setSrc,
loop, setLoop,
gain, setGain,
isPlaying,
play: () => void,
pause: () => void,
stop: () => void,
currentTime: number,
duration: number,
seek: (time: number) => void
}) => ReactNode}Example - Audio Player with Controls:
const audio = useModStream();
<MP3Deck output={audio} src="/audio/track.mp3">
{({ isPlaying, play, pause, currentTime, duration, seek, gain, setGain }) => (
<div>
<Button onClick={isPlaying ? pause : play}>
{isPlaying ? 'Pause' : 'Play'}
</Button>
<Slider
value={currentTime}
onChange={seek}
min={0}
max={duration}
label="Position"
/>
<Slider value={gain} onChange={setGain} min={0} max={1} label="Volume" />
</div>
)}
</MP3Deck>VCA - Voltage Controlled Amplifier
Controls gain/volume with CV modulation.
Props:
input: ModStreamRef(required) - Input streamoutput: ModStreamRef(required) - Output streamgain: number- Base gain 0-1 (default: 1)onGainChange: (gain: number) => void- Gain change callbackcvInput: ModStreamRef- CV modulation inputcvAmount: number- Modulation depth 0-1 (default: 1)label: string- Component label
Render Props:
{({ gain, setGain }) => ReactNode}Oscilloscope - Waveform Visualizer
Visualizes audio waveforms. Use with OscilloscopeCanvas or custom visualization.
Props:
input: ModStreamRef(required) - Audio input to visualizefftSize: number- FFT size (default: 2048, must be power of 2)label: string- Component label
Render Props:
{({
dataArray: Uint8Array, // Waveform data
bufferLength: number // Data buffer length
}) => ReactNode}SpectrumAnalyzer - Frequency Visualizer
Visualizes frequency spectrum. Use with SpectrumAnalyzerCanvas or custom visualization.
Props:
input: ModStreamRef(required) - Audio input to analyzefftSize: number- FFT size (default: 2048, must be power of 2)smoothingTimeConstant: number- Smoothing 0-1 (default: 0.8)label: string- Component label
Render Props:
{({
dataArray: Uint8Array, // Frequency data
bufferLength: number // Data buffer length
}) => ReactNode}LevelMeter - Audio Level Meter
Measures audio levels with peak detection and clipping indicator.
Props:
input: ModStreamRef(required) - Audio input to measurelabel: string- Component label
Render Props:
{({
level: number, // Current RMS level 0-1
peak: number, // Peak level 0-1
isClipping: boolean // True if clipping detected
}) => ReactNode}Important Notes for AI Assistants
Common Mistakes to Avoid
- Missing AudioProvider - Always wrap everything in
<AudioProvider> - No Monitor - Audio won't play without
<Monitor input={finalStream} /> - Wrong prop names - It's
outputnotout,inputnotin,cvInputnotcv(except for ToneGenerator which usescv) - Forgetting useModStream - Create refs with
const ref = useModStream(), notuseRef(null) - CV vs Audio inputs - CV generators connect to
cvInput, audio sources connect toinput - Import errors - Everything imports from
@mode-7/mod, including UI components
Signal Flow Checklist
- ✅ AudioProvider wraps all mod components
- ✅ Create stream refs with
useModStream() - ✅ Sources (ToneGenerator, NoiseGenerator, etc.) have
outputprop - ✅ Processors (Filter, Delay, etc.) have both
inputandoutputprops - ✅ CV generators (LFO, ADSR) connect to
cvInputprops - ✅ Final output goes to
<Monitor input={...} /> - ✅ All components are connected in a valid chain
Quick Debugging
No sound?
- Check AudioProvider is wrapping components
- Check Monitor is connected to final output
- Check browser autoplay policy (user must interact first)
- Check gain/volume levels
TypeScript errors?
- Import types:
import type { ModStreamRef } from '@mode-7/mod' - Use component-specific Handle types for refs
Connection errors?
- Audio flows: Source → Processor → Monitor
- CV flows: CV Generator → Processor's cvInput
- Never connect CV to audio inputs or vice versa
For detailed examples and advanced patterns, explore the full documentation at /guide/getting-started
