UNPKG

@evan/wasm

Version:
453 lines (452 loc) 12.2 kB
var __defProp = Object.defineProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet = (obj, member, value, setter) => { __accessCheck(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; __export(exports, { Decoder: () => Decoder, Encoder: () => Encoder, ctl: () => ctl }); var _ptr, _ptr2; let u8; let wasm; let pptr; let bptr; let pptrs; let bptrs; { const module2 = new WebAssembly.Module(require('fs').readFileSync(require('path').join(__dirname, '../../src/opus/opus.wasm'))); const instance = new WebAssembly.Instance(module2, { wasi_snapshot_preview1: { fd_seek() { }, fd_write() { }, fd_close() { }, proc_exit() { } }, env: { emscripten_notify_memory_growth() { u8 = new Uint8Array(wasm.memory.buffer); pptrs = u8.subarray(pptr, pptr + 2 ** 13); bptrs = u8.subarray(bptr, bptr + 2 ** 15); } } }); wasm = instance.exports; pptr = wasm.malloc(2 ** 13); bptr = wasm.malloc(2 ** 15); u8 = new Uint8Array(wasm.memory.buffer); pptrs = u8.subarray(pptr, pptr + 2 ** 13); bptrs = u8.subarray(bptr, bptr + 2 ** 15); } function clamp(min, int, max) { const t = int < min ? min : int; return t > max ? max : t; } function err(code) { if (0 > code) throw new Error(`opus: ${load_static_string(u8, wasm.opus_strerror(code))}`); else return code; } function cgc(f) { return !("FinalizationRegistry" in globalThis) ? { delete(_) { }, add(_, __) { } } : { r: new FinalizationRegistry(f), delete(k) { this.r.unregister(k); }, add(k, v) { this.r.register(k, v, k); } }; } function load_static_string(u82, ptr) { let s = ""; const l = u82.length | 0; for (let o = ptr | 0; o < l; o++) { const x = u82[o]; if (x === 0) break; s += String.fromCharCode(x); } return s; } const ctl = { auto: -1e3, bitrate_max: -1, reset_state: 4028, signal: { auto: -1e3, voice: 3001, music: 3002 }, application: { voip: 2048, audio: 2049, restricted_lowdelay: 2051 }, bandwidth: { auto: -1e3, wideband: 1103, fullband: 1105, narrowband: 1101, mediumband: 1102, superwideband: 1104 }, framesize: { 5: 5002, 10: 5003, 20: 5004, 40: 5005, 60: 5006, 80: 5007, 100: 5008, 120: 5009, [2.5]: 5001, arg: 5e3 }, set: { vbr: 4006, dtx: 4016, gain: 4034, signal: 4024, bitrate: 4002, bandwidth: 4008, lsb_depth: 4036, complexity: 4010, inband_fec: 4012, application: 4e3, max_bandwidth: 4004, vbr_constraint: 4020, force_channels: 4022, packet_loss_perc: 4014, prediction_disabled: 4042, expert_frame_duration: 4040, phase_inversion_disabled: 4046 }, get: { vbr: 4007, dtx: 4017, gain: 4045, pitch: 4033, signal: 4025, in_dtx: 4049, bitrate: 4003, lsb_depth: 4037, bandwidth: 4009, lookahead: 4027, complexity: 4011, inband_fec: 4013, application: 4001, sample_rate: 4029, final_range: 4031, max_bandwidth: 4005, vbr_constraint: 4021, force_channels: 4023, packet_loss_perc: 4015, prediction_disabled: 4043, last_packet_duration: 4039, expert_frame_duration: 4041, phase_inversion_disabled: 4047 } }; const convert = { fc: { 1: 1, 2: 2, "auto": [ctl.auto], [ctl.auto]: "auto" }, s: { [ctl.auto]: "auto", [ctl.signal.voice]: "voice", [ctl.signal.music]: "music" }, a: { [ctl.application.voip]: "voip", [ctl.application.audio]: "audio", [ctl.application.restricted_lowdelay]: "restricted_lowdelay" }, b: { [ctl.auto]: "auto", [ctl.bandwidth.wideband]: "wideband", [ctl.bandwidth.fullband]: "fullband", [ctl.bandwidth.narrowband]: "narrowband", [ctl.bandwidth.mediumband]: "mediumband", [ctl.bandwidth.superwideband]: "superwideband" }, efd: { [ctl.framesize[5]]: 5, [ctl.framesize[10]]: 10, [ctl.framesize[20]]: 20, [ctl.framesize[40]]: 40, [ctl.framesize[60]]: 60, [ctl.framesize[80]]: 80, [ctl.framesize[2.5]]: 2.5, [ctl.framesize[100]]: 100, [ctl.framesize[120]]: 120, [ctl.framesize.arg]: "arg" } }; const pptrl = 2 ** 13; const gc = cgc((ptr) => wasm.free(ptr)); class RawDecoder { constructor({ channels, sample_rate }) { __privateAdd(this, _ptr, 0); gc.add(this, __privateSet(this, _ptr, wasm.malloc(wasm.opus_decoder_get_size(this.channels = channels || 2)))); try { err(wasm.opus_decoder_init(__privateGet(this, _ptr), sample_rate || 48e3, this.channels)); } catch (e) { throw this.drop(), e; } } drop() { if (__privateGet(this, _ptr)) gc.delete(this), wasm.free(__privateGet(this, _ptr)), __privateSet(this, _ptr, 0); } ctl(cmd, arg) { if (arg == null) return wasm.opus_decoder_ctl_get(__privateGet(this, _ptr), cmd); else return err(wasm.opus_decoder_ctl_set(__privateGet(this, _ptr), cmd, arg)); } decode(buffer) { pptrs.set(buffer = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)); return bptrs.slice(0, 2 * this.channels * err(wasm.opus_decode(__privateGet(this, _ptr), pptr, buffer.length, bptr, 5760, 0))); } } _ptr = new WeakMap(); class RawEncoder { constructor({ channels, application, sample_rate }) { __privateAdd(this, _ptr2, 0); this.channels = channels || 2; gc.add(this, __privateSet(this, _ptr2, wasm.malloc(wasm.opus_encoder_get_size(this.channels)))); application = { voip: 2048, audio: 2049, restricted_lowdelay: 2051 }[application || "audio"]; try { err(wasm.opus_encoder_init(__privateGet(this, _ptr2), sample_rate || 48e3, this.channels, application)); } catch (e) { throw this.drop(), e; } } drop() { if (__privateGet(this, _ptr2)) gc.delete(this), wasm.free(__privateGet(this, _ptr2)), __privateSet(this, _ptr2, 0); } ctl(cmd, arg) { if (arg == null) return wasm.opus_encoder_ctl_get(__privateGet(this, _ptr2), cmd); else return err(wasm.opus_encoder_ctl_set(__privateGet(this, _ptr2), cmd, arg)); } encode(buffer) { bptrs.set(buffer = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)); return pptrs.slice(0, err(wasm.opus_encode(__privateGet(this, _ptr2), bptr, buffer.length / 2 / this.channels, pptr, pptrl))); } } _ptr2 = new WeakMap(); class Decoder extends RawDecoder { constructor({ channels = 2, sample_rate = 48e3 } = {}) { super({ channels, sample_rate }); this.channels = channels; } get gain() { return this.ctl(ctl.get.gain); } set gain(int) { this.ctl(ctl.set.gain, clamp(-32768, int, 32767)); } get pitch() { const x = this.ctl(ctl.get.pitch); return x === 0 ? null : x; } get last_packet_duration() { return this.ctl(ctl.get.last_packet_duration); } reset() { this.ctl(ctl.reset_state); } get in_dtx() { return !!this.ctl(ctl.get.in_dtx); } get sample_rate() { return this.ctl(ctl.get.sample_rate); } get bandwidth() { return convert.b[this.ctl(ctl.get.bandwidth)]; } get phase_inversion_disabled() { return !!this.ctl(ctl.get.phase_inversion_disabled); } set phase_inversion_disabled(bool) { this.ctl(ctl.set.phase_inversion_disabled, bool ? 1 : 0); } } class Encoder extends RawEncoder { constructor({ channels = 2, application, sample_rate = 48e3 } = {}) { super({ channels, sample_rate, application: application || "audio" }); this.channels = channels; } async *encode_pcm_stream(size, iter) { let needle = 0; const self = this; const r = 2 * size * this.channels; const t8 = new Uint8Array(r); function* consume(buf) { let offset = 0; while (offset < buf.length) { const s = buf.subarray(offset, offset += r); if (r === s.length) yield self.encode(s); else { t8.set(s, needle); needle += s.length; break; } ; } } ; for await (const buffer of iter) { const b8 = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); if (needle === 0) for (const x of consume(b8)) yield x; else { const rr = r - needle; if (rr > b8.length) t8.set(b8, needle), needle += b8.length; else { t8.set(b8.subarray(0, rr), needle); yield (needle = 0, self.encode(t8)); for (const x of consume(b8.subarray(rr))) yield x; } } } } reset() { this.ctl(ctl.reset_state); } get in_dtx() { return !!this.ctl(ctl.get.in_dtx); } get sample_rate() { return this.ctl(ctl.get.sample_rate); } get bandwidth() { return convert.b[this.ctl(ctl.get.bandwidth)]; } get phase_inversion_disabled() { return !!this.ctl(ctl.get.phase_inversion_disabled); } set phase_inversion_disabled(bool) { this.ctl(ctl.set.phase_inversion_disabled, bool ? 1 : 0); } get vbr() { return !!this.ctl(ctl.get.vbr); } get dtx() { return !!this.ctl(ctl.get.dtx); } get bitrate() { return this.ctl(ctl.get.bitrate); } get lookahead() { return this.ctl(ctl.get.lookahead); } get lsb_depth() { return this.ctl(ctl.get.lsb_depth); } get complexity() { return this.ctl(ctl.get.complexity); } get inband_fec() { return !!this.ctl(ctl.get.inband_fec); } get signal() { return convert.s[this.ctl(ctl.get.signal)]; } get packet_loss() { return this.ctl(ctl.get.packet_loss_perc); } get vbr_constraint() { return !!this.ctl(ctl.get.vbr_constraint); } get application() { return convert.a[this.ctl(ctl.get.application)]; } get max_bandwidth() { return convert.b[this.ctl(ctl.get.max_bandwidth)]; } get force_channels() { return convert.fc[this.ctl(ctl.get.force_channels)]; } get prediction_disabled() { return !!this.ctl(ctl.get.prediction_disabled); } get expert_frame_duration() { return covert.efd[this.ctl(ctl.get.expert_frame_duration)]; } set vbr(bool) { this.ctl(ctl.set.vbr, bool ? 1 : 0); } set dtx(bool) { this.ctl(ctl.set.dtx, bool ? 1 : 0); } set signal(arg) { this.ctl(ctl.set.signal, ctl.signal[arg]); } set inband_fec(bool) { this.ctl(ctl.set.inband_fec, bool ? 1 : 0); } set lsb_depth(int) { this.ctl(ctl.set.lsb_depth, clamp(8, int, 24)); } set bandwidth(arg) { this.ctl(ctl.set.bandwidth, ctl.bandwidth[arg]); } set complexity(int) { this.ctl(ctl.set.complexity, clamp(0, int, 10)); } set vbr_constraint(bool) { this.ctl(ctl.set.vbr_constraint, bool ? 1 : 0); } set application(arg) { this.ctl(ctl.set.application, ctl.application[arg]); } set force_channels(arg) { this.ctl(ctl.set.force_channels, convert.fc[arg]); } set packet_loss(int) { this.ctl(ctl.set.packet_loss_perc, clamp(0, int, 100)); } set prediction_disabled(bool) { this.ctl(ctl.set.prediction_disabled, bool ? 1 : 0); } set expert_frame_duration(arg) { this.ctl(ctl.set.expert_frame_duration, ctl.framesize[arg]); } set max_bandwidth(arg) { this.ctl(ctl.set.max_bandwidth, ctl.bandwidth[arg === "auto" ? "fullband" : arg]); } set bitrate(arg) { this.ctl(ctl.set.bitrate, arg === "max" ? ctl.bitrate_max : arg === "auto" ? ctl.auto : clamp(500, arg | 0, 512e3)); } }