ngx-tencent-im
Version:
Instant messaging for Angular.
1,368 lines (1,251 loc) • 1.13 MB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.BenzAMRRecorder = factory());
}(this, function () {
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var recorder_build = createCommonjsModule(function (module, exports) {
(function (global, factory) {
module.exports = factory();
}(commonjsGlobal, (function () {
var recorderWorker = function () {
var recLength = 0,
recBuffersL = [],
recBuffersR = [],
sampleRate;
self.onmessage = function (e) {
switch (e.data.command) {
case 'init':
init(e.data.config);
break;
case 'record':
record(e.data.buffer);
break;
case 'exportWAV':
exportWAV(e.data.type);
break;
case 'getBuffer':
getBuffer();
break;
case 'clear':
clear();
break;
}
};
function init(config) {
sampleRate = config.sampleRate;
}
function record(inputBuffer) {
recBuffersL.push(inputBuffer[0]);
recBuffersR.push(inputBuffer[1]);
recLength += inputBuffer[0].length;
}
function exportWAV(type) {
var bufferL = mergeBuffers(recBuffersL, recLength);
var bufferR = mergeBuffers(recBuffersR, recLength);
var interleaved = interleave(bufferL, bufferR);
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], {type: type});
self.postMessage({
type: 'blob',
data: audioBlob
});
}
function getBuffer() {
var buffers = [];
buffers.push(mergeBuffers(recBuffersL, recLength));
buffers.push(mergeBuffers(recBuffersR, recLength));
self.postMessage({
type: 'buffer',
data: buffers
});
}
function clear() {
recLength = 0;
recBuffersL = [];
recBuffersR = [];
}
function mergeBuffers(recBuffers, recLength) {
var result = new Float32Array(recLength);
var offset = 0;
for (var i = 0; i < recBuffers.length; i++) {
result.set(recBuffers[i], offset);
offset += recBuffers[i].length;
}
return result;
}
function interleave(inputL, inputR) {
var length = inputL.length + inputR.length;
var result = new Float32Array(length);
var index = 0,
inputIndex = 0;
while (index < length) {
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
}
function floatTo16BitPCM(output, offset, input) {
for (var i = 0; i < input.length; i++, offset += 2) {
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
function writeString(view, offset, string) {
for (var i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
function encodeWAV(samples) {
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
/* RIFF identifier */
writeString(view, 0, 'RIFF');
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, 'WAVE');
/* format chunk identifier */
writeString(view, 12, 'fmt ');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, 2, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
view.setUint32(28, sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, 4, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
writeString(view, 36, 'data');
/* data chunk length */
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return view;
}
};
var recorderWorkerStr = recorderWorker.toString()
.replace(/^\s*function.*?\(\)\s*{/, '')
.replace(/}\s*$/, '');
// var WORKER_PATH = './recorderWorker.js';
var Recorder = function(source, cfg){
var config = cfg || {};
var bufferLen = config.bufferLen || 4096;
this.context = source.context;
this.node = (this.context.createScriptProcessor ||
this.context.createJavaScriptNode).call(this.context,
bufferLen, 2, 2);
var worker = new Worker((window.URL || window.webkitURL).createObjectURL(new Blob([recorderWorkerStr], {type:"text/javascript"})));
worker.onmessage = function(e){
if (e.data.type === 'blob') {
currCallbackWithBlob(e.data.data);
} else {
currCallbackWithBuffer(e.data.data);
}
};
worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate
}
});
var recording = false,
currCallbackWithBuffer,
currCallbackWithBlob;
this.node.onaudioprocess = function(e){
if (!recording) return;
worker.postMessage({
command: 'record',
buffer: [
e.inputBuffer.getChannelData(0),
e.inputBuffer.getChannelData(1)
]
});
};
this.configure = function(cfg){
for (var prop in cfg){
if (cfg.hasOwnProperty(prop)){
config[prop] = cfg[prop];
}
}
};
this.record = function(){
recording = true;
};
this.stop = function(){
recording = false;
};
this.clear = function(){
worker.postMessage({ command: 'clear' });
};
this.getBuffer = function(cb) {
currCallbackWithBuffer = cb || config.callback;
worker.postMessage({ command: 'getBuffer' });
};
this.exportWAV = function(cb, type){
currCallbackWithBlob = cb || config.callback;
type = type || config.type || 'audio/wav';
if (!currCallbackWithBlob) throw new Error('Callback not set');
worker.postMessage({
command: 'exportWAV',
type: type
});
};
this.release = function() {
this.stop();
this.clear();
this.configure = this.record = this.stop = this.clear = this.getBuffer = this.exportWAV = function () {};
source.disconnect(this.node);
this.node.onaudioprocess = null;
this.node.disconnect();
worker.terminate();
};
source.connect(this.node);
this.node.connect(this.context.destination); //this should not be necessary
};
Recorder.forceDownload = function(blob, filename){
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var link = window.document.createElement('a');
link.href = url;
link.download = filename || 'output.wav';
var click = document.createEvent("Event");
click.initEvent("click", true, true);
link.dispatchEvent(click);
};
var recorder = Recorder;
return recorder;
})));
});
/**
* @file 公共的 Web Audio API Context
* @author BenzLeung(https://github.com/BenzLeung)
* @date 2017/11/12
* Created by JetBrains PhpStorm.
*
* 每位工程师都有保持代码优雅的义务
* each engineer has a duty to keep the code elegant
*/
const AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
let ctx = null;
if (AudioContext) {
ctx = new AudioContext();
} else {
console.error(new Error('Web Audio API is Unsupported.'));
}
class RecorderControl {
constructor() {
this._recorderStream = null;
this._recorderStreamSourceNode = null;
this._recorder = null;
this._isRecording = false;
this._curSourceNode = null;
}
playPcm(samples, sampleRate, onEnded) {
sampleRate = sampleRate || 8000;
this.stopPcm();
this._curSourceNode = ctx['createBufferSource']();
let _samples = samples;
let buffer, channelBuffer;
try {
buffer = ctx['createBuffer'](1, samples.length, sampleRate);
} catch (e) {
// iOS 不支持 22050 以下的采样率,于是先提升采样率,然后用慢速播放
if (sampleRate < 11025) {
/*buffer = ctx['createBuffer'](1, samples.length * 3, sampleRate * 3);
_samples = this._increaseSampleRate(samples, 3);*/
buffer = ctx['createBuffer'](1, samples.length, sampleRate * 4);
this._curSourceNode['playbackRate'].value = 0.25;
} else {
/*buffer = ctx['createBuffer'](1, samples.length * 2, sampleRate * 2);
_samples = this._increaseSampleRate(samples, 2);*/
buffer = ctx['createBuffer'](1, samples.length, sampleRate * 2);
this._curSourceNode['playbackRate'].value = 0.5;
}
}
if (buffer['copyToChannel']) {
buffer['copyToChannel'](_samples, 0, 0);
} else {
channelBuffer = buffer['getChannelData'](0);
channelBuffer.set(_samples);
}
this._curSourceNode['buffer'] = buffer;
this._curSourceNode['loop'] = false;
this._curSourceNode['connect'](ctx['destination']);
this._curSourceNode.onended = onEnded;
this._curSourceNode.start();
}
stopPcm() {
if (this._curSourceNode) {
this._curSourceNode.stop();
this._curSourceNode = null;
}
}
initRecorder() {
return new Promise((resolve, reject) => {
let s = stream => {
this._recorderStream = stream;
this._recorderStreamSourceNode = ctx.createMediaStreamSource(stream);
this._recorder = new recorder_build(this._recorderStreamSourceNode);
this._isRecording = false;
resolve();
};
let j = e => {
reject(e);
};
if (!this._recorder) {
if (window.navigator.mediaDevices && window.navigator.mediaDevices.getUserMedia) {
window.navigator.mediaDevices.getUserMedia({
audio: true
}).then(s).catch(j);
} else if (window.navigator.getUserMedia) {
window.navigator.getUserMedia({
audio: true
}, s, j);
} else {
j();
}
} else {
resolve();
}
});
}
isRecording() {
return this._recorder && this._isRecording;
}
startRecord() {
if (this._recorder) {
this._recorder.clear();
this._recorder.record();
this._isRecording = true;
}
}
stopRecord() {
if (this._recorder) {
this._recorder.stop();
this._isRecording = false;
}
}
generateRecordSamples() {
return new Promise(resolve => {
if (this._recorder) {
this._recorder.getBuffer(buffers => {
resolve(buffers[0]);
});
}
});
}
releaseRecord() {
if (this._recorderStream && this._recorderStream.getTracks) {
this._recorderStream.getTracks().forEach(track => {
track.stop();
});
this._recorderStream = null;
}
if (this._recorder) {
this._recorder.release();
this._recorder = null;
}
}
static getCtxSampleRate() {
return ctx.sampleRate;
}
static decodeAudioArrayBufferByContext(array) {
return new Promise((resolve, reject) => {
ctx['decodeAudioData'](array, audioBuf => {
// 把多声道音频 mix 成单声道
const numberOfChannels = audioBuf.numberOfChannels;
let dest = new Float32Array(audioBuf.length);
switch (numberOfChannels) {
default:
case 1:
{
dest = audioBuf.getChannelData(0);
break;
}
case 2:
{
const left = audioBuf.getChannelData(0);
const right = audioBuf.getChannelData(1);
for (let i = 0, l = dest.length; i < l; i++) {
dest[i] = .5 * (left[i] + right[i]);
}
break;
}
case 4:
{
const left = audioBuf.getChannelData(0);
const right = audioBuf.getChannelData(1);
const sLeft = audioBuf.getChannelData(2);
const sRight = audioBuf.getChannelData(3);
for (let i = 0, l = dest.length; i < l; i++) {
dest[i] = .25 * (left[i] + right[i] + sLeft[i] + sRight[i]);
}
break;
}
case 6:
{
const left = audioBuf.getChannelData(0);
const right = audioBuf.getChannelData(1);
const center = audioBuf.getChannelData(2);
const sLeft = audioBuf.getChannelData(4);
const sRight = audioBuf.getChannelData(5);
for (let i = 0, l = dest.length; i < l; i++) {
dest[i] = 0.7071 * (left[i] + right[i]) + center[i] + 0.5 * (sLeft[i] + sRight[i]);
}
break;
}
}
resolve(dest);
}, reject);
});
}
/*
static _increaseSampleRate(samples, multiple) {
let sampleLen = samples.length;
let newSamples = new Float32Array(sampleLen * multiple);
for (let i = 0; i < sampleLen; i ++) {
for (let j = 0; j < multiple; j ++) {
newSamples[i * multiple + j] = samples[i];
}
}
return newSamples;
};
*/
}
var amrnb = function() {
var AMR = (function () {
var AMR = {
toWAV: (function (amr) {
var decoded = this._decode(amr);
if (!decoded) {
return null
}
var raw = new Uint8Array(decoded.buffer, decoded.byteOffset, decoded.byteLength);
var out = new Uint8Array(raw.length + this.WAV_HEADER_SIZE);
var offset = 0;
var write_int16 = (function (value) {
var a = new Uint8Array(2);
(new Int16Array(a.buffer))[0] = value;
out.set(a, offset);
offset += 2;
});
var write_int32 = (function (value) {
var a = new Uint8Array(4);
(new Int32Array(a.buffer))[0] = value;
out.set(a, offset);
offset += 4;
});
var write_string = (function (value) {
var d = (new TextEncoder("utf-8")).encode(value);
out.set(d, offset);
offset += d.length;
});
write_string("RIFF");
write_int32(4 + 8 + 16 + 8 + raw.length);
write_string("WAVEfmt ");
write_int32(16);
var bits_per_sample = 16;
var sample_rate = 8e3;
var channels = 1;
var bytes_per_frame = bits_per_sample / 8 * channels;
var bytes_per_sec = bytes_per_frame * sample_rate;
write_int16(1);
write_int16(1);
write_int32(sample_rate);
write_int32(bytes_per_sec);
write_int16(bytes_per_frame);
write_int16(bits_per_sample);
write_string("data");
write_int32(raw.length);
out.set(raw, offset);
return out
}),
decode: (function (amr) {
var raw = this._decode(amr);
if (!raw) {
return null
}
var out = new Float32Array(raw.length);
for (var i = 0; i < out.length; i++) {
out[i] = raw[i] / 32768;
}
return out
}),
_decode: (function (amr) {
if (String.fromCharCode.apply(null, amr.subarray(0, this.AMR_HEADER.length)) !== this.AMR_HEADER) {
return null
}
var decoder = this.Decoder_Interface_init();
if (!decoder) {
return null
}
var out = new Int16Array(Math.floor(amr.length / 6 * this.PCM_BUFFER_COUNT));
var buf = Module._malloc(this.AMR_BUFFER_COUNT);
var decodeInBuffer = new Uint8Array(Module.HEAPU8.buffer, buf, this.AMR_BUFFER_COUNT);
buf = Module._malloc(this.PCM_BUFFER_COUNT * 2);
var decodeOutBuffer = new Int16Array(Module.HEAPU8.buffer, buf, this.PCM_BUFFER_COUNT);
var inOffset = 6;
var outOffset = 0;
while (inOffset + 1 < amr.length && outOffset + 1 < out.length) {
var size = this.SIZES[amr[inOffset] >> 3 & 15];
if (inOffset + size + 1 > amr.length) {
break
}
decodeInBuffer.set(amr.subarray(inOffset, inOffset + size + 1));
this.Decoder_Interface_Decode(decoder, decodeInBuffer.byteOffset, decodeOutBuffer.byteOffset, 0);
if (outOffset + this.PCM_BUFFER_COUNT > out.length) {
var newOut = new Int16Array(out.length * 2);
newOut.set(out.subarray(0, outOffset));
out = newOut;
}
out.set(decodeOutBuffer, outOffset);
outOffset += this.PCM_BUFFER_COUNT;
inOffset += size + 1;
}
Module._free(decodeInBuffer.byteOffset);
Module._free(decodeOutBuffer.byteOffset);
this.Decoder_Interface_exit(decoder);
return out.subarray(0, outOffset)
}),
encode: (function (pcm, pcmSampleRate, mode) {
if (pcmSampleRate < 8e3) {
console.error("pcmSampleRate should not be less than 8000.");
return null
}
if (typeof mode === "undefined") {
mode = this.Mode.MR795;
}
var encoder = this.Encoder_Interface_init();
if (!encoder) {
return null
}
var buf = Module._malloc(this.PCM_BUFFER_COUNT * 2);
var encodeInBuffer = new Int16Array(Module.HEAPU8.buffer, buf, this.PCM_BUFFER_COUNT);
buf = Module._malloc(this.AMR_BUFFER_COUNT);
var encodeOutBuffer = new Uint8Array(Module.HEAPU8.buffer, buf, this.AMR_BUFFER_COUNT);
var ratio = pcmSampleRate / 8e3;
var inLength = Math.floor(pcm.length / ratio);
var inData = new Int16Array(inLength);
for (var i = 0; i < inLength; i++) {
inData[i] = pcm[Math.floor(i * ratio)] * (32768 - 1);
}
var blockSize = this.SIZES[mode] + 1;
var out = new Uint8Array(Math.ceil(inLength / this.PCM_BUFFER_COUNT * blockSize) + this.AMR_HEADER.length);
out.set((new TextEncoder("utf-8")).encode(this.AMR_HEADER));
var inOffset = 0;
var outOffset = this.AMR_HEADER.length;
while (inOffset + this.PCM_BUFFER_COUNT < inData.length && outOffset + blockSize < out.length) {
encodeInBuffer.set(inData.subarray(inOffset, inOffset + this.PCM_BUFFER_COUNT));
var n = this.Encoder_Interface_Encode(encoder, mode, encodeInBuffer.byteOffset, encodeOutBuffer.byteOffset, 0);
if (n != blockSize) {
console.error([n, blockSize]);
break
}
out.set(encodeOutBuffer.subarray(0, n), outOffset);
inOffset += this.PCM_BUFFER_COUNT;
outOffset += n;
}
Module._free(encodeInBuffer.byteOffset);
Module._free(encodeOutBuffer.byteOffset);
this.Encoder_Interface_exit(encoder);
return out.subarray(0, outOffset)
}),
Decoder_Interface_init: (function () {
console.warn("Decoder_Interface_init not initialized.");
return 0
}),
Decoder_Interface_exit: (function (state) {
console.warn("Decoder_Interface_exit not initialized.");
}),
Decoder_Interface_Decode: (function (state, inBuffer, outBuffer, bfi) {
console.warn("Decoder_Interface_Decode not initialized.");
}),
Encoder_Interface_init: (function (dtx) {
console.warn("Encoder_Interface_init not initialized.");
return 0
}),
Encoder_Interface_exit: (function (state) {
console.warn("Encoder_Interface_exit not initialized.");
}),
Encoder_Interface_Encode: (function (state, mode, speech, out, forceSpeech) {
console.warn("Encoder_Interface_Encode not initialized.");
}),
Mode: {MR475: 0, MR515: 1, MR59: 2, MR67: 3, MR74: 4, MR795: 5, MR102: 6, MR122: 7, MRDTX: 8},
SIZES: [12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0],
AMR_BUFFER_COUNT: 32,
PCM_BUFFER_COUNT: 160,
AMR_HEADER: "#!AMR\n",
WAV_HEADER_SIZE: 44
};
var Module = {
canvas: {}, print: (function (text) {
console.log(text);
}), _main: (function () {
AMR.Decoder_Interface_init = Module._Decoder_Interface_init;
AMR.Decoder_Interface_exit = Module._Decoder_Interface_exit;
AMR.Decoder_Interface_Decode = Module._Decoder_Interface_Decode;
AMR.Encoder_Interface_init = Module._Encoder_Interface_init;
AMR.Encoder_Interface_exit = Module._Encoder_Interface_exit;
AMR.Encoder_Interface_Encode = Module._Encoder_Interface_Encode;
return 0
})
};
var Module;
if (!Module) Module = (typeof Module !== "undefined" ? Module : null) || {};
var moduleOverrides = {};
for (var key in Module) {
if (Module.hasOwnProperty(key)) {
moduleOverrides[key] = Module[key];
}
}
var ENVIRONMENT_IS_WEB = typeof window === "object";
var ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
var ENVIRONMENT_IS_NODE = false;/*typeof process === "object" && typeof require === "function" && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;*/
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
if (ENVIRONMENT_IS_SHELL) {
if (!Module["print"]) Module["print"] = print;
if (typeof printErr != "undefined") Module["printErr"] = printErr;
if (typeof read != "undefined") {
Module["read"] = read;
} else {
Module["read"] = function read() {
throw"no read() available (jsc?)"
};
}
Module["readBinary"] = function readBinary(f) {
if (typeof readbuffer === "function") {
return new Uint8Array(readbuffer(f))
}
var data = read(f, "binary");
assert(typeof data === "object");
return data
};
if (typeof scriptArgs != "undefined") {
Module["arguments"] = scriptArgs;
} else if (typeof arguments != "undefined") {
Module["arguments"] = arguments;
}
} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
Module["read"] = function read(url) {
var xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
xhr.send(null);
return xhr.responseText
};
if (typeof arguments != "undefined") {
Module["arguments"] = arguments;
}
if (typeof console !== "undefined") {
if (!Module["print"]) Module["print"] = function print(x) {
console.log(x);
};
if (!Module["printErr"]) Module["printErr"] = function printErr(x) {
console.log(x);
};
} else {
var TRY_USE_DUMP = false;
if (!Module["print"]) Module["print"] = TRY_USE_DUMP && typeof dump !== "undefined" ? (function (x) {
dump(x);
}) : (function (x) {
});
}
if (ENVIRONMENT_IS_WORKER) {
Module["load"] = importScripts;
}
if (typeof Module["setWindowTitle"] === "undefined") {
Module["setWindowTitle"] = (function (title) {
document.title = title;
});
}
} else {
throw"Unknown runtime environment. Where are we?"
}
function globalEval(x) {
eval.call(null, x);
}
if (!Module["load"] && Module["read"]) {
Module["load"] = function load(f) {
globalEval(Module["read"](f));
};
}
if (!Module["print"]) {
Module["print"] = (function () {
});
}
if (!Module["printErr"]) {
Module["printErr"] = Module["print"];
}
if (!Module["arguments"]) {
Module["arguments"] = [];
}
if (!Module["thisProgram"]) {
Module["thisProgram"] = "./this.program";
}
Module.print = Module["print"];
Module.printErr = Module["printErr"];
Module["preRun"] = [];
Module["postRun"] = [];
for (var key in moduleOverrides) {
if (moduleOverrides.hasOwnProperty(key)) {
Module[key] = moduleOverrides[key];
}
}
var Runtime = {
setTempRet0: (function (value) {
tempRet0 = value;
}), getTempRet0: (function () {
return tempRet0
}), stackSave: (function () {
return STACKTOP
}), stackRestore: (function (stackTop) {
STACKTOP = stackTop;
}), getNativeTypeSize: (function (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 Runtime.QUANTUM_SIZE
} else if (type[0] === "i") {
var bits = parseInt(type.substr(1));
assert(bits % 8 === 0);
return bits / 8
} else {
return 0
}
}
}
}), getNativeFieldSize: (function (type) {
return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE)
}), STACK_ALIGN: 16, prepVararg: (function (ptr, type) {
if (type === "double" || type === "i64") {
if (ptr & 7) {
assert((ptr & 7) === 4);
ptr += 4;
}
} else {
assert((ptr & 3) === 0);
}
return ptr
}), getAlignSize: (function (type, size, vararg) {
if (!vararg && (type == "i64" || type == "double")) return 8;
if (!type) return Math.min(size, 8);
return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE)
}), dynCall: (function (sig, ptr, args) {
if (args && args.length) {
if (!args.splice) args = Array.prototype.slice.call(args);
args.splice(0, 0, ptr);
return Module["dynCall_" + sig].apply(null, args)
} else {
return Module["dynCall_" + sig].call(null, ptr)
}
}), functionPointers: [], addFunction: (function (func) {
for (var i = 0; i < Runtime.functionPointers.length; i++) {
if (!Runtime.functionPointers[i]) {
Runtime.functionPointers[i] = func;
return 2 * (1 + i)
}
}
throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."
}), removeFunction: (function (index) {
Runtime.functionPointers[(index - 2) / 2] = null;
}), warnOnce: (function (text) {
if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
if (!Runtime.warnOnce.shown[text]) {
Runtime.warnOnce.shown[text] = 1;
Module.printErr(text);
}
}), funcWrappers: {}, getFuncWrapper: (function (func, sig) {
assert(sig);
if (!Runtime.funcWrappers[sig]) {
Runtime.funcWrappers[sig] = {};
}
var sigCache = Runtime.funcWrappers[sig];
if (!sigCache[func]) {
sigCache[func] = function dynCall_wrapper() {
return Runtime.dynCall(sig, func, arguments)
};
}
return sigCache[func]
}), getCompilerSetting: (function (name) {
throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"
}), stackAlloc: (function (size) {
var ret = STACKTOP;
STACKTOP = STACKTOP + size | 0;
STACKTOP = STACKTOP + 15 & -16;
return ret
}), staticAlloc: (function (size) {
var ret = STATICTOP;
STATICTOP = STATICTOP + size | 0;
STATICTOP = STATICTOP + 15 & -16;
return ret
}), dynamicAlloc: (function (size) {
var ret = DYNAMICTOP;
DYNAMICTOP = DYNAMICTOP + size | 0;
DYNAMICTOP = DYNAMICTOP + 15 & -16;
if (DYNAMICTOP >= TOTAL_MEMORY) {
var success = enlargeMemory();
if (!success) {
DYNAMICTOP = ret;
return 0
}
}
return ret
}), alignMemory: (function (size, quantum) {
var ret = size = Math.ceil(size / (quantum ? quantum : 16)) * (quantum ? quantum : 16);
return ret
}), makeBigInt: (function (low, high, unsigned) {
var ret = unsigned ? +(low >>> 0) + +(high >>> 0) * +4294967296 : +(low >>> 0) + +(high | 0) * +4294967296;
return ret
}), GLOBAL_BASE: 8, QUANTUM_SIZE: 4, __dummy__: 0
};
Module["Runtime"] = Runtime;
var ABORT = false;
var tempDouble;
var tempI64;
var tempRet0;
function assert(condition, text) {
if (!condition) {
abort("Assertion failed: " + text);
}
}
function getCFunc(ident) {
var func = Module["_" + ident];
if (!func) {
try {
func = [eval][0]("_" + ident);
} catch (e) {
}
}
assert(func, "Cannot call unknown function " + ident + " (perhaps LLVM optimizations or closure removed it?)");
return func
}
var cwrap, ccall;
((function () {
var JSfuncs = {
"stackSave": (function () {
Runtime.stackSave();
}), "stackRestore": (function () {
Runtime.stackRestore();
}), "arrayToC": (function (arr) {
var ret = Runtime.stackAlloc(arr.length);
writeArrayToMemory(arr, ret);
return ret
}), "stringToC": (function (str) {
var ret = 0;
if (str !== null && str !== undefined && str !== 0) {
ret = Runtime.stackAlloc((str.length << 2) + 1);
writeStringToMemory(str, ret);
}
return ret
})
};
var toC = {"string": JSfuncs["stringToC"], "array": JSfuncs["arrayToC"]};
ccall = function ccallFunc(ident, returnType, argTypes, args, opts) {
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 = Runtime.stackSave();
cArgs[i] = converter(args[i]);
} else {
cArgs[i] = args[i];
}
}
}
var ret = func.apply(null, cArgs);
if (returnType === "string") ret = Pointer_stringify(ret);
if (stack !== 0) {
if (opts && opts.async) {
EmterpreterAsync.asyncFinalizers.push((function () {
Runtime.stackRestore(stack);
}));
return
}
Runtime.stackRestore(stack);
}
return ret
};
var sourceRegex = /^function\s\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;
function parseJSFunc(jsfunc) {
// Match the body and the return value of a javascript function source
var parsed = jsfunc.toString().match(sourceRegex);
if (!parsed) { return {}; }
parsed = parsed.slice(1);
return {arguments: parsed[0], body: parsed[1], returnValue: parsed[2]}
}
var JSsource = {};
for (var fun in JSfuncs) {
if (JSfuncs.hasOwnProperty(fun)) {
JSsource[fun] = parseJSFunc(JSfuncs[fun]);
}
}
cwrap = function cwrap(ident, returnType, argTypes) {
argTypes = argTypes || [];
var cfunc = getCFunc(ident);
var numericArgs = argTypes.every((function (type) {
return type === "number"
}));
var numericRet = returnType !== "string";
if (numericRet && numericArgs) {
return cfunc
}
var argNames = argTypes.map((function (x, i) {
return "$" + i
}));
var funcstr = "(function(" + argNames.join(",") + ") {";
var nargs = argTypes.length;
if (!numericArgs) {
funcstr += "var stack = " + JSsource["stackSave"].body + ";";
for (var i = 0; i < nargs; i++) {
var arg = argNames[i], type = argTypes[i];
if (type === "number") continue;
var convertCode = JSsource[type + "ToC"];
funcstr += "var " + convertCode.arguments + " = " + arg + ";";
funcstr += convertCode.body + ";";
funcstr += arg + "=" + convertCode.returnValue + ";";
}
}
var cfuncname = parseJSFunc((function () {
return cfunc
})).returnValue;
funcstr += "var ret = " + cfuncname + "(" + argNames.join(",") + ");";
if (!numericRet) {
var strgfy = parseJSFunc((function () {
return Pointer_stringify
})).returnValue;
funcstr += "ret = " + strgfy + "(ret);";
}
if (!numericArgs) {
funcstr += JSsource["stackRestore"].body.replace("()", "(stack)") + ";";
}
funcstr += "return ret})";
return [eval][0](funcstr)
};
}))();
Module["ccall"] = ccall;
Module["cwrap"] = cwrap;
function setValue(ptr, value, type, noSafe) {
type = type || "i8";
if (type.charAt(type.length - 1) === "*") type = "i32";
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 ? tempDouble > +0 ? (Math_min(+Math_floor(tempDouble / +4294967296), +4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / +4294967296) >>> 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);
}
}
Module["setValue"] = setValue;
function getValue(ptr, type, noSafe) {
type = type || "i8";
if (type.charAt(type.length - 1) === "*") type = "i32";
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 setValue: " + type);
}
return null
}
Module["getValue"] = getValue;
var ALLOC_NORMAL = 0;
var ALLOC_STACK = 1;
var ALLOC_STATIC = 2;
var ALLOC_DYNAMIC = 3;
var ALLOC_NONE = 4;
Module["ALLOC_NORMAL"] = ALLOC_NORMAL;
Module["ALLOC_STACK"] = ALLOC_STACK;
Module["ALLOC_STATIC"] = ALLOC_STATIC;
Module["ALLOC_DYNAMIC"] = ALLOC_DYNAMIC;
Module["ALLOC_NONE"] = ALLOC_NONE;
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, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
}
if (zeroinit) {
var ptr = ret, stop;
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(slab, ret);
} else {
HEAPU8.set(new Uint8Array(slab), ret);
}
return ret
}
var i = 0, type, typeSize, previousType;
while (i < size) {
var curr = slab[i];
if (typeof curr === "function") {
curr = Runtime.getFunctionIndex(curr);
}
type = singleType || types[i];
if (type === 0) {
i++;
continue
}
if (type == "i64") type = "i32";
setValue(ret + i, curr, type);
if (previousType !== type) {
typeSize = Runtime.getNativeTypeSize(type);
previousType = type;
}
i += typeSize;
}
return ret
}
Module["allocate"] = allocate;
function getMemory(size) {
if (!staticSealed) return Runtime.staticAlloc(size);
if (typeof _sbrk !== "undefined" && !_sbrk.called || !runtimeInitialized) return Runtime.dynamicAlloc(size);
return _malloc(size)
}
Module["getMemory"] = getMemory;
function Pointer_stringify(ptr, length) {
if (length === 0 || !ptr) return "";
var hasUtf = 0;
var t;
var i = 0;
while (1) {
t = HEAPU8[ptr + i >> 0];
hasUtf |= t;
if (t == 0 && !length) break;
i++;
if (length && i == length) break
}
if (!length) length = i;
var ret = "";
if (hasUtf < 128) {
var MAX_CHUNK = 1024;
var curr;
while (length > 0) {
curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
ret = ret ? ret + curr : curr;
ptr += MAX_CHUNK;
length -= MAX_CHUNK;
}
return ret
}
return Module["UTF8ToString"](ptr)
}
Module["Pointer_stringify"] = Pointer_stringify;
function AsciiToString(ptr) {
var str = "";
while (1) {
var ch = HEAP8[ptr++ >> 0];
if (!ch) return str;
str += String.fromCharCode(ch);
}
}
Module["AsciiToString"] = AsciiToString;
function stringToAscii(str, outPtr) {
return writeAsciiToMemory(str, outPtr, false)
}
Module["stringToAscii"] = stringToAscii;
function UTF8ArrayToString(u8Array, idx) {
var u0, u1, u2, u3, u4, u5;
var str = "";
while (1) {
u0 = u8Array[idx++];
if (!u0) return str;
if (!(u0 & 128)) {
str += String.fromCharCode(u0);
continue
}
u1 = u8Array[idx++] & 63;
if ((u0 & 224) == 192) {
str += String.fromCharCode((u0 & 31) << 6 | u1);
continue
}
u2 = u8Array[idx++] & 63;
if ((u0 & 240) == 224) {
u0 = (u0 & 15) << 12 | u1 << 6 | u2;
} else {
u3 = u8Array[idx++] & 63;
if ((u0 & 248) == 240) {
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | u3;
} else {
u4 = u8Array[idx++] & 63;
if ((u0 & 252) == 248) {
u0 = (u0 & 3) << 24 | u1 << 18 | u2 << 12 | u3 << 6 | u4;
} else {
u5 = u8Array[idx++] & 63;
u0 = (u0 & 1) << 30 | u1 << 24 | u2 << 18 | u3 << 12 | u4 << 6 | u5;
}
}
}
if (u0 < 65536) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 65536;
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
}
}
}
Module["UTF8ArrayToString"] = UTF8ArrayToString;
function UTF8ToString(ptr) {
return UTF8ArrayToString(HEAPU8, ptr)
}
Module["UTF8ToString"] = UTF8ToString;
function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {
if (!(maxBytesToWrite > 0)) return 0;
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
if (u <= 127) {
if (outIdx >= endIdx) break;
outU8Array[outIdx++] = u;
} else if (u <= 2047) {
if (outIdx + 1 >= endIdx) break;
outU8Array[outIdx++] = 192 | u >> 6;
outU8Array[outIdx++] = 128 | u & 63;
} else if (u <= 65535) {
if (outIdx + 2 >= endIdx) break;
outU8Array[outIdx++] = 224 | u >> 12;
outU8Array[outIdx++] = 128 | u >> 6 & 63;
outU8Array[outIdx++] = 128 | u & 63;
} else if (u <= 2097151) {
if (outIdx + 3 >= endIdx) break;
outU8Array[outIdx++] = 240 | u >> 18;
outU8Array[outIdx++] = 128 | u >> 12 & 63;
outU8Array[outIdx++] = 128 | u >> 6 & 63;
outU8Array[outIdx++] = 128 | u & 63;
} else if (u <= 67108863) {
if (outIdx + 4 >= endIdx) break;
outU8Array[outIdx++] = 248 | u >> 24;
outU8Array[outIdx++] = 128 | u >> 18 & 63;
outU8Array[outIdx++] = 128 | u >> 12 & 63;
outU8Array[outIdx++] = 128 | u >> 6 & 63;
outU8Array[outIdx++] = 128 | u & 63;
} else {
if (outIdx + 5 >= endIdx) break;
outU8Array[outIdx++] = 252 | u >> 30;
outU8Array[outIdx++] = 128 | u >> 24 & 63;
outU8Array[outIdx++] = 128 | u >> 18 & 63;
outU8Array[outIdx++] = 128 | u >> 12 & 63;
outU8Array[outIdx++] = 128 | u >> 6 & 63;
outU8Array[outIdx++] = 128 | u & 63;
}
}
outU8Array[outIdx] = 0;
return outIdx - startIdx
}
Module["stringToUTF8Array"] = stringToUTF8Array;
function stringToUTF8(str, outPtr, maxBytesToWrite) {
return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite)
}
Module["stringToUTF8"] = stringToUTF8;
function lengthBytesUTF8(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
if (u <= 127) {
++len;
} else if (u <= 2047) {
len += 2;
} else if (u <= 65535) {
len += 3;
} else if (u <= 2097151) {
len += 4;
} else if (u <= 67108863) {
len += 5;
} else {
len += 6;
}
}
return len
}
Module["lengthBytesUTF8"] = lengthBytesUTF8;
function UTF16ToString(ptr) {
var i = 0;
var str = "";
while (1) {
var codeUnit = HEAP16[ptr + i * 2 >> 1];
if (codeUnit == 0) return str;
++i;
str += String.fromCharCode(codeUnit);
}
}
Module["UTF16ToString"] = UTF16ToString;
function stringToUTF16(str, outPtr, maxBytesToWrite) {
if (maxBytesToWrite === undefined) {
maxBy