Initial release: 8-bit sound synthesizer with LLM/MCP integration
Soundgen is a Rust workspace for generating 8-bit/chiptune sound effects, UI sounds, and ambient textures for game audio assets. It features JSON-first sound specs, an MCP server for LLM tool-use, an egui GUI editor, and a runtime library with NES-authentic DAC emulation. Features: - 6 voice types: pulse, triangle, noise, DPCM, wavetable, FM - Effects: ADSR envelope, frequency sweep, biquad filter, vibrato - 13 built-in presets (SFX/UI/ambient) as JSON data files - MCP server: list_presets, generate_sfx, render_sound tools - Pattern-based sequencer (JSON song format) - egui GUI: virtual keyboard, preset browser, channel editor, undo/redo - Runtime: NES nonlinear DAC + SoundBank for game embedding - 90 tests, 0 warnings Crates: - soundgen-core: synthesis engine (no I/O) - soundgen-fmt: SoundSpec JSON schema + PresetRegistry - soundgen-io: WAV writer + audio playback - soundgen-seq: sequencer (patterns, songs) - soundgen-cli: gen/render/render-song/list-presets - soundgen-mcp: MCP server for LLM integration - soundgen-gui: egui editor - soundgen-runtime: NES DAC + SoundBank
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "drone",
|
||||
"duration": 5.0,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "triangle",
|
||||
"frequency": { "start": 55, "end": 55 },
|
||||
"envelope": { "attack": 1.0, "decay": 0.0, "sustain": 0.9, "release": 1.0 },
|
||||
"volume": 0.4,
|
||||
"pan": -0.3
|
||||
},
|
||||
{
|
||||
"type": "triangle",
|
||||
"frequency": { "start": 82.5, "end": 82.5 },
|
||||
"envelope": { "attack": 1.5, "decay": 0.0, "sustain": 0.7, "release": 1.0 },
|
||||
"volume": 0.3,
|
||||
"pan": 0.3
|
||||
},
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 12,
|
||||
"frequency": { "start": 110, "end": 110 },
|
||||
"envelope": { "attack": 2.0, "decay": 0.0, "sustain": 0.3, "release": 1.0 },
|
||||
"volume": 0.15,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "rain",
|
||||
"duration": 5.0,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 10000,
|
||||
"filter": {
|
||||
"type": "highpass",
|
||||
"cutoff": 2000,
|
||||
"q": 0.7
|
||||
},
|
||||
"envelope": { "attack": 0.5, "decay": 0.0, "sustain": 0.5, "release": 0.5 },
|
||||
"volume": 0.15,
|
||||
"pan": 0.0
|
||||
},
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 8000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 1500,
|
||||
"q": 0.5
|
||||
},
|
||||
"envelope": { "attack": 0.8, "decay": 0.0, "sustain": 0.4, "release": 0.5 },
|
||||
"volume": 0.1,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "wind",
|
||||
"duration": 5.0,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 6000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 800,
|
||||
"q": 0.5
|
||||
},
|
||||
"envelope": { "attack": 1.0, "decay": 0.0, "sustain": 0.8, "release": 1.0 },
|
||||
"volume": 0.3,
|
||||
"pan": -0.2
|
||||
},
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 4000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 400,
|
||||
"q": 0.5
|
||||
},
|
||||
"envelope": { "attack": 1.5, "decay": 0.0, "sustain": 0.6, "release": 1.0 },
|
||||
"volume": 0.25,
|
||||
"pan": 0.2
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "coin",
|
||||
"duration": 0.15,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 800, "end": 1200, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.001, "decay": 0.04, "sustain": 0.0, "release": 0.1 },
|
||||
"volume": 0.5,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "explosion",
|
||||
"duration": 0.8,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 12000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 3000,
|
||||
"cutoff_sweep": { "start": 3000, "end": 100, "curve": "exponential" },
|
||||
"q": 0.7
|
||||
},
|
||||
"envelope": { "attack": 0.002, "decay": 0.6, "sustain": 0.0, "release": 0.18 },
|
||||
"volume": 0.85,
|
||||
"pan": 0.0
|
||||
},
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 4000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 800,
|
||||
"cutoff_sweep": { "start": 800, "end": 50, "curve": "exponential" },
|
||||
"q": 1.0
|
||||
},
|
||||
"envelope": { "attack": 0.0, "decay": 0.4, "sustain": 0.0, "release": 0.1 },
|
||||
"volume": 0.5,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "hit",
|
||||
"duration": 0.12,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "noise",
|
||||
"mode": "white",
|
||||
"frequency": 6000,
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 1500,
|
||||
"q": 1.5
|
||||
},
|
||||
"envelope": { "attack": 0.0, "decay": 0.02, "sustain": 0.0, "release": 0.08 },
|
||||
"volume": 0.7,
|
||||
"pan": 0.0
|
||||
},
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 200, "end": 50, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.0, "decay": 0.03, "sustain": 0.0, "release": 0.06 },
|
||||
"volume": 0.4,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "jump",
|
||||
"duration": 0.25,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 150, "end": 600, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.005, "decay": 0.08, "sustain": 0.0, "release": 0.15 },
|
||||
"volume": 0.6,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "laser",
|
||||
"duration": 0.3,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 25,
|
||||
"frequency": { "start": 1200, "end": 80, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.001, "decay": 0.1, "sustain": 0.0, "release": 0.18 },
|
||||
"filter": {
|
||||
"type": "lowpass",
|
||||
"cutoff": 4000,
|
||||
"q": 2.0
|
||||
},
|
||||
"volume": 0.55,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "powerup",
|
||||
"duration": 0.5,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 200, "end": 1600, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.01, "decay": 0.2, "sustain": 0.3, "release": 0.25 },
|
||||
"volume": 0.5,
|
||||
"pan": 0.0
|
||||
},
|
||||
{
|
||||
"type": "triangle",
|
||||
"frequency": { "start": 100, "end": 800, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.02, "decay": 0.25, "sustain": 0.2, "release": 0.2 },
|
||||
"volume": 0.3,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "click",
|
||||
"duration": 0.05,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 1000, "end": 1000 },
|
||||
"envelope": { "attack": 0.0, "decay": 0.0, "sustain": 0.0, "release": 0.04 },
|
||||
"volume": 0.3,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "confirm",
|
||||
"duration": 0.15,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 600, "end": 900, "curve": "exponential" },
|
||||
"envelope": { "attack": 0.005, "decay": 0.03, "sustain": 0.0, "release": 0.1 },
|
||||
"volume": 0.35,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "error",
|
||||
"duration": 0.2,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "pulse",
|
||||
"duty": 50,
|
||||
"frequency": { "start": 200, "end": 150 },
|
||||
"envelope": { "attack": 0.005, "decay": 0.05, "sustain": 0.3, "release": 0.12 },
|
||||
"volume": 0.4,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "hover",
|
||||
"duration": 0.04,
|
||||
"sample_rate": 44100,
|
||||
"channels": [
|
||||
{
|
||||
"type": "triangle",
|
||||
"frequency": { "start": 600, "end": 900 },
|
||||
"envelope": { "attack": 0.0, "decay": 0.0, "sustain": 0.0, "release": 0.035 },
|
||||
"volume": 0.2,
|
||||
"pan": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user