@node-3d/webaudio 6.0.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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/audio-buffer.d.ts +11 -0
- package/dist/audio-context.d.ts +4 -0
- package/dist/audio-destination-node.d.ts +7 -0
- package/dist/audio-listener.d.ts +9 -0
- package/dist/audio-node.d.ts +7 -0
- package/dist/audio-param.d.ts +12 -0
- package/dist/audio-scheduled-source-node.d.ts +7 -0
- package/dist/base-audio-context.d.ts +30 -0
- package/dist/core.d.ts +1 -0
- package/dist/events.d.ts +3 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +358 -0
- package/dist/native.d.ts +252 -0
- package/dist/nodes.d.ts +18 -0
- package/install.js +6 -0
- package/package.json +82 -0
- package/tsconfig.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Luis Blanco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# WebAudio for Node.js
|
|
2
|
+
|
|
3
|
+
This is a part of [Node3D](https://github.com/node-3d) project.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/@node-3d%2Fwebaudio)
|
|
6
|
+
[](https://github.com/node-3d/webaudio/actions/workflows/lint.yml)
|
|
7
|
+
[](https://github.com/node-3d/webaudio/actions/workflows/test.yml)
|
|
8
|
+
[](https://github.com/node-3d/webaudio/actions/workflows/cpplint.yml)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @node-3d/webaudio
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
**Node.js** addon implementing the
|
|
18
|
+
[Web Audio Api](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API).
|
|
19
|
+
|
|
20
|
+
Import any class you like from the module and then follow the
|
|
21
|
+
[doc](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API):
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import { AudioContext } from '@node-3d/webaudio'; // usually this is enough
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**This module is WORK IN PROGRESS.**
|
|
28
|
+
Some features are missing for good.
|
|
29
|
+
|
|
30
|
+
Currently exported classes:
|
|
31
|
+
|
|
32
|
+
* `AudioBuffer`
|
|
33
|
+
* `AudioContext`
|
|
34
|
+
* `AudioParam`
|
|
35
|
+
* `AnalyserNode`
|
|
36
|
+
* `BiquadFilterNode`
|
|
37
|
+
* `ConvolverNode`
|
|
38
|
+
* `GainNode`
|
|
39
|
+
* `PannerNode`
|
|
40
|
+
* `AudioBufferSourceNode`
|
|
41
|
+
* `OscillatorNode`
|
|
42
|
+
* `AudioScheduledSourceNode`
|
|
43
|
+
|
|
44
|
+
In examples directory, currently working examples are prepended with `_`.
|
|
45
|
+
|
|
46
|
+
## Binary Origin
|
|
47
|
+
|
|
48
|
+
Release archives are built by this repository's public GitHub Actions workflows.
|
|
49
|
+
|
|
50
|
+
Attestations: https://github.com/node-3d/webaudio/attestations
|
|
51
|
+
|
|
52
|
+
To verify a downloaded archive:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
gh release download <tag> -R node-3d/webaudio -p <platform>.gz
|
|
56
|
+
gh attestation verify <platform>.gz -R node-3d/webaudio
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> This addon is ABI-compatible across Node.js versions. **There is no compilation** during `npm install`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
declare const AudioBuffer: import("./native.ts").TNativeEs5Constructor<[context: import("./native.ts").TBaseAudioContext, source?: Readonly<{
|
|
3
|
+
length?: number;
|
|
4
|
+
numberOfChannels?: number;
|
|
5
|
+
sampleRate?: number;
|
|
6
|
+
}> | import("./native.ts").TNativeExternal | undefined], import("./native.ts").TAudioBuffer>;
|
|
7
|
+
declare class JsAudioBuffer extends AudioBuffer {
|
|
8
|
+
[inspect.custom](): string;
|
|
9
|
+
toString(): string;
|
|
10
|
+
}
|
|
11
|
+
export { JsAudioBuffer as AudioBuffer };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TJsBaseAudioContext } from './base-audio-context.ts';
|
|
2
|
+
import type { TAudioContext, TAudioContextOptions, TNativeConstructor } from './native.ts';
|
|
3
|
+
declare const WrappedAudioContext: TNativeConstructor<[opts?: TAudioContextOptions], TAudioContext & TJsBaseAudioContext>;
|
|
4
|
+
export { WrappedAudioContext as AudioContext };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TAudioDestinationNode, TBaseAudioContext, TNativeConstructor, TNativeExternal } from './native.ts';
|
|
2
|
+
type TAudioDestinationNodeConstructor = TNativeConstructor<[
|
|
3
|
+
ctx: TBaseAudioContext,
|
|
4
|
+
node: TNativeExternal
|
|
5
|
+
], TAudioDestinationNode>;
|
|
6
|
+
declare const JsAudioDestinationNode: TAudioDestinationNodeConstructor;
|
|
7
|
+
export { JsAudioDestinationNode as AudioDestinationNode };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import type { TBaseAudioContext, TNativeExternal } from './native.ts';
|
|
3
|
+
declare const AudioListener: import("./native.ts").TNativeEs5Constructor<[context: TBaseAudioContext, listener: TNativeExternal, paramCtor: import("./native.ts").TAudioParamConstructor], import("./native.ts").TAudioListener>;
|
|
4
|
+
declare class JsAudioListener extends AudioListener {
|
|
5
|
+
constructor(ctx: TBaseAudioContext, listener: TNativeExternal);
|
|
6
|
+
[inspect.custom](): string;
|
|
7
|
+
toString(): string;
|
|
8
|
+
}
|
|
9
|
+
export { JsAudioListener as AudioListener };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TAudioNode, TBaseAudioContext, TNativeConstructor, TNativeExternal } from './native.ts';
|
|
2
|
+
type TAudioNodeConstructor = TNativeConstructor<[
|
|
3
|
+
ctx: TBaseAudioContext,
|
|
4
|
+
node: TNativeExternal
|
|
5
|
+
], TAudioNode>;
|
|
6
|
+
declare const JsAudioNode: TAudioNodeConstructor;
|
|
7
|
+
export { JsAudioNode as AudioNode };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import type { TAudioEventCallbackList } from './native.ts';
|
|
3
|
+
declare const AudioParam: import("./native.ts").TAudioParamConstructor;
|
|
4
|
+
declare class JsAudioParam extends AudioParam {
|
|
5
|
+
get onerror(): TAudioEventCallbackList;
|
|
6
|
+
set onerror(cb: TAudioEventCallbackList);
|
|
7
|
+
get onended(): TAudioEventCallbackList;
|
|
8
|
+
set onended(cb: TAudioEventCallbackList);
|
|
9
|
+
[inspect.custom](): string;
|
|
10
|
+
toString(): string;
|
|
11
|
+
}
|
|
12
|
+
export { JsAudioParam as AudioParam };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TAudioScheduledSourceNode, TBaseAudioContext, TNativeConstructor, TNativeExternal } from './native.ts';
|
|
2
|
+
type TAudioScheduledSourceNodeConstructor = TNativeConstructor<[
|
|
3
|
+
ctx: TBaseAudioContext,
|
|
4
|
+
node: TNativeExternal
|
|
5
|
+
], TAudioScheduledSourceNode>;
|
|
6
|
+
declare const JsAudioScheduledSourceNode: TAudioScheduledSourceNodeConstructor;
|
|
7
|
+
export { JsAudioScheduledSourceNode as AudioScheduledSourceNode };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AudioDestinationNode } from './audio-destination-node.ts';
|
|
2
|
+
import { AudioListener } from './audio-listener.ts';
|
|
3
|
+
import type { TAnalyserNode, TAudioBuffer, TAudioBufferSourceNode, TAudioNodeOptions, TBaseAudioContext, TBiquadFilterNode, TConvolverNode, TDelayNode, TGainNode, TNativeConstructor, TNativeExternal, TOscillatorNode, TPannerNode } from './native.ts';
|
|
4
|
+
export type TJsBaseAudioContext = TBaseAudioContext & {
|
|
5
|
+
_initListener: (destinationCtor: typeof AudioDestinationNode, listenerCtor: typeof AudioListener, sampleRate: number) => void;
|
|
6
|
+
createAnalyser: (opts?: TAudioNodeOptions) => TAnalyserNode;
|
|
7
|
+
createBiquadFilter: (opts?: TAudioNodeOptions) => TBiquadFilterNode;
|
|
8
|
+
createBuffer: (opts?: TAudioNodeOptions) => TAudioBuffer;
|
|
9
|
+
createBufferSource: (opts?: TAudioNodeOptions) => TAudioBufferSourceNode;
|
|
10
|
+
createConvolver: (opts?: TAudioNodeOptions) => TConvolverNode;
|
|
11
|
+
createDelay: (maxDelayTime?: number) => TDelayNode;
|
|
12
|
+
createGain: (opts?: TAudioNodeOptions) => TGainNode;
|
|
13
|
+
createOscillator: (opts?: TAudioNodeOptions) => TOscillatorNode;
|
|
14
|
+
createPanner: (opts?: TAudioNodeOptions) => TPannerNode;
|
|
15
|
+
createChannelMerger: (opts?: TAudioNodeOptions) => object;
|
|
16
|
+
createChannelSplitter: (opts?: TAudioNodeOptions) => object;
|
|
17
|
+
createConstantSource: (opts?: TAudioNodeOptions) => object;
|
|
18
|
+
createDynamicsCompressor: (opts?: TAudioNodeOptions) => object;
|
|
19
|
+
createIIRFilter: (opts?: TAudioNodeOptions) => object;
|
|
20
|
+
createPeriodicWave: (opts?: TAudioNodeOptions) => object;
|
|
21
|
+
createScriptProcessor: (opts?: TAudioNodeOptions) => object;
|
|
22
|
+
createStereoPanner: (opts?: TAudioNodeOptions) => object;
|
|
23
|
+
createWaveShaper: (opts?: TAudioNodeOptions) => object;
|
|
24
|
+
};
|
|
25
|
+
type TBaseAudioContextConstructor = TNativeConstructor<[
|
|
26
|
+
ctx: TNativeExternal,
|
|
27
|
+
sampleRate?: number
|
|
28
|
+
], TJsBaseAudioContext>;
|
|
29
|
+
declare const JsBaseAudioContext: TBaseAudioContextConstructor;
|
|
30
|
+
export { JsBaseAudioContext as BaseAudioContext };
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { native } from './native.ts';
|
package/dist/events.d.ts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { inherits, inspect } from "node:util";
|
|
2
|
+
import node_events from "node:events";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { getBin } from "@node-3d/addon-tools";
|
|
5
|
+
import "@node-3d/segfault";
|
|
6
|
+
import { hrtf } from "@node-3d/deps-labsound";
|
|
7
|
+
const loadAddon = createRequire(import.meta.url);
|
|
8
|
+
const native_native = loadAddon(`../${getBin()}/webaudio.node`);
|
|
9
|
+
function _to_primitive(input, hint) {
|
|
10
|
+
if ("object" !== _type_of(input) || null === input) return input;
|
|
11
|
+
var prim = input[Symbol.toPrimitive];
|
|
12
|
+
if (void 0 !== prim) {
|
|
13
|
+
var res = prim.call(input, hint || "default");
|
|
14
|
+
if ("object" !== _type_of(res)) return res;
|
|
15
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
16
|
+
}
|
|
17
|
+
return ("string" === hint ? String : Number)(input);
|
|
18
|
+
}
|
|
19
|
+
function _to_property_key(arg) {
|
|
20
|
+
var key = _to_primitive(arg, "string");
|
|
21
|
+
return "symbol" === _type_of(key) ? key : String(key);
|
|
22
|
+
}
|
|
23
|
+
function _type_of(obj) {
|
|
24
|
+
return obj && "u" > typeof Symbol && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
25
|
+
}
|
|
26
|
+
let audio_buffer_computedKey;
|
|
27
|
+
const { AudioBuffer: AudioBuffer } = native_native;
|
|
28
|
+
inherits(AudioBuffer, node_events);
|
|
29
|
+
audio_buffer_computedKey = _to_property_key(inspect.custom);
|
|
30
|
+
class JsAudioBuffer extends AudioBuffer {
|
|
31
|
+
[audio_buffer_computedKey]() {
|
|
32
|
+
return this.toString();
|
|
33
|
+
}
|
|
34
|
+
toString() {
|
|
35
|
+
return 'AudioBuffer {}';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const setEventCallbacks = (emitter, eventName, callbacks)=>{
|
|
39
|
+
if (!callbacks) return void emitter.removeAllListeners(eventName);
|
|
40
|
+
if ('function' == typeof callbacks) return void emitter.on(eventName, callbacks);
|
|
41
|
+
for (const callback of callbacks)emitter.on(eventName, callback);
|
|
42
|
+
};
|
|
43
|
+
const { AudioNode: AudioNode } = native_native;
|
|
44
|
+
inherits(AudioNode, node_events);
|
|
45
|
+
const nonGcRefs = new Set();
|
|
46
|
+
const audio_node_JsAudioNode = function(ctx, node) {
|
|
47
|
+
AudioNode.call(this, ctx, node);
|
|
48
|
+
nonGcRefs.add(this);
|
|
49
|
+
this.on('destroy', ()=>{
|
|
50
|
+
nonGcRefs.delete(this);
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const audioNodePrototype = {
|
|
54
|
+
get onerror () {
|
|
55
|
+
return this.listeners('error');
|
|
56
|
+
},
|
|
57
|
+
set onerror (cb){
|
|
58
|
+
setEventCallbacks(this, 'error', cb);
|
|
59
|
+
},
|
|
60
|
+
get onended () {
|
|
61
|
+
return this.listeners('ended');
|
|
62
|
+
},
|
|
63
|
+
set onended (cb){
|
|
64
|
+
setEventCallbacks(this, 'ended', cb);
|
|
65
|
+
},
|
|
66
|
+
[inspect.custom] () {
|
|
67
|
+
return this.toString();
|
|
68
|
+
},
|
|
69
|
+
toString () {
|
|
70
|
+
return 'AudioNode {}';
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
audio_node_JsAudioNode.prototype = audioNodePrototype;
|
|
74
|
+
inherits(audio_node_JsAudioNode, AudioNode);
|
|
75
|
+
const { AudioDestinationNode: AudioDestinationNode } = native_native;
|
|
76
|
+
inherits(AudioDestinationNode, audio_node_JsAudioNode);
|
|
77
|
+
const audio_destination_node_JsAudioDestinationNode = function(ctx, node) {
|
|
78
|
+
AudioDestinationNode.call(this, ctx, node);
|
|
79
|
+
};
|
|
80
|
+
audio_destination_node_JsAudioDestinationNode.prototype = {
|
|
81
|
+
[inspect.custom] () {
|
|
82
|
+
return this.toString();
|
|
83
|
+
},
|
|
84
|
+
toString () {
|
|
85
|
+
return 'AudioDestinationNode {}';
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
inherits(audio_destination_node_JsAudioDestinationNode, AudioDestinationNode);
|
|
89
|
+
function audio_param_to_primitive(input, hint) {
|
|
90
|
+
if ("object" !== audio_param_type_of(input) || null === input) return input;
|
|
91
|
+
var prim = input[Symbol.toPrimitive];
|
|
92
|
+
if (void 0 !== prim) {
|
|
93
|
+
var res = prim.call(input, hint || "default");
|
|
94
|
+
if ("object" !== audio_param_type_of(res)) return res;
|
|
95
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
96
|
+
}
|
|
97
|
+
return ("string" === hint ? String : Number)(input);
|
|
98
|
+
}
|
|
99
|
+
function audio_param_to_property_key(arg) {
|
|
100
|
+
var key = audio_param_to_primitive(arg, "string");
|
|
101
|
+
return "symbol" === audio_param_type_of(key) ? key : String(key);
|
|
102
|
+
}
|
|
103
|
+
function audio_param_type_of(obj) {
|
|
104
|
+
return obj && "u" > typeof Symbol && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
105
|
+
}
|
|
106
|
+
let audio_param_computedKey;
|
|
107
|
+
const { AudioParam: AudioParam } = native_native;
|
|
108
|
+
inherits(AudioParam, node_events);
|
|
109
|
+
audio_param_computedKey = audio_param_to_property_key(inspect.custom);
|
|
110
|
+
class JsAudioParam extends AudioParam {
|
|
111
|
+
get onerror() {
|
|
112
|
+
return this.listeners('error');
|
|
113
|
+
}
|
|
114
|
+
set onerror(cb1) {
|
|
115
|
+
setEventCallbacks(this, 'error', cb1);
|
|
116
|
+
}
|
|
117
|
+
get onended() {
|
|
118
|
+
return this.listeners('ended');
|
|
119
|
+
}
|
|
120
|
+
set onended(cb1) {
|
|
121
|
+
setEventCallbacks(this, 'ended', cb1);
|
|
122
|
+
}
|
|
123
|
+
[audio_param_computedKey]() {
|
|
124
|
+
return this.toString();
|
|
125
|
+
}
|
|
126
|
+
toString() {
|
|
127
|
+
return `AudioParam { ${this.value} }`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function audio_listener_to_primitive(input, hint) {
|
|
131
|
+
if ("object" !== audio_listener_type_of(input) || null === input) return input;
|
|
132
|
+
var prim = input[Symbol.toPrimitive];
|
|
133
|
+
if (void 0 !== prim) {
|
|
134
|
+
var res = prim.call(input, hint || "default");
|
|
135
|
+
if ("object" !== audio_listener_type_of(res)) return res;
|
|
136
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
137
|
+
}
|
|
138
|
+
return ("string" === hint ? String : Number)(input);
|
|
139
|
+
}
|
|
140
|
+
function audio_listener_to_property_key(arg) {
|
|
141
|
+
var key = audio_listener_to_primitive(arg, "string");
|
|
142
|
+
return "symbol" === audio_listener_type_of(key) ? key : String(key);
|
|
143
|
+
}
|
|
144
|
+
function audio_listener_type_of(obj) {
|
|
145
|
+
return obj && "u" > typeof Symbol && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
146
|
+
}
|
|
147
|
+
let audio_listener_computedKey;
|
|
148
|
+
const { AudioListener: AudioListener } = native_native;
|
|
149
|
+
inherits(AudioListener, node_events);
|
|
150
|
+
audio_listener_computedKey = audio_listener_to_property_key(inspect.custom);
|
|
151
|
+
class JsAudioListener extends AudioListener {
|
|
152
|
+
constructor(ctx, listener){
|
|
153
|
+
super(ctx, listener, JsAudioParam);
|
|
154
|
+
}
|
|
155
|
+
[audio_listener_computedKey]() {
|
|
156
|
+
return this.toString();
|
|
157
|
+
}
|
|
158
|
+
toString() {
|
|
159
|
+
return 'AudioListener {}';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const { AudioScheduledSourceNode: AudioScheduledSourceNode } = native_native;
|
|
163
|
+
inherits(AudioScheduledSourceNode, audio_node_JsAudioNode);
|
|
164
|
+
const audio_scheduled_source_node_JsAudioScheduledSourceNode = function(ctx, node) {
|
|
165
|
+
AudioScheduledSourceNode.call(this, ctx, node);
|
|
166
|
+
};
|
|
167
|
+
audio_scheduled_source_node_JsAudioScheduledSourceNode.prototype = {
|
|
168
|
+
[inspect.custom] () {
|
|
169
|
+
return this.toString();
|
|
170
|
+
},
|
|
171
|
+
toString () {
|
|
172
|
+
return 'AudioScheduledSourceNode {}';
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
inherits(audio_scheduled_source_node_JsAudioScheduledSourceNode, AudioScheduledSourceNode);
|
|
176
|
+
function nodes_to_primitive(input, hint) {
|
|
177
|
+
if ("object" !== nodes_type_of(input) || null === input) return input;
|
|
178
|
+
var prim = input[Symbol.toPrimitive];
|
|
179
|
+
if (void 0 !== prim) {
|
|
180
|
+
var res = prim.call(input, hint || "default");
|
|
181
|
+
if ("object" !== nodes_type_of(res)) return res;
|
|
182
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
183
|
+
}
|
|
184
|
+
return ("string" === hint ? String : Number)(input);
|
|
185
|
+
}
|
|
186
|
+
function nodes_to_property_key(arg) {
|
|
187
|
+
var key = nodes_to_primitive(arg, "string");
|
|
188
|
+
return "symbol" === nodes_type_of(key) ? key : String(key);
|
|
189
|
+
}
|
|
190
|
+
function nodes_type_of(obj) {
|
|
191
|
+
return obj && "u" > typeof Symbol && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
192
|
+
}
|
|
193
|
+
const baseDescs = [
|
|
194
|
+
'AnalyserNode',
|
|
195
|
+
'BiquadFilterNode',
|
|
196
|
+
'ConvolverNode',
|
|
197
|
+
'DelayNode',
|
|
198
|
+
'GainNode',
|
|
199
|
+
'PannerNode'
|
|
200
|
+
];
|
|
201
|
+
const scheduledDescs = [
|
|
202
|
+
'AudioBufferSourceNode',
|
|
203
|
+
'OscillatorNode'
|
|
204
|
+
];
|
|
205
|
+
const subclassBase = (name, SuperNode)=>{
|
|
206
|
+
let _computedKey;
|
|
207
|
+
const SuperClass = native_native[name];
|
|
208
|
+
inherits(SuperClass, SuperNode);
|
|
209
|
+
_computedKey = nodes_to_property_key(inspect.custom);
|
|
210
|
+
class JsNode extends SuperClass {
|
|
211
|
+
_opts;
|
|
212
|
+
constructor(ctx, opts = {}){
|
|
213
|
+
super(ctx, JsAudioParam, opts);
|
|
214
|
+
this._opts = opts;
|
|
215
|
+
}
|
|
216
|
+
[_computedKey]() {
|
|
217
|
+
return this.toString();
|
|
218
|
+
}
|
|
219
|
+
toString() {
|
|
220
|
+
return `${name} ${JSON.stringify(this._opts, null, '\t')}`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return JsNode;
|
|
224
|
+
};
|
|
225
|
+
const baseNodes = {
|
|
226
|
+
AudioScheduledSourceNode: audio_scheduled_source_node_JsAudioScheduledSourceNode
|
|
227
|
+
};
|
|
228
|
+
for (const name of baseDescs)baseNodes[name] = subclassBase(name, audio_node_JsAudioNode);
|
|
229
|
+
const scheduledNodes = {};
|
|
230
|
+
for (const name of scheduledDescs)scheduledNodes[name] = subclassBase(name, audio_scheduled_source_node_JsAudioScheduledSourceNode);
|
|
231
|
+
const nodes = {
|
|
232
|
+
...baseNodes,
|
|
233
|
+
...scheduledNodes
|
|
234
|
+
};
|
|
235
|
+
const { AudioScheduledSourceNode: nodes_AudioScheduledSourceNode, AnalyserNode: AnalyserNode, BiquadFilterNode: BiquadFilterNode, ConvolverNode: ConvolverNode, DelayNode: DelayNode, GainNode: GainNode, PannerNode: PannerNode, AudioBufferSourceNode: AudioBufferSourceNode, OscillatorNode: OscillatorNode } = nodes;
|
|
236
|
+
const BaseAudioContext = native_native.BaseAudioContext;
|
|
237
|
+
inherits(BaseAudioContext, node_events);
|
|
238
|
+
BaseAudioContext.hrtf = hrtf;
|
|
239
|
+
const base_audio_context_JsBaseAudioContext = function(ctx, sampleRate = -1) {
|
|
240
|
+
BaseAudioContext.call(this, ctx, sampleRate);
|
|
241
|
+
this._initListener(audio_destination_node_JsAudioDestinationNode, JsAudioListener, sampleRate);
|
|
242
|
+
};
|
|
243
|
+
const baseAudioContextPrototype = {
|
|
244
|
+
get onerror () {
|
|
245
|
+
return this.listeners('error');
|
|
246
|
+
},
|
|
247
|
+
set onerror (cb){
|
|
248
|
+
setEventCallbacks(this, 'error', cb);
|
|
249
|
+
},
|
|
250
|
+
get onstatechange () {
|
|
251
|
+
return this.listeners('statechange');
|
|
252
|
+
},
|
|
253
|
+
set onstatechange (cb){
|
|
254
|
+
setEventCallbacks(this, 'statechange', cb);
|
|
255
|
+
},
|
|
256
|
+
[inspect.custom] () {
|
|
257
|
+
return this.toString();
|
|
258
|
+
},
|
|
259
|
+
toString () {
|
|
260
|
+
return 'BaseAudioContext {}';
|
|
261
|
+
},
|
|
262
|
+
decodeAudioData (audioData, successCallback) {
|
|
263
|
+
BaseAudioContext.prototype.decodeAudioData.call(this, audioData, successCallback, JsAudioBuffer);
|
|
264
|
+
},
|
|
265
|
+
createAnalyser (opts = {}) {
|
|
266
|
+
return new nodes.AnalyserNode(this, opts);
|
|
267
|
+
},
|
|
268
|
+
createBiquadFilter (opts = {}) {
|
|
269
|
+
return new nodes.BiquadFilterNode(this, opts);
|
|
270
|
+
},
|
|
271
|
+
createBuffer (opts = {}) {
|
|
272
|
+
return new JsAudioBuffer(this, opts);
|
|
273
|
+
},
|
|
274
|
+
createBufferSource (opts = {}) {
|
|
275
|
+
return new nodes.AudioBufferSourceNode(this, opts);
|
|
276
|
+
},
|
|
277
|
+
createChannelMerger (opts = {}) {
|
|
278
|
+
return new nodes.ChannelMergerNode(this, opts);
|
|
279
|
+
},
|
|
280
|
+
createChannelSplitter (opts = {}) {
|
|
281
|
+
return new nodes.ChannelSplitterNode(this, opts);
|
|
282
|
+
},
|
|
283
|
+
createConstantSource (opts = {}) {
|
|
284
|
+
return new nodes.ConstantSourceNode(this, opts);
|
|
285
|
+
},
|
|
286
|
+
createConvolver (opts = {}) {
|
|
287
|
+
return new nodes.ConvolverNode(this, opts);
|
|
288
|
+
},
|
|
289
|
+
createDelay (maxDelayTime = 1) {
|
|
290
|
+
return new nodes.DelayNode(this, {
|
|
291
|
+
maxDelayTime
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
createDynamicsCompressor (opts = {}) {
|
|
295
|
+
return new nodes.DynamicsCompressorNode(this, opts);
|
|
296
|
+
},
|
|
297
|
+
createGain (opts = {}) {
|
|
298
|
+
return new nodes.GainNode(this, opts);
|
|
299
|
+
},
|
|
300
|
+
createIIRFilter (opts = {}) {
|
|
301
|
+
return new nodes.IIRFilterNode(this, opts);
|
|
302
|
+
},
|
|
303
|
+
createOscillator (opts = {}) {
|
|
304
|
+
return new nodes.OscillatorNode(this, opts);
|
|
305
|
+
},
|
|
306
|
+
createPanner (opts = {}) {
|
|
307
|
+
return new nodes.PannerNode(this, opts);
|
|
308
|
+
},
|
|
309
|
+
createPeriodicWave (opts = {}) {
|
|
310
|
+
return new nodes.PeriodicWaveNode(this, opts);
|
|
311
|
+
},
|
|
312
|
+
createScriptProcessor (opts = {}) {
|
|
313
|
+
return new nodes.ScriptProcessorNode(this, opts);
|
|
314
|
+
},
|
|
315
|
+
createStereoPanner (opts = {}) {
|
|
316
|
+
return new nodes.StereoPannerNode(this, opts);
|
|
317
|
+
},
|
|
318
|
+
createWaveShaper (opts = {}) {
|
|
319
|
+
return new nodes.WaveShaperNode(this, opts);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
base_audio_context_JsBaseAudioContext.prototype = baseAudioContextPrototype;
|
|
323
|
+
inherits(base_audio_context_JsBaseAudioContext, BaseAudioContext);
|
|
324
|
+
function audio_context_to_primitive(input, hint) {
|
|
325
|
+
if ("object" !== audio_context_type_of(input) || null === input) return input;
|
|
326
|
+
var prim = input[Symbol.toPrimitive];
|
|
327
|
+
if (void 0 !== prim) {
|
|
328
|
+
var res = prim.call(input, hint || "default");
|
|
329
|
+
if ("object" !== audio_context_type_of(res)) return res;
|
|
330
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
331
|
+
}
|
|
332
|
+
return ("string" === hint ? String : Number)(input);
|
|
333
|
+
}
|
|
334
|
+
function audio_context_to_property_key(arg) {
|
|
335
|
+
var key = audio_context_to_primitive(arg, "string");
|
|
336
|
+
return "symbol" === audio_context_type_of(key) ? key : String(key);
|
|
337
|
+
}
|
|
338
|
+
function audio_context_type_of(obj) {
|
|
339
|
+
return obj && "u" > typeof Symbol && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
340
|
+
}
|
|
341
|
+
let audio_context_computedKey;
|
|
342
|
+
const { AudioContext: AudioContext } = native_native;
|
|
343
|
+
inherits(AudioContext, base_audio_context_JsBaseAudioContext);
|
|
344
|
+
audio_context_computedKey = audio_context_to_property_key(inspect.custom);
|
|
345
|
+
class JsAudioContext extends AudioContext {
|
|
346
|
+
constructor(opts = {}){
|
|
347
|
+
if (void 0 === opts.sampleRate) super();
|
|
348
|
+
else super(opts.sampleRate);
|
|
349
|
+
}
|
|
350
|
+
[audio_context_computedKey]() {
|
|
351
|
+
return this.toString();
|
|
352
|
+
}
|
|
353
|
+
toString() {
|
|
354
|
+
return 'AudioContext {}';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const WrappedAudioContext = JsAudioContext;
|
|
358
|
+
export { AnalyserNode, AudioBufferSourceNode, BiquadFilterNode, ConvolverNode, DelayNode, GainNode, JsAudioBuffer as AudioBuffer, JsAudioParam as AudioParam, OscillatorNode, PannerNode, WrappedAudioContext as AudioContext, nodes, nodes_AudioScheduledSourceNode as AudioScheduledSourceNode };
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { EventEmitter } from 'node:events';
|
|
2
|
+
import '@node-3d/segfault';
|
|
3
|
+
import '@node-3d/deps-labsound';
|
|
4
|
+
export type TAudioEvent = Readonly<{
|
|
5
|
+
type: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}>;
|
|
8
|
+
export type TAudioEventCallback<T extends TAudioEvent = TAudioEvent> = (event: T) => boolean | undefined;
|
|
9
|
+
export type TAudioEventCallbackList<T extends TAudioEvent = TAudioEvent> = TAudioEventCallback<T> | readonly TAudioEventCallback<T>[] | null | undefined;
|
|
10
|
+
export type TAudioContextState = 'closed' | 'interrupted' | 'running' | 'suspended';
|
|
11
|
+
export type TChannelCountMode = 'clamped-max' | 'explicit' | 'max';
|
|
12
|
+
export type TChannelInterpretation = 'discrete' | 'speakers';
|
|
13
|
+
export type TDistanceModel = 'exponential' | 'inverse' | 'linear';
|
|
14
|
+
export type TPanningModel = 'HRTF' | 'equalpower';
|
|
15
|
+
export type TOscillatorType = 'custom' | 'sawtooth' | 'sine' | 'square' | 'triangle';
|
|
16
|
+
export type TNativeExternal = object & {
|
|
17
|
+
readonly __nativeExternal: unique symbol;
|
|
18
|
+
};
|
|
19
|
+
export type TNativeConstructor<TArgs extends readonly unknown[], TInstance extends object> = {
|
|
20
|
+
prototype: TInstance;
|
|
21
|
+
new (...args: TArgs): TInstance;
|
|
22
|
+
};
|
|
23
|
+
export type TNativeEs5Constructor<TArgs extends readonly unknown[], TInstance extends object> = TNativeConstructor<TArgs, TInstance> & ((...args: TArgs) => TInstance);
|
|
24
|
+
export type TAudioBufferData = ArrayLike<number> & object;
|
|
25
|
+
export type TAudioBufferOptions = Readonly<{
|
|
26
|
+
length?: number;
|
|
27
|
+
numberOfChannels?: number;
|
|
28
|
+
sampleRate?: number;
|
|
29
|
+
}>;
|
|
30
|
+
export type TAudioContextOptions = Readonly<{
|
|
31
|
+
sampleRate?: number;
|
|
32
|
+
}>;
|
|
33
|
+
export type TAudioNodeOptions = Readonly<Record<string, unknown>>;
|
|
34
|
+
export type TAudioObject = EventEmitter & {
|
|
35
|
+
destroy: () => void;
|
|
36
|
+
};
|
|
37
|
+
export type TNativeAudioParam = TAudioObject & {
|
|
38
|
+
value: number;
|
|
39
|
+
readonly defaultValue: number;
|
|
40
|
+
readonly maxValue: number;
|
|
41
|
+
readonly minValue: number;
|
|
42
|
+
cancelAndHoldAtTime: (startTime: number) => void;
|
|
43
|
+
cancelScheduledValues: (startTime: number) => void;
|
|
44
|
+
exponentialRampToValueAtTime: (value: number, time: number) => void;
|
|
45
|
+
linearRampToValueAtTime: (value: number, time: number) => void;
|
|
46
|
+
setTargetAtTime: (target: number, time: number, timeConstant: number) => void;
|
|
47
|
+
setValueAtTime: (value: number, time: number) => void;
|
|
48
|
+
setValueCurveAtTime: (values: readonly number[], time: number, duration: number) => void;
|
|
49
|
+
};
|
|
50
|
+
export type TAudioParam = TNativeAudioParam & {
|
|
51
|
+
onended: TAudioEventCallbackList;
|
|
52
|
+
onerror: TAudioEventCallbackList;
|
|
53
|
+
};
|
|
54
|
+
export type TAudioNode = TAudioObject & {
|
|
55
|
+
channelCount: number;
|
|
56
|
+
channelCountMode: TChannelCountMode;
|
|
57
|
+
channelInterpretation: TChannelInterpretation;
|
|
58
|
+
readonly context: TBaseAudioContext;
|
|
59
|
+
readonly numberOfInputs: number;
|
|
60
|
+
readonly numberOfOutputs: number;
|
|
61
|
+
connect: (destination: TAudioNode | TAudioParam, output?: number, input?: number) => void;
|
|
62
|
+
diagnose: () => void;
|
|
63
|
+
disconnect: (destination?: TAudioNode | TAudioParam | number, output?: number, input?: number) => void;
|
|
64
|
+
onended: TAudioEventCallbackList;
|
|
65
|
+
onerror: TAudioEventCallbackList;
|
|
66
|
+
};
|
|
67
|
+
export type TAudioBuffer = TAudioObject & {
|
|
68
|
+
readonly duration: number;
|
|
69
|
+
readonly length: number;
|
|
70
|
+
readonly numberOfChannels: number;
|
|
71
|
+
readonly sampleRate: number;
|
|
72
|
+
copyFromChannel: (destination: TAudioBufferData, channelNumber: number, startInChannel: number) => void;
|
|
73
|
+
copyToChannel: (source: TAudioBufferData, channelNumber: number, startInChannel: number) => void;
|
|
74
|
+
getChannelData: (channelIndex: number) => void;
|
|
75
|
+
};
|
|
76
|
+
export type TAudioListener = TAudioObject & {
|
|
77
|
+
readonly forwardX: TAudioParam;
|
|
78
|
+
readonly forwardY: TAudioParam;
|
|
79
|
+
readonly forwardZ: TAudioParam;
|
|
80
|
+
readonly positionX: TAudioParam;
|
|
81
|
+
readonly positionY: TAudioParam;
|
|
82
|
+
readonly positionZ: TAudioParam;
|
|
83
|
+
readonly upX: TAudioParam;
|
|
84
|
+
readonly upY: TAudioParam;
|
|
85
|
+
readonly upZ: TAudioParam;
|
|
86
|
+
setOrientation: (x: number, y: number, z: number, xUp: number, yUp: number, zUp: number) => void;
|
|
87
|
+
setPosition: (x: number, y: number, z: number) => void;
|
|
88
|
+
};
|
|
89
|
+
export type TBaseAudioContext = TAudioObject & {
|
|
90
|
+
readonly currentTime: number;
|
|
91
|
+
readonly destination: TAudioDestinationNode;
|
|
92
|
+
readonly listener: TAudioListener;
|
|
93
|
+
readonly sampleRate: number;
|
|
94
|
+
readonly state: TAudioContextState;
|
|
95
|
+
decodeAudioData: (source: Buffer, cb: (buffer: TAudioBuffer) => void) => void;
|
|
96
|
+
onerror: TAudioEventCallbackList;
|
|
97
|
+
onstatechange: TAudioEventCallbackList;
|
|
98
|
+
resume: () => void;
|
|
99
|
+
update: () => void;
|
|
100
|
+
};
|
|
101
|
+
export type TAudioContext = TBaseAudioContext & {
|
|
102
|
+
readonly baseLatency: number;
|
|
103
|
+
close: () => void;
|
|
104
|
+
getOutputTimestamp: () => void;
|
|
105
|
+
suspend: () => void;
|
|
106
|
+
};
|
|
107
|
+
export type TAudioDestinationNode = TAudioNode & {
|
|
108
|
+
readonly maxChannelCount: number;
|
|
109
|
+
};
|
|
110
|
+
export type TAudioScheduledSourceNode = TAudioNode & {
|
|
111
|
+
start: (when?: number) => void;
|
|
112
|
+
stop: (when?: number) => void;
|
|
113
|
+
};
|
|
114
|
+
export type TAnalyserNode = TAudioNode & {
|
|
115
|
+
fftSize: number;
|
|
116
|
+
maxDecibels: number;
|
|
117
|
+
minDecibels: number;
|
|
118
|
+
smoothingTimeConstant: number;
|
|
119
|
+
readonly frequencyBinCount: number;
|
|
120
|
+
getByteFrequencyData: (array: Uint8Array) => void;
|
|
121
|
+
getByteTimeDomainData: (array: Uint8Array) => void;
|
|
122
|
+
getFloatFrequencyData: (array: Float32Array) => void;
|
|
123
|
+
getFloatTimeDomainData: (array: Float32Array) => void;
|
|
124
|
+
};
|
|
125
|
+
export type TBiquadFilterNode = TAudioNode & {
|
|
126
|
+
type: number;
|
|
127
|
+
readonly Q: TAudioParam;
|
|
128
|
+
readonly detune: TAudioParam;
|
|
129
|
+
readonly frequency: TAudioParam;
|
|
130
|
+
readonly gain: TAudioParam;
|
|
131
|
+
getFrequencyResponse: () => void;
|
|
132
|
+
};
|
|
133
|
+
export type TConvolverNode = TAudioNode & {
|
|
134
|
+
buffer: TAudioBuffer;
|
|
135
|
+
normalize: boolean;
|
|
136
|
+
};
|
|
137
|
+
export type TDelayNode = TAudioNode & {
|
|
138
|
+
readonly delayTime: TAudioParam;
|
|
139
|
+
};
|
|
140
|
+
export type TGainNode = TAudioNode & {
|
|
141
|
+
readonly gain: TAudioParam;
|
|
142
|
+
};
|
|
143
|
+
export type TPannerNode = TAudioNode & {
|
|
144
|
+
coneInnerAngle: number;
|
|
145
|
+
coneOuterAngle: number;
|
|
146
|
+
coneOuterGain: number;
|
|
147
|
+
distanceModel: TDistanceModel;
|
|
148
|
+
maxDistance: number;
|
|
149
|
+
panningModel: TPanningModel;
|
|
150
|
+
readonly orientationX: TAudioParam;
|
|
151
|
+
readonly orientationY: TAudioParam;
|
|
152
|
+
readonly orientationZ: TAudioParam;
|
|
153
|
+
readonly positionX: TAudioParam;
|
|
154
|
+
readonly positionY: TAudioParam;
|
|
155
|
+
readonly positionZ: TAudioParam;
|
|
156
|
+
refDistance: number;
|
|
157
|
+
rolloffFactor: number;
|
|
158
|
+
setOrientation: (x: number, y: number, z: number) => void;
|
|
159
|
+
setPosition: (x: number, y: number, z: number) => void;
|
|
160
|
+
setVelocity: (x: number, y: number, z: number) => void;
|
|
161
|
+
};
|
|
162
|
+
export type TAudioBufferSourceNode = TAudioScheduledSourceNode & {
|
|
163
|
+
buffer: TAudioBuffer;
|
|
164
|
+
loop: boolean;
|
|
165
|
+
loopEnd: number;
|
|
166
|
+
loopStart: number;
|
|
167
|
+
readonly detune: TAudioParam;
|
|
168
|
+
readonly playbackRate: TAudioParam;
|
|
169
|
+
start: (when?: number, grainOffset?: number, grainDuration?: number) => void;
|
|
170
|
+
};
|
|
171
|
+
export type TOscillatorNode = TAudioScheduledSourceNode & {
|
|
172
|
+
type: TOscillatorType;
|
|
173
|
+
readonly detune: TAudioParam;
|
|
174
|
+
readonly frequency: TAudioParam;
|
|
175
|
+
setPeriodicWave: (periodicWave: object) => void;
|
|
176
|
+
};
|
|
177
|
+
export type TNative = Readonly<{
|
|
178
|
+
AnalyserNode: TNativeEs5Constructor<[
|
|
179
|
+
context: TBaseAudioContext,
|
|
180
|
+
paramCtor: TAudioParamConstructor,
|
|
181
|
+
opts: TAudioNodeOptions
|
|
182
|
+
], TAnalyserNode>;
|
|
183
|
+
AudioBuffer: TNativeEs5Constructor<[
|
|
184
|
+
context: TBaseAudioContext,
|
|
185
|
+
source?: TNativeExternal | TAudioBufferOptions
|
|
186
|
+
], TAudioBuffer>;
|
|
187
|
+
AudioBufferSourceNode: TNativeEs5Constructor<[
|
|
188
|
+
context: TBaseAudioContext,
|
|
189
|
+
paramCtor: TAudioParamConstructor,
|
|
190
|
+
opts: TAudioNodeOptions
|
|
191
|
+
], TAudioBufferSourceNode>;
|
|
192
|
+
AudioContext: TNativeEs5Constructor<[sampleRate?: number], TAudioContext>;
|
|
193
|
+
AudioDestinationNode: TNativeEs5Constructor<[
|
|
194
|
+
context: TBaseAudioContext,
|
|
195
|
+
node: TNativeExternal
|
|
196
|
+
], TAudioDestinationNode>;
|
|
197
|
+
AudioListener: TNativeEs5Constructor<[
|
|
198
|
+
context: TBaseAudioContext,
|
|
199
|
+
listener: TNativeExternal,
|
|
200
|
+
paramCtor: TAudioParamConstructor
|
|
201
|
+
], TAudioListener>;
|
|
202
|
+
AudioNode: TNativeEs5Constructor<[
|
|
203
|
+
context: TBaseAudioContext,
|
|
204
|
+
node: TNativeExternal
|
|
205
|
+
], TAudioNode>;
|
|
206
|
+
AudioParam: TAudioParamConstructor;
|
|
207
|
+
AudioScheduledSourceNode: TNativeEs5Constructor<[
|
|
208
|
+
context: TBaseAudioContext,
|
|
209
|
+
node: TNativeExternal
|
|
210
|
+
], TAudioScheduledSourceNode>;
|
|
211
|
+
BaseAudioContext: TNativeEs5Constructor<[
|
|
212
|
+
context: TNativeExternal,
|
|
213
|
+
sampleRate: number
|
|
214
|
+
], TBaseAudioContext> & {
|
|
215
|
+
hrtf: string;
|
|
216
|
+
};
|
|
217
|
+
BiquadFilterNode: TNativeEs5Constructor<[
|
|
218
|
+
context: TBaseAudioContext,
|
|
219
|
+
paramCtor: TAudioParamConstructor,
|
|
220
|
+
opts: TAudioNodeOptions
|
|
221
|
+
], TBiquadFilterNode>;
|
|
222
|
+
ConvolverNode: TNativeEs5Constructor<[
|
|
223
|
+
context: TBaseAudioContext,
|
|
224
|
+
paramCtor: TAudioParamConstructor,
|
|
225
|
+
opts: TAudioNodeOptions
|
|
226
|
+
], TConvolverNode>;
|
|
227
|
+
DelayNode: TNativeEs5Constructor<[
|
|
228
|
+
context: TBaseAudioContext,
|
|
229
|
+
paramCtor: TAudioParamConstructor,
|
|
230
|
+
opts: TAudioNodeOptions
|
|
231
|
+
], TDelayNode>;
|
|
232
|
+
GainNode: TNativeEs5Constructor<[
|
|
233
|
+
context: TBaseAudioContext,
|
|
234
|
+
paramCtor: TAudioParamConstructor,
|
|
235
|
+
opts: TAudioNodeOptions
|
|
236
|
+
], TGainNode>;
|
|
237
|
+
OscillatorNode: TNativeEs5Constructor<[
|
|
238
|
+
context: TBaseAudioContext,
|
|
239
|
+
paramCtor: TAudioParamConstructor,
|
|
240
|
+
opts: TAudioNodeOptions
|
|
241
|
+
], TOscillatorNode>;
|
|
242
|
+
PannerNode: TNativeEs5Constructor<[
|
|
243
|
+
context: TBaseAudioContext,
|
|
244
|
+
paramCtor: TAudioParamConstructor,
|
|
245
|
+
opts: TAudioNodeOptions
|
|
246
|
+
], TPannerNode>;
|
|
247
|
+
}>;
|
|
248
|
+
export type TAudioParamConstructor = TNativeConstructor<[
|
|
249
|
+
context: TBaseAudioContext,
|
|
250
|
+
param: TNativeExternal
|
|
251
|
+
], TNativeAudioParam>;
|
|
252
|
+
export declare const native: TNative;
|
package/dist/nodes.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TAnalyserNode, TAudioBufferSourceNode, TAudioNode, TAudioNodeOptions, TAudioScheduledSourceNode, TBaseAudioContext, TBiquadFilterNode, TConvolverNode, TDelayNode, TGainNode, TOscillatorNode, TPannerNode } from './native.ts';
|
|
2
|
+
type TNodeConstructor<TInstance extends object = TAudioNode> = new (ctx: TBaseAudioContext, opts?: TAudioNodeOptions) => TInstance;
|
|
3
|
+
type TExportedNodeName = 'AnalyserNode' | 'AudioBufferSourceNode' | 'AudioScheduledSourceNode' | 'BiquadFilterNode' | 'ConvolverNode' | 'DelayNode' | 'GainNode' | 'OscillatorNode' | 'PannerNode';
|
|
4
|
+
type TNodeMap = {
|
|
5
|
+
AnalyserNode: TNodeConstructor<TAnalyserNode>;
|
|
6
|
+
AudioBufferSourceNode: TNodeConstructor<TAudioBufferSourceNode>;
|
|
7
|
+
AudioScheduledSourceNode: TNodeConstructor<TAudioScheduledSourceNode>;
|
|
8
|
+
BiquadFilterNode: TNodeConstructor<TBiquadFilterNode>;
|
|
9
|
+
ConvolverNode: TNodeConstructor<TConvolverNode>;
|
|
10
|
+
DelayNode: TNodeConstructor<TDelayNode>;
|
|
11
|
+
GainNode: TNodeConstructor<TGainNode>;
|
|
12
|
+
OscillatorNode: TNodeConstructor<TOscillatorNode>;
|
|
13
|
+
PannerNode: TNodeConstructor<TPannerNode>;
|
|
14
|
+
} & Record<TExportedNodeName, TNodeConstructor> & Record<string, TNodeConstructor>;
|
|
15
|
+
declare const nodes: TNodeMap;
|
|
16
|
+
declare const AudioScheduledSourceNode: TNodeConstructor<TAudioScheduledSourceNode> & TNodeConstructor<TAudioNode>, AnalyserNode: TNodeConstructor<TAnalyserNode> & TNodeConstructor<TAudioNode>, BiquadFilterNode: TNodeConstructor<TBiquadFilterNode> & TNodeConstructor<TAudioNode>, ConvolverNode: TNodeConstructor<TConvolverNode> & TNodeConstructor<TAudioNode>, DelayNode: TNodeConstructor<TDelayNode> & TNodeConstructor<TAudioNode>, GainNode: TNodeConstructor<TGainNode> & TNodeConstructor<TAudioNode>, PannerNode: TNodeConstructor<TPannerNode> & TNodeConstructor<TAudioNode>, AudioBufferSourceNode: TNodeConstructor<TAudioBufferSourceNode> & TNodeConstructor<TAudioNode>, OscillatorNode: TNodeConstructor<TOscillatorNode> & TNodeConstructor<TAudioNode>;
|
|
17
|
+
export { AudioScheduledSourceNode, AnalyserNode, BiquadFilterNode, ConvolverNode, DelayNode, GainNode, PannerNode, AudioBufferSourceNode, OscillatorNode, };
|
|
18
|
+
export { nodes };
|
package/install.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Luis Blanco <luisblanco1337@gmail.com>",
|
|
3
|
+
"name": "@node-3d/webaudio",
|
|
4
|
+
"version": "6.0.0",
|
|
5
|
+
"description": "Web Audio for Node.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"addon",
|
|
10
|
+
"webaudio",
|
|
11
|
+
"labsound",
|
|
12
|
+
"audio",
|
|
13
|
+
"sound",
|
|
14
|
+
"c++",
|
|
15
|
+
"bindings",
|
|
16
|
+
"native",
|
|
17
|
+
"gyp"
|
|
18
|
+
],
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"install.js",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"package.json",
|
|
24
|
+
"tsconfig.json"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=24.13.0",
|
|
28
|
+
"npm": ">=11.6.2"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"postinstall": "node install.js",
|
|
32
|
+
"build:rebuild": "cd src && node-gyp rebuild -j max && node -e \"import('@node-3d/addon-tools').then((m) => m.cpbin('webaudio'))\"",
|
|
33
|
+
"build:compile": "cd src && node-gyp build -j max && node -e \"import('@node-3d/addon-tools').then((m) => m.cpbin('webaudio'))\"",
|
|
34
|
+
"test:watch": "node --test --watch \"ts/**/*.test.ts\"",
|
|
35
|
+
"test:ci": "node --test \"ts/**/*.test.ts\"",
|
|
36
|
+
"lint:all": "npm run lint:gypi && npm run lint:ts && npm run lint:oxlint",
|
|
37
|
+
"lint:gypi": "node -e \"import('@node-3d/addon-tools').then((m) => m.checkGypi())\"",
|
|
38
|
+
"lint:oxlint": "oxlint .",
|
|
39
|
+
"build:ci": "rslib build",
|
|
40
|
+
"build:watch": "rslib build --watch",
|
|
41
|
+
"lint:ts": "tsc -p tsconfig.json --noEmit",
|
|
42
|
+
"prepack": "npm run build:ci",
|
|
43
|
+
"format:src": "node -e \"import('@node-3d/addon-tools').then((m) => m.cpclangformat())\" && node -e \"const { readdirSync } = require('node:fs'); const { execFileSync } = require('node:child_process'); const { clangFormatPath } = require('clang-format-node'); const files = readdirSync('src/cpp').filter((file) => /\\.(?:cpp|hpp)$/.test(file)).map((file) => 'src/cpp/' + file); execFileSync(clangFormatPath, ['-i', ...files], { stdio: 'inherit' });\"",
|
|
44
|
+
"format:src:ci": "node -e \"import('@node-3d/addon-tools').then((m) => m.cpclangformat())\" && node -e \"const { readdirSync } = require('node:fs'); const { execFileSync } = require('node:child_process'); const { clangFormatPath } = require('clang-format-node'); const files = readdirSync('src/cpp').filter((file) => /\\.(?:cpp|hpp)$/.test(file)).map((file) => 'src/cpp/' + file); execFileSync(clangFormatPath, ['--dry-run', '--Werror', ...files], { stdio: 'inherit' });\"",
|
|
45
|
+
"format:ts": "oxfmt -c ./oxfmt.config.ts --no-error-on-unmatched-pattern \"**/*.{js,jsx,ts,tsx}\"",
|
|
46
|
+
"format:ts:ci": "oxfmt -c ./oxfmt.config.ts --check --no-error-on-unmatched-pattern \"**/*.{js,jsx,ts,tsx}\""
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/node-3d/webaudio.git"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@node-3d/addon-tools": "~10.0.1",
|
|
54
|
+
"@node-3d/deps-labsound": "~7.0.0",
|
|
55
|
+
"@node-3d/segfault": "~4.0.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "24.13.2",
|
|
59
|
+
"node-addon-api": "8.9.0",
|
|
60
|
+
"oxlint": "1.72.0",
|
|
61
|
+
"tslib": "2.8.1",
|
|
62
|
+
"@rslib/core": "0.23.2",
|
|
63
|
+
"oxfmt": "0.57.0",
|
|
64
|
+
"typescript": "7.0.2",
|
|
65
|
+
"clang-format-node": "3.0.7"
|
|
66
|
+
},
|
|
67
|
+
"type": "module",
|
|
68
|
+
"types": "dist/index.d.ts",
|
|
69
|
+
"exports": {
|
|
70
|
+
".": {
|
|
71
|
+
"types": "./dist/index.d.ts",
|
|
72
|
+
"default": "./dist/index.js"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"bugs": {
|
|
76
|
+
"url": "https://github.com/node-3d/node-3d/issues"
|
|
77
|
+
},
|
|
78
|
+
"homepage": "https://github.com/node-3d/node-3d#readme",
|
|
79
|
+
"publishConfig": {
|
|
80
|
+
"access": "public"
|
|
81
|
+
}
|
|
82
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"allowImportingTsExtensions": true,
|
|
8
|
+
"rewriteRelativeImportExtensions": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"declarationMap": false,
|
|
11
|
+
"sourceMap": false,
|
|
12
|
+
"rootDir": ".",
|
|
13
|
+
"outDir": "dist",
|
|
14
|
+
"paths": {
|
|
15
|
+
"@node-3d/webaudio": [
|
|
16
|
+
"./ts/index.ts"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"verbatimModuleSyntax": true,
|
|
20
|
+
"skipLibCheck": true,
|
|
21
|
+
"types": [
|
|
22
|
+
"node"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"*.ts",
|
|
27
|
+
"ts/**/*.ts",
|
|
28
|
+
"examples/**/*.ts"
|
|
29
|
+
]
|
|
30
|
+
}
|