@opendaw/studio-adapters 0.0.119 → 0.0.120
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/dist/RingBuffer.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare namespace RingBuffer {
|
|
|
12
12
|
interface Reader {
|
|
13
13
|
stop(): void;
|
|
14
14
|
}
|
|
15
|
-
const reader: (
|
|
15
|
+
const reader: (config: Config, append: Procedure<Array<Float32Array>>) => Reader;
|
|
16
16
|
const writer: ({ sab, numChunks, numberOfChannels, bufferSize }: Config) => Writer;
|
|
17
17
|
}
|
|
18
18
|
export declare const mergeChunkPlanes: (chunks: ReadonlyArray<ReadonlyArray<Float32Array>>, bufferSize: int, maxFrames?: int) => ReadonlyArray<Float32Array>;
|
package/dist/RingBuffer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RingBuffer.d.ts","sourceRoot":"","sources":["../src/RingBuffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAS,SAAS,EAAC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"RingBuffer.d.ts","sourceRoot":"","sources":["../src/RingBuffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAS,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAEtE,yBAAiB,UAAU,CAAC;IACxB,UAAiB,MAAM;QACnB,GAAG,EAAE,iBAAiB,CAAA;QACtB,SAAS,EAAE,GAAG,CAAA;QACd,gBAAgB,EAAE,GAAG,CAAA;QACrB,UAAU,EAAE,GAAG,CAAA;KAClB;IAED,UAAiB,MAAM;QAAE,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,IAAI,CAAA;KAAC;IAE5E,UAAiB,MAAM;QAAE,IAAI,IAAI,IAAI,CAAA;KAAC;IAM/B,MAAM,MAAM,GAAI,QAAQ,MAAM,EAAE,QAAQ,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,KAAG,MA8C/E,CAAA;IAEM,MAAM,MAAM,GAAI,kDAAgD,MAAM,KAAG,MAqB/E,CAAA;CACJ;AAED,eAAO,MAAM,gBAAgB,GAAI,QAAQ,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,EAClD,YAAY,GAAG,EACf,YAAW,GAA6B,KAAG,aAAa,CAAC,YAAY,CAkBrG,CAAA"}
|
package/dist/RingBuffer.js
CHANGED
|
@@ -1,48 +1,58 @@
|
|
|
1
1
|
import { Arrays, assert, panic } from "@opendaw/lib-std";
|
|
2
2
|
export var RingBuffer;
|
|
3
3
|
(function (RingBuffer) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
// The reader drains the ring on a dedicated worker that blocks on `Atomics.wait` (woken by the writer's
|
|
5
|
+
// `Atomics.notify`). This avoids the main-thread `setTimeout` polling that Chrome throttles to ~1s in hidden
|
|
6
|
+
// tabs, which used to overrun the ring (~0.37s) and silently drop recorded audio. Drained chunks are posted
|
|
7
|
+
// back (transferred) so the caller's `append` still runs on the main thread. See issue #290.
|
|
8
|
+
RingBuffer.reader = (config, append) => {
|
|
9
|
+
const code = `
|
|
10
|
+
onmessage = (event) => {
|
|
11
|
+
const {sab, numChunks, numberOfChannels, bufferSize} = event.data
|
|
12
|
+
const pointers = new Int32Array(sab, 0, 2)
|
|
13
|
+
const audio = new Float32Array(sab, 8)
|
|
14
|
+
const chunkFloats = numberOfChannels * bufferSize
|
|
15
|
+
while (true) {
|
|
16
|
+
let readPtr = Atomics.load(pointers, 1)
|
|
17
|
+
let writePtr = Atomics.load(pointers, 0)
|
|
18
|
+
if (readPtr === writePtr) {
|
|
19
|
+
Atomics.wait(pointers, 0, writePtr)
|
|
20
|
+
writePtr = Atomics.load(pointers, 0)
|
|
21
|
+
}
|
|
22
|
+
const batch = []
|
|
23
|
+
const transfer = []
|
|
24
|
+
while (readPtr !== writePtr) {
|
|
25
|
+
const offset = readPtr * chunkFloats
|
|
26
|
+
const channels = []
|
|
27
|
+
for (let channel = 0; channel < numberOfChannels; channel++) {
|
|
28
|
+
const start = offset + channel * bufferSize
|
|
29
|
+
const frames = audio.slice(start, start + bufferSize)
|
|
30
|
+
channels.push(frames)
|
|
31
|
+
transfer.push(frames.buffer)
|
|
32
|
+
}
|
|
33
|
+
readPtr = (readPtr + 1) % numChunks
|
|
34
|
+
Atomics.store(pointers, 1, readPtr)
|
|
35
|
+
batch.push(channels)
|
|
36
|
+
}
|
|
37
|
+
postMessage(batch, transfer)
|
|
23
38
|
}
|
|
24
|
-
writePtr = Atomics.load(pointers, 0);
|
|
25
39
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const end = start + bufferSize;
|
|
33
|
-
channels.push(planarChunk.slice(start, end));
|
|
34
|
-
}
|
|
35
|
-
readPtr = (readPtr + 1) % numChunks;
|
|
36
|
-
Atomics.store(pointers, 1, readPtr);
|
|
37
|
-
if (!running) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
+
`;
|
|
41
|
+
const url = URL.createObjectURL(new Blob([code], { type: "application/javascript" }));
|
|
42
|
+
const worker = new Worker(url);
|
|
43
|
+
worker.onmessage = (event) => {
|
|
44
|
+
const batch = event.data;
|
|
45
|
+
for (const channels of batch) {
|
|
40
46
|
append(channels);
|
|
41
47
|
}
|
|
42
|
-
step();
|
|
43
48
|
};
|
|
44
|
-
|
|
45
|
-
return {
|
|
49
|
+
worker.postMessage(config);
|
|
50
|
+
return {
|
|
51
|
+
stop: () => {
|
|
52
|
+
worker.terminate();
|
|
53
|
+
URL.revokeObjectURL(url);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
46
56
|
};
|
|
47
57
|
RingBuffer.writer = ({ sab, numChunks, numberOfChannels, bufferSize }) => {
|
|
48
58
|
const pointers = new Int32Array(sab, 0, 2);
|
|
@@ -17,8 +17,8 @@ export declare class VocoderDeviceBoxAdapter implements AudioEffectDeviceAdapter
|
|
|
17
17
|
readonly carrierMaxFreq: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
18
18
|
readonly modulatorMinFreq: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
19
19
|
readonly modulatorMaxFreq: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
20
|
+
readonly qStart: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
21
|
+
readonly qEnd: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
22
22
|
readonly envAttack: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
23
23
|
readonly envRelease: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
24
24
|
readonly gain: import("../..").AutomatableParameterFieldAdapter<number>;
|
|
@@ -59,8 +59,8 @@ _VocoderDeviceBoxAdapter_context = new WeakMap(), _VocoderDeviceBoxAdapter_box =
|
|
|
59
59
|
carrierMaxFreq: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.carrierMaxFreq, freqMap, freqStr, "Carrier Max"),
|
|
60
60
|
modulatorMinFreq: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.modulatorMinFreq, freqMap, freqStr, "Mod Min"),
|
|
61
61
|
modulatorMaxFreq: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.modulatorMaxFreq, freqMap, freqStr, "Mod Max"),
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
qStart: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.qStart, qMap, qStr, "Q Start"),
|
|
63
|
+
qEnd: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.qEnd, qMap, qStr, "Q End"),
|
|
64
64
|
envAttack: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.envAttack, ValueMapping.exponential(0.1, 100.0), StringMapping.numeric({ unit: "ms", fractionDigits: 1 }), "Attack"),
|
|
65
65
|
envRelease: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.envRelease, ValueMapping.exponential(1.0, 1000.0), StringMapping.numeric({ unit: "ms", fractionDigits: 0 }), "Release"),
|
|
66
66
|
gain: __classPrivateFieldGet(this, _VocoderDeviceBoxAdapter_parametric, "f").createParameter(box.gain, ValueMapping.linear(-20.0, 20.0), StringMapping.decible, "Gain"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendaw/studio-adapters",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.120",
|
|
4
4
|
"license": "LGPL-3.0-or-later",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
"pregenerate-all-boxes": "npm run build -w @opendaw/studio-forge-boxes && npm run build -w @opendaw/studio-boxes"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@opendaw/lib-box": "^0.0.
|
|
29
|
-
"@opendaw/lib-dsp": "^0.0.
|
|
30
|
-
"@opendaw/lib-fusion": "^0.0.
|
|
31
|
-
"@opendaw/lib-midi": "^0.0.
|
|
32
|
-
"@opendaw/lib-runtime": "^0.0.
|
|
33
|
-
"@opendaw/lib-std": "^0.0.
|
|
34
|
-
"@opendaw/studio-boxes": "^0.0.
|
|
35
|
-
"@opendaw/studio-enums": "^0.0.
|
|
28
|
+
"@opendaw/lib-box": "^0.0.89",
|
|
29
|
+
"@opendaw/lib-dsp": "^0.0.87",
|
|
30
|
+
"@opendaw/lib-fusion": "^0.0.97",
|
|
31
|
+
"@opendaw/lib-midi": "^0.0.69",
|
|
32
|
+
"@opendaw/lib-runtime": "^0.0.82",
|
|
33
|
+
"@opendaw/lib-std": "^0.0.81",
|
|
34
|
+
"@opendaw/studio-boxes": "^0.0.97",
|
|
35
|
+
"@opendaw/studio-enums": "^0.0.80",
|
|
36
36
|
"soundfont2": "^0.5.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@opendaw/eslint-config": "^0.0.28",
|
|
40
40
|
"@opendaw/typescript-config": "^0.0.32"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "8b806c880c2642b10f277e8b74c31aeafe7e6bfc"
|
|
43
43
|
}
|