node-web-audio-api 0.8.0 → 0.10.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/CHANGELOG.md +8 -0
- package/README.md +22 -4
- package/monkey-patch.js +10 -36
- package/node-web-audio-api.darwin-arm64.node +0 -0
- package/node-web-audio-api.darwin-x64.node +0 -0
- package/node-web-audio-api.linux-arm-gnueabihf.node +0 -0
- package/node-web-audio-api.linux-x64-gnu.node +0 -0
- package/node-web-audio-api.win32-arm64-msvc.node +0 -0
- package/node-web-audio-api.win32-x64-msvc.node +0 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -64,11 +64,11 @@ npm run build
|
|
|
64
64
|
node examples/granular-scrub.mjs
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
If
|
|
68
|
+
|
|
67
69
|
## Caveats
|
|
68
70
|
|
|
69
71
|
- The async methods are not trully async for now and are just patched on the JS side. This will evolve once the "trully" async version of the methods are implemented in the upstream library.
|
|
70
|
-
- On Linux systems, the audio backend is currently Alsa, which limits the number of online `AudioContext` to 1. This is subject to change in the future.
|
|
71
|
-
- On Raspberry Pi, the default render quantum size (128) is too small and underruns occurs frequently. To prevent that, if you do not explicitely provide a latency hint in the AudioContext options, the value is automatically set to 'playback' which uses a buffer of 1024 samples (~21ms at 48000Hz). While this is not per se spec compliant, it allows usage of the library in a more user friendly manner. In the future, this might change according to the support of other audio backend.
|
|
72
72
|
- On Raspberry Pi, the `Linux arm gnueabihf` binary provided only works on 32bit OS. We will provide a version for the 64 bit OS in the future.
|
|
73
73
|
|
|
74
74
|
## Supported Platforms
|
|
@@ -83,6 +83,22 @@ node examples/granular-scrub.mjs
|
|
|
83
83
|
| Linux arm gnueabihf (RPi) | ✓ | ✓ |
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
## Notes for Linux users
|
|
87
|
+
|
|
88
|
+
Using the library on Linux with the ALSA backend might lead to unexpected cranky sound with the default render size (i.e. 128 frames). In such cases, a simple workaround is to pass the `playback` latency hint when creating the audio context, which will increase the render size to 1024 frames:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const audioContext = new AudioContext({ latencyHint: 'playback' });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You can pass the `WEB_AUDIO_LATENCY=playback` env variable to all examples to create the audio context with the playback latency hint, e.g.:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
WEB_AUDIO_LATENCY=playback node examples/amplitude-modulation.mjs
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
For real-time and interactive applications where low latency is crucial, you should instead rely on the JACK backend provided by `cpal`. By default the audio context will use that backend if a running JACK server is found.
|
|
101
|
+
|
|
86
102
|
### Manual Build
|
|
87
103
|
|
|
88
104
|
If prebuilt binaries are not shippped for your platform, you will need to:
|
|
@@ -96,13 +112,15 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
|
96
112
|
2. Install and build from github
|
|
97
113
|
|
|
98
114
|
```sh
|
|
99
|
-
|
|
115
|
+
git clone https://github.com/ircam-ismm/node-web-audio-api.git node_modules/node-web-audio-api
|
|
100
116
|
cd node_modules/node-web-audio-api
|
|
101
117
|
npm install
|
|
102
118
|
npm run build
|
|
103
119
|
```
|
|
104
120
|
|
|
105
|
-
The package will be built on your machine, which might take some time
|
|
121
|
+
The package will be built on your machine, which might take some time.
|
|
122
|
+
|
|
123
|
+
Be aware that the package won't be listed on your `package.json` file, and that it won't be re-installed if running `npm install` again. A possible workaround would be to include the above in a postinstall script.
|
|
106
124
|
|
|
107
125
|
## Development notes
|
|
108
126
|
|
package/monkey-patch.js
CHANGED
|
@@ -29,34 +29,6 @@ let contextIds = {
|
|
|
29
29
|
let enumerateDevicesSync = null;
|
|
30
30
|
|
|
31
31
|
function handleDefaultOptions(options, kind) {
|
|
32
|
-
if (platform === 'linux') {
|
|
33
|
-
const list = enumerateDevicesSync();
|
|
34
|
-
const jackDevice = list.find(device => device.kind === kind && device.label === 'jack');
|
|
35
|
-
|
|
36
|
-
if (jackDevice === undefined) {
|
|
37
|
-
// throw meaningfull error if several contexts are created on linux,
|
|
38
|
-
// because of alsa backend we currently use
|
|
39
|
-
if (contextIds[kind] === 1) {
|
|
40
|
-
throw new Error(`[node-web-audio-api] node-web-audio-api uses alsa as backend, therefore only one context or audio input stream can be safely created`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// force latencyHint to "playback" on RPi if not explicitely defined
|
|
44
|
-
if (arch === 'arm') {
|
|
45
|
-
if (kind === 'audiooutput' && !('latencyHint' in options)) {
|
|
46
|
-
options.latencyHint = 'playback';
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
// default to jack if jack source or sink is found
|
|
51
|
-
const deviceKey = kind === 'audioinput' ? 'deviceId' : 'sinkId';
|
|
52
|
-
|
|
53
|
-
if (!(deviceKey in options)) {
|
|
54
|
-
console.log(`> JACK ${kind} device found, use as default`);
|
|
55
|
-
options[deviceKey] = jackDevice.deviceId;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
32
|
// increment contextIds as they are used to keep the process awake
|
|
61
33
|
contextIds[kind] += 1;
|
|
62
34
|
|
|
@@ -139,22 +111,24 @@ function patchOfflineAudioContext(nativeBinding) {
|
|
|
139
111
|
constructor(...args) {
|
|
140
112
|
// handle initialisation with either an options object or a sequence of parameters
|
|
141
113
|
// https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-constructor-contextoptions-contextoptions
|
|
142
|
-
if (
|
|
114
|
+
if (isPlainObject(args[0])
|
|
143
115
|
&& 'numberOfChannels' in args[0] && 'length' in args[0] && 'sampleRate' in args[0]
|
|
144
116
|
) {
|
|
145
117
|
const { numberOfChannels, length, sampleRate } = args[0];
|
|
146
118
|
args = [numberOfChannels, length, sampleRate];
|
|
147
119
|
}
|
|
148
120
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
throw new NotSupportedError(`Unsupported value for
|
|
153
|
-
} else if (!
|
|
154
|
-
throw new NotSupportedError(`Unsupported value for
|
|
121
|
+
const [numberOfChannels, length, sampleRate] = args;
|
|
122
|
+
|
|
123
|
+
if (!isPositiveInt(numberOfChannels)) {
|
|
124
|
+
throw new NotSupportedError(`Unsupported value for numberOfChannels: ${numberOfChannels}`);
|
|
125
|
+
} else if (!isPositiveInt(length)) {
|
|
126
|
+
throw new NotSupportedError(`Unsupported value for length: ${length}`);
|
|
127
|
+
} else if (!isPositiveNumber(sampleRate)) {
|
|
128
|
+
throw new NotSupportedError(`Unsupported value for sampleRate: ${sampleRate}`);
|
|
155
129
|
}
|
|
156
130
|
|
|
157
|
-
super(
|
|
131
|
+
super(numberOfChannels, length, sampleRate);
|
|
158
132
|
}
|
|
159
133
|
|
|
160
134
|
// promisify sync APIs
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-web-audio-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"author": "Benjamin Matuszewski",
|
|
5
5
|
"description": "Node.js bindings for web-audio-api-rs using napi-rs",
|
|
6
6
|
"exports": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"artifacts": "napi artifacts",
|
|
34
34
|
"build": "npm run generate && napi build --platform --release",
|
|
35
|
-
"build:jack": "npm run generate && napi build --platform --features
|
|
35
|
+
"build:jack": "npm run generate && napi build --platform --features jack --release",
|
|
36
36
|
"build:debug": "npm run generate && napi build --platform",
|
|
37
37
|
"check": "cargo fmt && cargo clippy",
|
|
38
38
|
"generate": "node generator/index.mjs && cargo fmt",
|