romdevtools 0.84.0 → 0.84.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ All notable changes to `romdevtools`. Dates are release dates.
4
4
  (Published as `romdev-mcp` through 0.11.0; renamed to `romdevtools` in 0.13.0 —
5
5
  the `romdev-mcp` bin is kept as an alias.)
6
6
 
7
+ ## 0.84.1 — 2026-06-30
8
+
9
+ - **New package `romdev-audio-resampler`** — the WASM+SIMD linear audio resampler (interleaved
10
+ S16LE stereo, any src→dst rate) is carved out of `src/playtest/resampler/` into its own
11
+ standalone, zero-dep npm package so other projects can consume it (retroemu's terminal audio
12
+ path needs it to resample fractional-rate cores like the GameTank ACP's ~13983 Hz up to a
13
+ fixed device rate — the way a libretro frontend does). romdevtools now depends on it; the
14
+ playtest audio sink imports it instead of the in-tree copy. No behavior change here.
15
+
7
16
  ## 0.84.0 — 2026-06-30
8
17
 
9
18
  **The 3D GL cores are now PLAYABLE in the SDL playtest window — N64 + PS1 at full speed.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "romdevtools",
3
- "version": "0.84.0",
3
+ "version": "0.84.1",
4
4
  "description": "Tool server giving coding agents full control of homebrew ROM development AND reverse-engineering/romhacking across 17 retro platforms (NES, SNES, GB, Genesis, Atari, C64, PC Engine, MSX, PlayStation, N64, Dreamcast, ...) via WASM toolchains + emulator cores. Use over plain HTTP, as an Agent Skill, or as an MCP server.",
5
5
  "type": "module",
6
6
  "main": "src/mcp/server.js",
@@ -52,16 +52,17 @@
52
52
  "pngjs": "^7.0.0",
53
53
  "romdev-analysis": "0.1.0",
54
54
  "romdev-analysis-decompiler": "0.1.0",
55
+ "romdev-audio-resampler": "0.1.0",
56
+ "romdev-core-beetle-psx-hw": "0.2.0",
55
57
  "romdev-core-bluemsx": "0.7.0",
56
58
  "romdev-core-fceumm": "0.11.0",
59
+ "romdev-core-flycast": "0.2.0",
57
60
  "romdev-core-gambatte": "0.10.0",
61
+ "romdev-core-gametank": "0.1.0",
58
62
  "romdev-core-geargrafx": "0.8.0",
59
63
  "romdev-core-gpgx": "0.13.0",
60
64
  "romdev-core-handy": "0.8.0",
61
- "romdev-core-gametank": "0.1.0",
62
- "romdev-core-flycast": "0.2.0",
63
65
  "romdev-core-parallel-n64": "0.2.0",
64
- "romdev-core-beetle-psx-hw": "0.2.0",
65
66
  "romdev-core-prosystem": "0.9.0",
66
67
  "romdev-core-vice": "0.10.0",
67
68
  "romdev-famitone": "0.1.0",
@@ -9,7 +9,7 @@ import {
9
9
  ROMDEV_PIXEL_FORMAT_RGBA8888,
10
10
  } from "../host/retroConstants.js";
11
11
  import { log } from "../mcp/log.js";
12
- import { initResampler, resampleS16Stereo } from "./resampler/index.mjs";
12
+ import { initResampler, resampleS16Stereo } from "romdev-audio-resampler";
13
13
  import path from "node:path";
14
14
  import { existsSync, writeFileSync, renameSync, mkdirSync } from "node:fs";
15
15
  import { execFile } from "node:child_process";
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Build the WASM+SIMD audio resampler for the playtest sink.
3
- # Mirrors simdpipe's emcc style (-O3 -msimd128, MODULARIZE ES6). Single-thread,
4
- # small heap (audio chunks are a few KB). Output: resampler.mjs + resampler.wasm.
5
- set -euo pipefail
6
- cd "$(dirname "$0")"
7
-
8
- source "$HOME/code/mine/emsdk/emsdk_env.sh" >/dev/null 2>&1 || true
9
-
10
- emcc resampler.c \
11
- -O3 -msimd128 -ffast-math \
12
- -s WASM=1 -s MODULARIZE=1 -s EXPORT_ES6=1 \
13
- -s ENVIRONMENT=node,web,worker \
14
- -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=4194304 \
15
- -s EXPORTED_RUNTIME_METHODS='["HEAP16","HEAPU8","cwrap","ccall"]' \
16
- -s EXPORTED_FUNCTIONS='["_rs_alloc","_rs_free","_rs_resample","_malloc","_free"]' \
17
- -o resampler.mjs
18
-
19
- echo "built resampler.mjs + resampler.wasm ($(stat -c%s resampler.wasm 2>/dev/null || echo '?') bytes)"
@@ -1,75 +0,0 @@
1
- /* ── resampler/index.mjs — JS wrapper for the WASM+SIMD audio resampler ────────
2
- *
3
- * Loads the WASM module once and exposes resampleS16Stereo(buf, src, dst) that
4
- * resamples an interleaved S16LE stereo Node Buffer. Used by the playtest audio
5
- * sink for low-rate cores (the GameTank ACP at ~13983 Hz) — see resampler.c for
6
- * the why (libretro frontends resample; only GameTank is low enough to need it).
7
- *
8
- * The WASM scratch buffers are sized once to the largest chunk seen and reused.
9
- */
10
- import path from "node:path";
11
- import { fileURLToPath } from "node:url";
12
-
13
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
-
15
- let mod = null; // the emscripten Module
16
- let inPtr = 0, inCap = 0; // input scratch (bytes)
17
- let outPtr = 0, outCap = 0; // output scratch (bytes)
18
-
19
- /** Lazily instantiate the WASM module. Returns true once ready, false if it
20
- * failed to load (caller falls back to passing audio through unresampled). */
21
- export async function initResampler() {
22
- if (mod) return true;
23
- try {
24
- const factory = (await import(path.join(__dirname, "resampler.mjs"))).default;
25
- mod = await factory();
26
- return true;
27
- } catch (e) {
28
- mod = null;
29
- return false;
30
- }
31
- }
32
-
33
- function ensureCap(needIn, needOut) {
34
- if (needIn > inCap) {
35
- if (inPtr) mod._rs_free(inPtr);
36
- inCap = needIn * 2; // grow with headroom
37
- inPtr = mod._rs_alloc(inCap);
38
- }
39
- if (needOut > outCap) {
40
- if (outPtr) mod._rs_free(outPtr);
41
- outCap = needOut * 2;
42
- outPtr = mod._rs_alloc(outCap);
43
- }
44
- }
45
-
46
- /**
47
- * Resample an interleaved S16LE stereo Buffer from srcRate to dstRate using the
48
- * WASM+SIMD core. Synchronous; initResampler() must have resolved true first.
49
- * Falls back to returning the input unchanged if the module isn't loaded.
50
- * @param {Buffer} buf interleaved S16LE stereo at srcRate
51
- * @param {number} srcRate
52
- * @param {number} dstRate
53
- * @returns {Buffer} interleaved S16LE stereo at dstRate
54
- */
55
- export function resampleS16Stereo(buf, srcRate, dstRate) {
56
- if (!mod || srcRate === dstRate || srcRate <= 0 || dstRate <= 0) return buf;
57
- const inFrames = (buf.length / 4) | 0; // 4 bytes/stereo frame
58
- if (inFrames < 2) return buf;
59
- const maxOutFrames = Math.ceil(inFrames * (dstRate / srcRate)) + 2;
60
-
61
- ensureCap(inFrames * 4, maxOutFrames * 4);
62
-
63
- // copy input into WASM heap
64
- mod.HEAPU8.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.length), inPtr);
65
-
66
- const outFrames = mod._rs_resample(
67
- inPtr, inFrames, outPtr, maxOutFrames, srcRate, dstRate
68
- );
69
- if (outFrames <= 0) return buf;
70
-
71
- // copy result out into a fresh Buffer (the audio device owns its own memory,
72
- // and the WASM heap may move on the next call).
73
- const outBytes = outFrames * 4;
74
- return Buffer.from(new Uint8Array(mod.HEAPU8.buffer, outPtr, outBytes));
75
- }
@@ -1,129 +0,0 @@
1
- /* ── resampler.c — WASM+SIMD linear resampler for the romdev playtest audio sink ─
2
- *
3
- * Resamples interleaved S16 STEREO PCM from a source rate to a device rate.
4
- *
5
- * WHY this exists: the libretro CONTRACT is that a core declares its native audio
6
- * rate in get_system_av_info and emits raw samples at that rate; the FRONTEND is
7
- * responsible for resampling to the audio device (RetroArch does this in C with a
8
- * sinc resampler). Every romdev core sits at 31–48 kHz EXCEPT the GameTank ACP at
9
- * ~13983 Hz — 2.3x lower than the next core. At that rate SDL's fixed device
10
- * buffer (4096 samples ≈ 293 ms) starves between 60 fps ticks that each feed only
11
- * ~233 samples → clicks and pops. So the playtest sink opens the device at 48 kHz
12
- * and resamples low-rate cores up to it. Doing that per-frame in JS is wasteful;
13
- * this is the native-speed SIMD path (linear interp, 4 output frames/iteration).
14
- *
15
- * Build: see build.sh (emcc -O3 -msimd128). Exports rs_alloc/rs_free/rs_resample.
16
- *
17
- * Contract:
18
- * rs_resample(inPtr, inFrames, outPtr, outCap, srcRate, dstRate) -> outFrames
19
- * inPtr : int16_t* interleaved L,R,L,R… at srcRate (inFrames stereo frames)
20
- * outPtr : int16_t* interleaved buffer with room for outCap stereo frames
21
- * returns the number of stereo frames written (<= outCap).
22
- * The caller sizes outCap >= ceil(inFrames * dstRate/srcRate) + 1.
23
- */
24
- #include <stdint.h>
25
- #include <wasm_simd128.h>
26
- #include <emscripten.h>
27
-
28
- #define EXPORT EMSCRIPTEN_KEEPALIVE
29
-
30
- /* scratch buffers live in the WASM heap, allocated from JS via rs_alloc. */
31
- EXPORT void *rs_alloc(int bytes) { return __builtin_malloc((unsigned long)bytes); }
32
- EXPORT void rs_free(void *p) { __builtin_free(p); }
33
-
34
- /* Linear-resample interleaved S16 stereo. Returns stereo frames written.
35
- *
36
- * For output frame i: srcPos = i / ratio = i * srcRate/dstRate. We split srcPos
37
- * into integer index i0 and fraction f in [0,1): out = in[i0]*(1-f) + in[i0+1]*f
38
- * per channel. We vectorize across 4 consecutive output frames: compute their 4
39
- * srcPos in f32x4, their 4 integer indices and 4 fractions, gather the 8 source
40
- * samples (can't SIMD-gather in wasm128, so scalar gather) but do the lerp math in
41
- * SIMD. The gather dominates, but keeping the arithmetic in f32x4 + a single
42
- * saturating narrow per 4 frames is still a clear win over per-sample JS.
43
- */
44
- EXPORT int rs_resample(const int16_t *in, int inFrames,
45
- int16_t *out, int outCap,
46
- int srcRate, int dstRate) {
47
- if (inFrames < 2 || srcRate <= 0 || dstRate <= 0) return 0;
48
- if (srcRate == dstRate) {
49
- int n = inFrames < outCap ? inFrames : outCap;
50
- for (int i = 0; i < n * 2; i++) out[i] = in[i];
51
- return n;
52
- }
53
-
54
- /* step = srcRate/dstRate in source frames per output frame (fixed math in f64). */
55
- const double step = (double)srcRate / (double)dstRate;
56
- long outFrames = (long)((double)inFrames * (double)dstRate / (double)srcRate);
57
- if (outFrames > outCap) outFrames = outCap;
58
- const int maxI0 = inFrames - 2; /* so i0+1 is valid */
59
-
60
- long i = 0;
61
- /* SIMD body: 4 output frames per iteration. */
62
- for (; i + 4 <= outFrames; i += 4) {
63
- /* source positions for the 4 frames */
64
- double p0 = (double)(i + 0) * step;
65
- double p1 = (double)(i + 1) * step;
66
- double p2 = (double)(i + 2) * step;
67
- double p3 = (double)(i + 3) * step;
68
-
69
- int i0_0 = (int)p0, i0_1 = (int)p1, i0_2 = (int)p2, i0_3 = (int)p3;
70
- if (i0_0 > maxI0) i0_0 = maxI0; if (i0_1 > maxI0) i0_1 = maxI0;
71
- if (i0_2 > maxI0) i0_2 = maxI0; if (i0_3 > maxI0) i0_3 = maxI0;
72
-
73
- /* fractions as f32x4 */
74
- v128_t frac = wasm_f32x4_make((float)(p0 - i0_0), (float)(p1 - i0_1),
75
- (float)(p2 - i0_2), (float)(p3 - i0_3));
76
- v128_t inv = wasm_f32x4_sub(wasm_f32x4_splat(1.0f), frac);
77
-
78
- /* gather the 8 source samples per channel (scalar — no wasm128 gather). */
79
- v128_t l0 = wasm_f32x4_make((float)in[(i0_0*2)], (float)in[(i0_1*2)],
80
- (float)in[(i0_2*2)], (float)in[(i0_3*2)]);
81
- v128_t l1 = wasm_f32x4_make((float)in[(i0_0*2)+2], (float)in[(i0_1*2)+2],
82
- (float)in[(i0_2*2)+2], (float)in[(i0_3*2)+2]);
83
- v128_t r0 = wasm_f32x4_make((float)in[(i0_0*2)+1], (float)in[(i0_1*2)+1],
84
- (float)in[(i0_2*2)+1], (float)in[(i0_3*2)+1]);
85
- v128_t r1 = wasm_f32x4_make((float)in[(i0_0*2)+3], (float)in[(i0_1*2)+3],
86
- (float)in[(i0_2*2)+3], (float)in[(i0_3*2)+3]);
87
-
88
- /* lerp: l = l0*inv + l1*frac */
89
- v128_t lo = wasm_f32x4_add(wasm_f32x4_mul(l0, inv), wasm_f32x4_mul(l1, frac));
90
- v128_t ro = wasm_f32x4_add(wasm_f32x4_mul(r0, inv), wasm_f32x4_mul(r1, frac));
91
-
92
- /* round to nearest, convert to i32, store interleaved. */
93
- v128_t half = wasm_f32x4_splat(0.5f);
94
- v128_t lneg = wasm_f32x4_lt(lo, wasm_f32x4_splat(0.0f));
95
- v128_t rneg = wasm_f32x4_lt(ro, wasm_f32x4_splat(0.0f));
96
- lo = wasm_f32x4_add(lo, wasm_v128_bitselect(wasm_f32x4_splat(-0.5f), half, lneg));
97
- ro = wasm_f32x4_add(ro, wasm_v128_bitselect(wasm_f32x4_splat(-0.5f), half, rneg));
98
- v128_t li = wasm_i32x4_trunc_sat_f32x4(lo);
99
- v128_t ri = wasm_i32x4_trunc_sat_f32x4(ro);
100
-
101
- int li_[4], ri_[4];
102
- wasm_v128_store(li_, li);
103
- wasm_v128_store(ri_, ri);
104
- for (int k = 0; k < 4; k++) {
105
- int lv = li_[k], rv = ri_[k];
106
- if (lv > 32767) lv = 32767; else if (lv < -32768) lv = -32768;
107
- if (rv > 32767) rv = 32767; else if (rv < -32768) rv = -32768;
108
- out[(i + k) * 2] = (int16_t)lv;
109
- out[(i + k) * 2 + 1] = (int16_t)rv;
110
- }
111
- }
112
-
113
- /* scalar tail */
114
- for (; i < outFrames; i++) {
115
- double p = (double)i * step;
116
- int i0 = (int)p; if (i0 > maxI0) i0 = maxI0;
117
- float f = (float)(p - i0), invf = 1.0f - f;
118
- float l = in[i0*2] * invf + in[(i0+1)*2] * f;
119
- float r = in[i0*2+1] * invf + in[(i0+1)*2+1] * f;
120
- int lv = (int)(l < 0 ? l - 0.5f : l + 0.5f);
121
- int rv = (int)(r < 0 ? r - 0.5f : r + 0.5f);
122
- if (lv > 32767) lv = 32767; else if (lv < -32768) lv = -32768;
123
- if (rv > 32767) rv = 32767; else if (rv < -32768) rv = -32768;
124
- out[i*2] = (int16_t)lv;
125
- out[i*2+1] = (int16_t)rv;
126
- }
127
-
128
- return (int)outFrames;
129
- }
@@ -1,2 +0,0 @@
1
- async function Module(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(ENVIRONMENT_IS_NODE){const{createRequire}=await import("module");var require=createRequire(import.meta.url)}var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=import.meta.url;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");if(_scriptName.startsWith("file:")){scriptDirectory=require("path").dirname(require("url").fileURLToPath(_scriptName))+"/"}readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){if(Module["locateFile"]){return locateFile("resampler.wasm")}return new URL("resampler.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,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.codePointAt(i);if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array: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(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _rs_alloc,_malloc,_rs_free,_free,_rs_resample,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_rs_alloc=Module["_rs_alloc"]=wasmExports["d"];_malloc=Module["_malloc"]=wasmExports["e"];_rs_free=Module["_rs_free"]=wasmExports["f"];_free=Module["_free"]=wasmExports["g"];_rs_resample=Module["_rs_resample"]=wasmExports["h"];__emscripten_stack_restore=wasmExports["i"];__emscripten_stack_alloc=wasmExports["j"];_emscripten_stack_get_current=wasmExports["k"];memory=wasmMemory=wasmExports["b"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={a:_emscripten_resize_heap};function run(){preRun();function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
2
- ;return moduleRtn}export default Module;