The Colored Noise composition engine allows you to programmatically create complex, evolving soundscapes using a JSON schema. Compositions support unlimited voices, timed events, repeat blocks, and dynamic global effects.
The engine that reads this format is also published on its own, so you
can use it in your own project without the site:
npm install colorednoise-engine.
It is MIT licensed, has no dependencies, and ships the worklet, the
presets, offline WAV rendering and the validator for the format
documented below.
A composition has two main sections: voices (named voice channels with event sequences) and global (master effects that change over time).
{
"voices": {
"bass": [ /* events */ ],
"melody": [ /* events */ ]
},
"global": [ /* effect changes */ ]
}
Each voice is an array of events that play sequentially. Events can be sound triggers, waits, or repeat blocks.
| Property | Type | Range | Description |
|---|---|---|---|
color |
Number | 0 - 4 | Noise color: 0=Violet, 1=Blue, 2=White, 3=Pink, 4=Brown |
volume |
Number | 0 - 1 | Voice amplitude |
pan |
Number | -1 to 1 | Stereo position (-1=Left, 0=Center, 1=Right) |
attack |
Number | 0+ | Fade-in time in seconds |
decay |
Number | 0+ | Time to reach sustain level |
sustain |
Number | 0 - 1 | Sustain level (fraction of peak) |
release |
Number | 0+ | Fade-out time in seconds |
duration |
Number | 0+ | Total event duration (attack + hold + release) |
Pause before the next event:
{ "wait": 2 } // Wait 2 seconds
Loop a sequence of events:
{
"repeat": 4,
"events": [
{ "color": 3, "volume": 0.5, "duration": 1, "attack": 0.2, "release": 0.3 },
{ "wait": 0.5 }
]
}
The global array contains events that modify master effects over time. All properties are optional—only include what you want to change.
| Property | Type | Description |
|---|---|---|
grey |
Boolean | Enable perceptual EQ (grey noise filter) |
pulse |
Number | Modulation speed (0-10 Hz) |
pulseShape |
String | "sine", "triangle", or "square" |
texture |
Number | Modulation depth (0-1) |
panRate |
Number | Stereo LFO speed (Hz) |
panDepth |
Number | Stereo LFO depth (0-1) |
color2 |
Number | Secondary noise color for blending |
colorBlend |
Number | Blend amount (0=primary only, 1=secondary only) |
reverbMix |
Number | Reverb wet/dry mix (0-1) |
reverbSize |
String | "small", "medium", or "large" |
saturation |
Number | Distortion amount (0-1) |
saturationMode |
String | "soft", "hard", or "tube" |
bitDepth |
Number | Bit reduction (1-16, 16=off) |
sampleRateReduction |
Number | Sample rate reduction factor (1-100) |
This composition creates an evolving ambient texture with two voices and changing reverb:
{
"voices": {
"bass": [
{
"color": 4,
"volume": 0.7,
"pan": 0,
"attack": 2,
"decay": 0.5,
"sustain": 0.6,
"release": 2,
"duration": 6
},
{ "wait": 1 },
{
"repeat": 2,
"events": [
{
"color": 3.5,
"volume": 0.6,
"pan": -0.3,
"attack": 1,
"duration": 4,
"release": 1.5
},
{ "wait": 0.5 }
]
}
],
"melody": [
{ "wait": 3 },
{
"color": 2,
"volume": 0.4,
"pan": 0.5,
"attack": 0.3,
"duration": 2,
"release": 0.8
}
]
},
"global": [
{
"grey": true,
"reverbMix": 0.3,
"reverbSize": "medium"
},
{ "wait": 8 },
{
"reverbMix": 0.6,
"reverbSize": "large",
"saturation": 0.15,
"saturationMode": "tube"
}
]
}
For complex compositions, use the Python module in the composer/ directory:
from composer import *
bass_swell = phrase(color=BROWN, attack=2, duration=3, release=2, volume=0.7)
high_ping = phrase(color=BLUE, attack=0.1, duration=0.5, release=0.3, volume=0.5)
comp = composition(
voices={
"bass": [bass_swell, wait(2), repeat(3, bass_swell)],
"melody": [wait(1), repeat(8, high_ping, wait(0.5))]
},
global_events=[
global_settings(reverb_mix=0.4, reverb_size="large")
]
)
save(comp, "my_composition.json")
See the example files in composer/ for more patterns.
color values (e.g., 3.5) to blend between noise typespan values for stereo widthrepeat blocks with different loop lengths for polyrhythmssaturation values (0.1-0.2) for warmth without distortionwait events in global to create evolving soundscapes