-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.d.ts
335 lines (318 loc) · 15.4 KB
/
types.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
import { WamNodeOptions, WamParameterInfoMap, WamNode, WamParameterConfiguration, WamEvent, WebAudioModule, WamEventMap, WamParameter, WamProcessor, WamParameterInfo } from '@webaudiomodules/api';
import { TypedAudioWorkletNode, TypedAudioWorkletNodeOptions } from './TypedAudioWorklet';
export class AudioWorkletRegister {
/**
* Register a AudioWorklet processor in a closure,
* sending to AudioWorkletProcessor with an unique identifier
* avoiding double registration
*
* @param {string} moduleId if duplicated, the processor will not be readded.
* @param {(id: string, ...injections: any[]) => void} processor a serializable function that contains an AudioWorkletProcessor
* with its registration in the AudioWorkletGlobalScope
* @param {AudioWorklet} audioWorklet AudioWorklet instance
* @param {...any[]} injection this will be serialized and injected to the `processor` function
* @returns {Promise<void>} a Promise<void>
*/
static register(moduleId: string, processor: (id: string, ...injections: any[]) => void, audioWorklet: AudioWorklet, ...injection: any[]): Promise<void>;
}
export interface InternalParameterDescriptor {
/** `0` by default */
defaultValue?: number;
/** `0` by default */
minValue?: number;
/** `1` by default */
maxValue?: number;
/** `30` (1/30s for each change check) by default */
automationRate?: number;
/** The default event listener, the event will be fired when the param get changed */
onChange?: (value: number, previousValue: number) => any;
}
export type InternalParametersDescriptor<InternalParams extends string = string> = Record<InternalParams, AudioParam | InternalParameterDescriptor>;
export interface ParameterMappingTarget {
/** Source param's `[minValue, maxValue]` by default */
sourceRange?: [number, number];
/** Source param's `[minValue, maxValue]` by default */
targetRange?: [number, number];
}
export type ParametersMapping<Params extends string = string, InternalParams extends string = string> = Record<Params, Record<InternalParams, ParameterMappingTarget>>;
export interface ParametersMappingConfiguratorOptions<Params extends string = string, InternalParams extends string = string> {
paramsConfig?: Record<Params, WamParameterConfiguration>;
paramsMapping?: ParametersMapping<Params, InternalParams>;
internalParamsConfig?: InternalParametersDescriptor<InternalParams>;
groupId?: string;
instanceId?: string;
}
export type PromisifiedFunction<F extends (...args: any[]) => any> = (...args: Parameters<F>) => PromiseLike<ReturnType<F>>;
export type UnPromisifiedFunction<F extends (...args: any[]) => any> = (...args: Parameters<F>) => ReturnType<F> extends PromiseLike<infer P> ? P : ReturnType<F>;
export type PromisifiedFunctionMap<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? PromisifiedFunction<T[K]> : T[K];
};
export type UnPromisifiedFunctionMap<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? UnPromisifiedFunction<T[K]> : T[K];
};
export interface MessagePortRequest<M = Record<string, (...args: any[]) => any>, K extends keyof M = keyof M> {
id: number;
call: K;
args?: M[K] extends (...args: any[]) => any ? Parameters<M[K]> : M[K];
}
export interface MessagePortResponse<M = Record<string, any>, K extends keyof M = keyof M> {
id: number;
value?: M[K] extends (...args: any[]) => any ? ReturnType<M[K]> : M[K];
error?: Error;
}
export interface ParamMgrCallToProcessor extends UnPromisifiedFunctionMap<Pick<WamNode, 'destroy' | 'getCompensationDelay' | 'getParameterInfo' | 'getParameterValues' | 'scheduleEvents' | 'clearEvents'>> {
connectEvents(wamInstanceId: string, from: number): void;
disconnectEvents(wamInstanceId: string, from: number): void;
emitEvents(...events: WamEvent[]): void;
setParamsMapping(mapping: ParametersMapping): void;
getBuffer(): { lock: Int32Array, paramsBuffer: Float32Array };
}
export interface ParamMgrCallFromProcessor {
setBuffer(buffer: { lock: Int32Array, paramsBuffer: Float32Array }): void;
dispatchWamEvent(event: WamEvent): void;
}
export interface ParamMgrAudioWorkletOptions extends WamNodeOptions {
paramsConfig: WamParameterInfoMap;
paramsMapping: ParametersMapping;
internalParamsMinValues: number[];
internalParams: string[];
}
export interface ParamMgrOptions extends TypedAudioWorkletNodeOptions<ParamMgrAudioWorkletOptions> {
internalParamsConfig: InternalParametersDescriptor;
}
/**
* A `WamParameter` API-compatible `AudioParam` class/interface.
* All `AudioParam`s generated from the `ParamMgr` will inherit this class
*/
export interface MgrAudioParam extends AudioParam, WamParameter {
_info: WamParameterInfo;
// normalized version of methods
cancelAndHoldAtTime(cancelTime: number): MgrAudioParam;
cancelScheduledValues(cancelTime: number): MgrAudioParam;
exponentialRampToValueAtTime(value: number, endTime: number): MgrAudioParam;
exponentialRampToNormalizedValueAtTime(value: number, endTime: number): MgrAudioParam;
linearRampToValueAtTime(value: number, endTime: number): MgrAudioParam;
linearRampToNormalizedValueAtTime(value: number, endTime: number): MgrAudioParam;
setTargetAtTime(target: number, startTime: number, timeConstant: number): MgrAudioParam;
setNormalizedTargetAtTime(target: number, startTime: number, timeConstant: number): MgrAudioParam;
setValueAtTime(value: number, startTime: number): MgrAudioParam;
setNormalizedValueAtTime(value: number, startTime: number): MgrAudioParam;
setValueCurveAtTime(values: number[] | Float32Array | Iterable<number>, startTime: number, duration: number): MgrAudioParam;
setNormalizedValueCurveAtTime(values: number[] | Float32Array | Iterable<number>, startTime: number, duration: number): MgrAudioParam;
}
export const MgrAudioParam: {
prototype: MgrAudioParam;
};
// ParamMgrNode
export interface ParamMgrNodeMsgIn extends MessagePortResponse<ParamMgrCallToProcessor>, MessagePortRequest<ParamMgrCallFromProcessor> {}
export interface ParamMgrNodeMsgOut extends MessagePortRequest<ParamMgrCallToProcessor>, MessagePortResponse<ParamMgrCallFromProcessor> {}
/**
* Parameter Manager is an implementation of `WamNode`,
* it uses native `WebAudio` `AudioParam` to adapt `WamParameter` API for automations.
* It can be used to create automatable values that will be changed with two methods:
*
* 1. if the automated value is an `AudioParam`:
*
* According to the `WebAudio` [Spec](https://webaudio.github.io/web-audio-api/#computation-of-value),
* the `computedValue` of the automated `AudioParam` is the sum of its `paramIntrinsicValue` (`value` attribute) and its audio input.
* The `ParamMgr` uses this property to automate `AudioParam`s.
* It will create corresponding audio output that is connected to the automated `AudioParam`.
*
* Meanwhile, the `paramIntrinsicValue` will be set to its `minValue`.
*
* Note: as the automated `AudioParam` value is fixed, to get its actual value, please use `getIParamValue()` method.
* `BiquadFilterNode.getFrequencyResponse()` will not work if its `AudioParam`s are automated in this case.
*
* 2. if the automated value is not an `AudioParam`
*
* While setting up the `ParamMgr`, user can provide an `onChange` callback for any furthur opertion
* along with an `automationRate` in milliseconds as the frequency of calling the callback if the value has been changed.
*
* The rate cannot succeed `k-rate` as the function call on the main thread.
*/
export interface ParamMgrNode<Params extends string = string, InternalParams extends string = Params> extends TypedAudioWorkletNode<ParamMgrNodeMsgIn, ParamMgrNodeMsgOut, Params, WamEventMap>, Omit<WamNode, keyof AudioWorkletNode>, ParamMgrCallFromProcessor {
readonly module: WebAudioModule;
/**
* The state of the initialization.
*/
readonly initialized: boolean;
/**
* An array that contains ordered internal params names.
* The order is important for the output connections and for the parameters' values buffer
* @deprecated
*/
readonly internalParams: InternalParams[];
/**
* The plugin's internal parameters description.
* Used for denormalize normalized exposed parameters values
*/
readonly internalParamsConfig: InternalParametersDescriptor<InternalParams>;
/**
* The lock will be true if the `$paramsBuffer` is changing by the processor.
* This is a view of a `SharedArrayBuffer`
* @deprecated
*/
readonly $lock: Int32Array;
/**
* The values of internal parameters,
* contains one value for each param,
* will be updated each `AudioWorklet` buffer.
* This is a view of a `SharedArrayBuffer`
* @deprecated
*/
readonly $paramsBuffer: Float32Array;
/**
* Previous params value since last event dispatch of any
* non-AudioParam internal parameters
* @deprecated
*/
readonly $prevParamsBuffer: Float32Array;
/**
* Event dispatch callbacks reference of the `setTimeout` calls.
* Used to clear the callbacks while destroying the plugin.
* @deprecated
*/
readonly paramsUpdateCheckFnRef: number[];
/**
* Event dispatch callback functions bound to specific values for the parameter.
* @deprecated
*/
readonly paramsUpdateCheckFn: number[];
/**
* waiting for the processor that gives the `paramsBuffer` `SharedArrayBuffer`
*/
initialize(): Promise<ParamMgrNode>;
/**
* convert an WebAudio time stamp to frame index
*/
convertTimeToFrame(time: number): number;
/**
* convert a frame index to WebAudio time stamp
*/
convertFrameToTime(frame: number): number;
/**
* Force to check if an internal param is updated to dispatch immediately value change event if necessary.
* Note that the event will also be throttled to the automation rate.
*/
requestDispatchIParamChange(name: InternalParams): void;
/**
* get the output index of an internal parameter from its name,
* null if not exist
*/
getIParamIndex(name: InternalParams): number | null;
/**
* connect an internal parameter audio output to an AudioParam or an AudioNode.
* Note that if the destination is declared in the `internalParamsConfig`,
* there is no need to reconnect it.
*/
connectIParam(name: InternalParams, dest: AudioParam | AudioNode, index?: number): void;
/**
* disonnect an internal parameter audio output to an AudioParam or an AudioNode.
*/
disconnectIParam(name: InternalParams, dest?: AudioParam | AudioNode, index?: number): void;
/**
* get the current value of an internal parameter
*/
getIParamValue(name: InternalParams): number;
/**
* get the current value of every internal parameters
*/
getIParamsValues(): Record<InternalParams, number>;
/**
* get the `AudioParam` instance of an exposed parameter
*/
getParam(name: Params): AudioParam;
/**
* get the `AudioParam` instance of every exposed parameters
*/
getParams(): Record<Params, AudioParam>;
/**
* get the current value of an exposed parameter,
* shorthand for `AudioParam.prototype.value`
*/
getParamValue(name: Params): number;
/**
* get the current value of an exposed parameter,
* shorthand for `AudioParam.prototype.value = value`
*/
setParamValue(name: Params, value: number): void;
/**
* get the current value of every exposed parameters
*/
getParamsValues(): Record<Params, number>;
/**
* set the current value of every exposed parameters
*/
setParamsValues(values: Partial<Record<Params, number>>): void;
/**
* normalized value version of `getParamValue()`
*/
getNormalizedParamValue(name: Params): number;
/**
* normalized value version of `setParamValue()`
*/
setNormalizedParamValue(name: Params, value: number): void;
/**
* normalized value version of `getParamsValues()`
*/
getNormalizedParamsValues(): Partial<Record<Params, number>>;
/**
* normalized value version of `setParamsValues()`
*/
setNormalizedParamsValues(values: Record<Params, number>): void;
// `AudioParam.prototype` methods with there normlized value version
setParamValueAtTime(name: Params, value: number, startTime: number): AudioParam;
setNormalizedParamValueAtTime(name: Params, value: number, startTime: number): AudioParam;
linearRampToParamValueAtTime(name: Params, value: number, endTime: number): AudioParam;
linearRampToNormalizedParamValueAtTime(name: Params, value: number, endTime: number): AudioParam;
exponentialRampToParamValueAtTime(name: Params, value: number, endTime: number): AudioParam;
exponentialRampToNormalizedParamValueAtTime(name: Params, value: number, endTime: number): AudioParam;
setParamTargetAtTime(name: Params, target: number, startTime: number, timeConstant: number): AudioParam;
setNormalizedParamTargetAtTime(name: Params, target: number, startTime: number, timeConstant: number): AudioParam;
setParamValueCurveAtTime(name: Params, values: Iterable<number> | number[] | Float32Array, startTime: number, duration: number): AudioParam;
setNormalizedParamValueCurveAtTime(name: Params, values: Iterable<number> | number[] | Float32Array, startTime: number, duration: number): AudioParam;
cancelScheduledParamValues(name: Params, cancelTime: number): AudioParam;
cancelAndHoldParamAtTime(name: Params, cancelTime: number): AudioParam;
}
export const ParamMgrNode: {
prototype: ParamMgrNode;
/**
* Creates an instance of ParamMgrNode.
*
* @param {WebAudioModule} module WebAudioModule
* @param {ParamMgrOptions} options AudioWorkletNode options
*/
new <Params extends string = string, InternalParams extends string = string>(
module: WebAudioModule,
options: ParamMgrOptions
): ParamMgrNode<Params, InternalParams>;
};
export interface ParamMgrProcessor extends WamProcessor {
handleEvent?: (event: WamEvent) => any;
}
/**
* Use `create` static method to create a new `ParamMgr` instance
*/
export const ParamMgrFactory: {
/**
* Get a ParamManager as an AudioWorkletNode instance
*
* The second argument `optionsIn` decides how `ParamMgr` should automate parameters and generate `WamParameter`-compatible `AudioParam`s.
*
* The option could have three possible properties: `paramsConfig`, `paramsMapping` and `internalParamsConfig`.
*
* If you do not have to configure one-to-many parameters, please declare `internalParamsConfig` only,
* where you can put an `AudioParam` or an object that contains default, min, max values, automation rate with the `onChange` callback.
* The factory will generate automatically automatable `AudioParam`s for you.
*
* Else, you can declare `paramsConfig` with exposed parameters' configs.
* The omitted properties will be filled according the internal parameter with the same name.
* In the `paramsMapping`, you can declare how one-to-many parameters maps values to the internal parameters.
* @param {WebAudioModule} module the module instance
* @param {ParametersMappingConfiguratorOptions} [optionsIn = {}] config of the parameters
*/
create<Params extends string = string, InternalParams extends string = string>(module: WebAudioModule, optionsIn?: ParametersMappingConfiguratorOptions<Params, InternalParams>): Promise<ParamMgrNode<Params, InternalParams>>;
};
export interface WamParamMgrSDKBaseModuleScope {
paramMgrProcessors?: { [instanceId: string]: ParamMgrProcessor };
}