@effetune/dsp 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -5
- package/dist/assets/effetune-dsp.meta.json +491 -7
- package/dist/assets/effetune-dsp.simd.wasm +0 -0
- package/dist/assets/effetune-dsp.wasm +0 -0
- package/dist/catalog/effects-v1.json +1778 -242
- package/dist/errors.js +21 -0
- package/dist/generated-effects.d.ts +317 -1
- package/dist/generated-effects.js +185 -3
- package/dist/generated-graph-contract.js +8 -0
- package/dist/graph-document.js +644 -0
- package/dist/graph-engine.js +493 -0
- package/dist/graph.js +467 -0
- package/dist/index.d.ts +268 -1
- package/dist/index.js +36 -0
- package/dist/internal/dsp-engine-binding.js +162 -1
- package/dist/internal/dsp-params.generated.js +537 -70
- package/dist/internal/dsp-wasm-loader.js +2 -0
- package/dist/preset.js +29 -0
- package/dist/runtime.js +73 -5
- package/dist/schemas/chain-v1.schema.json +1740 -167
- package/dist/schemas/graph-v1.schema.json +8208 -0
- package/dist/semantics.js +88 -30
- package/dist/worklet-processor.js +8 -1
- package/dist/worklet.d.ts +1 -0
- package/dist/worklet.js +15 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
<!-- BEGIN DSP-LIBRARY-JAVASCRIPT-SUMMARY -->
|
|
4
4
|
EffeTune DSP provides the same MIT-licensed C++ audio kernels used by EffeTune
|
|
5
5
|
as a self-contained WebAssembly package for Node.js and evergreen browsers.
|
|
6
|
-
Version 0.
|
|
7
|
-
`createEffect` APIs and
|
|
6
|
+
Version 0.5.0 exposes all 90 catalog types through the generic Chain and
|
|
7
|
+
`createEffect` APIs and 90 generated named convenience classes,
|
|
8
8
|
decoded analyzer telemetry, versioned semantic presets, deterministic seeds, and an AudioWorklet wrapper.
|
|
9
9
|
<!-- END DSP-LIBRARY-JAVASCRIPT-SUMMARY -->
|
|
10
10
|
|
|
@@ -39,6 +39,44 @@ const output = await chain.process(input, { sampleRate: 48000 });
|
|
|
39
39
|
console.log(output.length, output[0].length, output[0][0]);
|
|
40
40
|
chain.close();
|
|
41
41
|
```
|
|
42
|
+
|
|
43
|
+
### Graph v1 quickstart
|
|
44
|
+
|
|
45
|
+
Graph v1 is opt-in routing for branching and merging:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { Graph, createGraph, createVolume } from '@effetune/dsp';
|
|
49
|
+
|
|
50
|
+
const input = [
|
|
51
|
+
new Float32Array(128).fill(0.25),
|
|
52
|
+
new Float32Array(128).fill(0.25)
|
|
53
|
+
];
|
|
54
|
+
const graphDocument = Graph.wetDry(
|
|
55
|
+
createVolume({ id: 'wet', volume: -6 }),
|
|
56
|
+
{ dry: 0.5, wet: 0.5 }
|
|
57
|
+
);
|
|
58
|
+
const graph = await createGraph(graphDocument);
|
|
59
|
+
let stream;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const offline = await graph.process(input, { sampleRate: 48000 });
|
|
63
|
+
stream = await graph.stream({
|
|
64
|
+
sampleRate: 48000,
|
|
65
|
+
channels: 2,
|
|
66
|
+
blockSize: 128
|
|
67
|
+
});
|
|
68
|
+
const continuous = await stream.process(input);
|
|
69
|
+
console.log(
|
|
70
|
+
offline[0][0],
|
|
71
|
+
continuous[0][0],
|
|
72
|
+
stream.latencySamples,
|
|
73
|
+
stream.compileSnapshot.effectiveSchedule
|
|
74
|
+
);
|
|
75
|
+
} finally {
|
|
76
|
+
stream?.close();
|
|
77
|
+
graph.close();
|
|
78
|
+
}
|
|
79
|
+
```
|
|
42
80
|
<!-- END DSP-LIBRARY-JAVASCRIPT-START -->
|
|
43
81
|
|
|
44
82
|
The package is ESM-only. Save the example as `start.mjs` and run
|
|
@@ -51,10 +89,14 @@ Public package entry points are:
|
|
|
51
89
|
- `@effetune/dsp/worklet` for `EffeTuneNode`
|
|
52
90
|
- `@effetune/dsp/processor` for the side-effect AudioWorklet processor
|
|
53
91
|
- `@effetune/dsp/schemas/chain-v1.json` for the Chain v1 JSON Schema
|
|
92
|
+
- `@effetune/dsp/schemas/graph-v1.json` for the Graph v1 JSON Schema
|
|
54
93
|
- `@effetune/dsp/schemas/bundle-v1.json` for the Bundle v1 JSON Schema
|
|
55
94
|
- `@effetune/dsp/catalog` for ESM catalog exports
|
|
56
95
|
- `@effetune/dsp/catalog.json` for the machine-readable catalog JSON
|
|
57
96
|
|
|
97
|
+
Graph v1 is opt-in. Its current capacities and delay-storage accounting are
|
|
98
|
+
published in the [Graph v1 guide](https://effetune.frieve.com/dsp/reference/graph-v1/#capacity).
|
|
99
|
+
|
|
58
100
|
Every offline `process()` call starts from fresh DSP state and returns newly
|
|
59
101
|
owned `Float32Array` channels. Input arrays are never mutated. Effects run in
|
|
60
102
|
array order; a disabled effect and an empty chain are identity operations.
|
|
@@ -134,15 +176,73 @@ verify exact byte length and SHA-256 before accepting an ETA1 payload. The
|
|
|
134
176
|
complete payload and convolution footprint must fit the 32 MiB kernel cap.
|
|
135
177
|
|
|
136
178
|
`EFFECT_CATALOG` and `getEffectCatalog()` expose the machine-readable semantic
|
|
137
|
-
catalog for all
|
|
179
|
+
catalog for all 90 root classes and their `create<Type>()` factories. The
|
|
138
180
|
catalog contains channel choices, parameters, required assets, telemetry, and
|
|
139
181
|
latency declarations, but no private implementation mapping.
|
|
140
182
|
|
|
183
|
+
### Modulation Style recipes
|
|
184
|
+
|
|
185
|
+
The application-only **Style** selector is not a DSP parameter or a second
|
|
186
|
+
preset API. The following JSON-compatible objects are the equivalent public
|
|
187
|
+
parameter dictionaries. Copy one into a named constructor, for example
|
|
188
|
+
`new Chorus(MODULATION_STYLES.Chorus.Flanger)`, or into a Chain effect's
|
|
189
|
+
`parameters` object.
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
const MODULATION_STYLES = {
|
|
193
|
+
AutoFilter: {
|
|
194
|
+
"Auto Filter Sweep": { mode: "LFO", filterType: "Low-pass", minimumFrequency: 200, maximumFrequency: 4000, resonance: 1.5, mix: 80, rate: 0.5, waveform: "Sine", stereoPhase: 0, sensitivity: 24, attack: 20, release: 250, direction: "Up" },
|
|
195
|
+
"Stereo Filter Sweep": { mode: "LFO", filterType: "Low-pass", minimumFrequency: 160, maximumFrequency: 6000, resonance: 2, mix: 85, rate: 0.35, waveform: "Sine", stereoPhase: 120, sensitivity: 24, attack: 20, release: 250, direction: "Up" },
|
|
196
|
+
"Envelope Filter": { mode: "Envelope", filterType: "Low-pass", minimumFrequency: 100, maximumFrequency: 5000, resonance: 1.2, mix: 85, rate: 0.5, waveform: "Sine", stereoPhase: 0, sensitivity: 24, attack: 18, release: 300, direction: "Up" },
|
|
197
|
+
"Auto Wah": { mode: "Envelope", filterType: "Band-pass", minimumFrequency: 180, maximumFrequency: 2400, resonance: 5, mix: 100, rate: 0.5, waveform: "Sine", stereoPhase: 0, sensitivity: 30, attack: 8, release: 180, direction: "Up" },
|
|
198
|
+
"Reverse Auto Wah": { mode: "Envelope", filterType: "Band-pass", minimumFrequency: 180, maximumFrequency: 2800, resonance: 4, mix: 100, rate: 0.5, waveform: "Sine", stereoPhase: 0, sensitivity: 30, attack: 12, release: 350, direction: "Down" }
|
|
199
|
+
},
|
|
200
|
+
AutoPan: {
|
|
201
|
+
"Gentle Auto Pan": { rate: 0.35, depth: 45, center: 0, width: 70, waveform: "Sine", phase: 0 },
|
|
202
|
+
"Wide Auto Pan": { rate: 0.7, depth: 100, center: 0, width: 100, waveform: "Sine", phase: 0 },
|
|
203
|
+
"Fast Auto Pan": { rate: 4, depth: 85, center: 0, width: 100, waveform: "Triangle", phase: 0 }
|
|
204
|
+
},
|
|
205
|
+
Chorus: {
|
|
206
|
+
"Classic Chorus": { mode: "Chorus", rate: 0.8, delay: 12, depth: 3, voices: 3, stereoSpread: 60, feedback: 0, mix: 45 },
|
|
207
|
+
"Stereo Chorus": { mode: "Stereo Chorus", rate: 0.65, delay: 15, depth: 4, voices: 2, stereoSpread: 80, feedback: 0, mix: 50 },
|
|
208
|
+
Ensemble: { mode: "Ensemble", rate: 0.45, delay: 20, depth: 6, voices: 6, stereoSpread: 100, feedback: 0, mix: 60 },
|
|
209
|
+
Flanger: { mode: "Flanger", rate: 0.35, delay: 2.5, depth: 2, voices: 1, stereoSpread: 35, feedback: 45, mix: 50 },
|
|
210
|
+
"Jet Flanger": { mode: "Flanger", rate: 0.18, delay: 1.5, depth: 1.4, voices: 1, stereoSpread: 70, feedback: -75, mix: 55 },
|
|
211
|
+
Vibrato: { mode: "Vibrato", rate: 4.5, delay: 8, depth: 5, voices: 1, stereoSpread: 50, feedback: 0, mix: 100 }
|
|
212
|
+
},
|
|
213
|
+
FrequencyShifter: {
|
|
214
|
+
"Shift Up": { mode: "Shift", shift: 8, carrierFrequency: 440, minimumShift: 20, maximumShift: 800, rate: 0.15, direction: "Up", stereoPhase: 0, mix: 100 },
|
|
215
|
+
"Shift Down": { mode: "Shift", shift: -8, carrierFrequency: 440, minimumShift: 20, maximumShift: 800, rate: 0.15, direction: "Down", stereoPhase: 0, mix: 100 },
|
|
216
|
+
"Fine Detune": { mode: "Shift", shift: 2, carrierFrequency: 440, minimumShift: 20, maximumShift: 800, rate: 0.15, direction: "Up", stereoPhase: 90, mix: 55 },
|
|
217
|
+
"Ring Modulator": { mode: "Ring Mod", shift: 8, carrierFrequency: 440, minimumShift: 20, maximumShift: 800, rate: 0.15, direction: "Up", stereoPhase: 0, mix: 100 },
|
|
218
|
+
"Barber-pole Up": { mode: "Barber-pole", shift: 8, carrierFrequency: 440, minimumShift: 20, maximumShift: 900, rate: 0.12, direction: "Up", stereoPhase: 90, mix: 85 },
|
|
219
|
+
"Barber-pole Down": { mode: "Barber-pole", shift: -8, carrierFrequency: 440, minimumShift: 20, maximumShift: 900, rate: 0.12, direction: "Down", stereoPhase: 90, mix: 85 }
|
|
220
|
+
},
|
|
221
|
+
Phaser: {
|
|
222
|
+
"Classic Phaser": { mode: "Classic", rate: 0.5, centerFrequency: 1000, range: 3, stages: 6, feedback: 20, stereoPhase: 90, direction: "Up", mix: 50 },
|
|
223
|
+
"Deep Phaser": { mode: "Classic", rate: 0.25, centerFrequency: 700, range: 4.5, stages: 12, feedback: 55, stereoPhase: 30, direction: "Up", mix: 55 },
|
|
224
|
+
"Stereo Phaser": { mode: "Classic", rate: 0.65, centerFrequency: 1200, range: 3.5, stages: 8, feedback: 25, stereoPhase: 120, direction: "Up", mix: 50 },
|
|
225
|
+
"Barber-pole Up": { mode: "Barber-pole", rate: 0.35, centerFrequency: 1000, range: 5, stages: 8, feedback: 30, stereoPhase: 60, direction: "Up", mix: 55 },
|
|
226
|
+
"Barber-pole Down": { mode: "Barber-pole", rate: 0.35, centerFrequency: 1000, range: 5, stages: 8, feedback: 30, stereoPhase: 60, direction: "Down", mix: 55 }
|
|
227
|
+
},
|
|
228
|
+
RotarySpeaker: {
|
|
229
|
+
"Rotary Slow": { speedState: "Slow", speed: 100, acceleration: 2.2, crossover: 800, rotorBalance: 0, stereoWidth: 75, dopplerDepth: 45, amplitudeDepth: 55, mix: 70 },
|
|
230
|
+
"Rotary Fast": { speedState: "Fast", speed: 100, acceleration: 1.4, crossover: 800, rotorBalance: 0, stereoWidth: 85, dopplerDepth: 65, amplitudeDepth: 70, mix: 78 },
|
|
231
|
+
"Gentle Rotary": { speedState: "Slow", speed: 75, acceleration: 3, crossover: 900, rotorBalance: 0, stereoWidth: 45, dopplerDepth: 25, amplitudeDepth: 30, mix: 55 },
|
|
232
|
+
"Leslie Slow": { speedState: "Slow", speed: 100, acceleration: 2.8, crossover: 800, rotorBalance: -5, stereoWidth: 80, dopplerDepth: 50, amplitudeDepth: 60, mix: 75 },
|
|
233
|
+
"Leslie Fast": { speedState: "Fast", speed: 100, acceleration: 1.8, crossover: 800, rotorBalance: -5, stereoWidth: 90, dopplerDepth: 70, amplitudeDepth: 75, mix: 82 }
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
|
|
141
238
|
For stateful processing, `ChainStream.latencySamples` reports aggregate runtime
|
|
142
239
|
latency and matches Python `Stream.latency_samples` for the same chain and
|
|
143
240
|
sample rate. `chain.latencySamples({ sampleRate })` reports the same value
|
|
144
|
-
without opening a stream
|
|
145
|
-
|
|
241
|
+
without opening a stream. `EffeTuneNode.latencySamples` exposes the cached
|
|
242
|
+
aggregate for real-time processing; initialization and awaited `setParam()` or
|
|
243
|
+
`reset()` calls update it before returning. These APIs report latency without
|
|
244
|
+
trimming or padding offline output, so the host decides how to place rendered
|
|
245
|
+
audio.
|
|
146
246
|
|
|
147
247
|
For real-time processing:
|
|
148
248
|
|
|
@@ -156,6 +256,7 @@ const node = await EffeTuneNode.create(context, preset, {
|
|
|
156
256
|
});
|
|
157
257
|
source.connect(node).connect(context.destination);
|
|
158
258
|
await node.setParam('voice', 'threshold', -20);
|
|
259
|
+
console.log(node.latencySamples);
|
|
159
260
|
await node.reset();
|
|
160
261
|
node.close();
|
|
161
262
|
```
|