@weasel-js/audio 1.11.0 → 1.12.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 +21 -0
- package/dist/index.d.ts +160 -2
- package/dist/index.js +890 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,6 +180,27 @@ fade is `insertFadeMs`, default 15. A move is a splice out and a splice back in,
|
|
|
180
180
|
so the moved effect drops out for one fade. A removed effect's `dispose` runs
|
|
181
181
|
once it has left the graph.
|
|
182
182
|
|
|
183
|
+
## Patchable graph
|
|
184
|
+
|
|
185
|
+
`engine.graph(bus)` returns a graph of nodes feeding that bus's input (the
|
|
186
|
+
first bus by default), which can be edited while it plays. Every structural
|
|
187
|
+
edit crossfades — `add`, `remove`, `replace`, `connect`, `disconnect` — and
|
|
188
|
+
`set` ramps a param. Sources are `createFileSourceNode` (a looping buffer),
|
|
189
|
+
`createOscillatorNode` and `createNoiseNode`; `createGainNode`,
|
|
190
|
+
`createPanNode`, `createMixNode`, `filterNode`, `delayNode`, `reverbNode` and
|
|
191
|
+
`compressorNode` process, and `insertNode` wraps any insert effect. `tap(id)`
|
|
192
|
+
puts an analyser on a node. The graph is disposed with the engine.
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
const g = engine.graph('music');
|
|
196
|
+
g.add('osc', createOscillatorNode(engine.context, { frequency: 220 }));
|
|
197
|
+
g.add('echo', delayNode(engine.context, { time: 300, feedback: 0.4 }));
|
|
198
|
+
g.connect('osc', { node: 'echo', port: 'in' });
|
|
199
|
+
g.connect('echo', { output: true });
|
|
200
|
+
g.start();
|
|
201
|
+
g.replace('osc', createOscillatorNode(engine.context, { wave: 'square', frequency: 220 }));
|
|
202
|
+
```
|
|
203
|
+
|
|
183
204
|
## Streaming
|
|
184
205
|
|
|
185
206
|
`load` and `decode` hold a whole sound in memory, which is wrong for a long
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ interface AnalyserTap {
|
|
|
24
24
|
}
|
|
25
25
|
/** Attach a new `AnalyserNode` to `source`. The tap only listens, adding no
|
|
26
26
|
* path to the destination; `dispose()` detaches it. */
|
|
27
|
-
declare function createAnalyserTap(ctx:
|
|
27
|
+
declare function createAnalyserTap(ctx: BaseAudioContext, source: AudioNode, opts?: AnalyserTapOptions): AnalyserTap;
|
|
28
28
|
|
|
29
29
|
/** A one-shot timer pair, as `AudioEngineOptions.setTimer` takes it. */
|
|
30
30
|
interface Timers {
|
|
@@ -127,6 +127,88 @@ type BusGraphOptions = InsertChainOptions;
|
|
|
127
127
|
*/
|
|
128
128
|
declare function createBusGraph(ctx: AudioContext, names: string[], opts?: BusGraphOptions): BusGraph;
|
|
129
129
|
|
|
130
|
+
/** What a node factory returns and the graph wraps. `inputs` is empty for a source. */
|
|
131
|
+
interface GraphNodeDef {
|
|
132
|
+
readonly inputs: Readonly<Record<string, AudioNode>>;
|
|
133
|
+
readonly output: AudioNode;
|
|
134
|
+
/** `rampMs` is always passed; the graph supplies its fade when the caller gives none. */
|
|
135
|
+
readonly params: Readonly<Record<string, (value: number, rampMs: number) => void>>;
|
|
136
|
+
/** Sources only. `when` is context seconds. Called when the graph starts, or on add/replace while it runs. A source must be startable again after `stop`.
|
|
137
|
+
* A source that stops on its own, as a non-looping file reaching its end does, calls `ended` so the graph can start it again. */
|
|
138
|
+
start?(when: number, ended?: () => void): void;
|
|
139
|
+
/** Sources only. Stop at `when` (context seconds). */
|
|
140
|
+
stop?(when: number): void;
|
|
141
|
+
/** Called once, after the node has faded out of the graph. */
|
|
142
|
+
dispose?(): void;
|
|
143
|
+
}
|
|
144
|
+
/** A connection's far end: a node's named input port, or the graph's output. */
|
|
145
|
+
type GraphTarget = {
|
|
146
|
+
node: string;
|
|
147
|
+
port: string;
|
|
148
|
+
} | {
|
|
149
|
+
output: true;
|
|
150
|
+
};
|
|
151
|
+
/** One edit to an `AudioGraph`, applied by its `apply` in order. */
|
|
152
|
+
type GraphPatch = {
|
|
153
|
+
kind: 'add';
|
|
154
|
+
id: string;
|
|
155
|
+
def: GraphNodeDef;
|
|
156
|
+
} | {
|
|
157
|
+
kind: 'remove';
|
|
158
|
+
id: string;
|
|
159
|
+
} | {
|
|
160
|
+
kind: 'replace';
|
|
161
|
+
id: string;
|
|
162
|
+
def: GraphNodeDef;
|
|
163
|
+
} | {
|
|
164
|
+
kind: 'connect';
|
|
165
|
+
from: string;
|
|
166
|
+
to: GraphTarget;
|
|
167
|
+
} | {
|
|
168
|
+
kind: 'disconnect';
|
|
169
|
+
from: string;
|
|
170
|
+
to: GraphTarget;
|
|
171
|
+
} | {
|
|
172
|
+
kind: 'set';
|
|
173
|
+
id: string;
|
|
174
|
+
param: string;
|
|
175
|
+
value: number;
|
|
176
|
+
rampMs?: number;
|
|
177
|
+
};
|
|
178
|
+
/** Options for `AudioGraph`: the crossfade length (`fadeMs`) and any timer overrides. */
|
|
179
|
+
interface AudioGraphOptions extends Partial<Timers> {
|
|
180
|
+
/** Crossfade for every structural edit, and the default ramp for `set`, in ms. Default 15. */
|
|
181
|
+
fadeMs?: number;
|
|
182
|
+
}
|
|
183
|
+
/** A patchable graph of nodes that can be added, wired and set while it plays. */
|
|
184
|
+
interface AudioGraph {
|
|
185
|
+
add(id: string, def: GraphNodeDef): void;
|
|
186
|
+
remove(id: string): void;
|
|
187
|
+
replace(id: string, def: GraphNodeDef): void;
|
|
188
|
+
connect(from: string, to: GraphTarget): void;
|
|
189
|
+
disconnect(from: string, to: GraphTarget): void;
|
|
190
|
+
set(id: string, param: string, value: number, rampMs?: number): void;
|
|
191
|
+
/** Applies in order; each patch calls the method of the same name.
|
|
192
|
+
* A structural error anywhere in the list throws before anything changes.
|
|
193
|
+
* A param write that throws is skipped; the rest apply, then its error is rethrown. */
|
|
194
|
+
apply(patches: readonly GraphPatch[]): void;
|
|
195
|
+
/** Start every source now, and every source added later, until `stop`. */
|
|
196
|
+
start(): void;
|
|
197
|
+
/** Fade the graph's output to silence over `fadeMs`, then stop every source. */
|
|
198
|
+
stop(): void;
|
|
199
|
+
playing(): boolean;
|
|
200
|
+
has(id: string): boolean;
|
|
201
|
+
ids(): string[];
|
|
202
|
+
/** Listens to a node's output; survives `replace`; disposed with the node. */
|
|
203
|
+
tap(id: string, opts?: AnalyserTapOptions): AnalyserTap;
|
|
204
|
+
/** Resolves once no fade is in flight. */
|
|
205
|
+
settled(): Promise<void>;
|
|
206
|
+
/** Cancels fades, stops sources, disposes every def and tap, disconnects from the destination.
|
|
207
|
+
* While it may be sounding on a running context, it first fades the output out over `fadeMs`;
|
|
208
|
+
* every mutator throws from the call on. */
|
|
209
|
+
dispose(): void;
|
|
210
|
+
}
|
|
211
|
+
|
|
130
212
|
/** Opaque reference to a decoded sound. Mirrors `TextureHandle` in core. */
|
|
131
213
|
interface SoundHandle {
|
|
132
214
|
readonly id: string;
|
|
@@ -522,6 +604,8 @@ interface AudioEngine {
|
|
|
522
604
|
* for a future `when` is not counted until it starts. */
|
|
523
605
|
activeVoices(bus?: string): number;
|
|
524
606
|
analyser(busName?: string, opts?: AnalyserTapOptions): AnalyserTap;
|
|
607
|
+
/** A graph feeding `bus`'s input (default: the first bus). Disposed with the engine. */
|
|
608
|
+
graph(bus?: string): AudioGraph;
|
|
525
609
|
setListener(p: Vec2, opts?: SpatialOptions): void;
|
|
526
610
|
dispose(): void;
|
|
527
611
|
}
|
|
@@ -1008,4 +1092,78 @@ declare function biquadCoefficients(type: BiquadFilterType, frequency: number, s
|
|
|
1008
1092
|
/** How much a filter with coefficients `c` passes at `hz`, in dB. */
|
|
1009
1093
|
declare function biquadResponseDb(c: BiquadCoefficients, hz: number, sampleRate: number): number;
|
|
1010
1094
|
|
|
1011
|
-
|
|
1095
|
+
/** Options for `impulseResponse`: the tail's decay, channel count and noise seed. */
|
|
1096
|
+
interface ImpulseResponseOptions {
|
|
1097
|
+
/** How far the tail falls by its end, dB. Default 60 (an RT60). */
|
|
1098
|
+
decayDb?: number;
|
|
1099
|
+
/** Default 2. */
|
|
1100
|
+
channels?: number;
|
|
1101
|
+
/** Seed for the noise, so the same call makes the same buffer. Default 1. */
|
|
1102
|
+
seed?: number;
|
|
1103
|
+
}
|
|
1104
|
+
/** Noise under an exponential decay that falls `decayDb` over `seconds`. */
|
|
1105
|
+
declare function impulseResponse(ctx: BaseAudioContext, seconds: number, opts?: ImpulseResponseOptions): AudioBuffer;
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* A patchable graph of node defs feeding `destination`. Every structural edit
|
|
1109
|
+
* fades: a connection opens through its own gain and closes through it before
|
|
1110
|
+
* the cut, and a removed node leaves once its edges have closed.
|
|
1111
|
+
*/
|
|
1112
|
+
declare function createAudioGraph(ctx: BaseAudioContext, destination: AudioNode, opts?: AudioGraphOptions): AudioGraph;
|
|
1113
|
+
|
|
1114
|
+
/** The waves an oscillator node takes: any `Waveform` except an inharmonic one. */
|
|
1115
|
+
type OscillatorWave = Exclude<Waveform, Inharmonic>;
|
|
1116
|
+
/** Options for `createFileSourceNode`: the buffer to play and whether it loops. */
|
|
1117
|
+
interface FileSourceNodeOptions {
|
|
1118
|
+
buffer: AudioBuffer;
|
|
1119
|
+
/** Default true. */
|
|
1120
|
+
loop?: boolean;
|
|
1121
|
+
}
|
|
1122
|
+
/** Plays a buffer, picking up where `stop` left it. Params: `rate`, `level`. */
|
|
1123
|
+
declare function createFileSourceNode(ctx: BaseAudioContext, opts: FileSourceNodeOptions): GraphNodeDef;
|
|
1124
|
+
/** Options for `createOscillatorNode`: the wave shape and starting frequency. */
|
|
1125
|
+
interface OscillatorNodeOptions {
|
|
1126
|
+
/** Default 'sine'. An array is the amplitude of each whole-number partial. */
|
|
1127
|
+
wave?: OscillatorWave;
|
|
1128
|
+
/** Hz. Default 440. */
|
|
1129
|
+
frequency?: number;
|
|
1130
|
+
}
|
|
1131
|
+
/** A tone. Params: `frequency`, `detune`, `level`. */
|
|
1132
|
+
declare function createOscillatorNode(ctx: BaseAudioContext, opts: OscillatorNodeOptions): GraphNodeDef;
|
|
1133
|
+
/** Options for `createNoiseNode`: the noise color whose shared buffer it loops. */
|
|
1134
|
+
interface NoiseNodeOptions {
|
|
1135
|
+
color: NoiseColor;
|
|
1136
|
+
}
|
|
1137
|
+
/** A loop of the shared noise buffer for its color. Param: `level`. */
|
|
1138
|
+
declare function createNoiseNode(ctx: BaseAudioContext, opts: NoiseNodeOptions): GraphNodeDef;
|
|
1139
|
+
|
|
1140
|
+
/** A graph node that multiplies its input by a gain: port `in`; param `gain`. */
|
|
1141
|
+
declare function createGainNode(ctx: BaseAudioContext, opts?: {
|
|
1142
|
+
gain?: number;
|
|
1143
|
+
}): GraphNodeDef;
|
|
1144
|
+
/** A graph node that pans its input in stereo: port `in`; param `pan`. */
|
|
1145
|
+
declare function createPanNode(ctx: BaseAudioContext, opts?: {
|
|
1146
|
+
pan?: number;
|
|
1147
|
+
}): GraphNodeDef;
|
|
1148
|
+
/** One port and one level param per name in `inputs`, summed into `output`. */
|
|
1149
|
+
declare function createMixNode(ctx: BaseAudioContext, opts: {
|
|
1150
|
+
inputs: readonly string[];
|
|
1151
|
+
}): GraphNodeDef;
|
|
1152
|
+
/** Wrap an insert effect as a node with one port, `in`. */
|
|
1153
|
+
declare function insertNode(effect: InsertEffect, params: GraphNodeDef['params']): GraphNodeDef;
|
|
1154
|
+
/** A graph node over a filter insert: port `in`; params `frequency`, `Q`, `gain`. */
|
|
1155
|
+
declare function filterNode(ctx: BaseAudioContext, opts?: FilterEffectOptions): GraphNodeDef;
|
|
1156
|
+
/** A graph node over a delay insert: port `in`; params `time` (ms), `feedback`, `mix`. */
|
|
1157
|
+
declare function delayNode(ctx: BaseAudioContext, opts?: DelayEffectOptions): GraphNodeDef;
|
|
1158
|
+
/** Options for `reverbNode`: the reverb effect's options, plus an `impulse` or the `seconds` of a synthesized one. */
|
|
1159
|
+
type ReverbNodeOptions = Omit<ReverbEffectOptions, 'impulse'> & {
|
|
1160
|
+
impulse?: AudioBuffer;
|
|
1161
|
+
/** Length of the synthesized impulse when none is given. Default 2. */
|
|
1162
|
+
seconds?: number;
|
|
1163
|
+
};
|
|
1164
|
+
/** A graph node over a reverb insert: port `in`; param `mix`. */
|
|
1165
|
+
declare function reverbNode(ctx: BaseAudioContext, opts?: ReverbNodeOptions): GraphNodeDef;
|
|
1166
|
+
/** A graph node over a compressor insert: port `in`; params `threshold`, `knee`, `ratio`, `attack` (ms), `release` (ms), `makeup`. */
|
|
1167
|
+
declare function compressorNode(ctx: BaseAudioContext, opts?: CompressorEffectOptions): GraphNodeDef;
|
|
1168
|
+
|
|
1169
|
+
export { type Acquisition, type AnalyserTap, type AnalyserTapOptions, type AudioEngine, type AudioEngineOptions, type AudioGraph, type AudioGraphOptions, type BiquadCoefficients, type BusGraph, type BusGraphOptions, type BusHandle, type CompressorEffect, type CompressorEffectOptions, type DelayEffect, type DelayEffectOptions, type Envelope, type EnvelopePoint, type FileSourceNodeOptions, type FilterEffect, type FilterEffectOptions, type Glide, type GraphNodeDef, type GraphPatch, type GraphTarget, type ImpulseResponseOptions, type Inharmonic, type InsertAddOptions, type InsertChain, type InsertChainOptions, type InsertEffect, type InsertSlot, type KernelNoise, type KernelNote, type NoiseColor, type NoiseNodeOptions, type NoiseOptions, type NoisePatch, type NoteOptions, type OscillatorNodeOptions, type OscillatorWave, type PatternDetune, type PatternEvent, type PatternHit, type PatternLoadOptions, type PatternNoise, type PatternNote, type PatternPlayer, type PatternPlayerOptions, type Pitch, type PlayOptions, type ResolvedEnvelope, type ReverbEffect, type ReverbEffectOptions, type ReverbNodeOptions, SCORE_BAR_STEPS, type Scheduler, type SchedulerOptions, type Score, type ScoreBarOptions, type ScoreCue, type ScoreCueName, type ScoreCueReading, type ScoreMode, type ScoreMood, type ScoreOptions, type ScoreParams, type ScoreState, type SoundCache, type SoundHandle, type SpatialOptions, type StealPolicy, type StreamOptions, type SynthPartial, type SynthPatch, type TickTimer, type Vec2, type VoiceDropReason, type VoiceFilter, type VoiceHandle, type VoiceKernel, type VoicePool, type VoicePoolOptions, type VoiceRecord, type Waveform, type WetDryMix, biquadCoefficients, biquadResponseDb, compressorNode, createAnalyserTap, createAudioEngine, createAudioGraph, createBusGraph, createCompressorEffect, createDelayEffect, createFileSourceNode, createFilterEffect, createGainNode, createMixNode, createNoiseKernel, createNoiseNode, createNoteKernel, createOscillatorNode, createPanNode, createPatternPlayer, createReverbEffect, createScheduler, createScore, createSoundCache, createTickTimer, createVoicePool, delayNode, envelopeLevel, envelopePoints, filterNode, impulseResponse, insertNode, midiToFrequency, noiseSamples, noteToMidi, partialPresets, patternLength, patternVoicePeaks, readScoreCue, renderNoise, renderNote, resolveEnvelope, reverbNode, scoreBar, scoreChord, scoreCues, scoreModes, scoreParams, spatialize, toFrequency };
|