Play a sound through a graph of gain, pitch and EQ effects #311
A sound could only be played as it was uploaded. A Sound FX asset is
a node graph like a shader: Input, effects, Output. Play sound has a
new input fx that sends the voice through it.
- New asset type soundfx ("Sound FX"), not placeable, with a graph
and its own tab. The heading in the asset panel is "Sound effects",
so it does not take the click meant for the + menu entry.
- Nodes in core/soundfx/nodes.ts, category sound, port type audio
that only fits audio: Input, Output, Gain (dB), Pitch (semitones),
EQ (80 Hz and 12 kHz shelves, peaks at 250 Hz, 1 kHz and 4 kHz).
- compileSoundFx walks back from the Output with the shared graph
emitter. An input takes one edge, so the result is one line: a
pitch and a list of gain and filter stages. A node without input
or a graph without Output reports a problem on the node.
- Pitch is the playback rate of the source. It applies to the whole
sound and also changes its length, the node description says so.
- The BehaviorSystem resolves fx and hands the line to the AudioSink.
An fx that is missing or does not compile plays the sound dry.
- SoundLibrary wires source, stages, volume, destination in that
order. stats().last now also names pitch and stage count.
- The tab header picks one of the project's sounds and plays it
through the graph as it stands. Stop there ends only its own voice.
Tests:
- soundfx.test.ts (new, 11), sound-library (9, +2 for the wiring),
node-catalog (+1 for fx), graph and asset-groups adjusted
- e2e 34: ALL PASSED - 26 checks (+5: + menu opens the tab, palette,
2 effects, tab Play and game Play through the FX at -12 st)
- Gate on melektaus-atx: typecheck, lint, prettier clean, 239 of 240
test files green. The red one was sound-library (its fake
AudioContext had no playbackRate), fixed afterwards, gate not
re-run in full.
- Counter-check: without the audio rule in portsCompatible the port
test fails.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
93c0a80b7d
commit
de14f0f9e2
34 files changed
+899
-43
No files matched your search
@@ -72,6 +72,7 @@ import { type PlayHost, PlaySession, type WorldSnapshot } from './PlaySession';
|
||||
import { ProjectSession } from './ProjectSession';
|
||||
import { ParticlesEditor } from './particles/ParticlesEditor';
|
||||
import { ShaderEditor } from './shader/ShaderEditor';
|
||||
import { SoundFxEditor } from './soundfx/SoundFxEditor';
|
||||
import { StateMachineEditor } from './statemachine/StateMachineEditor';
|
||||
import { installShortcuts } from './shortcuts';
|
||||
import type { PlayFrom } from '../core/model/playSettings';
|
||||
@@ -93,6 +94,7 @@ export type CentreTab =
|
||||
| 'statemachine'
|
||||
| 'shader'
|
||||
| 'particles'
|
||||
| 'soundfx'
|
||||
| 'game'
|
||||
| 'texture'
|
||||
| 'vectorart'
|
||||
@@ -142,6 +144,7 @@ const PANE_ORDER = [
|
||||
'statemachine',
|
||||
'shader',
|
||||
'particles',
|
||||
'soundfx',
|
||||
'texture',
|
||||
'vectorart',
|
||||
'pixelart',
|
||||
@@ -161,6 +164,7 @@ const TAB_LABELS: Record<CentreTab, string> = {
|
||||
statemachine: 'State machine',
|
||||
shader: 'Shader',
|
||||
particles: 'Particles',
|
||||
soundfx: 'Sound FX',
|
||||
texture: 'Texture',
|
||||
vectorart: 'Vector art',
|
||||
pixelart: 'Pixel art',
|
||||
@@ -209,6 +213,7 @@ export class Editor implements PlayHost {
|
||||
readonly stateMachineEditor: StateMachineEditor;
|
||||
readonly shaderEditor: ShaderEditor;
|
||||
readonly particlesEditor: ParticlesEditor;
|
||||
readonly soundFxEditor: SoundFxEditor;
|
||||
readonly textureEditor: TextureEditor;
|
||||
readonly vectorArtEditor: VectorArtEditor;
|
||||
readonly pixelArtEditor: PixelArtEditor;
|
||||
@@ -294,6 +299,7 @@ export class Editor implements PlayHost {
|
||||
this.stateMachineEditor = new StateMachineEditor(state);
|
||||
this.shaderEditor = new ShaderEditor(state);
|
||||
this.particlesEditor = new ParticlesEditor(state);
|
||||
this.soundFxEditor = new SoundFxEditor(state);
|
||||
this.textureEditor = new TextureEditor(state);
|
||||
this.vectorArtEditor = new VectorArtEditor(state);
|
||||
this.pixelArtEditor = new PixelArtEditor(state);
|
||||
@@ -402,6 +408,7 @@ export class Editor implements PlayHost {
|
||||
statemachine: this.stateMachineEditor,
|
||||
shader: this.shaderEditor,
|
||||
particles: this.particlesEditor,
|
||||
soundfx: this.soundFxEditor,
|
||||
texture: this.textureEditor,
|
||||
vectorart: this.vectorArtEditor,
|
||||
pixelart: this.pixelArtEditor,
|
||||
@@ -591,6 +598,8 @@ export class Editor implements PlayHost {
|
||||
return this.shaderEditor.canvas.paste();
|
||||
case 'particles':
|
||||
return this.particlesEditor.canvas.paste();
|
||||
case 'soundfx':
|
||||
return this.soundFxEditor.canvas.paste();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user