@ikonai/sdk-libopus 0.0.1
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/index.d.ts +5 -0
- package/index.js +45 -0
- package/lib/opus-constants.d.ts +45 -0
- package/lib/opus-constants.js +37 -0
- package/lib/opus-decoder.d.ts +54 -0
- package/lib/opus-decoder.js +106 -0
- package/lib/opus-encoder.d.ts +66 -0
- package/lib/opus-encoder.js +117 -0
- package/lib/opus-module.d.ts +15 -0
- package/lib/opus-module.js +72 -0
- package/lib/types.d.ts +35 -0
- package/package.json +17 -0
- package/wasm/libopus-simd.d.ts +3 -0
- package/wasm/libopus-simd.js +13 -0
- package/wasm/libopus-simd.wasm +0 -0
- package/wasm/libopus.d.ts +3 -0
- package/wasm/libopus.js +13 -0
- package/wasm/libopus.wasm +0 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { OpusDecoder } from './lib/opus-decoder';
|
|
2
|
+
export { OpusEncoder } from './lib/opus-encoder';
|
|
3
|
+
export { getOpusModule, isModuleLoaded, isSimdSupported } from './lib/opus-module';
|
|
4
|
+
export { OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_RESTRICTED_LOWDELAY, OPUS_SET_BITRATE_REQUEST, OPUS_GET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, OPUS_GET_COMPLEXITY_REQUEST, OPUS_SET_VBR_REQUEST, OPUS_GET_VBR_REQUEST, OPUS_SET_DTX_REQUEST, OPUS_GET_DTX_REQUEST, OPUS_SET_INBAND_FEC_REQUEST, OPUS_GET_INBAND_FEC_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST, OPUS_GET_PACKET_LOSS_PERC_REQUEST, OPUS_RESET_STATE, OPUS_OK, OPUS_BAD_ARG, OPUS_BUFFER_TOO_SMALL, OPUS_INTERNAL_ERROR, OPUS_INVALID_PACKET, OPUS_UNIMPLEMENTED, OPUS_INVALID_STATE, OPUS_ALLOC_FAIL, OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_FULLBAND, OPUS_SIGNAL_VOICE, OPUS_SIGNAL_MUSIC, MAX_FRAME_SIZE, MAX_PACKET_SIZE, MAX_CHANNELS, } from './lib/opus-constants';
|
|
5
|
+
export type { OpusModule, DecodedAudio, OpusDecoderOptions, OpusEncoderOptions, OpusModuleFactory, } from './lib/types';
|
package/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OpusDecoder as S } from "./lib/opus-decoder.js";
|
|
2
|
+
import { OpusEncoder as O } from "./lib/opus-encoder.js";
|
|
3
|
+
import { getOpusModule as P, isModuleLoaded as A, isSimdSupported as I } from "./lib/opus-module.js";
|
|
4
|
+
import { MAX_CHANNELS as D, MAX_FRAME_SIZE as N, MAX_PACKET_SIZE as L, OPUS_ALLOC_FAIL as B, OPUS_APPLICATION_AUDIO as C, OPUS_APPLICATION_RESTRICTED_LOWDELAY as o, OPUS_APPLICATION_VOIP as M, OPUS_BAD_ARG as e, OPUS_BANDWIDTH_FULLBAND as Q, OPUS_BANDWIDTH_MEDIUMBAND as r, OPUS_BANDWIDTH_NARROWBAND as p, OPUS_BANDWIDTH_SUPERWIDEBAND as G, OPUS_BANDWIDTH_WIDEBAND as W, OPUS_BUFFER_TOO_SMALL as d, OPUS_GET_BITRATE_REQUEST as F, OPUS_GET_COMPLEXITY_REQUEST as X, OPUS_GET_DTX_REQUEST as t, OPUS_GET_INBAND_FEC_REQUEST as u, OPUS_GET_PACKET_LOSS_PERC_REQUEST as H, OPUS_GET_VBR_REQUEST as V, OPUS_INTERNAL_ERROR as m, OPUS_INVALID_PACKET as s, OPUS_INVALID_STATE as K, OPUS_OK as f, OPUS_RESET_STATE as x, OPUS_SET_BITRATE_REQUEST as i, OPUS_SET_COMPLEXITY_REQUEST as Y, OPUS_SET_DTX_REQUEST as c, OPUS_SET_INBAND_FEC_REQUEST as l, OPUS_SET_PACKET_LOSS_PERC_REQUEST as Z, OPUS_SET_VBR_REQUEST as a, OPUS_SIGNAL_MUSIC as g, OPUS_SIGNAL_VOICE as n, OPUS_UNIMPLEMENTED as b } from "./lib/opus-constants.js";
|
|
5
|
+
export {
|
|
6
|
+
D as MAX_CHANNELS,
|
|
7
|
+
N as MAX_FRAME_SIZE,
|
|
8
|
+
L as MAX_PACKET_SIZE,
|
|
9
|
+
B as OPUS_ALLOC_FAIL,
|
|
10
|
+
C as OPUS_APPLICATION_AUDIO,
|
|
11
|
+
o as OPUS_APPLICATION_RESTRICTED_LOWDELAY,
|
|
12
|
+
M as OPUS_APPLICATION_VOIP,
|
|
13
|
+
e as OPUS_BAD_ARG,
|
|
14
|
+
Q as OPUS_BANDWIDTH_FULLBAND,
|
|
15
|
+
r as OPUS_BANDWIDTH_MEDIUMBAND,
|
|
16
|
+
p as OPUS_BANDWIDTH_NARROWBAND,
|
|
17
|
+
G as OPUS_BANDWIDTH_SUPERWIDEBAND,
|
|
18
|
+
W as OPUS_BANDWIDTH_WIDEBAND,
|
|
19
|
+
d as OPUS_BUFFER_TOO_SMALL,
|
|
20
|
+
F as OPUS_GET_BITRATE_REQUEST,
|
|
21
|
+
X as OPUS_GET_COMPLEXITY_REQUEST,
|
|
22
|
+
t as OPUS_GET_DTX_REQUEST,
|
|
23
|
+
u as OPUS_GET_INBAND_FEC_REQUEST,
|
|
24
|
+
H as OPUS_GET_PACKET_LOSS_PERC_REQUEST,
|
|
25
|
+
V as OPUS_GET_VBR_REQUEST,
|
|
26
|
+
m as OPUS_INTERNAL_ERROR,
|
|
27
|
+
s as OPUS_INVALID_PACKET,
|
|
28
|
+
K as OPUS_INVALID_STATE,
|
|
29
|
+
f as OPUS_OK,
|
|
30
|
+
x as OPUS_RESET_STATE,
|
|
31
|
+
i as OPUS_SET_BITRATE_REQUEST,
|
|
32
|
+
Y as OPUS_SET_COMPLEXITY_REQUEST,
|
|
33
|
+
c as OPUS_SET_DTX_REQUEST,
|
|
34
|
+
l as OPUS_SET_INBAND_FEC_REQUEST,
|
|
35
|
+
Z as OPUS_SET_PACKET_LOSS_PERC_REQUEST,
|
|
36
|
+
a as OPUS_SET_VBR_REQUEST,
|
|
37
|
+
g as OPUS_SIGNAL_MUSIC,
|
|
38
|
+
n as OPUS_SIGNAL_VOICE,
|
|
39
|
+
b as OPUS_UNIMPLEMENTED,
|
|
40
|
+
S as OpusDecoder,
|
|
41
|
+
O as OpusEncoder,
|
|
42
|
+
P as getOpusModule,
|
|
43
|
+
A as isModuleLoaded,
|
|
44
|
+
I as isSimdSupported
|
|
45
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const OPUS_APPLICATION_VOIP = 2048;
|
|
2
|
+
export declare const OPUS_APPLICATION_AUDIO = 2049;
|
|
3
|
+
export declare const OPUS_APPLICATION_RESTRICTED_LOWDELAY = 2051;
|
|
4
|
+
export declare const OPUS_SET_BITRATE_REQUEST = 4002;
|
|
5
|
+
export declare const OPUS_GET_BITRATE_REQUEST = 4003;
|
|
6
|
+
export declare const OPUS_SET_COMPLEXITY_REQUEST = 4010;
|
|
7
|
+
export declare const OPUS_GET_COMPLEXITY_REQUEST = 4011;
|
|
8
|
+
export declare const OPUS_SET_VBR_REQUEST = 4006;
|
|
9
|
+
export declare const OPUS_GET_VBR_REQUEST = 4007;
|
|
10
|
+
export declare const OPUS_SET_VBR_CONSTRAINT_REQUEST = 4020;
|
|
11
|
+
export declare const OPUS_GET_VBR_CONSTRAINT_REQUEST = 4021;
|
|
12
|
+
export declare const OPUS_SET_FORCE_CHANNELS_REQUEST = 4022;
|
|
13
|
+
export declare const OPUS_GET_FORCE_CHANNELS_REQUEST = 4023;
|
|
14
|
+
export declare const OPUS_SET_MAX_BANDWIDTH_REQUEST = 4004;
|
|
15
|
+
export declare const OPUS_GET_MAX_BANDWIDTH_REQUEST = 4005;
|
|
16
|
+
export declare const OPUS_SET_BANDWIDTH_REQUEST = 4008;
|
|
17
|
+
export declare const OPUS_SET_SIGNAL_REQUEST = 4024;
|
|
18
|
+
export declare const OPUS_GET_SIGNAL_REQUEST = 4025;
|
|
19
|
+
export declare const OPUS_SET_DTX_REQUEST = 4016;
|
|
20
|
+
export declare const OPUS_GET_DTX_REQUEST = 4017;
|
|
21
|
+
export declare const OPUS_SET_INBAND_FEC_REQUEST = 4012;
|
|
22
|
+
export declare const OPUS_GET_INBAND_FEC_REQUEST = 4013;
|
|
23
|
+
export declare const OPUS_SET_PACKET_LOSS_PERC_REQUEST = 4014;
|
|
24
|
+
export declare const OPUS_GET_PACKET_LOSS_PERC_REQUEST = 4015;
|
|
25
|
+
export declare const OPUS_RESET_STATE = 4028;
|
|
26
|
+
export declare const OPUS_GET_SAMPLE_RATE_REQUEST = 4029;
|
|
27
|
+
export declare const OPUS_GET_LOOKAHEAD_REQUEST = 4027;
|
|
28
|
+
export declare const OPUS_OK = 0;
|
|
29
|
+
export declare const OPUS_BAD_ARG = -1;
|
|
30
|
+
export declare const OPUS_BUFFER_TOO_SMALL = -2;
|
|
31
|
+
export declare const OPUS_INTERNAL_ERROR = -3;
|
|
32
|
+
export declare const OPUS_INVALID_PACKET = -4;
|
|
33
|
+
export declare const OPUS_UNIMPLEMENTED = -5;
|
|
34
|
+
export declare const OPUS_INVALID_STATE = -6;
|
|
35
|
+
export declare const OPUS_ALLOC_FAIL = -7;
|
|
36
|
+
export declare const OPUS_BANDWIDTH_NARROWBAND = 1101;
|
|
37
|
+
export declare const OPUS_BANDWIDTH_MEDIUMBAND = 1102;
|
|
38
|
+
export declare const OPUS_BANDWIDTH_WIDEBAND = 1103;
|
|
39
|
+
export declare const OPUS_BANDWIDTH_SUPERWIDEBAND = 1104;
|
|
40
|
+
export declare const OPUS_BANDWIDTH_FULLBAND = 1105;
|
|
41
|
+
export declare const OPUS_SIGNAL_VOICE = 3001;
|
|
42
|
+
export declare const OPUS_SIGNAL_MUSIC = 3002;
|
|
43
|
+
export declare const MAX_FRAME_SIZE = 5760;
|
|
44
|
+
export declare const MAX_PACKET_SIZE = 4000;
|
|
45
|
+
export declare const MAX_CHANNELS = 2;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const _ = 2048, E = 2049, S = 2051, T = 4002, U = 4003, O = 4010, P = 4011, A = 4006, I = 4007, o = 4016, t = 4017, c = 4012, n = 4013, s = 4014, R = 4015, D = 4028, N = 0, L = -1, B = -2, C = -3, M = -4, Q = -5, G = -6, W = -7, F = 1101, X = 1102, H = 1103, V = 1104, K = 1105, Y = 3001, e = 3002, Z = 5760, p = 4e3, r = 2;
|
|
2
|
+
export {
|
|
3
|
+
r as MAX_CHANNELS,
|
|
4
|
+
Z as MAX_FRAME_SIZE,
|
|
5
|
+
p as MAX_PACKET_SIZE,
|
|
6
|
+
W as OPUS_ALLOC_FAIL,
|
|
7
|
+
E as OPUS_APPLICATION_AUDIO,
|
|
8
|
+
S as OPUS_APPLICATION_RESTRICTED_LOWDELAY,
|
|
9
|
+
_ as OPUS_APPLICATION_VOIP,
|
|
10
|
+
L as OPUS_BAD_ARG,
|
|
11
|
+
K as OPUS_BANDWIDTH_FULLBAND,
|
|
12
|
+
X as OPUS_BANDWIDTH_MEDIUMBAND,
|
|
13
|
+
F as OPUS_BANDWIDTH_NARROWBAND,
|
|
14
|
+
V as OPUS_BANDWIDTH_SUPERWIDEBAND,
|
|
15
|
+
H as OPUS_BANDWIDTH_WIDEBAND,
|
|
16
|
+
B as OPUS_BUFFER_TOO_SMALL,
|
|
17
|
+
U as OPUS_GET_BITRATE_REQUEST,
|
|
18
|
+
P as OPUS_GET_COMPLEXITY_REQUEST,
|
|
19
|
+
t as OPUS_GET_DTX_REQUEST,
|
|
20
|
+
n as OPUS_GET_INBAND_FEC_REQUEST,
|
|
21
|
+
R as OPUS_GET_PACKET_LOSS_PERC_REQUEST,
|
|
22
|
+
I as OPUS_GET_VBR_REQUEST,
|
|
23
|
+
C as OPUS_INTERNAL_ERROR,
|
|
24
|
+
M as OPUS_INVALID_PACKET,
|
|
25
|
+
G as OPUS_INVALID_STATE,
|
|
26
|
+
N as OPUS_OK,
|
|
27
|
+
D as OPUS_RESET_STATE,
|
|
28
|
+
T as OPUS_SET_BITRATE_REQUEST,
|
|
29
|
+
O as OPUS_SET_COMPLEXITY_REQUEST,
|
|
30
|
+
o as OPUS_SET_DTX_REQUEST,
|
|
31
|
+
c as OPUS_SET_INBAND_FEC_REQUEST,
|
|
32
|
+
s as OPUS_SET_PACKET_LOSS_PERC_REQUEST,
|
|
33
|
+
A as OPUS_SET_VBR_REQUEST,
|
|
34
|
+
e as OPUS_SIGNAL_MUSIC,
|
|
35
|
+
Y as OPUS_SIGNAL_VOICE,
|
|
36
|
+
Q as OPUS_UNIMPLEMENTED
|
|
37
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DecodedAudio, OpusDecoderOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Opus audio decoder with zero per-frame allocations.
|
|
4
|
+
*
|
|
5
|
+
* All buffers are pre-allocated at construction time and reused for each decode call.
|
|
6
|
+
* The decoded audio is returned as views into internal buffers - callers must copy
|
|
7
|
+
* the data if they need it to persist beyond the next decode call.
|
|
8
|
+
*/
|
|
9
|
+
export declare class OpusDecoder {
|
|
10
|
+
private module;
|
|
11
|
+
private decoder;
|
|
12
|
+
private readonly channels;
|
|
13
|
+
private readonly sampleRate;
|
|
14
|
+
private inputPtr;
|
|
15
|
+
private outputPtr;
|
|
16
|
+
private readonly channelBuffers;
|
|
17
|
+
readonly ready: Promise<void>;
|
|
18
|
+
constructor(options: OpusDecoderOptions);
|
|
19
|
+
private initialize;
|
|
20
|
+
/**
|
|
21
|
+
* Decode an Opus frame.
|
|
22
|
+
*
|
|
23
|
+
* Returns views into pre-allocated buffers. The channelData arrays are reused
|
|
24
|
+
* on each call, so callers MUST copy the data if it needs to persist beyond
|
|
25
|
+
* the next decode call.
|
|
26
|
+
*
|
|
27
|
+
* @param opusData - The Opus-encoded audio frame
|
|
28
|
+
* @returns Decoded audio with channel data and sample count
|
|
29
|
+
*/
|
|
30
|
+
decodeFrame(opusData: Uint8Array): DecodedAudio;
|
|
31
|
+
/**
|
|
32
|
+
* Decode a frame and copy the result (when caller needs ownership).
|
|
33
|
+
* Use this when you need the decoded audio to persist.
|
|
34
|
+
*/
|
|
35
|
+
decodeFrameAndCopy(opusData: Uint8Array): DecodedAudio;
|
|
36
|
+
/**
|
|
37
|
+
* Reset the decoder state.
|
|
38
|
+
* Call this when there's a discontinuity in the audio stream.
|
|
39
|
+
*/
|
|
40
|
+
reset(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get the number of channels this decoder was created with.
|
|
43
|
+
*/
|
|
44
|
+
getChannels(): number;
|
|
45
|
+
/**
|
|
46
|
+
* Get the sample rate this decoder was created with.
|
|
47
|
+
*/
|
|
48
|
+
getSampleRate(): number;
|
|
49
|
+
/**
|
|
50
|
+
* Release all resources.
|
|
51
|
+
* The decoder cannot be used after calling destroy().
|
|
52
|
+
*/
|
|
53
|
+
destroy(): void;
|
|
54
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { getOpusModule as d } from "./opus-module.js";
|
|
2
|
+
import { MAX_FRAME_SIZE as i, MAX_PACKET_SIZE as h, OPUS_RESET_STATE as a } from "./opus-constants.js";
|
|
3
|
+
class m {
|
|
4
|
+
module = null;
|
|
5
|
+
decoder = 0;
|
|
6
|
+
channels;
|
|
7
|
+
sampleRate;
|
|
8
|
+
// Pre-allocated WASM heap pointers (allocated once, reused)
|
|
9
|
+
inputPtr = 0;
|
|
10
|
+
outputPtr = 0;
|
|
11
|
+
// Pre-allocated output arrays (reused, caller must copy if needed)
|
|
12
|
+
channelBuffers;
|
|
13
|
+
ready;
|
|
14
|
+
constructor(e) {
|
|
15
|
+
this.channels = e.channels, this.sampleRate = e.sampleRate, this.channelBuffers = Array.from({ length: this.channels }, () => new Float32Array(i)), this.ready = this.initialize();
|
|
16
|
+
}
|
|
17
|
+
async initialize() {
|
|
18
|
+
this.module = await d();
|
|
19
|
+
const e = this.module._malloc(4);
|
|
20
|
+
this.decoder = this.module._opus_decoder_create(this.sampleRate, this.channels, e);
|
|
21
|
+
const t = new DataView(this.module.HEAPU8.buffer).getInt32(e, !0);
|
|
22
|
+
if (this.module._free(e), t !== 0)
|
|
23
|
+
throw new Error(`opus_decoder_create failed with error code ${t}`);
|
|
24
|
+
this.inputPtr = this.module._malloc(h), this.outputPtr = this.module._malloc(i * this.channels * 4);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decode an Opus frame.
|
|
28
|
+
*
|
|
29
|
+
* Returns views into pre-allocated buffers. The channelData arrays are reused
|
|
30
|
+
* on each call, so callers MUST copy the data if it needs to persist beyond
|
|
31
|
+
* the next decode call.
|
|
32
|
+
*
|
|
33
|
+
* @param opusData - The Opus-encoded audio frame
|
|
34
|
+
* @returns Decoded audio with channel data and sample count
|
|
35
|
+
*/
|
|
36
|
+
decodeFrame(e) {
|
|
37
|
+
if (!this.module || !this.decoder)
|
|
38
|
+
throw new Error("Decoder not initialized");
|
|
39
|
+
if (e.length > h)
|
|
40
|
+
throw new Error(`Opus packet too large: ${e.length} > ${h}`);
|
|
41
|
+
this.module.HEAPU8.set(e, this.inputPtr);
|
|
42
|
+
const t = this.module._opus_decode_float(
|
|
43
|
+
this.decoder,
|
|
44
|
+
this.inputPtr,
|
|
45
|
+
e.length,
|
|
46
|
+
this.outputPtr,
|
|
47
|
+
i,
|
|
48
|
+
0
|
|
49
|
+
// decodeFec = false
|
|
50
|
+
);
|
|
51
|
+
if (t < 0)
|
|
52
|
+
throw new Error(`opus_decode_float failed with error code ${t}`);
|
|
53
|
+
const o = this.outputPtr / 4;
|
|
54
|
+
for (let s = 0; s < this.channels; s++) {
|
|
55
|
+
const l = this.channelBuffers[s];
|
|
56
|
+
for (let r = 0; r < t; r++)
|
|
57
|
+
l[r] = this.module.HEAPF32[o + r * this.channels + s];
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
channelData: this.channelBuffers,
|
|
61
|
+
samplesDecoded: t,
|
|
62
|
+
sampleRate: this.sampleRate
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Decode a frame and copy the result (when caller needs ownership).
|
|
67
|
+
* Use this when you need the decoded audio to persist.
|
|
68
|
+
*/
|
|
69
|
+
decodeFrameAndCopy(e) {
|
|
70
|
+
const t = this.decodeFrame(e);
|
|
71
|
+
return {
|
|
72
|
+
channelData: t.channelData.map((o) => o.slice(0, t.samplesDecoded)),
|
|
73
|
+
samplesDecoded: t.samplesDecoded,
|
|
74
|
+
sampleRate: t.sampleRate
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Reset the decoder state.
|
|
79
|
+
* Call this when there's a discontinuity in the audio stream.
|
|
80
|
+
*/
|
|
81
|
+
reset() {
|
|
82
|
+
this.module && this.decoder && this.module._opus_decoder_ctl(this.decoder, a);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get the number of channels this decoder was created with.
|
|
86
|
+
*/
|
|
87
|
+
getChannels() {
|
|
88
|
+
return this.channels;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the sample rate this decoder was created with.
|
|
92
|
+
*/
|
|
93
|
+
getSampleRate() {
|
|
94
|
+
return this.sampleRate;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Release all resources.
|
|
98
|
+
* The decoder cannot be used after calling destroy().
|
|
99
|
+
*/
|
|
100
|
+
destroy() {
|
|
101
|
+
this.module && (this.decoder && this.module._opus_decoder_destroy(this.decoder), this.inputPtr && this.module._free(this.inputPtr), this.outputPtr && this.module._free(this.outputPtr)), this.decoder = 0, this.inputPtr = 0, this.outputPtr = 0, this.module = null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
m as OpusDecoder
|
|
106
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { OpusEncoderOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Opus audio encoder with zero per-frame allocations.
|
|
4
|
+
*
|
|
5
|
+
* All buffers are pre-allocated at construction time and reused for each encode call.
|
|
6
|
+
* The encoded audio is returned as a view into an internal buffer - callers must copy
|
|
7
|
+
* the data if they need it to persist beyond the next encode call.
|
|
8
|
+
*/
|
|
9
|
+
export declare class OpusEncoder {
|
|
10
|
+
private module;
|
|
11
|
+
private encoder;
|
|
12
|
+
private readonly channels;
|
|
13
|
+
private readonly sampleRate;
|
|
14
|
+
private readonly bitrate;
|
|
15
|
+
private readonly application;
|
|
16
|
+
private inputPtr;
|
|
17
|
+
private outputPtr;
|
|
18
|
+
readonly ready: Promise<void>;
|
|
19
|
+
constructor(options: OpusEncoderOptions);
|
|
20
|
+
private initialize;
|
|
21
|
+
private setEncoderCtl;
|
|
22
|
+
/**
|
|
23
|
+
* Encode PCM float samples to Opus.
|
|
24
|
+
*
|
|
25
|
+
* Returns a view into a pre-allocated buffer. The returned Uint8Array is reused
|
|
26
|
+
* on each call, so callers MUST copy the data if it needs to persist beyond
|
|
27
|
+
* the next encode call.
|
|
28
|
+
*
|
|
29
|
+
* @param pcmFloat - Interleaved float PCM samples (-1.0 to 1.0)
|
|
30
|
+
* @returns Opus-encoded audio data (view into internal buffer)
|
|
31
|
+
*/
|
|
32
|
+
encode(pcmFloat: Float32Array): Uint8Array;
|
|
33
|
+
/**
|
|
34
|
+
* Encode and copy the result (when caller needs ownership).
|
|
35
|
+
* Use this when you need the encoded audio to persist, e.g., when sending to another thread.
|
|
36
|
+
*/
|
|
37
|
+
encodeAndCopy(pcmFloat: Float32Array): Uint8Array;
|
|
38
|
+
/**
|
|
39
|
+
* Reset the encoder state.
|
|
40
|
+
* Call this when there's a discontinuity in the audio stream.
|
|
41
|
+
*/
|
|
42
|
+
reset(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Set the encoder bitrate.
|
|
45
|
+
* @param bitrate - Target bitrate in bits per second
|
|
46
|
+
*/
|
|
47
|
+
setBitrate(bitrate: number): void;
|
|
48
|
+
/**
|
|
49
|
+
* Set the encoder complexity (0-10, higher = better quality but more CPU).
|
|
50
|
+
* @param complexity - Complexity value (0-10)
|
|
51
|
+
*/
|
|
52
|
+
setComplexity(complexity: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the number of channels this encoder was created with.
|
|
55
|
+
*/
|
|
56
|
+
getChannels(): number;
|
|
57
|
+
/**
|
|
58
|
+
* Get the sample rate this encoder was created with.
|
|
59
|
+
*/
|
|
60
|
+
getSampleRate(): number;
|
|
61
|
+
/**
|
|
62
|
+
* Release all resources.
|
|
63
|
+
* The encoder cannot be used after calling destroy().
|
|
64
|
+
*/
|
|
65
|
+
destroy(): void;
|
|
66
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { getOpusModule as l } from "./opus-module.js";
|
|
2
|
+
import { OPUS_APPLICATION_VOIP as u, OPUS_SET_BITRATE_REQUEST as o, OPUS_SET_COMPLEXITY_REQUEST as n, MAX_PACKET_SIZE as h, OPUS_RESET_STATE as d } from "./opus-constants.js";
|
|
3
|
+
const r = 2880;
|
|
4
|
+
class _ {
|
|
5
|
+
module = null;
|
|
6
|
+
encoder = 0;
|
|
7
|
+
channels;
|
|
8
|
+
sampleRate;
|
|
9
|
+
bitrate;
|
|
10
|
+
application;
|
|
11
|
+
// Pre-allocated WASM heap pointers
|
|
12
|
+
inputPtr = 0;
|
|
13
|
+
outputPtr = 0;
|
|
14
|
+
ready;
|
|
15
|
+
constructor(t) {
|
|
16
|
+
this.channels = t.channels, this.sampleRate = t.sampleRate, this.bitrate = t.bitrate ?? 32e3, this.application = t.application ?? u, this.ready = this.initialize(t);
|
|
17
|
+
}
|
|
18
|
+
async initialize(t) {
|
|
19
|
+
this.module = await l();
|
|
20
|
+
const e = this.module._malloc(4);
|
|
21
|
+
this.encoder = this.module._opus_encoder_create(
|
|
22
|
+
this.sampleRate,
|
|
23
|
+
this.channels,
|
|
24
|
+
this.application,
|
|
25
|
+
e
|
|
26
|
+
);
|
|
27
|
+
const i = new DataView(this.module.HEAPU8.buffer).getInt32(e, !0);
|
|
28
|
+
if (this.module._free(e), i !== 0)
|
|
29
|
+
throw new Error(`opus_encoder_create failed with error code ${i}`);
|
|
30
|
+
this.setEncoderCtl(o, this.bitrate), t.complexity !== void 0 && this.setEncoderCtl(n, t.complexity), this.inputPtr = this.module._malloc(r * this.channels * 4), this.outputPtr = this.module._malloc(h);
|
|
31
|
+
}
|
|
32
|
+
setEncoderCtl(t, e) {
|
|
33
|
+
if (!this.module || !this.encoder)
|
|
34
|
+
return;
|
|
35
|
+
const i = this.module._malloc(4);
|
|
36
|
+
new DataView(this.module.HEAPU8.buffer).setInt32(i, e, !0), this.module._opus_encoder_ctl(this.encoder, t, i), this.module._free(i);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Encode PCM float samples to Opus.
|
|
40
|
+
*
|
|
41
|
+
* Returns a view into a pre-allocated buffer. The returned Uint8Array is reused
|
|
42
|
+
* on each call, so callers MUST copy the data if it needs to persist beyond
|
|
43
|
+
* the next encode call.
|
|
44
|
+
*
|
|
45
|
+
* @param pcmFloat - Interleaved float PCM samples (-1.0 to 1.0)
|
|
46
|
+
* @returns Opus-encoded audio data (view into internal buffer)
|
|
47
|
+
*/
|
|
48
|
+
encode(t) {
|
|
49
|
+
if (!this.module || !this.encoder)
|
|
50
|
+
throw new Error("Encoder not initialized");
|
|
51
|
+
const e = t.length / this.channels;
|
|
52
|
+
if (e > r)
|
|
53
|
+
throw new Error(`Frame size too large: ${e} > ${r} samples`);
|
|
54
|
+
const i = this.inputPtr / 4;
|
|
55
|
+
this.module.HEAPF32.set(t, i);
|
|
56
|
+
const s = this.module._opus_encode_float(
|
|
57
|
+
this.encoder,
|
|
58
|
+
this.inputPtr,
|
|
59
|
+
e,
|
|
60
|
+
this.outputPtr,
|
|
61
|
+
h
|
|
62
|
+
);
|
|
63
|
+
if (s < 0)
|
|
64
|
+
throw new Error(`opus_encode_float failed with error code ${s}`);
|
|
65
|
+
return new Uint8Array(this.module.HEAPU8.buffer, this.outputPtr, s);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Encode and copy the result (when caller needs ownership).
|
|
69
|
+
* Use this when you need the encoded audio to persist, e.g., when sending to another thread.
|
|
70
|
+
*/
|
|
71
|
+
encodeAndCopy(t) {
|
|
72
|
+
return this.encode(t).slice();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reset the encoder state.
|
|
76
|
+
* Call this when there's a discontinuity in the audio stream.
|
|
77
|
+
*/
|
|
78
|
+
reset() {
|
|
79
|
+
this.module && this.encoder && this.module._opus_encoder_ctl(this.encoder, d);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Set the encoder bitrate.
|
|
83
|
+
* @param bitrate - Target bitrate in bits per second
|
|
84
|
+
*/
|
|
85
|
+
setBitrate(t) {
|
|
86
|
+
this.setEncoderCtl(o, t);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Set the encoder complexity (0-10, higher = better quality but more CPU).
|
|
90
|
+
* @param complexity - Complexity value (0-10)
|
|
91
|
+
*/
|
|
92
|
+
setComplexity(t) {
|
|
93
|
+
this.setEncoderCtl(n, t);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the number of channels this encoder was created with.
|
|
97
|
+
*/
|
|
98
|
+
getChannels() {
|
|
99
|
+
return this.channels;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the sample rate this encoder was created with.
|
|
103
|
+
*/
|
|
104
|
+
getSampleRate() {
|
|
105
|
+
return this.sampleRate;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Release all resources.
|
|
109
|
+
* The encoder cannot be used after calling destroy().
|
|
110
|
+
*/
|
|
111
|
+
destroy() {
|
|
112
|
+
this.module && (this.encoder && this.module._opus_encoder_destroy(this.encoder), this.inputPtr && this.module._free(this.inputPtr), this.outputPtr && this.module._free(this.outputPtr)), this.encoder = 0, this.inputPtr = 0, this.outputPtr = 0, this.module = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export {
|
|
116
|
+
_ as OpusEncoder
|
|
117
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OpusModule } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Get the shared OpusModule instance.
|
|
4
|
+
* The module is loaded lazily on first call and cached for subsequent calls.
|
|
5
|
+
* Automatically selects SIMD or non-SIMD version based on browser support.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getOpusModule(): Promise<OpusModule>;
|
|
8
|
+
/**
|
|
9
|
+
* Check if the OpusModule has been loaded.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isModuleLoaded(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Check if SIMD is supported by the current browser.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isSimdSupported(): Promise<boolean>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
let r = null, t = null;
|
|
2
|
+
const i = new Uint8Array([
|
|
3
|
+
0,
|
|
4
|
+
97,
|
|
5
|
+
115,
|
|
6
|
+
109,
|
|
7
|
+
// magic
|
|
8
|
+
1,
|
|
9
|
+
0,
|
|
10
|
+
0,
|
|
11
|
+
0,
|
|
12
|
+
// version
|
|
13
|
+
1,
|
|
14
|
+
5,
|
|
15
|
+
1,
|
|
16
|
+
96,
|
|
17
|
+
0,
|
|
18
|
+
1,
|
|
19
|
+
123,
|
|
20
|
+
// type section: () -> v128
|
|
21
|
+
3,
|
|
22
|
+
2,
|
|
23
|
+
1,
|
|
24
|
+
0,
|
|
25
|
+
// function section
|
|
26
|
+
10,
|
|
27
|
+
10,
|
|
28
|
+
1,
|
|
29
|
+
8,
|
|
30
|
+
0,
|
|
31
|
+
// code section start
|
|
32
|
+
65,
|
|
33
|
+
0,
|
|
34
|
+
// i32.const 0
|
|
35
|
+
253,
|
|
36
|
+
15,
|
|
37
|
+
// v128.load (SIMD)
|
|
38
|
+
253,
|
|
39
|
+
98,
|
|
40
|
+
// i32x4.extract_lane 0
|
|
41
|
+
11
|
|
42
|
+
// end
|
|
43
|
+
]);
|
|
44
|
+
async function o() {
|
|
45
|
+
try {
|
|
46
|
+
return WebAssembly.validate(i);
|
|
47
|
+
} catch {
|
|
48
|
+
return !1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function s() {
|
|
52
|
+
return t || (r || (r = (async () => {
|
|
53
|
+
const a = await o();
|
|
54
|
+
let n;
|
|
55
|
+
a ? n = (await import("../wasm/libopus-simd.js")).default : n = (await import("../wasm/libopus.js")).default;
|
|
56
|
+
const u = a ? "../wasm/libopus-simd.wasm" : "../wasm/libopus.wasm";
|
|
57
|
+
return t = await n({
|
|
58
|
+
locateFile: (e) => e.endsWith(".wasm") ? new URL(u, import.meta.url).href : e
|
|
59
|
+
}), t;
|
|
60
|
+
})()), r);
|
|
61
|
+
}
|
|
62
|
+
function l() {
|
|
63
|
+
return t !== null;
|
|
64
|
+
}
|
|
65
|
+
async function d() {
|
|
66
|
+
return o();
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
s as getOpusModule,
|
|
70
|
+
l as isModuleLoaded,
|
|
71
|
+
d as isSimdSupported
|
|
72
|
+
};
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface OpusModule {
|
|
2
|
+
_opus_decoder_create(sampleRate: number, channels: number, errorPtr: number): number;
|
|
3
|
+
_opus_decode_float(decoder: number, data: number, len: number, pcm: number, frameSize: number, decodeFec: number): number;
|
|
4
|
+
_opus_decoder_destroy(decoder: number): void;
|
|
5
|
+
_opus_decoder_ctl(decoder: number, request: number, ...args: number[]): number;
|
|
6
|
+
_opus_encoder_create(sampleRate: number, channels: number, application: number, errorPtr: number): number;
|
|
7
|
+
_opus_encode_float(encoder: number, pcm: number, frameSize: number, data: number, maxDataBytes: number): number;
|
|
8
|
+
_opus_encoder_destroy(encoder: number): void;
|
|
9
|
+
_opus_encoder_ctl(encoder: number, request: number, ...args: number[]): number;
|
|
10
|
+
_opus_strerror(error: number): number;
|
|
11
|
+
_malloc(size: number): number;
|
|
12
|
+
_free(ptr: number): void;
|
|
13
|
+
HEAPU8: Uint8Array;
|
|
14
|
+
HEAPF32: Float32Array;
|
|
15
|
+
}
|
|
16
|
+
export interface DecodedAudio {
|
|
17
|
+
channelData: Float32Array[];
|
|
18
|
+
samplesDecoded: number;
|
|
19
|
+
sampleRate: number;
|
|
20
|
+
}
|
|
21
|
+
export interface OpusDecoderOptions {
|
|
22
|
+
channels: number;
|
|
23
|
+
sampleRate: number;
|
|
24
|
+
}
|
|
25
|
+
export interface OpusEncoderOptions {
|
|
26
|
+
channels: number;
|
|
27
|
+
sampleRate: number;
|
|
28
|
+
bitrate?: number;
|
|
29
|
+
frameSize?: number;
|
|
30
|
+
application?: number;
|
|
31
|
+
complexity?: number;
|
|
32
|
+
}
|
|
33
|
+
export type OpusModuleFactory = (options?: {
|
|
34
|
+
locateFile?: (path: string) => string;
|
|
35
|
+
}) => Promise<OpusModule>;
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ikonai/sdk-libopus",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./index.js",
|
|
11
|
+
"types": "./index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./wasm/*": {
|
|
14
|
+
"import": "./wasm/*"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
async function Module(moduleArg={}){var moduleRtn;var b=moduleArg,m=!!globalThis.WorkerGlobalScope,aa=import.meta.url,n="",p,r;if(globalThis.window||m){try{n=(new URL(".",aa)).href}catch{}m&&(r=a=>{var c=new XMLHttpRequest;c.open("GET",a,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)});p=async a=>{a=await fetch(a,{credentials:"same-origin"});if(a.ok)return a.arrayBuffer();throw Error(a.status+" : "+a.url);}}var t=console.log.bind(console),u=console.error.bind(console),v,x=!1,y,z,A,B,C,D=!1;
|
|
2
|
+
function I(){var a=J.buffer;new Int8Array(a);new Int16Array(a);b.HEAPU8=B=new Uint8Array(a);new Uint16Array(a);new Int32Array(a);C=new Uint32Array(a);b.HEAPF32=new Float32Array(a);new Float64Array(a);new BigInt64Array(a);new BigUint64Array(a)}function K(a){b.onAbort?.(a);a="Aborted("+a+")";u(a);x=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");A?.(a);throw a;}var L;
|
|
3
|
+
async function ba(a){if(!v)try{var c=await p(a);return new Uint8Array(c)}catch{}if(a==L&&v)a=new Uint8Array(v);else if(r)a=r(a);else throw"both async and sync fetching of the wasm failed";return a}async function ca(a,c){try{var d=await ba(a);return await WebAssembly.instantiate(d,c)}catch(f){u(`failed to asynchronously prepare wasm: ${f}`),K(f)}}
|
|
4
|
+
async function da(a){var c=L;if(!v)try{var d=fetch(c,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(f){u(`wasm streaming compile failed: ${f}`),u("falling back to ArrayBuffer instantiation")}return ca(c,a)}class M{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
|
|
5
|
+
var N=a=>{for(;0<a.length;)a.shift()(b)},O=[],P=[],ea=()=>{var a=b.preRun.shift();P.push(a)},Q=!0,R=0,S={},T=a=>{if(!(a instanceof M||"unwind"==a))throw a;},U=a=>{y=a;Q||0<R||(b.onExit?.(a),x=!0);throw new M(a);},fa=a=>{if(!x)try{if(a(),!(Q||0<R))try{y=a=y,U(a)}catch(c){T(c)}}catch(c){T(c)}},ha=[null,[],[]],V=globalThis.TextDecoder&&new TextDecoder;b.noExitRuntime&&(Q=b.noExitRuntime);b.print&&(t=b.print);b.printErr&&(u=b.printErr);b.wasmBinary&&(v=b.wasmBinary);
|
|
6
|
+
if(b.preInit)for("function"==typeof b.preInit&&(b.preInit=[b.preInit]);0<b.preInit.length;)b.preInit.shift()();
|
|
7
|
+
var W,J,ja={e:()=>K(""),b:()=>{Q=!1;R=0},c:(a,c)=>{S[a]&&(clearTimeout(S[a].id),delete S[a]);if(!c)return 0;var d=setTimeout(()=>{delete S[a];fa(()=>W(a,performance.now()))},c);S[a]={id:d,u:c};return 0},d:a=>{var c=B.length;a>>>=0;if(67108864<a)return!1;for(var d=1;4>=d;d*=2){var f=c*(1+.2/d);f=Math.min(f,a+100663296);a:{f=(Math.min(67108864,65536*Math.ceil(Math.max(a,f)/65536))-J.buffer.byteLength+65535)/65536|0;try{J.grow(f);I();var l=1;break a}catch(E){}l=void 0}if(l)return!0}return!1},f:(a,c,
|
|
8
|
+
d,f)=>{for(var l=0,E=0;E<d;E++){var ia=C[c>>2],Y=C[c+4>>2];c+=8;for(var F=0;F<Y;F++){var w=a,g=B[ia+F],G=ha[w];if(0===g||10===g){w=1===w?t:u;g=G;var k=0;var q=g;for(var h=k,e=h+void 0;q[h]&&!(h>=e);)++h;q=h;if(16<q-k&&g.buffer&&V)g=V.decode(g.subarray(k,q));else{for(h="";k<q;)if(e=g[k++],e&128){var H=g[k++]&63;if(192==(e&224))h+=String.fromCharCode((e&31)<<6|H);else{var Z=g[k++]&63;e=224==(e&240)?(e&15)<<12|H<<6|Z:(e&7)<<18|H<<12|Z<<6|g[k++]&63;65536>e?h+=String.fromCharCode(e):(e-=65536,h+=String.fromCharCode(55296|
|
|
9
|
+
e>>10,56320|e&1023))}}else h+=String.fromCharCode(e);g=h}w(g);G.length=0}else G.push(g)}l+=Y}C[f>>2]=l;return 0},a:U},X;
|
|
10
|
+
X=await (async function(){function a(d){d=X=d.exports;b._opus_strerror=d.i;b._opus_decoder_create=d.j;b._opus_decode_float=d.k;b._opus_decoder_ctl=d.l;b._opus_decoder_destroy=d.m;b._opus_encoder_create=d.n;b._opus_encode_float=d.o;b._opus_encoder_ctl=d.p;b._opus_encoder_destroy=d.q;W=d.r;b._malloc=d.s;b._free=d.t;J=d.g;I();return X}var c={a:ja};if(b.instantiateWasm)return new Promise(d=>{b.instantiateWasm(c,(f,l)=>{d(a(f,l))})});L??=b.locateFile?b.locateFile?b.locateFile("libopus-simd.wasm",
|
|
11
|
+
n):n+"libopus-simd.wasm":(new URL("libopus-simd.wasm",import.meta.url)).href;return a((await da(c)).instance)}());
|
|
12
|
+
(function(){function a(){b.calledRun=!0;if(!x){D=!0;X.h();z?.(b);b.onRuntimeInitialized?.();if(b.postRun)for("function"==typeof b.postRun&&(b.postRun=[b.postRun]);b.postRun.length;){var c=b.postRun.shift();O.push(c)}N(O)}}if(b.preRun)for("function"==typeof b.preRun&&(b.preRun=[b.preRun]);b.preRun.length;)ea();N(P);b.setStatus?(b.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>b.setStatus(""),1);a()},1)):a()})();D?moduleRtn=b:moduleRtn=new Promise((a,c)=>{z=a;A=c});
|
|
13
|
+
;return moduleRtn}export default Module;
|
|
Binary file
|
package/wasm/libopus.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
async function Module(moduleArg={}){var moduleRtn;var b=moduleArg,m=!!globalThis.WorkerGlobalScope,aa=import.meta.url,n="",p,r;if(globalThis.window||m){try{n=(new URL(".",aa)).href}catch{}m&&(r=a=>{var c=new XMLHttpRequest;c.open("GET",a,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)});p=async a=>{a=await fetch(a,{credentials:"same-origin"});if(a.ok)return a.arrayBuffer();throw Error(a.status+" : "+a.url);}}var t=console.log.bind(console),u=console.error.bind(console),v,x=!1,y,z,A,B,C,D=!1;
|
|
2
|
+
function I(){var a=J.buffer;new Int8Array(a);new Int16Array(a);b.HEAPU8=B=new Uint8Array(a);new Uint16Array(a);new Int32Array(a);C=new Uint32Array(a);b.HEAPF32=new Float32Array(a);new Float64Array(a);new BigInt64Array(a);new BigUint64Array(a)}function K(a){b.onAbort?.(a);a="Aborted("+a+")";u(a);x=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");A?.(a);throw a;}var L;
|
|
3
|
+
async function ba(a){if(!v)try{var c=await p(a);return new Uint8Array(c)}catch{}if(a==L&&v)a=new Uint8Array(v);else if(r)a=r(a);else throw"both async and sync fetching of the wasm failed";return a}async function ca(a,c){try{var d=await ba(a);return await WebAssembly.instantiate(d,c)}catch(f){u(`failed to asynchronously prepare wasm: ${f}`),K(f)}}
|
|
4
|
+
async function da(a){var c=L;if(!v)try{var d=fetch(c,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(f){u(`wasm streaming compile failed: ${f}`),u("falling back to ArrayBuffer instantiation")}return ca(c,a)}class M{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
|
|
5
|
+
var N=a=>{for(;0<a.length;)a.shift()(b)},O=[],P=[],ea=()=>{var a=b.preRun.shift();P.push(a)},Q=!0,R=0,S={},T=a=>{if(!(a instanceof M||"unwind"==a))throw a;},U=a=>{y=a;Q||0<R||(b.onExit?.(a),x=!0);throw new M(a);},fa=a=>{if(!x)try{if(a(),!(Q||0<R))try{y=a=y,U(a)}catch(c){T(c)}}catch(c){T(c)}},ha=[null,[],[]],V=globalThis.TextDecoder&&new TextDecoder;b.noExitRuntime&&(Q=b.noExitRuntime);b.print&&(t=b.print);b.printErr&&(u=b.printErr);b.wasmBinary&&(v=b.wasmBinary);
|
|
6
|
+
if(b.preInit)for("function"==typeof b.preInit&&(b.preInit=[b.preInit]);0<b.preInit.length;)b.preInit.shift()();
|
|
7
|
+
var W,J,ja={e:()=>K(""),b:()=>{Q=!1;R=0},c:(a,c)=>{S[a]&&(clearTimeout(S[a].id),delete S[a]);if(!c)return 0;var d=setTimeout(()=>{delete S[a];fa(()=>W(a,performance.now()))},c);S[a]={id:d,u:c};return 0},d:a=>{var c=B.length;a>>>=0;if(67108864<a)return!1;for(var d=1;4>=d;d*=2){var f=c*(1+.2/d);f=Math.min(f,a+100663296);a:{f=(Math.min(67108864,65536*Math.ceil(Math.max(a,f)/65536))-J.buffer.byteLength+65535)/65536|0;try{J.grow(f);I();var l=1;break a}catch(E){}l=void 0}if(l)return!0}return!1},f:(a,c,
|
|
8
|
+
d,f)=>{for(var l=0,E=0;E<d;E++){var ia=C[c>>2],Y=C[c+4>>2];c+=8;for(var F=0;F<Y;F++){var w=a,g=B[ia+F],G=ha[w];if(0===g||10===g){w=1===w?t:u;g=G;var k=0;var q=g;for(var h=k,e=h+void 0;q[h]&&!(h>=e);)++h;q=h;if(16<q-k&&g.buffer&&V)g=V.decode(g.subarray(k,q));else{for(h="";k<q;)if(e=g[k++],e&128){var H=g[k++]&63;if(192==(e&224))h+=String.fromCharCode((e&31)<<6|H);else{var Z=g[k++]&63;e=224==(e&240)?(e&15)<<12|H<<6|Z:(e&7)<<18|H<<12|Z<<6|g[k++]&63;65536>e?h+=String.fromCharCode(e):(e-=65536,h+=String.fromCharCode(55296|
|
|
9
|
+
e>>10,56320|e&1023))}}else h+=String.fromCharCode(e);g=h}w(g);G.length=0}else G.push(g)}l+=Y}C[f>>2]=l;return 0},a:U},X;
|
|
10
|
+
X=await (async function(){function a(d){d=X=d.exports;b._opus_strerror=d.i;b._opus_decoder_create=d.j;b._opus_decode_float=d.k;b._opus_decoder_ctl=d.l;b._opus_decoder_destroy=d.m;b._opus_encoder_create=d.n;b._opus_encode_float=d.o;b._opus_encoder_ctl=d.p;b._opus_encoder_destroy=d.q;W=d.r;b._malloc=d.s;b._free=d.t;J=d.g;I();return X}var c={a:ja};if(b.instantiateWasm)return new Promise(d=>{b.instantiateWasm(c,(f,l)=>{d(a(f,l))})});L??=b.locateFile?b.locateFile?b.locateFile("libopus.wasm",
|
|
11
|
+
n):n+"libopus.wasm":(new URL("libopus.wasm",import.meta.url)).href;return a((await da(c)).instance)}());
|
|
12
|
+
(function(){function a(){b.calledRun=!0;if(!x){D=!0;X.h();z?.(b);b.onRuntimeInitialized?.();if(b.postRun)for("function"==typeof b.postRun&&(b.postRun=[b.postRun]);b.postRun.length;){var c=b.postRun.shift();O.push(c)}N(O)}}if(b.preRun)for("function"==typeof b.preRun&&(b.preRun=[b.preRun]);b.preRun.length;)ea();N(P);b.setStatus?(b.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>b.setStatus(""),1);a()},1)):a()})();D?moduleRtn=b:moduleRtn=new Promise((a,c)=>{z=a;A=c});
|
|
13
|
+
;return moduleRtn}export default Module;
|
|
Binary file
|