From 05c012b35763997c9a331c26d5ea087ef410951b Mon Sep 17 00:00:00 2001
From: Arun Purushan
Date: Fri, 14 Aug 2020 19:12:26 -0700
Subject: [PATCH 1/2] Enable audio denoise using rnnoise-wasm
---
scripts/Gruntfile.js | 4 +-
src/samples/p2p/js/peercall.js | 61 +-
src/samples/p2p/peercall.html | 6 +
src/sdk/base/denoise.js | 84 +
src/sdk/base/mediastream-factory.js | 39 +
src/sdk/base/rnn_denoise.js | 2298 +++++++++++++++++++++++++++
src/sdk/base/rnn_denoise.wasm | Bin 0 -> 235255 bytes
7 files changed, 2474 insertions(+), 18 deletions(-)
create mode 100644 src/sdk/base/denoise.js
create mode 100644 src/sdk/base/rnn_denoise.js
create mode 100644 src/sdk/base/rnn_denoise.wasm
diff --git a/scripts/Gruntfile.js b/scripts/Gruntfile.js
index 3cccdbd7..10fa2bb0 100644
--- a/scripts/Gruntfile.js
+++ b/scripts/Gruntfile.js
@@ -5,7 +5,7 @@ module.exports = function(grunt) {
const sdkOutput = 'dist/sdk/owt.js';
var srcFiles = [
- 'src/sdk/base/**',
+ 'src/sdk/base/*.js',
'src/sdk/p2p/**',
'src/sdk/conference/**'
];
@@ -175,6 +175,8 @@ window.L = L;\n\
copy:{
dist:{
files:[
+ {expand: true,cwd:'src/sdk/base/',src:['*.wasm'],dest:'dist/samples/p2p/js',flatten:false},
+ {expand: true,cwd:'src/sdk/base/',src:['*.wasm'],dest:'dist/sdk/',flatten:false},
{expand: true,cwd:'src/samples/p2p/',src:['**'],dest:'dist/samples/p2p/',flatten:false},
{expand: true,cwd:'src/samples/conference/',src:['**'],dest:'dist/samples/conference/',flatten:false},
{expand: true,cwd:'src/samples/conference/',src:['initcert.js'],dest:'dist/samples/conference/',flatten:false,mode:true},
diff --git a/src/samples/p2p/js/peercall.js b/src/samples/p2p/js/peercall.js
index e2a68cd9..fdb40399 100644
--- a/src/samples/p2p/js/peercall.js
+++ b/src/samples/p2p/js/peercall.js
@@ -48,6 +48,10 @@ const getTargetId = function() {
return $('#remote-uid').val();
};
+function denoiseCheckboxChanged() {
+ document.getElementById("denoise-message").innerHTML=": Click 'Stop Camera' and 'share camera' if video sharing is already in progress."
+}
+
$(document).ready(function() {
$('#set-remote-uid').click(function() {
p2p.allowedRemoteIds = [getTargetId()];
@@ -94,6 +98,8 @@ $(document).ready(function() {
localStream = undefined;
});
+ let denoiseCheckbox = document.getElementById('apply-denoise-checkbox');
+
$('#target-video-publish').click(function() {
$('#target-video-unpublish').prop('disabled', false);
$('#target-video-publish').prop('disabled', true);
@@ -109,23 +115,44 @@ $(document).ready(function() {
const videoConstraintsForCamera = new Owt.Base
.VideoTrackConstraints(Owt.Base.VideoSourceInfo.CAMERA);
let mediaStream;
- Owt.Base.MediaStreamFactory.createMediaStream(new Owt.Base
- .StreamConstraints(audioConstraintsForMic,
- videoConstraintsForCamera)).then((stream) => {
- mediaStream = stream;
- localStream = new Owt.Base.LocalStream(mediaStream, new Owt
- .Base.StreamSourceInfo('mic', 'camera'));
- $('#local').children('video').get(0).srcObject = localStream
- .mediaStream;
- p2p.publish(getTargetId(), localStream).then(
- (publication) => {
- publicationForCamera = publication;
- }, (error) => {
- console.log('Failed to share video.');
- });
- }, (err) => {
- console.error('Failed to create MediaStream, ' + err);
- });
+ if(denoiseCheckbox.checked){
+ Owt.Base.MediaStreamFactory.createMediaStreamDenoised(new Owt.Base
+ .StreamConstraints(audioConstraintsForMic,
+ videoConstraintsForCamera)).then((stream) => {
+ mediaStream = stream;
+ localStream = new Owt.Base.LocalStream(mediaStream, new Owt
+ .Base.StreamSourceInfo('mic', 'camera'));
+ $('#local').children('video').get(0).srcObject = localStream
+ .mediaStream;
+ p2p.publish(getTargetId(), localStream).then(
+ (publication) => {
+ publicationForCamera = publication;
+ }, (error) => {
+ console.log('Failed to share video.');
+ });
+ }, (err) => {
+ console.error('Failed to create MediaStream, ' + err);
+ });
+ }
+ else {
+ Owt.Base.MediaStreamFactory.createMediaStream(new Owt.Base
+ .StreamConstraints(audioConstraintsForMic,
+ videoConstraintsForCamera)).then((stream) => {
+ mediaStream = stream;
+ localStream = new Owt.Base.LocalStream(mediaStream, new Owt
+ .Base.StreamSourceInfo('mic', 'camera'));
+ $('#local').children('video').get(0).srcObject = localStream
+ .mediaStream;
+ p2p.publish(getTargetId(), localStream).then(
+ (publication) => {
+ publicationForCamera = publication;
+ }, (error) => {
+ console.log('Failed to share video.');
+ });
+ }, (err) => {
+ console.error('Failed to create MediaStream, ' + err);
+ });
+ }
}
});
diff --git a/src/samples/p2p/peercall.html b/src/samples/p2p/peercall.html
index 9c867913..d9cfc900 100644
--- a/src/samples/p2p/peercall.html
+++ b/src/samples/p2p/peercall.html
@@ -85,6 +85,12 @@ P2P Sample
+
+
+
+
+
+
diff --git a/src/sdk/base/denoise.js b/src/sdk/base/denoise.js
new file mode 100644
index 00000000..abe546a4
--- /dev/null
+++ b/src/sdk/base/denoise.js
@@ -0,0 +1,84 @@
+// Copyright (C) <2020> Intel Corporation
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/* global window, AudioContext, Float32Array */
+
+'use strict';
+// ///////////////////////////////////////////////////////////////////////////////
+// Handles the WebAssembly kernel for denoising raw audio files in F32Arrayformat
+// ///////////////////////////////////////////////////////////////////////////////
+
+import {Module, wasmMemory} from './rnn_denoise.js';
+
+// cwrap wasm API's used here make wasm calls from JS simpler.
+const wasmRnndenoiseRawmem = Module.cwrap('rnnDenoise_rawmem',
+ 'number', ['number', 'number', 'number', 'number']);
+
+const sampleRate = 44100; // Audio Sample rate can be set and controlled here.
+const numChannels = 1; // Current channel support limited to 1. Stereo is ToDo.
+
+/**
+ * @function wasmDenoiseStream
+ * @desc Apply denoising into raw audio data in F32Array format using
+ * a WebAssembly port of RNNoise denoising algoritm.
+ * @return {Float32Array} fProcessdArr with denoised audio data
+ * @param {Float32Array} f32buffer
+ */
+export function wasmDenoiseStream(f32buffer) {
+ // Create and Initialize Wasm memory with input audio data.
+ const wasmMemPtr = Module._malloc(f32buffer.length * 4 );
+ const wasmMemArr = new Float32Array(wasmMemory.buffer,
+ wasmMemPtr, f32buffer.length);
+ wasmMemArr.set(f32buffer);
+
+ // Call Wasm denoising kernel
+ const wasmRetPtr = wasmRnndenoiseRawmem(wasmMemPtr,
+ sampleRate, numChannels, f32buffer.length);
+
+ // Create JS Array from Wasm memory with results
+ const fProcessedArr = new Float32Array(wasmMemory.buffer,
+ wasmRetPtr, f32buffer.length);
+
+ return fProcessedArr;
+}
+
+// ////////////////////////////////////////////////////////////////////
+// Creates a WebAudio Based filter for applying audio denoising.
+// ///////////////////////////////////////////////////////////////////
+
+// WebAuddio context
+window.AudioContext = window.AudioContext || window.webkitAudioContext;
+export const audioContext = new AudioContext(); // new AudioContext({sampleRate: 48000});
+
+
+// Audio buffer size:
+// Accepts powers of 2 between 0 and 16384.
+// Too low causes audio glitches due to buffer underruns
+// Too high could increase latency.
+// Set to 0 and WebAudio API will autopick a value.
+const bufferSize = 4096;
+
+export const audioDenoise = (function() {
+ const numberOfInputChannels = 1;
+ const numberOfOutputChannels = 1;
+ let recorder;
+
+ if (audioContext.createScriptProcessor) {
+ recorder = audioContext.createScriptProcessor(bufferSize,
+ numberOfInputChannels, numberOfOutputChannels);
+ } else {
+ recorder = audioContext.createJavaScriptNode(bufferSize,
+ numberOfInputChannels, numberOfOutputChannels);
+ }
+
+ recorder.onaudioprocess = function(e) {
+ const input = e.inputBuffer.getChannelData(0);
+
+ const wasmOutput = wasmDenoiseStream(input);
+
+ e.outputBuffer.copyToChannel(wasmOutput, 0, 0);
+ };
+ return recorder;
+})();
+
diff --git a/src/sdk/base/mediastream-factory.js b/src/sdk/base/mediastream-factory.js
index 6b072731..0ad0401b 100644
--- a/src/sdk/base/mediastream-factory.js
+++ b/src/sdk/base/mediastream-factory.js
@@ -7,6 +7,7 @@
'use strict';
import * as utils from './utils.js';
import * as MediaFormatModule from './mediaformat.js';
+import * as denoise from './denoise.js';
/**
* @class AudioTrackConstraints
@@ -226,4 +227,42 @@ export class MediaStreamFactory {
return navigator.mediaDevices.getUserMedia(mediaConstraints);
}
}
+ /**
+ * @function createMediaStreamDenoised
+ * @static
+ * @desc Create a MediaStream with given constraints. Applies Rnnoise based
+ * noise cancellation on all audio streams. If you want to create a
+ * MediaStream for screen cast, please make sure both audio and video's source
+ * are "screen-cast".
+ * @memberof Owt.Base.MediaStreamFactory
+ * @return {Promise} Return a promise that is resolved
+ * when stream is successfully created, or rejected if one of the following
+ * error happened:
+ * - One or more parameters cannot be satisfied.
+ * - Specified device is busy.
+ * - Cannot obtain necessary permission or operation is canceled by user.
+ * - Video source is screen cast, while audio source is not.
+ * - Audio source is screen cast, while video source is disabled.
+ * @param {Owt.Base.StreamConstraints} constraints
+ */
+ static createMediaStreamDenoised(constraints) {
+ return this.createMediaStream(constraints).then(
+ (stream) => {
+ const audioTracks = stream.getAudioTracks();
+ const videoTracks = stream.getVideoTracks();
+ const peer = denoise.audioContext.createMediaStreamDestination();
+
+ audioTracks.forEach(function(track) {
+ const microphone =
+ denoise.audioContext.createMediaStreamSource(stream);
+ microphone.connect(denoise.audioDenoise);
+ denoise.audioDenoise.connect(peer);
+ });
+ videoTracks.forEach(function(track) {
+ peer.stream.addTrack(track);
+ });
+ return peer.stream;
+ }
+ );
+ }
}
diff --git a/src/sdk/base/rnn_denoise.js b/src/sdk/base/rnn_denoise.js
new file mode 100644
index 00000000..c61ed5c6
--- /dev/null
+++ b/src/sdk/base/rnn_denoise.js
@@ -0,0 +1,2298 @@
+// Copyright (C) <2020> Intel Corporation
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/* eslint-disable */
+// Disabling eslint on auto-generated file.
+
+////////////////////////////////////////////////////////////////////////////////////
+// This file was generated using Emscripten https://emscripten.org/
+//
+// This is to add the capability of denoising audio streams captured through
+// the browser using WebAudio API. The core of denoising is done using a
+// WebAssembly port of the RNNoise denoising library https://github.com/xiph/rnnoise.
+//
+// This file is accompanied by two files
+// 1. rnnoise_denose.wasm: Wasm binary file & web version of RNNoise library
+// 2. denoise.js: Helper for integrating the capability into OWT. 'Module' and
+// 'wasmMemory' globals needs to be manually exported below to be used by
+// denoise.js.
+////////////////////////////////////////////////////////////////////////////////////
+
+// Auto generated content below.
+
+// The Module object: Our interface to the outside world. We import
+// and export values on it. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to check if Module already exists (e.g. case 3 above).
+// Substitution will be replaced with actual code on later stage of the build,
+// this way Closure Compiler will not mangle it (e.g. case 4. above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define var Module = {};
+// before the code. Then that object will be used in the code, and you
+
+
+// can continue to use Module afterwards as well.
+export var Module = typeof Module !== 'undefined' ? Module : {};
+
+
+
+// --pre-jses are emitted after the Module integration code, so that they can
+// refer to Module (if they choose; they can also define Module)
+// {{PRE_JSES}}
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+var key;
+for (key in Module) {
+ if (Module.hasOwnProperty(key)) {
+ moduleOverrides[key] = Module[key];
+ }
+}
+
+var arguments_ = [];
+var thisProgram = './this.program';
+var quit_ = function(status, toThrow) {
+ throw toThrow;
+};
+
+// Determine the runtime environment we are in. You can customize this by
+// setting the ENVIRONMENT setting at compile time (see settings.js).
+
+var ENVIRONMENT_IS_WEB = false;
+var ENVIRONMENT_IS_WORKER = false;
+var ENVIRONMENT_IS_NODE = false;
+var ENVIRONMENT_IS_SHELL = false;
+ENVIRONMENT_IS_WEB = typeof window === 'object';
+ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+// N.b. Electron.js environment is simultaneously a NODE-environment, but
+// also a web environment.
+ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
+ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+
+
+
+// `/` should be present at the end if `scriptDirectory` is not empty
+var scriptDirectory = '';
+function locateFile(path) {
+ if (Module['locateFile']) {
+ return Module['locateFile'](path, scriptDirectory);
+ }
+ return scriptDirectory + path;
+}
+
+// Hooks that are implemented differently in different runtime environments.
+var read_,
+ readAsync,
+ readBinary,
+ setWindowTitle;
+
+var nodeFS;
+var nodePath;
+
+if (ENVIRONMENT_IS_NODE) {
+ if (ENVIRONMENT_IS_WORKER) {
+ scriptDirectory = require('path').dirname(scriptDirectory) + '/';
+ } else {
+ scriptDirectory = __dirname + '/';
+ }
+
+
+
+
+ read_ = function shell_read(filename, binary) {
+ if (!nodeFS) nodeFS = require('fs');
+ if (!nodePath) nodePath = require('path');
+ filename = nodePath['normalize'](filename);
+ return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
+ };
+
+ readBinary = function readBinary(filename) {
+ var ret = read_(filename, true);
+ if (!ret.buffer) {
+ ret = new Uint8Array(ret);
+ }
+ assert(ret.buffer);
+ return ret;
+ };
+
+
+
+
+ if (process['argv'].length > 1) {
+ thisProgram = process['argv'][1].replace(/\\/g, '/');
+ }
+
+ arguments_ = process['argv'].slice(2);
+
+ if (typeof module !== 'undefined') {
+ module['exports'] = Module;
+ }
+
+ process['on']('uncaughtException', function(ex) {
+ // suppress ExitStatus exceptions from showing an error
+ if (!(ex instanceof ExitStatus)) {
+ throw ex;
+ }
+ });
+
+ process['on']('unhandledRejection', abort);
+
+ quit_ = function(status) {
+ process['exit'](status);
+ };
+
+ Module['inspect'] = function () { return '[Emscripten Module object]'; };
+
+
+
+} else
+if (ENVIRONMENT_IS_SHELL) {
+
+
+ if (typeof read != 'undefined') {
+ read_ = function shell_read(f) {
+ return read(f);
+ };
+ }
+
+ readBinary = function readBinary(f) {
+ var data;
+ if (typeof readbuffer === 'function') {
+ return new Uint8Array(readbuffer(f));
+ }
+ data = read(f, 'binary');
+ assert(typeof data === 'object');
+ return data;
+ };
+
+ if (typeof scriptArgs != 'undefined') {
+ arguments_ = scriptArgs;
+ } else if (typeof arguments != 'undefined') {
+ arguments_ = arguments;
+ }
+
+ if (typeof quit === 'function') {
+ quit_ = function(status) {
+ quit(status);
+ };
+ }
+
+ if (typeof print !== 'undefined') {
+ // Prefer to use print/printErr where they exist, as they usually work better.
+ if (typeof console === 'undefined') console = /** @type{!Console} */({});
+ console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
+ console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);
+ }
+
+
+} else
+
+// Note that this includes Node.js workers when relevant (pthreads is enabled).
+// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
+// ENVIRONMENT_IS_NODE.
+if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+ if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
+ scriptDirectory = self.location.href;
+ } else if (document.currentScript) { // web
+ scriptDirectory = document.currentScript.src;
+ }
+ // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
+ // otherwise, slice off the final part of the url to find the script directory.
+ // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
+ // and scriptDirectory will correctly be replaced with an empty string.
+ if (scriptDirectory.indexOf('blob:') !== 0) {
+ scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);
+ } else {
+ scriptDirectory = '';
+ }
+
+
+ // Differentiate the Web Worker from the Node Worker case, as reading must
+ // be done differently.
+ {
+
+
+
+
+ read_ = function shell_read(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.send(null);
+ return xhr.responseText;
+ };
+
+ if (ENVIRONMENT_IS_WORKER) {
+ readBinary = function readBinary(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.responseType = 'arraybuffer';
+ xhr.send(null);
+ return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
+ };
+ }
+
+ readAsync = function readAsync(url, onload, onerror) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.responseType = 'arraybuffer';
+ xhr.onload = function xhr_onload() {
+ if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+ onload(xhr.response);
+ return;
+ }
+ onerror();
+ };
+ xhr.onerror = onerror;
+ xhr.send(null);
+ };
+
+
+
+
+ }
+
+ setWindowTitle = function(title) { document.title = title };
+} else
+{
+}
+
+
+// Set up the out() and err() hooks, which are how we can print to stdout or
+// stderr, respectively.
+var out = Module['print'] || console.log.bind(console);
+var err = Module['printErr'] || console.warn.bind(console);
+
+// Merge back in the overrides
+for (key in moduleOverrides) {
+ if (moduleOverrides.hasOwnProperty(key)) {
+ Module[key] = moduleOverrides[key];
+ }
+}
+// Free the object hierarchy contained in the overrides, this lets the GC
+// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
+moduleOverrides = null;
+
+// Emit code to handle expected values on the Module object. This applies Module.x
+// to the proper local x. This has two benefits: first, we only emit it if it is
+// expected to arrive, and second, by using a local everywhere else that can be
+// minified.
+if (Module['arguments']) arguments_ = Module['arguments'];
+if (Module['thisProgram']) thisProgram = Module['thisProgram'];
+if (Module['quit']) quit_ = Module['quit'];
+
+// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
+
+
+
+
+
+// {{PREAMBLE_ADDITIONS}}
+
+var STACK_ALIGN = 16;
+
+function dynamicAlloc(size) {
+ var ret = HEAP32[DYNAMICTOP_PTR>>2];
+ var end = (ret + size + 15) & -16;
+ HEAP32[DYNAMICTOP_PTR>>2] = end;
+ return ret;
+}
+
+function alignMemory(size, factor) {
+ if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default
+ return Math.ceil(size / factor) * factor;
+}
+
+function getNativeTypeSize(type) {
+ switch (type) {
+ case 'i1': case 'i8': return 1;
+ case 'i16': return 2;
+ case 'i32': return 4;
+ case 'i64': return 8;
+ case 'float': return 4;
+ case 'double': return 8;
+ default: {
+ if (type[type.length-1] === '*') {
+ return 4; // A pointer
+ } else if (type[0] === 'i') {
+ var bits = Number(type.substr(1));
+ assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
+ return bits / 8;
+ } else {
+ return 0;
+ }
+ }
+ }
+}
+
+function warnOnce(text) {
+ if (!warnOnce.shown) warnOnce.shown = {};
+ if (!warnOnce.shown[text]) {
+ warnOnce.shown[text] = 1;
+ err(text);
+ }
+}
+
+
+
+
+
+
+
+
+// Wraps a JS function as a wasm function with a given signature.
+function convertJsFunctionToWasm(func, sig) {
+
+ // If the type reflection proposal is available, use the new
+ // "WebAssembly.Function" constructor.
+ // Otherwise, construct a minimal wasm module importing the JS function and
+ // re-exporting it.
+ if (typeof WebAssembly.Function === "function") {
+ var typeNames = {
+ 'i': 'i32',
+ 'j': 'i64',
+ 'f': 'f32',
+ 'd': 'f64'
+ };
+ var type = {
+ parameters: [],
+ results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
+ };
+ for (var i = 1; i < sig.length; ++i) {
+ type.parameters.push(typeNames[sig[i]]);
+ }
+ return new WebAssembly.Function(type, func);
+ }
+
+ // The module is static, with the exception of the type section, which is
+ // generated based on the signature passed in.
+ var typeSection = [
+ 0x01, // id: section,
+ 0x00, // length: 0 (placeholder)
+ 0x01, // count: 1
+ 0x60, // form: func
+ ];
+ var sigRet = sig.slice(0, 1);
+ var sigParam = sig.slice(1);
+ var typeCodes = {
+ 'i': 0x7f, // i32
+ 'j': 0x7e, // i64
+ 'f': 0x7d, // f32
+ 'd': 0x7c, // f64
+ };
+
+ // Parameters, length + signatures
+ typeSection.push(sigParam.length);
+ for (var i = 0; i < sigParam.length; ++i) {
+ typeSection.push(typeCodes[sigParam[i]]);
+ }
+
+ // Return values, length + signatures
+ // With no multi-return in MVP, either 0 (void) or 1 (anything else)
+ if (sigRet == 'v') {
+ typeSection.push(0x00);
+ } else {
+ typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
+ }
+
+ // Write the overall length of the type section back into the section header
+ // (excepting the 2 bytes for the section id and length)
+ typeSection[1] = typeSection.length - 2;
+
+ // Rest of the module is static
+ var bytes = new Uint8Array([
+ 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
+ 0x01, 0x00, 0x00, 0x00, // version: 1
+ ].concat(typeSection, [
+ 0x02, 0x07, // import section
+ // (import "e" "f" (func 0 (type 0)))
+ 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
+ 0x07, 0x05, // export section
+ // (export "f" (func 0 (type 0)))
+ 0x01, 0x01, 0x66, 0x00, 0x00,
+ ]));
+
+ // We can compile this wasm module synchronously because it is very small.
+ // This accepts an import (at "e.f"), that it reroutes to an export (at "f")
+ var module = new WebAssembly.Module(bytes);
+ var instance = new WebAssembly.Instance(module, {
+ 'e': {
+ 'f': func
+ }
+ });
+ var wrappedFunc = instance.exports['f'];
+ return wrappedFunc;
+}
+
+var freeTableIndexes = [];
+
+// Weak map of functions in the table to their indexes, created on first use.
+var functionsInTableMap;
+
+// Add a wasm function to the table.
+function addFunctionWasm(func, sig) {
+ var table = wasmTable;
+
+ // Check if the function is already in the table, to ensure each function
+ // gets a unique index. First, create the map if this is the first use.
+ if (!functionsInTableMap) {
+ functionsInTableMap = new WeakMap();
+ for (var i = 0; i < table.length; i++) {
+ var item = table.get(i);
+ // Ignore null values.
+ if (item) {
+ functionsInTableMap.set(item, i);
+ }
+ }
+ }
+ if (functionsInTableMap.has(func)) {
+ return functionsInTableMap.get(func);
+ }
+
+ // It's not in the table, add it now.
+
+
+ var ret;
+ // Reuse a free index if there is one, otherwise grow.
+ if (freeTableIndexes.length) {
+ ret = freeTableIndexes.pop();
+ } else {
+ ret = table.length;
+ // Grow the table
+ try {
+ table.grow(1);
+ } catch (err) {
+ if (!(err instanceof RangeError)) {
+ throw err;
+ }
+ throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
+ }
+ }
+
+ // Set the new value.
+ try {
+ // Attempting to call this with JS function will cause of table.set() to fail
+ table.set(ret, func);
+ } catch (err) {
+ if (!(err instanceof TypeError)) {
+ throw err;
+ }
+ var wrapped = convertJsFunctionToWasm(func, sig);
+ table.set(ret, wrapped);
+ }
+
+ functionsInTableMap.set(func, ret);
+
+ return ret;
+}
+
+function removeFunctionWasm(index) {
+ functionsInTableMap.delete(wasmTable.get(index));
+ freeTableIndexes.push(index);
+}
+
+// 'sig' parameter is required for the llvm backend but only when func is not
+// already a WebAssembly function.
+function addFunction(func, sig) {
+
+ return addFunctionWasm(func, sig);
+}
+
+function removeFunction(index) {
+ removeFunctionWasm(index);
+}
+
+
+
+var funcWrappers = {};
+
+function getFuncWrapper(func, sig) {
+ if (!func) return; // on null pointer, return undefined
+ assert(sig);
+ if (!funcWrappers[sig]) {
+ funcWrappers[sig] = {};
+ }
+ var sigCache = funcWrappers[sig];
+ if (!sigCache[func]) {
+ // optimize away arguments usage in common cases
+ if (sig.length === 1) {
+ sigCache[func] = function dynCall_wrapper() {
+ return dynCall(sig, func);
+ };
+ } else if (sig.length === 2) {
+ sigCache[func] = function dynCall_wrapper(arg) {
+ return dynCall(sig, func, [arg]);
+ };
+ } else {
+ // general case
+ sigCache[func] = function dynCall_wrapper() {
+ return dynCall(sig, func, Array.prototype.slice.call(arguments));
+ };
+ }
+ }
+ return sigCache[func];
+}
+
+
+
+
+
+
+
+function makeBigInt(low, high, unsigned) {
+ return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
+}
+
+/** @param {Array=} args */
+function dynCall(sig, ptr, args) {
+ if (args && args.length) {
+ return Module['dynCall_' + sig].apply(null, [ptr].concat(args));
+ } else {
+ return Module['dynCall_' + sig].call(null, ptr);
+ }
+}
+
+var tempRet0 = 0;
+
+var setTempRet0 = function(value) {
+ tempRet0 = value;
+};
+
+var getTempRet0 = function() {
+ return tempRet0;
+};
+
+
+// The address globals begin at. Very low in memory, for code size and optimization opportunities.
+// Above 0 is static memory, starting with globals.
+// Then the stack.
+// Then 'dynamic' memory for sbrk.
+var GLOBAL_BASE = 1024;
+
+
+
+
+
+// === Preamble library stuff ===
+
+// Documentation for the public APIs defined in this file must be updated in:
+// site/source/docs/api_reference/preamble.js.rst
+// A prebuilt local version of the documentation is available at:
+// site/build/text/docs/api_reference/preamble.js.txt
+// You can also build docs locally as HTML or other formats in site/
+// An online HTML version (which may be of a different version of Emscripten)
+// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
+
+
+var wasmBinary;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
+var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];
+
+
+if (typeof WebAssembly !== 'object') {
+ err('no native wasm support detected');
+}
+
+
+
+
+// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
+// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
+
+/** @param {number} ptr
+ @param {number} value
+ @param {string} type
+ @param {number|boolean=} noSafe */
+function setValue(ptr, value, type, noSafe) {
+ type = type || 'i8';
+ if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+ switch(type) {
+ case 'i1': HEAP8[((ptr)>>0)]=value; break;
+ case 'i8': HEAP8[((ptr)>>0)]=value; break;
+ case 'i16': HEAP16[((ptr)>>1)]=value; break;
+ case 'i32': HEAP32[((ptr)>>2)]=value; break;
+ case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+ case 'float': HEAPF32[((ptr)>>2)]=value; break;
+ case 'double': HEAPF64[((ptr)>>3)]=value; break;
+ default: abort('invalid type for setValue: ' + type);
+ }
+}
+
+/** @param {number} ptr
+ @param {string} type
+ @param {number|boolean=} noSafe */
+function getValue(ptr, type, noSafe) {
+ type = type || 'i8';
+ if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+ switch(type) {
+ case 'i1': return HEAP8[((ptr)>>0)];
+ case 'i8': return HEAP8[((ptr)>>0)];
+ case 'i16': return HEAP16[((ptr)>>1)];
+ case 'i32': return HEAP32[((ptr)>>2)];
+ case 'i64': return HEAP32[((ptr)>>2)];
+ case 'float': return HEAPF32[((ptr)>>2)];
+ case 'double': return HEAPF64[((ptr)>>3)];
+ default: abort('invalid type for getValue: ' + type);
+ }
+ return null;
+}
+
+
+
+
+
+
+// Wasm globals
+
+export var wasmMemory;
+
+// In fastcomp asm.js, we don't need a wasm Table at all.
+// In the wasm backend, we polyfill the WebAssembly object,
+// so this creates a (non-native-wasm) table for us.
+var wasmTable = new WebAssembly.Table({
+ 'initial': 4,
+ 'maximum': 4 + 0,
+ 'element': 'anyfunc'
+});
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+// whether we are quitting the application. no code should run after this.
+// set in exit() and abort()
+var ABORT = false;
+
+// set by exit() and abort(). Passed to 'onExit' handler.
+// NOTE: This is also used as the process return code code in shell environments
+// but only when noExitRuntime is false.
+var EXITSTATUS = 0;
+
+/** @type {function(*, string=)} */
+function assert(condition, text) {
+ if (!condition) {
+ abort('Assertion failed: ' + text);
+ }
+}
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+ var func = Module['_' + ident]; // closure exported function
+ assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
+ return func;
+}
+
+// C calling interface.
+/** @param {string|null=} returnType
+ @param {Array=} argTypes
+ @param {Arguments|Array=} args
+ @param {Object=} opts */
+function ccall(ident, returnType, argTypes, args, opts) {
+ // For fast lookup of conversion functions
+ var toC = {
+ 'string': function(str) {
+ var ret = 0;
+ if (str !== null && str !== undefined && str !== 0) { // null string
+ // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
+ var len = (str.length << 2) + 1;
+ ret = stackAlloc(len);
+ stringToUTF8(str, ret, len);
+ }
+ return ret;
+ },
+ 'array': function(arr) {
+ var ret = stackAlloc(arr.length);
+ writeArrayToMemory(arr, ret);
+ return ret;
+ }
+ };
+
+ function convertReturnValue(ret) {
+ if (returnType === 'string') return UTF8ToString(ret);
+ if (returnType === 'boolean') return Boolean(ret);
+ return ret;
+ }
+
+ var func = getCFunc(ident);
+ var cArgs = [];
+ var stack = 0;
+ if (args) {
+ for (var i = 0; i < args.length; i++) {
+ var converter = toC[argTypes[i]];
+ if (converter) {
+ if (stack === 0) stack = stackSave();
+ cArgs[i] = converter(args[i]);
+ } else {
+ cArgs[i] = args[i];
+ }
+ }
+ }
+ var ret = func.apply(null, cArgs);
+
+ ret = convertReturnValue(ret);
+ if (stack !== 0) stackRestore(stack);
+ return ret;
+}
+
+/** @param {string=} returnType
+ @param {Array=} argTypes
+ @param {Object=} opts */
+function cwrap(ident, returnType, argTypes, opts) {
+ argTypes = argTypes || [];
+ // When the function takes numbers and returns a number, we can just return
+ // the original function
+ var numericArgs = argTypes.every(function(type){ return type === 'number'});
+ var numericRet = returnType !== 'string';
+ if (numericRet && numericArgs && !opts) {
+ return getCFunc(ident);
+ }
+ return function() {
+ return ccall(ident, returnType, argTypes, arguments, opts);
+ }
+}
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk
+var ALLOC_NONE = 3; // Do not allocate
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+// is a little tricky (see docs right below). The reason is that it is optimized
+// for multiple syntaxes to save space in generated code. So you should
+// normally not use allocate(), and instead allocate memory using _malloc(),
+// initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+// in *bytes* (note that this is sometimes confusing: the next parameter does not
+// affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+// or a single type which is used for the entire block. This only matters if there
+// is initial data - if @slab is a number, then this does not matter at all and is
+// ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+/** @type {function((TypedArray|Array|number), string, number, number=)} */
+function allocate(slab, types, allocator, ptr) {
+ var zeroinit, size;
+ if (typeof slab === 'number') {
+ zeroinit = true;
+ size = slab;
+ } else {
+ zeroinit = false;
+ size = slab.length;
+ }
+
+ var singleType = typeof types === 'string' ? types : null;
+
+ var ret;
+ if (allocator == ALLOC_NONE) {
+ ret = ptr;
+ } else {
+ ret = [_malloc,
+ stackAlloc,
+ dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length));
+ }
+
+ if (zeroinit) {
+ var stop;
+ ptr = ret;
+ assert((ret & 3) == 0);
+ stop = ret + (size & ~3);
+ for (; ptr < stop; ptr += 4) {
+ HEAP32[((ptr)>>2)]=0;
+ }
+ stop = ret + size;
+ while (ptr < stop) {
+ HEAP8[((ptr++)>>0)]=0;
+ }
+ return ret;
+ }
+
+ if (singleType === 'i8') {
+ if (slab.subarray || slab.slice) {
+ HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret);
+ } else {
+ HEAPU8.set(new Uint8Array(slab), ret);
+ }
+ return ret;
+ }
+
+ var i = 0, type, typeSize, previousType;
+ while (i < size) {
+ var curr = slab[i];
+
+ type = singleType || types[i];
+ if (type === 0) {
+ i++;
+ continue;
+ }
+
+ if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+ setValue(ret+i, curr, type);
+
+ // no need to look up size unless type changes, so cache it
+ if (previousType !== type) {
+ typeSize = getNativeTypeSize(type);
+ previousType = type;
+ }
+ i += typeSize;
+ }
+
+ return ret;
+}
+
+// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
+function getMemory(size) {
+ if (!runtimeInitialized) return dynamicAlloc(size);
+ return _malloc(size);
+}
+
+
+
+
+// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
+
+// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
+// a copy of that string as a Javascript String object.
+
+var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
+
+/**
+ * @param {number} idx
+ * @param {number=} maxBytesToRead
+ * @return {string}
+ */
+function UTF8ArrayToString(heap, idx, maxBytesToRead) {
+ var endIdx = idx + maxBytesToRead;
+ var endPtr = idx;
+ // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
+ // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
+ // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
+ while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
+
+ if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
+ return UTF8Decoder.decode(heap.subarray(idx, endPtr));
+ } else {
+ var str = '';
+ // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
+ while (idx < endPtr) {
+ // For UTF8 byte structure, see:
+ // http://en.wikipedia.org/wiki/UTF-8#Description
+ // https://www.ietf.org/rfc/rfc2279.txt
+ // https://tools.ietf.org/html/rfc3629
+ var u0 = heap[idx++];
+ if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
+ var u1 = heap[idx++] & 63;
+ if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
+ var u2 = heap[idx++] & 63;
+ if ((u0 & 0xF0) == 0xE0) {
+ u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
+ } else {
+ u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
+ }
+
+ if (u0 < 0x10000) {
+ str += String.fromCharCode(u0);
+ } else {
+ var ch = u0 - 0x10000;
+ str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+ }
+ }
+ }
+ return str;
+}
+
+// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
+// copy of that string as a Javascript String object.
+// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
+// this parameter to scan the string until the first \0 byte. If maxBytesToRead is
+// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
+// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
+// not produce a string of exact length [ptr, ptr+maxBytesToRead[)
+// N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may
+// throw JS JIT optimizations off, so it is worth to consider consistently using one
+// style or the other.
+/**
+ * @param {number} ptr
+ * @param {number=} maxBytesToRead
+ * @return {string}
+ */
+function UTF8ToString(ptr, maxBytesToRead) {
+ return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
+}
+
+// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
+// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
+// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
+// Parameters:
+// str: the Javascript string to copy.
+// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
+// outIdx: The starting offset in the array to begin the copying.
+// maxBytesToWrite: The maximum number of bytes this function can write to the array.
+// This count should include the null terminator,
+// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
+// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
+// Returns the number of bytes written, EXCLUDING the null terminator.
+
+function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
+ if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
+ return 0;
+
+ var startIdx = outIdx;
+ var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
+ for (var i = 0; i < str.length; ++i) {
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
+ // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
+ var u = str.charCodeAt(i); // possibly a lead surrogate
+ if (u >= 0xD800 && u <= 0xDFFF) {
+ var u1 = str.charCodeAt(++i);
+ u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
+ }
+ if (u <= 0x7F) {
+ if (outIdx >= endIdx) break;
+ heap[outIdx++] = u;
+ } else if (u <= 0x7FF) {
+ if (outIdx + 1 >= endIdx) break;
+ heap[outIdx++] = 0xC0 | (u >> 6);
+ heap[outIdx++] = 0x80 | (u & 63);
+ } else if (u <= 0xFFFF) {
+ if (outIdx + 2 >= endIdx) break;
+ heap[outIdx++] = 0xE0 | (u >> 12);
+ heap[outIdx++] = 0x80 | ((u >> 6) & 63);
+ heap[outIdx++] = 0x80 | (u & 63);
+ } else {
+ if (outIdx + 3 >= endIdx) break;
+ heap[outIdx++] = 0xF0 | (u >> 18);
+ heap[outIdx++] = 0x80 | ((u >> 12) & 63);
+ heap[outIdx++] = 0x80 | ((u >> 6) & 63);
+ heap[outIdx++] = 0x80 | (u & 63);
+ }
+ }
+ // Null-terminate the pointer to the buffer.
+ heap[outIdx] = 0;
+ return outIdx - startIdx;
+}
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
+// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
+// Returns the number of bytes written, EXCLUDING the null terminator.
+
+function stringToUTF8(str, outPtr, maxBytesToWrite) {
+ return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
+}
+
+// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
+function lengthBytesUTF8(str) {
+ var len = 0;
+ for (var i = 0; i < str.length; ++i) {
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
+ var u = str.charCodeAt(i); // possibly a lead surrogate
+ if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
+ if (u <= 0x7F) ++len;
+ else if (u <= 0x7FF) len += 2;
+ else if (u <= 0xFFFF) len += 3;
+ else len += 4;
+ }
+ return len;
+}
+
+
+
+
+
+// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
+
+// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+
+function AsciiToString(ptr) {
+ var str = '';
+ while (1) {
+ var ch = HEAPU8[((ptr++)>>0)];
+ if (!ch) return str;
+ str += String.fromCharCode(ch);
+ }
+}
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
+
+function stringToAscii(str, outPtr) {
+ return writeAsciiToMemory(str, outPtr, false);
+}
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+
+var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;
+
+function UTF16ToString(ptr, maxBytesToRead) {
+ var endPtr = ptr;
+ // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
+ // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
+ var idx = endPtr >> 1;
+ var maxIdx = idx + maxBytesToRead / 2;
+ // If maxBytesToRead is not passed explicitly, it will be undefined, and this
+ // will always evaluate to true. This saves on code size.
+ while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
+ endPtr = idx << 1;
+
+ if (endPtr - ptr > 32 && UTF16Decoder) {
+ return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
+ } else {
+ var i = 0;
+
+ var str = '';
+ while (1) {
+ var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+ if (codeUnit == 0 || i == maxBytesToRead / 2) return str;
+ ++i;
+ // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+ str += String.fromCharCode(codeUnit);
+ }
+ }
+}
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
+// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
+// Parameters:
+// str: the Javascript string to copy.
+// outPtr: Byte address in Emscripten HEAP where to write the string to.
+// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
+// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
+// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
+// Returns the number of bytes written, EXCLUDING the null terminator.
+
+function stringToUTF16(str, outPtr, maxBytesToWrite) {
+ // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
+ if (maxBytesToWrite === undefined) {
+ maxBytesToWrite = 0x7FFFFFFF;
+ }
+ if (maxBytesToWrite < 2) return 0;
+ maxBytesToWrite -= 2; // Null terminator.
+ var startPtr = outPtr;
+ var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
+ for (var i = 0; i < numCharsToWrite; ++i) {
+ // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+ var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+ HEAP16[((outPtr)>>1)]=codeUnit;
+ outPtr += 2;
+ }
+ // Null-terminate the pointer to the HEAP.
+ HEAP16[((outPtr)>>1)]=0;
+ return outPtr - startPtr;
+}
+
+// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
+
+function lengthBytesUTF16(str) {
+ return str.length*2;
+}
+
+function UTF32ToString(ptr, maxBytesToRead) {
+ var i = 0;
+
+ var str = '';
+ // If maxBytesToRead is not passed explicitly, it will be undefined, and this
+ // will always evaluate to true. This saves on code size.
+ while (!(i >= maxBytesToRead / 4)) {
+ var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+ if (utf32 == 0) break;
+ ++i;
+ // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
+ if (utf32 >= 0x10000) {
+ var ch = utf32 - 0x10000;
+ str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+ } else {
+ str += String.fromCharCode(utf32);
+ }
+ }
+ return str;
+}
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
+// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
+// Parameters:
+// str: the Javascript string to copy.
+// outPtr: Byte address in Emscripten HEAP where to write the string to.
+// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
+// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
+// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
+// Returns the number of bytes written, EXCLUDING the null terminator.
+
+function stringToUTF32(str, outPtr, maxBytesToWrite) {
+ // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
+ if (maxBytesToWrite === undefined) {
+ maxBytesToWrite = 0x7FFFFFFF;
+ }
+ if (maxBytesToWrite < 4) return 0;
+ var startPtr = outPtr;
+ var endPtr = startPtr + maxBytesToWrite - 4;
+ for (var i = 0; i < str.length; ++i) {
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
+ var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+ if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+ var trailSurrogate = str.charCodeAt(++i);
+ codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+ }
+ HEAP32[((outPtr)>>2)]=codeUnit;
+ outPtr += 4;
+ if (outPtr + 4 > endPtr) break;
+ }
+ // Null-terminate the pointer to the HEAP.
+ HEAP32[((outPtr)>>2)]=0;
+ return outPtr - startPtr;
+}
+
+// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
+
+function lengthBytesUTF32(str) {
+ var len = 0;
+ for (var i = 0; i < str.length; ++i) {
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
+ var codeUnit = str.charCodeAt(i);
+ if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
+ len += 4;
+ }
+
+ return len;
+}
+
+// Allocate heap space for a JS string, and write it there.
+// It is the responsibility of the caller to free() that memory.
+function allocateUTF8(str) {
+ var size = lengthBytesUTF8(str) + 1;
+ var ret = _malloc(size);
+ if (ret) stringToUTF8Array(str, HEAP8, ret, size);
+ return ret;
+}
+
+// Allocate stack space for a JS string, and write it there.
+function allocateUTF8OnStack(str) {
+ var size = lengthBytesUTF8(str) + 1;
+ var ret = stackAlloc(size);
+ stringToUTF8Array(str, HEAP8, ret, size);
+ return ret;
+}
+
+// Deprecated: This function should not be called because it is unsafe and does not provide
+// a maximum length limit of how many bytes it is allowed to write. Prefer calling the
+// function stringToUTF8Array() instead, which takes in a maximum length that can be used
+// to be secure from out of bounds writes.
+/** @deprecated
+ @param {boolean=} dontAddNull */
+function writeStringToMemory(string, buffer, dontAddNull) {
+ warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
+
+ var /** @type {number} */ lastChar, /** @type {number} */ end;
+ if (dontAddNull) {
+ // stringToUTF8Array always appends null. If we don't want to do that, remember the
+ // character that existed at the location where the null will be placed, and restore
+ // that after the write (below).
+ end = buffer + lengthBytesUTF8(string);
+ lastChar = HEAP8[end];
+ }
+ stringToUTF8(string, buffer, Infinity);
+ if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
+}
+
+function writeArrayToMemory(array, buffer) {
+ HEAP8.set(array, buffer);
+}
+
+/** @param {boolean=} dontAddNull */
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+ for (var i = 0; i < str.length; ++i) {
+ HEAP8[((buffer++)>>0)]=str.charCodeAt(i);
+ }
+ // Null-terminate the pointer to the HEAP.
+ if (!dontAddNull) HEAP8[((buffer)>>0)]=0;
+}
+
+
+
+// Memory management
+
+var PAGE_SIZE = 16384;
+var WASM_PAGE_SIZE = 65536;
+var ASMJS_PAGE_SIZE = 16777216;
+
+function alignUp(x, multiple) {
+ if (x % multiple > 0) {
+ x += multiple - (x % multiple);
+ }
+ return x;
+}
+
+var HEAP,
+/** @type {ArrayBuffer} */
+ buffer,
+/** @type {Int8Array} */
+ HEAP8,
+/** @type {Uint8Array} */
+ HEAPU8,
+/** @type {Int16Array} */
+ HEAP16,
+/** @type {Uint16Array} */
+ HEAPU16,
+/** @type {Int32Array} */
+ HEAP32,
+/** @type {Uint32Array} */
+ HEAPU32,
+/** @type {Float32Array} */
+ HEAPF32,
+/** @type {Float64Array} */
+ HEAPF64;
+
+function updateGlobalBufferAndViews(buf) {
+ buffer = buf;
+ Module['HEAP8'] = HEAP8 = new Int8Array(buf);
+ Module['HEAP16'] = HEAP16 = new Int16Array(buf);
+ Module['HEAP32'] = HEAP32 = new Int32Array(buf);
+ Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
+ Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
+ Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
+ Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
+ Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
+}
+
+var STATIC_BASE = 1024,
+ STACK_BASE = 5340160,
+ STACKTOP = STACK_BASE,
+ STACK_MAX = 97280,
+ DYNAMIC_BASE = 5340160,
+ DYNAMICTOP_PTR = 97120;
+
+
+
+var TOTAL_STACK = 5242880;
+
+var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;
+
+
+// In non-standalone/normal mode, we create the memory here.
+
+// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm
+// memory is created in the wasm, not in JS.)
+
+ if (Module['wasmMemory']) {
+ wasmMemory = Module['wasmMemory'];
+ } else
+ {
+ wasmMemory = new WebAssembly.Memory({
+ 'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE
+ ,
+ 'maximum': 2147483648 / WASM_PAGE_SIZE
+ });
+ }
+
+
+if (wasmMemory) {
+ buffer = wasmMemory.buffer;
+}
+
+// If the user provides an incorrect length, just use that length instead rather than providing the user to
+// specifically provide the memory length with Module['INITIAL_MEMORY'].
+INITIAL_INITIAL_MEMORY = buffer.byteLength;
+updateGlobalBufferAndViews(buffer);
+
+HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;
+
+
+function callRuntimeCallbacks(callbacks) {
+ while(callbacks.length > 0) {
+ var callback = callbacks.shift();
+ if (typeof callback == 'function') {
+ callback(Module); // Pass the module as the first argument.
+ continue;
+ }
+ var func = callback.func;
+ if (typeof func === 'number') {
+ if (callback.arg === undefined) {
+ Module['dynCall_v'](func);
+ } else {
+ Module['dynCall_vi'](func, callback.arg);
+ }
+ } else {
+ func(callback.arg === undefined ? null : callback.arg);
+ }
+ }
+}
+
+var __ATPRERUN__ = []; // functions called before the runtime is initialized
+var __ATINIT__ = []; // functions called during startup
+var __ATMAIN__ = []; // functions called when main() is to be run
+var __ATEXIT__ = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the main() is called
+
+var runtimeInitialized = false;
+var runtimeExited = false;
+
+
+function preRun() {
+
+ if (Module['preRun']) {
+ if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+ while (Module['preRun'].length) {
+ addOnPreRun(Module['preRun'].shift());
+ }
+ }
+
+ callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function initRuntime() {
+ runtimeInitialized = true;
+
+ callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+
+ callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+ runtimeExited = true;
+}
+
+function postRun() {
+
+ if (Module['postRun']) {
+ if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+ while (Module['postRun'].length) {
+ addOnPostRun(Module['postRun'].shift());
+ }
+ }
+
+ callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+ __ATPRERUN__.unshift(cb);
+}
+
+function addOnInit(cb) {
+ __ATINIT__.unshift(cb);
+}
+
+function addOnPreMain(cb) {
+ __ATMAIN__.unshift(cb);
+}
+
+function addOnExit(cb) {
+}
+
+function addOnPostRun(cb) {
+ __ATPOSTRUN__.unshift(cb);
+}
+
+/** @param {number|boolean=} ignore */
+function unSign(value, bits, ignore) {
+ if (value >= 0) {
+ return value;
+ }
+ return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+ : Math.pow(2, bits) + value;
+}
+/** @param {number|boolean=} ignore */
+function reSign(value, bits, ignore) {
+ if (value <= 0) {
+ return value;
+ }
+ var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+ : Math.pow(2, bits-1);
+ if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+ // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+ // TODO: In i64 mode 1, resign the two parts separately and safely
+ value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+ }
+ return value;
+}
+
+
+
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_round = Math.round;
+var Math_min = Math.min;
+var Math_max = Math.max;
+var Math_clz32 = Math.clz32;
+var Math_trunc = Math.trunc;
+
+
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// Module.preRun (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function getUniqueRunDependency(id) {
+ return id;
+}
+
+function addRunDependency(id) {
+ runDependencies++;
+
+ if (Module['monitorRunDependencies']) {
+ Module['monitorRunDependencies'](runDependencies);
+ }
+
+}
+
+function removeRunDependency(id) {
+ runDependencies--;
+
+ if (Module['monitorRunDependencies']) {
+ Module['monitorRunDependencies'](runDependencies);
+ }
+
+ if (runDependencies == 0) {
+ if (runDependencyWatcher !== null) {
+ clearInterval(runDependencyWatcher);
+ runDependencyWatcher = null;
+ }
+ if (dependenciesFulfilled) {
+ var callback = dependenciesFulfilled;
+ dependenciesFulfilled = null;
+ callback(); // can add another dependenciesFulfilled
+ }
+ }
+}
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+/** @param {string|number=} what */
+function abort(what) {
+ if (Module['onAbort']) {
+ Module['onAbort'](what);
+ }
+
+ what += '';
+ out(what);
+ err(what);
+
+ ABORT = true;
+ EXITSTATUS = 1;
+
+ what = 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.';
+
+ // Throw a wasm runtime error, because a JS error might be seen as a foreign
+ // exception, which means we'd run destructors on it. We need the error to
+ // simply make the program stop.
+ throw new WebAssembly.RuntimeError(what);
+}
+
+
+var memoryInitializer = null;
+
+
+
+
+
+
+
+
+
+
+
+
+function hasPrefix(str, prefix) {
+ return String.prototype.startsWith ?
+ str.startsWith(prefix) :
+ str.indexOf(prefix) === 0;
+}
+
+// Prefix of data URIs emitted by SINGLE_FILE and related options.
+var dataURIPrefix = 'data:application/octet-stream;base64,';
+
+// Indicates whether filename is a base64 data URI.
+function isDataURI(filename) {
+ return hasPrefix(filename, dataURIPrefix);
+}
+
+var fileURIPrefix = "file://";
+
+// Indicates whether filename is delivered via file protocol (as opposed to http/https)
+function isFileURI(filename) {
+ return hasPrefix(filename, fileURIPrefix);
+}
+
+
+
+
+var wasmBinaryFile = 'rnn_denoise.wasm';
+if (!isDataURI(wasmBinaryFile)) {
+ wasmBinaryFile = locateFile(wasmBinaryFile);
+}
+
+function getBinary() {
+ try {
+ if (wasmBinary) {
+ return new Uint8Array(wasmBinary);
+ }
+
+ if (readBinary) {
+ return readBinary(wasmBinaryFile);
+ } else {
+ throw "both async and sync fetching of the wasm failed";
+ }
+ }
+ catch (err) {
+ abort(err);
+ }
+}
+
+function getBinaryPromise() {
+ // If we don't have the binary yet, and have the Fetch api, use that;
+ // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
+ if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function'
+ // Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file://
+ && !isFileURI(wasmBinaryFile)
+ ) {
+ return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
+ if (!response['ok']) {
+ throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
+ }
+ return response['arrayBuffer']();
+ }).catch(function () {
+ return getBinary();
+ });
+ }
+ // Otherwise, getBinary should be able to get it synchronously
+ return new Promise(function(resolve, reject) {
+ resolve(getBinary());
+ });
+}
+
+
+
+// Create the wasm instance.
+// Receives the wasm imports, returns the exports.
+function createWasm() {
+ // prepare imports
+ var info = {
+ 'env': asmLibraryArg,
+ 'wasi_snapshot_preview1': asmLibraryArg
+ };
+ // Load the wasm module and create an instance of using native support in the JS engine.
+ // handle a generated wasm instance, receiving its exports and
+ // performing other necessary setup
+ /** @param {WebAssembly.Module=} module*/
+ function receiveInstance(instance, module) {
+ var exports = instance.exports;
+ Module['asm'] = exports;
+ removeRunDependency('wasm-instantiate');
+ }
+ // we can't run yet (except in a pthread, where we have a custom sync instantiator)
+ addRunDependency('wasm-instantiate');
+
+
+ function receiveInstantiatedSource(output) {
+ // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
+ // receiveInstance() will swap in the exports (to Module.asm) so they can be called
+ // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
+ // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
+ receiveInstance(output['instance']);
+ }
+
+
+ function instantiateArrayBuffer(receiver) {
+ return getBinaryPromise().then(function(binary) {
+ return WebAssembly.instantiate(binary, info);
+ }).then(receiver, function(reason) {
+ err('failed to asynchronously prepare wasm: ' + reason);
+ abort(reason);
+ });
+ }
+
+ // Prefer streaming instantiation if available.
+ function instantiateAsync() {
+ if (!wasmBinary &&
+ typeof WebAssembly.instantiateStreaming === 'function' &&
+ !isDataURI(wasmBinaryFile) &&
+ // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
+ !isFileURI(wasmBinaryFile) &&
+ typeof fetch === 'function') {
+ fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {
+ var result = WebAssembly.instantiateStreaming(response, info);
+ return result.then(receiveInstantiatedSource, function(reason) {
+ // We expect the most common failure cause to be a bad MIME type for the binary,
+ // in which case falling back to ArrayBuffer instantiation should work.
+ err('wasm streaming compile failed: ' + reason);
+ err('falling back to ArrayBuffer instantiation');
+ return instantiateArrayBuffer(receiveInstantiatedSource);
+ });
+ });
+ } else {
+ return instantiateArrayBuffer(receiveInstantiatedSource);
+ }
+ }
+ // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
+ // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
+ // to any other async startup actions they are performing.
+ if (Module['instantiateWasm']) {
+ try {
+ var exports = Module['instantiateWasm'](info, receiveInstance);
+ return exports;
+ } catch(e) {
+ err('Module.instantiateWasm callback failed with error: ' + e);
+ return false;
+ }
+ }
+
+ instantiateAsync();
+ return {}; // no exports yet; we'll fill them in later
+}
+
+
+// Globals used by JS i64 conversions
+var tempDouble;
+var tempI64;
+
+// === Body ===
+
+var ASM_CONSTS = {
+
+};
+
+
+
+
+// STATICTOP = STATIC_BASE + 96256;
+/* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });
+
+
+
+
+/* no memory initializer */
+// {{PRE_LIBRARY}}
+
+
+ function demangle(func) {
+ return func;
+ }
+
+ function demangleAll(text) {
+ var regex =
+ /\b_Z[\w\d_]+/g;
+ return text.replace(regex,
+ function(x) {
+ var y = demangle(x);
+ return x === y ? x : (y + ' [' + x + ']');
+ });
+ }
+
+ function jsStackTrace() {
+ var err = new Error();
+ if (!err.stack) {
+ // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
+ // so try that as a special-case.
+ try {
+ throw new Error();
+ } catch(e) {
+ err = e;
+ }
+ if (!err.stack) {
+ return '(no stack trace available)';
+ }
+ }
+ return err.stack.toString();
+ }
+
+ function stackTrace() {
+ var js = jsStackTrace();
+ if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
+ return demangleAll(js);
+ }
+
+
+ var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
+ _emscripten_get_now = function() {
+ var t = process['hrtime']();
+ return t[0] * 1e3 + t[1] / 1e6;
+ };
+ } else if (typeof dateNow !== 'undefined') {
+ _emscripten_get_now = dateNow;
+ } else _emscripten_get_now = function() { return performance.now(); }
+ ;
+
+ var _emscripten_get_now_is_monotonic=true;;
+
+ function setErrNo(value) {
+ HEAP32[((___errno_location())>>2)]=value;
+ return value;
+ }function _clock_gettime(clk_id, tp) {
+ // int clock_gettime(clockid_t clk_id, struct timespec *tp);
+ var now;
+ if (clk_id === 0) {
+ now = Date.now();
+ } else if ((clk_id === 1 || clk_id === 4) && _emscripten_get_now_is_monotonic) {
+ now = _emscripten_get_now();
+ } else {
+ setErrNo(28);
+ return -1;
+ }
+ HEAP32[((tp)>>2)]=(now/1000)|0; // seconds
+ HEAP32[(((tp)+(4))>>2)]=((now % 1000)*1000*1000)|0; // nanoseconds
+ return 0;
+ }
+
+ function _emscripten_get_sbrk_ptr() {
+ return 97120;
+ }
+
+ function _emscripten_memcpy_big(dest, src, num) {
+ HEAPU8.copyWithin(dest, src, src + num);
+ }
+
+
+ function _emscripten_get_heap_size() {
+ return HEAPU8.length;
+ }
+
+ function emscripten_realloc_buffer(size) {
+ try {
+ // round size grow request up to wasm page size (fixed 64KB per spec)
+ wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size
+ updateGlobalBufferAndViews(wasmMemory.buffer);
+ return 1 /*success*/;
+ } catch(e) {
+ }
+ }function _emscripten_resize_heap(requestedSize) {
+ requestedSize = requestedSize >>> 0;
+ var oldSize = _emscripten_get_heap_size();
+ // With pthreads, races can happen (another thread might increase the size in between), so return a failure, and let the caller retry.
+
+
+ var PAGE_MULTIPLE = 65536;
+
+ // Memory resize rules:
+ // 1. When resizing, always produce a resized heap that is at least 16MB (to avoid tiny heap sizes receiving lots of repeated resizes at startup)
+ // 2. Always increase heap size to at least the requested size, rounded up to next page multiple.
+ // 3a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap geometrically: increase the heap size according to
+ // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%),
+ // At most overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
+ // 3b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap linearly: increase the heap size by at least MEMORY_GROWTH_LINEAR_STEP bytes.
+ // 4. Max size for the heap is capped at 2048MB-PAGE_MULTIPLE, or by MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
+ // 5. If we were unable to allocate as much memory, it may be due to over-eager decision to excessively reserve due to (3) above.
+ // Hence if an allocation fails, cut down on the amount of excess growth, in an attempt to succeed to perform a smaller allocation.
+
+ // A limit was set for how much we can grow. We should not exceed that
+ // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
+ var maxHeapSize = 2147483648;
+ if (requestedSize > maxHeapSize) {
+ return false;
+ }
+
+ var minHeapSize = 16777216;
+
+ // Loop through potential heap size increases. If we attempt a too eager reservation that fails, cut down on the
+ // attempted size and reserve a smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
+ for(var cutDown = 1; cutDown <= 4; cutDown *= 2) {
+ var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
+ // but limit overreserving (default to capping at +96MB overgrowth at most)
+ overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
+
+
+ var newSize = Math.min(maxHeapSize, alignUp(Math.max(minHeapSize, requestedSize, overGrownHeapSize), PAGE_MULTIPLE));
+
+ var replacement = emscripten_realloc_buffer(newSize);
+ if (replacement) {
+
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+ var PATH={splitPath:function(filename) {
+ var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+ return splitPathRe.exec(filename).slice(1);
+ },normalizeArray:function(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i];
+ if (last === '.') {
+ parts.splice(i, 1);
+ } else if (last === '..') {
+ parts.splice(i, 1);
+ up++;
+ } else if (up) {
+ parts.splice(i, 1);
+ up--;
+ }
+ }
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up; up--) {
+ parts.unshift('..');
+ }
+ }
+ return parts;
+ },normalize:function(path) {
+ var isAbsolute = path.charAt(0) === '/',
+ trailingSlash = path.substr(-1) === '/';
+ // Normalize the path
+ path = PATH.normalizeArray(path.split('/').filter(function(p) {
+ return !!p;
+ }), !isAbsolute).join('/');
+ if (!path && !isAbsolute) {
+ path = '.';
+ }
+ if (path && trailingSlash) {
+ path += '/';
+ }
+ return (isAbsolute ? '/' : '') + path;
+ },dirname:function(path) {
+ var result = PATH.splitPath(path),
+ root = result[0],
+ dir = result[1];
+ if (!root && !dir) {
+ // No dirname whatsoever
+ return '.';
+ }
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substr(0, dir.length - 1);
+ }
+ return root + dir;
+ },basename:function(path) {
+ // EMSCRIPTEN return '/'' for '/', not an empty string
+ if (path === '/') return '/';
+ var lastSlash = path.lastIndexOf('/');
+ if (lastSlash === -1) return path;
+ return path.substr(lastSlash+1);
+ },extname:function(path) {
+ return PATH.splitPath(path)[3];
+ },join:function() {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return PATH.normalize(paths.join('/'));
+ },join2:function(l, r) {
+ return PATH.normalize(l + '/' + r);
+ }};var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream, curr) {
+ var buffer = SYSCALLS.buffers[stream];
+ if (curr === 0 || curr === 10) {
+ (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0));
+ buffer.length = 0;
+ } else {
+ buffer.push(curr);
+ }
+ },varargs:undefined,get:function() {
+ SYSCALLS.varargs += 4;
+ var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
+ return ret;
+ },getStr:function(ptr) {
+ var ret = UTF8ToString(ptr);
+ return ret;
+ },get64:function(low, high) {
+ return low;
+ }};function _fd_close(fd) {
+ return 0;
+ }
+
+ function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
+ }
+
+
+ function flush_NO_FILESYSTEM() {
+ // flush anything remaining in the buffers during shutdown
+ if (typeof _fflush !== 'undefined') _fflush(0);
+ var buffers = SYSCALLS.buffers;
+ if (buffers[1].length) SYSCALLS.printChar(1, 10);
+ if (buffers[2].length) SYSCALLS.printChar(2, 10);
+ }function _fd_write(fd, iov, iovcnt, pnum) {
+ // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0
+ var num = 0;
+ for (var i = 0; i < iovcnt; i++) {
+ var ptr = HEAP32[(((iov)+(i*8))>>2)];
+ var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
+ for (var j = 0; j < len; j++) {
+ SYSCALLS.printChar(fd, HEAPU8[ptr+j]);
+ }
+ num += len;
+ }
+ HEAP32[((pnum)>>2)]=num
+ return 0;
+ }
+
+ function _setTempRet0($i) {
+ setTempRet0(($i) | 0);
+ }
+var ASSERTIONS = false;
+
+
+
+/** @type {function(string, boolean=, number=)} */
+function intArrayFromString(stringy, dontAddNull, length) {
+ var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
+ var u8array = new Array(len);
+ var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
+ if (dontAddNull) u8array.length = numBytesWritten;
+ return u8array;
+}
+
+function intArrayToString(array) {
+ var ret = [];
+ for (var i = 0; i < array.length; i++) {
+ var chr = array[i];
+ if (chr > 0xFF) {
+ if (ASSERTIONS) {
+ assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
+ }
+ chr &= 0xFF;
+ }
+ ret.push(String.fromCharCode(chr));
+ }
+ return ret.join('');
+}
+
+
+var asmGlobalArg = {};
+var asmLibraryArg = { "clock_gettime": _clock_gettime, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_resize_heap": _emscripten_resize_heap, "fd_close": _fd_close, "fd_seek": _fd_seek, "fd_write": _fd_write, "memory": wasmMemory, "setTempRet0": _setTempRet0, "table": wasmTable };
+var asm = createWasm();
+/** @type {function(...*):?} */
+var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
+ return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["__wasm_call_ctors"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnoise_get_size = Module["_rnnoise_get_size"] = function() {
+ return (_rnnoise_get_size = Module["_rnnoise_get_size"] = Module["asm"]["rnnoise_get_size"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnoise_init = Module["_rnnoise_init"] = function() {
+ return (_rnnoise_init = Module["_rnnoise_init"] = Module["asm"]["rnnoise_init"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnoise_create = Module["_rnnoise_create"] = function() {
+ return (_rnnoise_create = Module["_rnnoise_create"] = Module["asm"]["rnnoise_create"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _malloc = Module["_malloc"] = function() {
+ return (_malloc = Module["_malloc"] = Module["asm"]["malloc"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnoise_destroy = Module["_rnnoise_destroy"] = function() {
+ return (_rnnoise_destroy = Module["_rnnoise_destroy"] = Module["asm"]["rnnoise_destroy"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _free = Module["_free"] = function() {
+ return (_free = Module["_free"] = Module["asm"]["free"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnoise_process_frame = Module["_rnnoise_process_frame"] = function() {
+ return (_rnnoise_process_frame = Module["_rnnoise_process_frame"] = Module["asm"]["rnnoise_process_frame"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _denoise_proc = Module["_denoise_proc"] = function() {
+ return (_denoise_proc = Module["_denoise_proc"] = Module["asm"]["denoise_proc"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnDenoise_rawmem = Module["_rnnDenoise_rawmem"] = function() {
+ return (_rnnDenoise_rawmem = Module["_rnnDenoise_rawmem"] = Module["asm"]["rnnDenoise_rawmem"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _rnnDenoise_rawmem_perf = Module["_rnnDenoise_rawmem_perf"] = function() {
+ return (_rnnDenoise_rawmem_perf = Module["_rnnDenoise_rawmem_perf"] = Module["asm"]["rnnDenoise_rawmem_perf"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _get_rnnDenoise_rawmem_time = Module["_get_rnnDenoise_rawmem_time"] = function() {
+ return (_get_rnnDenoise_rawmem_time = Module["_get_rnnDenoise_rawmem_time"] = Module["asm"]["get_rnnDenoise_rawmem_time"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _getResultPointer = Module["_getResultPointer"] = function() {
+ return (_getResultPointer = Module["_getResultPointer"] = Module["asm"]["getResultPointer"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _getResultSize = Module["_getResultSize"] = function() {
+ return (_getResultSize = Module["_getResultSize"] = Module["asm"]["getResultSize"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _getsampleRate = Module["_getsampleRate"] = function() {
+ return (_getsampleRate = Module["_getsampleRate"] = Module["asm"]["getsampleRate"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _getchannels = Module["_getchannels"] = function() {
+ return (_getchannels = Module["_getchannels"] = Module["asm"]["getchannels"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _getsampleCount = Module["_getsampleCount"] = function() {
+ return (_getsampleCount = Module["_getsampleCount"] = Module["asm"]["getsampleCount"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _freeBuffer = Module["_freeBuffer"] = function() {
+ return (_freeBuffer = Module["_freeBuffer"] = Module["asm"]["freeBuffer"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var _main = Module["_main"] = function() {
+ return (_main = Module["_main"] = Module["asm"]["main"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var ___errno_location = Module["___errno_location"] = function() {
+ return (___errno_location = Module["___errno_location"] = Module["asm"]["__errno_location"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var stackSave = Module["stackSave"] = function() {
+ return (stackSave = Module["stackSave"] = Module["asm"]["stackSave"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var stackRestore = Module["stackRestore"] = function() {
+ return (stackRestore = Module["stackRestore"] = Module["asm"]["stackRestore"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var stackAlloc = Module["stackAlloc"] = function() {
+ return (stackAlloc = Module["stackAlloc"] = Module["asm"]["stackAlloc"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var __growWasmMemory = Module["__growWasmMemory"] = function() {
+ return (__growWasmMemory = Module["__growWasmMemory"] = Module["asm"]["__growWasmMemory"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var dynCall_ii = Module["dynCall_ii"] = function() {
+ return (dynCall_ii = Module["dynCall_ii"] = Module["asm"]["dynCall_ii"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var dynCall_iiii = Module["dynCall_iiii"] = function() {
+ return (dynCall_iiii = Module["dynCall_iiii"] = Module["asm"]["dynCall_iiii"]).apply(null, arguments);
+};
+
+/** @type {function(...*):?} */
+var dynCall_jiji = Module["dynCall_jiji"] = function() {
+ return (dynCall_jiji = Module["dynCall_jiji"] = Module["asm"]["dynCall_jiji"]).apply(null, arguments);
+};
+
+// === Auto-generated postamble setup entry stuff ===
+
+Module["cwrap"] = cwrap;
+var calledRun;
+
+/**
+ * @constructor
+ * @this {ExitStatus}
+ */
+function ExitStatus(status) {
+ this.name = "ExitStatus";
+ this.message = "Program terminated with exit(" + status + ")";
+ this.status = status;
+}
+
+var calledMain = false;
+
+
+dependenciesFulfilled = function runCaller() {
+ // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+ if (!calledRun) run();
+ if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+};
+
+function callMain(args) {
+
+ var entryFunction = Module['_main'];
+
+
+ args = args || [];
+
+ var argc = args.length+1;
+ var argv = stackAlloc((argc + 1) * 4);
+ HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
+ for (var i = 1; i < argc; i++) {
+ HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
+ }
+ HEAP32[(argv >> 2) + argc] = 0;
+
+ try {
+
+ var ret = entryFunction(argc, argv);
+ // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as execution is asynchronously handed
+ // off to a pthread.
+ // if we're not running an evented main loop, it's time to exit
+ exit(ret, /* implicit = */ true);
+ }
+ catch(e) {
+ if (e instanceof ExitStatus) {
+ // exit() throws this once it's done to make sure execution
+ // has been stopped completely
+ return;
+ } else if (e == 'unwind') {
+ // running an evented main loop, don't immediately exit
+ noExitRuntime = true;
+ return;
+ } else {
+ var toLog = e;
+ if (e && typeof e === 'object' && e.stack) {
+ toLog = [e, e.stack];
+ }
+ err('exception thrown: ' + toLog);
+ quit_(1, e);
+ }
+ } finally {
+ calledMain = true;
+ }
+}
+
+/** @type {function(Array=)} */
+function run(args) {
+ args = args || arguments_;
+
+ if (runDependencies > 0) {
+ return;
+ }
+
+
+ preRun();
+
+ if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+
+ function doRun() {
+ // run may have just been called through dependencies being fulfilled just in this very frame,
+ // or while the async setStatus time below was happening
+ if (calledRun) return;
+ calledRun = true;
+ Module['calledRun'] = true;
+
+ if (ABORT) return;
+
+ initRuntime();
+
+ preMain();
+
+ if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
+
+ if (shouldRunNow) callMain(args);
+
+ postRun();
+ }
+
+ if (Module['setStatus']) {
+ Module['setStatus']('Running...');
+ setTimeout(function() {
+ setTimeout(function() {
+ Module['setStatus']('');
+ }, 1);
+ doRun();
+ }, 1);
+ } else
+ {
+ doRun();
+ }
+}
+Module['run'] = run;
+
+
+/** @param {boolean|number=} implicit */
+function exit(status, implicit) {
+
+ // if this is just main exit-ing implicitly, and the status is 0, then we
+ // don't need to do anything here and can just leave. if the status is
+ // non-zero, though, then we need to report it.
+ // (we may have warned about this earlier, if a situation justifies doing so)
+ if (implicit && noExitRuntime && status === 0) {
+ return;
+ }
+
+ if (noExitRuntime) {
+ } else {
+
+ ABORT = true;
+ EXITSTATUS = status;
+
+ exitRuntime();
+
+ if (Module['onExit']) Module['onExit'](status);
+ }
+
+ quit_(status, new ExitStatus(status));
+}
+
+if (Module['preInit']) {
+ if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+ while (Module['preInit'].length > 0) {
+ Module['preInit'].pop()();
+ }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+
+if (Module['noInitialRun']) shouldRunNow = false;
+
+
+ noExitRuntime = true;
+
+run();
+
+// {{MODULE_ADDITIONS}}
diff --git a/src/sdk/base/rnn_denoise.wasm b/src/sdk/base/rnn_denoise.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..e48145aa82de7be8726c68021022d93441b19722
GIT binary patch
literal 235255
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