@sliverp/qqbot 1.4.2 → 1.4.4

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.
Files changed (42) hide show
  1. package/README.md +32 -1
  2. package/node_modules/silk-wasm/LICENSE +21 -0
  3. package/node_modules/silk-wasm/README.md +85 -0
  4. package/node_modules/silk-wasm/lib/index.cjs +16 -0
  5. package/node_modules/silk-wasm/lib/index.d.ts +70 -0
  6. package/node_modules/silk-wasm/lib/index.mjs +16 -0
  7. package/node_modules/silk-wasm/lib/silk.wasm +0 -0
  8. package/node_modules/silk-wasm/lib/utils.d.ts +4 -0
  9. package/node_modules/silk-wasm/package.json +39 -0
  10. package/package.json +17 -5
  11. package/src/gateway.ts +71 -4
  12. package/src/utils/audio-convert.ts +138 -0
  13. package/dist/index.d.ts +0 -17
  14. package/dist/index.js +0 -22
  15. package/dist/src/api.d.ts +0 -194
  16. package/dist/src/api.js +0 -555
  17. package/dist/src/channel.d.ts +0 -3
  18. package/dist/src/channel.js +0 -281
  19. package/dist/src/config.d.ts +0 -25
  20. package/dist/src/config.js +0 -156
  21. package/dist/src/gateway.d.ts +0 -18
  22. package/dist/src/gateway.js +0 -1475
  23. package/dist/src/image-server.d.ts +0 -62
  24. package/dist/src/image-server.js +0 -401
  25. package/dist/src/known-users.d.ts +0 -100
  26. package/dist/src/known-users.js +0 -264
  27. package/dist/src/onboarding.d.ts +0 -10
  28. package/dist/src/onboarding.js +0 -195
  29. package/dist/src/outbound.d.ts +0 -149
  30. package/dist/src/outbound.js +0 -476
  31. package/dist/src/proactive.d.ts +0 -170
  32. package/dist/src/proactive.js +0 -398
  33. package/dist/src/runtime.d.ts +0 -3
  34. package/dist/src/runtime.js +0 -10
  35. package/dist/src/session-store.d.ts +0 -49
  36. package/dist/src/session-store.js +0 -242
  37. package/dist/src/types.d.ts +0 -116
  38. package/dist/src/types.js +0 -1
  39. package/dist/src/utils/image-size.d.ts +0 -51
  40. package/dist/src/utils/image-size.js +0 -234
  41. package/dist/src/utils/payload.d.ts +0 -112
  42. package/dist/src/utils/payload.js +0 -186
package/README.md CHANGED
@@ -121,5 +121,36 @@ openclaw gateway
121
121
  <img width="990" height="984" alt="18" src="https://github.com/user-attachments/assets/b2776c8b-de72-4e37-b34d-e8287ce45de1" />
122
122
 
123
123
 
124
+ # Upgrade
125
+ ## Using openclaw/npm(Recommendation)
126
+
127
+ > only for installed by`openclaw plugins install`
128
+
129
+ ```
130
+ openclaw plugins upgrade @sliverp/qqbot@latest
131
+ ```
132
+
133
+ ## Using npx
134
+ ```
135
+ npx -y @sliverp/qqbot@latest upgrade
136
+ ```
137
+
138
+ ## Using resource code
139
+ ```
140
+ git clone https://github.com/sliverp/qqbot.git && cd qqbot
141
+
142
+ # run upgrade script
143
+ bash ./scripts/upgrade.sh
144
+
145
+ # re-install
146
+ clawdbot plugins install .
147
+
148
+ # re-config
149
+ clawdbot channels add --channel qqbot --token "AppID:AppSecret"
150
+
151
+ # restart gateway
152
+ clawdbot gateway restart
153
+ ```
154
+
124
155
  # Other Language README
125
- [简体中文](README.zh.md)
156
+ [简体中文](README.zh.md)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 idranme
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # silk-wasm
2
+
3
+ [![npm](https://img.shields.io/npm/v/silk-wasm?style=flat-square)](https://www.npmjs.com/package/silk-wasm)
4
+
5
+ QQ/微信语音编解码
6
+
7
+ ## API
8
+
9
+ ```ts
10
+ interface EncodeResult {
11
+ data: Uint8Array
12
+ duration: number
13
+ }
14
+
15
+ interface DecodeResult {
16
+ data: Uint8Array
17
+ duration: number
18
+ }
19
+
20
+ /**
21
+ * 编码为 SILK
22
+ * @param input WAV 或单声道 pcm_s16le 文件
23
+ * @param sampleRate `input` 的采样率,可为 8000/12000/16000/24000/32000/44100/48000,当 `input` 为 WAV 时可填入 0
24
+ * @returns SILK
25
+ */
26
+ function encode(input: ArrayBufferView | ArrayBuffer, sampleRate: number): Promise<EncodeResult>
27
+
28
+ /**
29
+ * 将 SILK 解码为 PCM
30
+ * @param input SILK 文件
31
+ * @param sampleRate `input` 的采样率
32
+ * @returns pcm_s16le
33
+ */
34
+ function decode(input: ArrayBufferView | ArrayBuffer, sampleRate: number): Promise<DecodeResult>
35
+
36
+ /**
37
+ * 获取 SILK 音频时长
38
+ * @param data SILK 文件
39
+ * @param frameMs SILK 的 frameMs,可为 20/40/60/80/100,默认为 20
40
+ * @returns 单位为毫秒的时长
41
+ */
42
+ function getDuration(data: ArrayBufferView | ArrayBuffer, frameMs?: number): number
43
+
44
+ /**
45
+ * 检测是否为 WAV 文件
46
+ * @param data 任意文件
47
+ */
48
+ function isWav(data: ArrayBufferView | ArrayBuffer): boolean
49
+
50
+ /**
51
+ * 获取 WAV 文件的信息
52
+ * @param data WAV 文件
53
+ * @returns metadata
54
+ */
55
+ function getWavFileInfo(data: ArrayBufferView | ArrayBuffer): WavFileInfo
56
+
57
+ /**
58
+ * 检测是否为 SILK 文件
59
+ * @param data 任意文件
60
+ */
61
+ function isSilk(data: ArrayBufferView | ArrayBuffer): boolean
62
+ ```
63
+
64
+ ## Example
65
+
66
+ ```ps1
67
+ ffmpeg -i canon.mp3 -ar 24000 -ac 1 -f s16le canon.pcm
68
+ ```
69
+
70
+ ```js
71
+ import { encode } from './lib/index.mjs' // use `silk-wasm` instead
72
+ import { readFile, writeFile } from 'fs/promises'
73
+
74
+ const pcm = await readFile('./testdata/canon.pcm')
75
+ const silk = await encode(pcm, 24000)
76
+ await writeFile('./test.silk', silk.data)
77
+ ```
78
+
79
+ ## Build wasm
80
+
81
+ ```
82
+ cd binding
83
+ emcmake cmake .
84
+ emmake ninja
85
+ ```
@@ -0,0 +1,16 @@
1
+ "use strict";var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod)),__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var index_exports={};__export(index_exports,{decode:()=>decode,encode:()=>encode,getDuration:()=>getDuration,getWavFileInfo:()=>getWavFileInfo2,isSilk:()=>isSilk,isWav:()=>isWav});module.exports=__toCommonJS(index_exports);var import_meta_url=require("url").pathToFileURL(__filename).href;var Module=async function(moduleArg={}){var moduleRtn,g=moduleArg,aa,q,ba=new Promise((a,b)=>{aa=a,q=b}),ca=typeof window=="object",da=typeof WorkerGlobalScope<"u",t=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";if(t){let{createRequire:a}=await import("module");var require2=a(import_meta_url)}var u=(a,b)=>{throw b},ea=import_meta_url,v="",fa,w;if(t){var fs=require2("fs"),ha=require2("path");ea.startsWith("file:")&&(v=ha.dirname(require2("url").fileURLToPath(ea))+"/"),w=a=>(a=y(a)?new URL(a):a,fs.readFileSync(a)),fa=async a=>(a=y(a)?new URL(a):a,fs.readFileSync(a,void 0)),process.argv.slice(2),u=(a,b)=>{throw process.exitCode=a,b}}else if(ca||da){try{v=new URL(".",ea).href}catch{}da&&(w=a=>{var b=new XMLHttpRequest;return b.open("GET",a,!1),b.responseType="arraybuffer",b.send(null),new Uint8Array(b.response)}),fa=async a=>{if(y(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0),e.responseType="arraybuffer",e.onload=()=>{e.status==200||e.status==0&&e.response?d(e.response):c(e.status)},e.onerror=c,e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url)}}console.log.bind(console);var A=console.error.bind(console),C,D,E=!1,ia,ja,F,G,H,I,J,ka,la,ma,na,y=a=>a.startsWith("file://");function pa(){var a=D.buffer;ja=new Int8Array(a),G=new Int16Array(a),F=new Uint8Array(a),H=new Uint16Array(a),I=new Int32Array(a),J=new Uint32Array(a),ka=new Float32Array(a),na=new Float64Array(a),la=new BigInt64Array(a),ma=new BigUint64Array(a)}var K=0,L=null;function qa(a){throw g.onAbort?.(a),a="Aborted("+a+")",A(a),E=!0,a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info."),q(a),a}var ra;async function sa(a){if(!C)try{var b=await fa(a);return new Uint8Array(b)}catch{}if(a==ra&&C)a=new Uint8Array(C);else if(w)a=w(a);else throw"both async and sync fetching of the wasm failed";return a}async function ta(a,b){try{var d=await sa(a);return await WebAssembly.instantiate(d,b)}catch(c){A(`failed to asynchronously prepare wasm: ${c}`),qa(c)}}async function ua(a){var b=ra;if(!C&&typeof WebAssembly.instantiateStreaming=="function"&&!y(b)&&!t)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){A(`wasm streaming compile failed: ${c}`),A("falling back to ArrayBuffer instantiation")}return ta(b,a)}class va{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`,this.status=a}}var wa=a=>{for(;0<a.length;)a.shift()(g)},xa=[],ya=[],za=()=>{var a=g.preRun.shift();ya.push(a)},O=!0;class Aa{constructor(a){this.I=a-24}}var Ba=0,Ca=0,Da,P=a=>{for(var b="";F[a];)b+=Da[F[a++]];return b},Q={},R={},S={},T=g.BindingError=class extends Error{constructor(a){super(a),this.name="BindingError"}},Ea=a=>{throw new T(a)};function Fa(a,b,d={}){var c=b.name;if(!a)throw new T(`type "${c}" must have a positive integer typeid pointer`);if(R.hasOwnProperty(a)){if(d.K)return;throw new T(`Cannot register type '${c}' twice`)}R[a]=b,delete S[a],Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(e=>e()))}function U(a,b,d={}){return Fa(a,b,d)}var Ga=(a,b,d)=>{switch(b){case 1:return d?c=>ja[c]:c=>F[c];case 2:return d?c=>G[c>>1]:c=>H[c>>1];case 4:return d?c=>I[c>>2]:c=>J[c>>2];case 8:return d?c=>la[c>>3]:c=>ma[c>>3];default:throw new TypeError(`invalid integer width (${b}): ${a}`)}},Ha=[],V=[],Ia=a=>{9<a&&--V[a+1]===0&&(V[a]=void 0,Ha.push(a))},Ja=a=>{if(!a)throw new T(`Cannot use deleted val. handle = ${a}`);return V[a]},Ka=a=>{switch(a){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:let b=Ha.pop()||V.length;return V[b]=a,V[b+1]=1,b}};function La(a){return this.fromWireType(J[a>>2])}var Ma={name:"emscripten::val",fromWireType:a=>{var b=Ja(a);return Ia(a),b},toWireType:(a,b)=>Ka(b),H:8,readValueFromPointer:La,G:null},Na=(a,b)=>{switch(b){case 4:return function(d){return this.fromWireType(ka[d>>2])};case 8:return function(d){return this.fromWireType(na[d>>3])};default:throw new TypeError(`invalid float width (${b}): ${a}`)}},Oa=a=>{for(;a.length;){var b=a.pop();a.pop()(b)}};function Pa(a){for(var b=1;b<a.length;++b)if(a[b]!==null&&a[b].G===void 0)return!0;return!1}var Sa=(a,b)=>{if(g[a].F===void 0){var d=g[a];g[a]=function(...c){if(!g[a].F.hasOwnProperty(c.length))throw new T(`Function '${b}' called with an invalid number of arguments (${c.length}) - expects one of (${g[a].F})!`);return g[a].F[c.length].apply(this,c)},g[a].F=[],g[a].F[d.J]=d}},Ta=(a,b,d)=>{if(g.hasOwnProperty(a)){if(d===void 0||g[a].F!==void 0&&g[a].F[d]!==void 0)throw new T(`Cannot register public name '${a}' twice`);if(Sa(a,a),g[a].F.hasOwnProperty(d))throw new T(`Cannot register multiple overloads of a function with the same number of arguments (${d})!`);g[a].F[d]=b}else g[a]=b,g[a].J=d},Ua=(a,b)=>{for(var d=[],c=0;c<a;c++)d.push(J[b+4*c>>2]);return d},Va=g.InternalError=class extends Error{constructor(a){super(a),this.name="InternalError"}},Wa=[],Xa,Ya=(a,b)=>{a=P(a);var d;if((d=Wa[b])||(Wa[b]=d=Xa.get(b)),typeof d!="function")throw new T(`unknown function pointer with signature ${a}: ${b}`);return d};class Za extends Error{}for(var ab=a=>{a=$a(a);var b=P(a);return W(a),b},bb=(a,b)=>{function d(f){e[f]||R[f]||(S[f]?S[f].forEach(d):(c.push(f),e[f]=!0))}var c=[],e={};throw b.forEach(d),new Za(`${a}: `+c.map(ab).join([", "]))},cb=(a,b)=>{function d(h){if(h=b(h),h.length!==c.length)throw new Va("Mismatched type converter count");for(var l=0;l<c.length;++l)U(c[l],h[l])}var c=[];c.forEach(h=>S[h]=a);var e=Array(a.length),f=[],m=0;a.forEach((h,l)=>{R.hasOwnProperty(h)?e[l]=R[h]:(f.push(h),Q.hasOwnProperty(h)||(Q[h]=[]),Q[h].push(()=>{e[l]=R[h],++m,m===f.length&&d(e)}))}),f.length===0&&d(e)},db=a=>{a=a.trim();let b=a.indexOf("(");return b===-1?a:a.slice(0,b)},eb=typeof TextDecoder<"u"?new TextDecoder:void 0,fb=(a=0,b=NaN)=>{var d=F,c=a+b;for(b=a;d[b]&&!(b>=c);)++b;if(16<b-a&&d.buffer&&eb)return eb.decode(d.subarray(a,b));for(c="";a<b;){var e=d[a++];if(e&128){var f=d[a++]&63;if((e&224)==192)c+=String.fromCharCode((e&31)<<6|f);else{var m=d[a++]&63;e=(e&240)==224?(e&15)<<12|f<<6|m:(e&7)<<18|f<<12|m<<6|d[a++]&63,65536>e?c+=String.fromCharCode(e):(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else c+=String.fromCharCode(e)}return c},gb=typeof TextDecoder<"u"?new TextDecoder("utf-16le"):void 0,hb=(a,b)=>{for(var d=a>>1,c=d+b/2;!(d>=c)&&H[d];)++d;if(d<<=1,32<d-a&&gb)return gb.decode(F.subarray(a,d));for(d="",c=0;!(c>=b/2);++c){var e=G[a+2*c>>1];if(e==0)break;d+=String.fromCharCode(e)}return d},ib=(a,b,d)=>{if(d??=2147483647,2>d)return 0;d-=2;var c=b;d=d<2*a.length?d/2:a.length;for(var e=0;e<d;++e)G[b>>1]=a.charCodeAt(e),b+=2;return G[b>>1]=0,b-c},jb=a=>2*a.length,kb=(a,b)=>{for(var d=0,c="";!(d>=b/4);){var e=I[a+4*d>>2];if(e==0)break;++d,65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}return c},lb=(a,b,d)=>{if(d??=2147483647,4>d)return 0;var c=b;d=c+d-4;for(var e=0;e<a.length;++e){var f=a.charCodeAt(e);if(55296<=f&&57343>=f){var m=a.charCodeAt(++e);f=65536+((f&1023)<<10)|m&1023}if(I[b>>2]=f,b+=4,b+4>d)break}return I[b>>2]=0,b-c},mb=a=>{for(var b=0,d=0;d<a.length;++d){var c=a.charCodeAt(d);55296<=c&&57343>=c&&++d,b+=4}return b},nb=0,ob=[],pb=a=>{var b=ob.length;return ob.push(a),b},qb=(a,b)=>{var d=R[a];if(d===void 0)throw a=`${b} has unknown type ${ab(a)}`,new T(a);return d},rb=(a,b)=>{for(var d=Array(a),c=0;c<a;++c)d[c]=qb(J[b+4*c>>2],`parameter ${c}`);return d},sb=(a,b,d)=>{var c=[];return a=a.toWireType(c,d),c.length&&(J[b>>2]=Ka(c)),a},X={},tb=a=>{ia=a,O||0<nb||(g.onExit?.(a),E=!0),u(a,new va(a))},ub=a=>{if(!E)try{if(a(),!(O||0<nb))try{ia=a=ia,tb(a)}catch(b){b instanceof va||b=="unwind"||u(1,b)}}catch(b){b instanceof va||b=="unwind"||u(1,b)}},vb=Array(256),Y=0;256>Y;++Y)vb[Y]=String.fromCharCode(Y);Da=vb,V.push(0,1,void 0,1,null,1,!0,1,!1,1),g.count_emval_handles=()=>V.length/2-5-Ha.length,g.noExitRuntime&&(O=g.noExitRuntime),g.printErr&&(A=g.printErr),g.wasmBinary&&(C=g.wasmBinary);var Ab={u:(a,b,d)=>{var c=new Aa(a);throw J[c.I+16>>2]=0,J[c.I+4>>2]=b,J[c.I+8>>2]=d,Ba=a,Ca++,Ba},v:()=>qa(""),l:(a,b,d)=>{b=P(b),U(a,{name:b,fromWireType:c=>c,toWireType:function(c,e){if(typeof e!="bigint"&&typeof e!="number")throw e===null?e="null":(c=typeof e,e=c==="object"||c==="array"||c==="function"?e.toString():""+e),new TypeError(`Cannot convert "${e}" to ${this.name}`);return typeof e=="number"&&(e=BigInt(e)),e},H:8,readValueFromPointer:Ga(b,d,b.indexOf("u")==-1),G:null})},o:(a,b,d,c)=>{b=P(b),U(a,{name:b,fromWireType:function(e){return!!e},toWireType:function(e,f){return f?d:c},H:8,readValueFromPointer:function(e){return this.fromWireType(F[e])},G:null})},m:a=>U(a,Ma),k:(a,b,d)=>{b=P(b),U(a,{name:b,fromWireType:c=>c,toWireType:(c,e)=>e,H:8,readValueFromPointer:Na(b,d),G:null})},c:(a,b,d,c,e,f,m)=>{var h=Ua(b,d);a=P(a),a=db(a),e=Ya(c,e),Ta(a,function(){bb(`Cannot call ${a} due to unbound types`,h)},b-1),cb(h,l=>{var k=[l[0],null].concat(l.slice(1));l=a;var p=a,z=e,n=k.length;if(2>n)throw new T("argTypes array size mismatch! Must at least get return value and 'this' types!");var B=k[1]!==null&&!1,M=Pa(k),Qa=k[0].name!=="void";z=[p,Ea,z,f,Oa,k[0],k[1]];for(var x=0;x<n-2;++x)z.push(k[x+2]);if(!M)for(x=B?1:2;x<k.length;++x)k[x].G!==null&&z.push(k[x].G);M=Pa(k),x=k.length-2;var r=[],N=["fn"];for(B&&N.push("thisWired"),n=0;n<x;++n)r.push(`arg${n}`),N.push(`arg${n}Wired`);r=r.join(","),N=N.join(","),r=`return function (${r}) {
2
+ `,M&&(r+=`var destructors = [];
3
+ `);var Ra=M?"destructors":"null",oa="humanName throwBindingError invoker fn runDestructors retType classParam".split(" ");for(B&&(r+=`var thisWired = classParam['toWireType'](${Ra}, this);
4
+ `),n=0;n<x;++n)r+=`var arg${n}Wired = argType${n}['toWireType'](${Ra}, arg${n});
5
+ `,oa.push(`argType${n}`);if(r+=(Qa||m?"var rv = ":"")+`invoker(${N});
6
+ `,M)r+=`runDestructors(destructors);
7
+ `;else for(n=B?1:2;n<k.length;++n)B=n===1?"thisWired":"arg"+(n-2)+"Wired",k[n].G!==null&&(r+=`${B}_dtor(${B});
8
+ `,oa.push(`${B}_dtor`));Qa&&(r+=`var ret = retType['fromWireType'](rv);
9
+ return ret;
10
+ `);let[yb,zb]=[oa,r+`}
11
+ `];if(k=new Function(...yb,zb)(...z),p=Object.defineProperty(k,"name",{value:p}),k=b-1,!g.hasOwnProperty(l))throw new Va("Replacing nonexistent public symbol");return g[l].F!==void 0&&k!==void 0?g[l].F[k]=p:(g[l]=p,g[l].J=k),[]})},b:(a,b,d,c,e)=>{if(b=P(b),e===-1&&(e=4294967295),e=h=>h,c===0){var f=32-8*d;e=h=>h<<f>>>f}var m=b.includes("unsigned")?function(h,l){return l>>>0}:function(h,l){return l};U(a,{name:b,fromWireType:e,toWireType:m,H:8,readValueFromPointer:Ga(b,d,c!==0),G:null})},a:(a,b,d)=>{function c(f){return new e(ja.buffer,J[f+4>>2],J[f>>2])}var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array][b];d=P(d),U(a,{name:d,fromWireType:c,H:8,readValueFromPointer:c},{K:!0})},n:(a,b)=>{b=P(b),U(a,{name:b,fromWireType:function(d){for(var c=J[d>>2],e=d+4,f,m=e,h=0;h<=c;++h){var l=e+h;(h==c||F[l]==0)&&(m=m?fb(m,l-m):"",f===void 0?f=m:(f+="\0",f+=m),m=l+1)}return W(d),f},toWireType:function(d,c){c instanceof ArrayBuffer&&(c=new Uint8Array(c));var e,f=typeof c=="string";if(!(f||ArrayBuffer.isView(c)&&c.BYTES_PER_ELEMENT==1))throw new T("Cannot pass non-string to std::string");var m;if(f)for(e=m=0;e<c.length;++e){var h=c.charCodeAt(e);127>=h?m++:2047>=h?m+=2:55296<=h&&57343>=h?(m+=4,++e):m+=3}else m=c.length;if(e=m,m=wb(4+e+1),h=m+4,J[m>>2]=e,f){if(f=h,h=e+1,e=F,0<h){h=f+h-1;for(var l=0;l<c.length;++l){var k=c.charCodeAt(l);if(55296<=k&&57343>=k){var p=c.charCodeAt(++l);k=65536+((k&1023)<<10)|p&1023}if(127>=k){if(f>=h)break;e[f++]=k}else{if(2047>=k){if(f+1>=h)break;e[f++]=192|k>>6}else{if(65535>=k){if(f+2>=h)break;e[f++]=224|k>>12}else{if(f+3>=h)break;e[f++]=240|k>>18,e[f++]=128|k>>12&63}e[f++]=128|k>>6&63}e[f++]=128|k&63}}e[f]=0}}else F.set(c,h);return d!==null&&d.push(W,m),m},H:8,readValueFromPointer:La,G(d){W(d)}})},e:(a,b,d)=>{if(d=P(d),b===2)var c=hb,e=ib,f=jb,m=h=>H[h>>1];else b===4&&(c=kb,e=lb,f=mb,m=h=>J[h>>2]);U(a,{name:d,fromWireType:h=>{for(var l=J[h>>2],k,p=h+4,z=0;z<=l;++z){var n=h+4+z*b;(z==l||m(n)==0)&&(p=c(p,n-p),k===void 0?k=p:(k+="\0",k+=p),p=n+b)}return W(h),k},toWireType:(h,l)=>{if(typeof l!="string")throw new T(`Cannot pass non-string to C++ string type ${d}`);var k=f(l),p=wb(4+k+b);return J[p>>2]=k/b,e(l,p+4,k+b),h!==null&&h.push(W,p),p},H:8,readValueFromPointer:La,G(h){W(h)}})},f:a=>{U(a,Ma)},p:(a,b)=>{b=P(b),U(a,{L:!0,name:b,H:0,fromWireType:()=>{},toWireType:()=>{}})},s:()=>{O=!1,nb=0},i:(a,b,d,c)=>(a=ob[a],b=Ja(b),a(null,b,d,c)),d:Ia,h:(a,b,d)=>{b=rb(a,b);var c=b.shift();a--;var e=`return function (obj, func, destructorsRef, args) {
12
+ `,f=0,m=[];d===0&&m.push("obj");for(var h=["retType"],l=[c],k=0;k<a;++k)m.push(`arg${k}`),h.push(`argType${k}`),l.push(b[k]),e+=` var arg${k} = argType${k}.readValueFromPointer(args${f?"+"+f:""});
13
+ `,f+=b[k].H;return e+=` var rv = ${d===1?"new func":"func.call"}(${m.join(", ")});
14
+ `,c.L||(h.push("emval_returnValue"),l.push(sb),e+=` return emval_returnValue(retType, destructorsRef, rv);
15
+ `),a=new Function(...h,e+`};
16
+ `)(...l),d=`methodCaller<(${b.map(p=>p.name).join(", ")}) => ${c.name}>`,pb(Object.defineProperty(a,"name",{value:d}))},q:a=>{9<a&&(V[a+1]+=1)},g:a=>{var b=Ja(a);Oa(b),Ia(a)},j:(a,b)=>(a=qb(a,"_emval_take_value"),a=a.readValueFromPointer(b),Ka(a)),t:(a,b)=>{if(X[a]&&(clearTimeout(X[a].id),delete X[a]),!b)return 0;var d=setTimeout(()=>{delete X[a],ub(()=>xb(a,performance.now()))},b);return X[a]={id:d,M:b},0},w:a=>{var b=F.length;if(a>>>=0,2147483648<a)return!1;for(var d=1;4>=d;d*=2){var c=b*(1+.2/d);c=Math.min(c,a+100663296);a:{c=(Math.min(2147483648,65536*Math.ceil(Math.max(a,c)/65536))-D.buffer.byteLength+65535)/65536|0;try{D.grow(c),pa();var e=1;break a}catch{}e=void 0}if(e)return!0}return!1},r:tb},Z=await async function(){function a(c){return Z=c.exports,D=Z.x,pa(),Xa=Z.D,K--,g.monitorRunDependencies?.(K),K==0&&L&&(c=L,L=null,c()),Z}K++,g.monitorRunDependencies?.(K);var b={a:Ab};if(g.instantiateWasm)return new Promise(c=>{g.instantiateWasm(b,(e,f)=>{c(a(e,f))})});ra??=g.locateFile?g.locateFile?g.locateFile("silk.wasm",v):v+"silk.wasm":new URL("silk.wasm",import_meta_url).href;try{var d=await ua(b);return a(d.instance)}catch(c){return q(c),Promise.reject(c)}}(),$a=Z.z,wb=Z.A,W=Z.B,xb=Z.C;function Bb(){function a(){if(g.calledRun=!0,!E){if(Z.y(),aa(g),g.onRuntimeInitialized?.(),g.postRun)for(typeof g.postRun=="function"&&(g.postRun=[g.postRun]);g.postRun.length;){var b=g.postRun.shift();xa.push(b)}wa(xa)}}if(0<K)L=Bb;else{if(g.preRun)for(typeof g.preRun=="function"&&(g.preRun=[g.preRun]);g.preRun.length;)za();wa(ya),0<K?L=Bb:g.setStatus?(g.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>g.setStatus(""),1),a()},1)):a()}}if(g.preInit)for(typeof g.preInit=="function"&&(g.preInit=[g.preInit]);0<g.preInit.length;)g.preInit.shift()();return Bb(),moduleRtn=ba,moduleRtn},silk_default=Module;function isWavFile(fileData){try{let chunks=unpackWavFileChunks(fileData),fmt=decodeFormatChunk(chunks.get("fmt")),data=chunks.get("data");return getWavFileType(fmt),verifyDataChunkLength(data,fmt),!0}catch{return!1}}var audioEncodingNames=["int","float"],wavFileTypeAudioEncodings=[0,0,0,1];function decodeWavFile(fileData){let chunks=unpackWavFileChunks(fileData),fmt=decodeFormatChunk(chunks.get("fmt")),data=chunks.get("data"),wavFileType=getWavFileType(fmt),audioEncoding=wavFileTypeAudioEncodings[wavFileType],wavFileTypeName=audioEncodingNames[audioEncoding]+fmt.bitsPerSample;return verifyDataChunkLength(data,fmt),{channelData:decodeDataChunk(data,fmt,wavFileType),sampleRate:fmt.sampleRate,numberOfChannels:fmt.numberOfChannels,audioEncoding,bitsPerSample:fmt.bitsPerSample,wavFileTypeName}}function unpackWavFileChunks(fileData){let dataView;fileData instanceof ArrayBuffer?dataView=new DataView(fileData):dataView=new DataView(fileData.buffer,fileData.byteOffset,fileData.byteLength);let fileLength=dataView.byteLength;if(fileLength<20)throw new Error("WAV file is too short.");if(getString(dataView,0,4)!="RIFF")throw new Error("Not a valid WAV file (no RIFF header).");let mainChunkLength=dataView.getUint32(4,!0);if(8+mainChunkLength!=fileLength)throw new Error(`Main chunk length of WAV file (${8+mainChunkLength}) does not match file size (${fileLength}).`);if(getString(dataView,8,4)!="WAVE")throw new Error("RIFF file is not a WAV file.");let chunks=new Map,fileOffset=12;for(;fileOffset<fileLength;){if(fileOffset+8>fileLength)throw new Error(`Incomplete chunk prefix in WAV file at offset ${fileOffset}.`);let chunkId=getString(dataView,fileOffset,4).trim(),chunkLength=dataView.getUint32(fileOffset+4,!0);if(fileOffset+8+chunkLength>fileLength)throw new Error(`Incomplete chunk data in WAV file at offset ${fileOffset}.`);let chunkData=new DataView(dataView.buffer,dataView.byteOffset+fileOffset+8,chunkLength);chunks.set(chunkId,chunkData);let padLength=chunkLength%2;fileOffset+=8+chunkLength+padLength}return chunks}function getString(dataView,offset,length){let a=new Uint8Array(dataView.buffer,dataView.byteOffset+offset,length);return String.fromCharCode.apply(null,a)}function getInt24(dataView,offset){let b0=dataView.getInt8(offset+2)*65536,b12=dataView.getUint16(offset,!0);return b0+b12}function decodeFormatChunk(dataView){if(!dataView)throw new Error("No format chunk found in WAV file.");if(dataView.byteLength<16)throw new Error("Format chunk of WAV file is too short.");let fmt={};return fmt.formatCode=dataView.getUint16(0,!0),fmt.numberOfChannels=dataView.getUint16(2,!0),fmt.sampleRate=dataView.getUint32(4,!0),fmt.bytesPerSec=dataView.getUint32(8,!0),fmt.bytesPerFrame=dataView.getUint16(12,!0),fmt.bitsPerSample=dataView.getUint16(14,!0),fmt}function getWavFileType(fmt){if(fmt.numberOfChannels<1||fmt.numberOfChannels>999)throw new Error("Invalid number of channels in WAV file.");let bytesPerSample=Math.ceil(fmt.bitsPerSample/8),expectedBytesPerFrame=fmt.numberOfChannels*bytesPerSample;if(fmt.formatCode==1&&fmt.bitsPerSample>=1&&fmt.bitsPerSample<=8&&fmt.bytesPerFrame==expectedBytesPerFrame)return 0;if(fmt.formatCode==1&&fmt.bitsPerSample>=9&&fmt.bitsPerSample<=16&&fmt.bytesPerFrame==expectedBytesPerFrame)return 1;if(fmt.formatCode==1&&fmt.bitsPerSample>=17&&fmt.bitsPerSample<=24&&fmt.bytesPerFrame==expectedBytesPerFrame)return 2;if(fmt.formatCode==3&&fmt.bitsPerSample==32&&fmt.bytesPerFrame==expectedBytesPerFrame)return 3;throw new Error(`Unsupported WAV file type, formatCode=${fmt.formatCode}, bitsPerSample=${fmt.bitsPerSample}, bytesPerFrame=${fmt.bytesPerFrame}, numberOfChannels=${fmt.numberOfChannels}.`)}function decodeDataChunk(data,fmt,wavFileType){switch(wavFileType){case 0:return decodeDataChunk_uint8(data,fmt);case 1:return decodeDataChunk_int16(data,fmt);case 2:return decodeDataChunk_int24(data,fmt);case 3:return decodeDataChunk_float32(data,fmt);default:throw new Error("No decoder.")}}function decodeDataChunk_int16(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=data.getInt16(offs,!0)/32768;channelData[channelNo][frameNo]=sampleValueFloat,offs+=2}return channelData}function decodeDataChunk_uint8(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=(data.getUint8(offs)-128)/128;channelData[channelNo][frameNo]=sampleValueFloat,offs+=1}return channelData}function decodeDataChunk_int24(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=getInt24(data,offs)/8388608;channelData[channelNo][frameNo]=sampleValueFloat,offs+=3}return channelData}function decodeDataChunk_float32(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=data.getFloat32(offs,!0);channelData[channelNo][frameNo]=sampleValueFloat,offs+=4}return channelData}function allocateChannelDataArrays(dataLength,fmt){let numberOfFrames=Math.floor(dataLength/fmt.bytesPerFrame),channelData=new Array(fmt.numberOfChannels);for(let channelNo=0;channelNo<fmt.numberOfChannels;channelNo++)channelData[channelNo]=new Float32Array(numberOfFrames);return channelData}function verifyDataChunkLength(data,fmt){if(!data)throw new Error("No data chunk found in WAV file.");if(data.byteLength%fmt.bytesPerFrame!=0)throw new Error("WAV file data chunk length is not a multiple of frame size.")}function getWavFileInfo(fileData){let chunks=unpackWavFileChunks(fileData),chunkInfo=getChunkInfo(chunks),fmt=decodeFormatChunk(chunks.get("fmt"));return{chunkInfo,fmt}}function getChunkInfo(chunks){let chunkInfo=[];for(let e of chunks){let ci={};ci.chunkId=e[0],ci.dataOffset=e[1].byteOffset,ci.dataLength=e[1].byteLength,chunkInfo.push(ci)}return chunkInfo.sort((e1,e2)=>e1.dataOffset-e2.dataOffset),chunkInfo}function ensureMonoPcm(channelData){let{length:numberOfChannels}=channelData;if(numberOfChannels===1)return channelData[0];let monoData=new Float32Array(channelData[0].length);for(let i=0;i<monoData.length;i++){let sum=0;for(let j=0;j<numberOfChannels;j++)sum+=channelData[j][i];monoData[i]=sum/numberOfChannels}return monoData}function ensureS16lePcm(input){let int16Array=new Int16Array(input.length);for(let offset=0;offset<input.length;offset++){let x=~~(input[offset]*32768);int16Array[offset]=x>32767?32767:x}return int16Array.buffer}function toUTF8String(input,start=0,end=input.byteLength){return new TextDecoder().decode(input.slice(start,end))}function binaryFromSource(source){return ArrayBuffer.isView(source)?source.buffer.slice(source.byteOffset,source.byteOffset+source.byteLength):source}async function encode(input,sampleRate){let instance=await silk_default(),buffer=binaryFromSource(input);if(!buffer?.byteLength)throw new Error("input data length is 0");if(isWavFile(input)){let{channelData,sampleRate:wavSampleRate}=decodeWavFile(input);sampleRate||=wavSampleRate,buffer=ensureS16lePcm(ensureMonoPcm(channelData))}let data=new Uint8Array,duration=instance.silk_encode(buffer,sampleRate,output=>{data=output.slice()});if(duration===0)throw new Error("silk encoding failure");return{data,duration}}async function decode(input,sampleRate){let instance=await silk_default(),buffer=binaryFromSource(input);if(!buffer?.byteLength)throw new Error("input data length is 0");let data=new Uint8Array,duration=instance.silk_decode(buffer,sampleRate,output=>{output.length>0&&(data=output.slice())});if(duration===0)throw new Error("silk decoding failure");return{data,duration}}function getDuration(data,frameMs=20){let buffer=binaryFromSource(data),view=new DataView(buffer),byteLength=view.byteLength,offset=view.getUint8(0)===2?10:9,blocks=0;for(;offset<byteLength;){let size=view.getUint16(offset,!0);blocks+=1,offset+=size+2}return blocks*frameMs}function isWav(data){return isWavFile(data)}function getWavFileInfo2(data){return getWavFileInfo(data)}function isSilk(data){let buffer=binaryFromSource(data);return buffer.byteLength<7?!1:toUTF8String(buffer,0,7).includes("#!SILK")}0&&(module.exports={decode,encode,getDuration,getWavFileInfo,isSilk,isWav});
@@ -0,0 +1,70 @@
1
+ export interface EncodeResult {
2
+ /** SILK */
3
+ data: Uint8Array;
4
+ /** in milliseconds */
5
+ duration: number;
6
+ }
7
+ export interface DecodeResult {
8
+ /** pcm_s16le */
9
+ data: Uint8Array;
10
+ /** in milliseconds */
11
+ duration: number;
12
+ }
13
+ /** @deprecated use `EncodeResult` instead */
14
+ export interface encodeResult extends EncodeResult {
15
+ }
16
+ /** @deprecated use `DecodeResult` instead */
17
+ export interface decodeResult extends DecodeResult {
18
+ }
19
+ export interface WavFileInfo {
20
+ chunkInfo: {
21
+ chunkId: string;
22
+ dataOffset: number;
23
+ dataLength: number;
24
+ }[];
25
+ fmt: {
26
+ formatCode: number;
27
+ numberOfChannels: number;
28
+ sampleRate: number;
29
+ bytesPerSec: number;
30
+ bytesPerFrame: number;
31
+ bitsPerSample: number;
32
+ };
33
+ }
34
+ /**
35
+ * 编码为 SILK
36
+ * @param input WAV 或单声道 pcm_s16le 文件
37
+ * @param sampleRate `input` 的采样率,可为 8000/12000/16000/24000/32000/44100/48000,当 `input` 为 WAV 时可填入 0
38
+ * @returns SILK
39
+ */
40
+ export declare function encode(input: ArrayBufferView | ArrayBuffer, sampleRate: number): Promise<EncodeResult>;
41
+ /**
42
+ * 将 SILK 解码为 PCM
43
+ * @param input SILK 文件
44
+ * @param sampleRate `input` 的采样率
45
+ * @returns pcm_s16le
46
+ */
47
+ export declare function decode(input: ArrayBufferView | ArrayBuffer, sampleRate: number): Promise<DecodeResult>;
48
+ /**
49
+ * 获取 SILK 音频时长
50
+ * @param data SILK 文件
51
+ * @param frameMs SILK 的 frameMs,可为 20/40/60/80/100,默认为 20
52
+ * @returns 单位为毫秒的时长
53
+ */
54
+ export declare function getDuration(data: ArrayBufferView | ArrayBuffer, frameMs?: number): number;
55
+ /**
56
+ * 检测是否为 WAV 文件
57
+ * @param data 任意文件
58
+ */
59
+ export declare function isWav(data: ArrayBufferView | ArrayBuffer): boolean;
60
+ /**
61
+ * 获取 WAV 文件的信息
62
+ * @param data WAV 文件
63
+ * @returns metadata
64
+ */
65
+ export declare function getWavFileInfo(data: ArrayBufferView | ArrayBuffer): WavFileInfo;
66
+ /**
67
+ * 检测是否为 SILK 文件
68
+ * @param data 任意文件
69
+ */
70
+ export declare function isSilk(data: ArrayBufferView | ArrayBuffer): boolean;
@@ -0,0 +1,16 @@
1
+ var Module=async function(moduleArg={}){var moduleRtn,g=moduleArg,aa,q,ba=new Promise((a,b)=>{aa=a,q=b}),ca=typeof window=="object",da=typeof WorkerGlobalScope<"u",t=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";if(t){let{createRequire:a}=await import("module");var require2=a(import.meta.url)}var u=(a,b)=>{throw b},ea=import.meta.url,v="",fa,w;if(t){var fs=require2("fs"),ha=require2("path");ea.startsWith("file:")&&(v=ha.dirname(require2("url").fileURLToPath(ea))+"/"),w=a=>(a=y(a)?new URL(a):a,fs.readFileSync(a)),fa=async a=>(a=y(a)?new URL(a):a,fs.readFileSync(a,void 0)),process.argv.slice(2),u=(a,b)=>{throw process.exitCode=a,b}}else if(ca||da){try{v=new URL(".",ea).href}catch{}da&&(w=a=>{var b=new XMLHttpRequest;return b.open("GET",a,!1),b.responseType="arraybuffer",b.send(null),new Uint8Array(b.response)}),fa=async a=>{if(y(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0),e.responseType="arraybuffer",e.onload=()=>{e.status==200||e.status==0&&e.response?d(e.response):c(e.status)},e.onerror=c,e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url)}}console.log.bind(console);var A=console.error.bind(console),C,D,E=!1,ia,ja,F,G,H,I,J,ka,la,ma,na,y=a=>a.startsWith("file://");function pa(){var a=D.buffer;ja=new Int8Array(a),G=new Int16Array(a),F=new Uint8Array(a),H=new Uint16Array(a),I=new Int32Array(a),J=new Uint32Array(a),ka=new Float32Array(a),na=new Float64Array(a),la=new BigInt64Array(a),ma=new BigUint64Array(a)}var K=0,L=null;function qa(a){throw g.onAbort?.(a),a="Aborted("+a+")",A(a),E=!0,a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info."),q(a),a}var ra;async function sa(a){if(!C)try{var b=await fa(a);return new Uint8Array(b)}catch{}if(a==ra&&C)a=new Uint8Array(C);else if(w)a=w(a);else throw"both async and sync fetching of the wasm failed";return a}async function ta(a,b){try{var d=await sa(a);return await WebAssembly.instantiate(d,b)}catch(c){A(`failed to asynchronously prepare wasm: ${c}`),qa(c)}}async function ua(a){var b=ra;if(!C&&typeof WebAssembly.instantiateStreaming=="function"&&!y(b)&&!t)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){A(`wasm streaming compile failed: ${c}`),A("falling back to ArrayBuffer instantiation")}return ta(b,a)}class va{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`,this.status=a}}var wa=a=>{for(;0<a.length;)a.shift()(g)},xa=[],ya=[],za=()=>{var a=g.preRun.shift();ya.push(a)},O=!0;class Aa{constructor(a){this.I=a-24}}var Ba=0,Ca=0,Da,P=a=>{for(var b="";F[a];)b+=Da[F[a++]];return b},Q={},R={},S={},T=g.BindingError=class extends Error{constructor(a){super(a),this.name="BindingError"}},Ea=a=>{throw new T(a)};function Fa(a,b,d={}){var c=b.name;if(!a)throw new T(`type "${c}" must have a positive integer typeid pointer`);if(R.hasOwnProperty(a)){if(d.K)return;throw new T(`Cannot register type '${c}' twice`)}R[a]=b,delete S[a],Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(e=>e()))}function U(a,b,d={}){return Fa(a,b,d)}var Ga=(a,b,d)=>{switch(b){case 1:return d?c=>ja[c]:c=>F[c];case 2:return d?c=>G[c>>1]:c=>H[c>>1];case 4:return d?c=>I[c>>2]:c=>J[c>>2];case 8:return d?c=>la[c>>3]:c=>ma[c>>3];default:throw new TypeError(`invalid integer width (${b}): ${a}`)}},Ha=[],V=[],Ia=a=>{9<a&&--V[a+1]===0&&(V[a]=void 0,Ha.push(a))},Ja=a=>{if(!a)throw new T(`Cannot use deleted val. handle = ${a}`);return V[a]},Ka=a=>{switch(a){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:let b=Ha.pop()||V.length;return V[b]=a,V[b+1]=1,b}};function La(a){return this.fromWireType(J[a>>2])}var Ma={name:"emscripten::val",fromWireType:a=>{var b=Ja(a);return Ia(a),b},toWireType:(a,b)=>Ka(b),H:8,readValueFromPointer:La,G:null},Na=(a,b)=>{switch(b){case 4:return function(d){return this.fromWireType(ka[d>>2])};case 8:return function(d){return this.fromWireType(na[d>>3])};default:throw new TypeError(`invalid float width (${b}): ${a}`)}},Oa=a=>{for(;a.length;){var b=a.pop();a.pop()(b)}};function Pa(a){for(var b=1;b<a.length;++b)if(a[b]!==null&&a[b].G===void 0)return!0;return!1}var Sa=(a,b)=>{if(g[a].F===void 0){var d=g[a];g[a]=function(...c){if(!g[a].F.hasOwnProperty(c.length))throw new T(`Function '${b}' called with an invalid number of arguments (${c.length}) - expects one of (${g[a].F})!`);return g[a].F[c.length].apply(this,c)},g[a].F=[],g[a].F[d.J]=d}},Ta=(a,b,d)=>{if(g.hasOwnProperty(a)){if(d===void 0||g[a].F!==void 0&&g[a].F[d]!==void 0)throw new T(`Cannot register public name '${a}' twice`);if(Sa(a,a),g[a].F.hasOwnProperty(d))throw new T(`Cannot register multiple overloads of a function with the same number of arguments (${d})!`);g[a].F[d]=b}else g[a]=b,g[a].J=d},Ua=(a,b)=>{for(var d=[],c=0;c<a;c++)d.push(J[b+4*c>>2]);return d},Va=g.InternalError=class extends Error{constructor(a){super(a),this.name="InternalError"}},Wa=[],Xa,Ya=(a,b)=>{a=P(a);var d;if((d=Wa[b])||(Wa[b]=d=Xa.get(b)),typeof d!="function")throw new T(`unknown function pointer with signature ${a}: ${b}`);return d};class Za extends Error{}for(var ab=a=>{a=$a(a);var b=P(a);return W(a),b},bb=(a,b)=>{function d(f){e[f]||R[f]||(S[f]?S[f].forEach(d):(c.push(f),e[f]=!0))}var c=[],e={};throw b.forEach(d),new Za(`${a}: `+c.map(ab).join([", "]))},cb=(a,b)=>{function d(h){if(h=b(h),h.length!==c.length)throw new Va("Mismatched type converter count");for(var l=0;l<c.length;++l)U(c[l],h[l])}var c=[];c.forEach(h=>S[h]=a);var e=Array(a.length),f=[],m=0;a.forEach((h,l)=>{R.hasOwnProperty(h)?e[l]=R[h]:(f.push(h),Q.hasOwnProperty(h)||(Q[h]=[]),Q[h].push(()=>{e[l]=R[h],++m,m===f.length&&d(e)}))}),f.length===0&&d(e)},db=a=>{a=a.trim();let b=a.indexOf("(");return b===-1?a:a.slice(0,b)},eb=typeof TextDecoder<"u"?new TextDecoder:void 0,fb=(a=0,b=NaN)=>{var d=F,c=a+b;for(b=a;d[b]&&!(b>=c);)++b;if(16<b-a&&d.buffer&&eb)return eb.decode(d.subarray(a,b));for(c="";a<b;){var e=d[a++];if(e&128){var f=d[a++]&63;if((e&224)==192)c+=String.fromCharCode((e&31)<<6|f);else{var m=d[a++]&63;e=(e&240)==224?(e&15)<<12|f<<6|m:(e&7)<<18|f<<12|m<<6|d[a++]&63,65536>e?c+=String.fromCharCode(e):(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else c+=String.fromCharCode(e)}return c},gb=typeof TextDecoder<"u"?new TextDecoder("utf-16le"):void 0,hb=(a,b)=>{for(var d=a>>1,c=d+b/2;!(d>=c)&&H[d];)++d;if(d<<=1,32<d-a&&gb)return gb.decode(F.subarray(a,d));for(d="",c=0;!(c>=b/2);++c){var e=G[a+2*c>>1];if(e==0)break;d+=String.fromCharCode(e)}return d},ib=(a,b,d)=>{if(d??=2147483647,2>d)return 0;d-=2;var c=b;d=d<2*a.length?d/2:a.length;for(var e=0;e<d;++e)G[b>>1]=a.charCodeAt(e),b+=2;return G[b>>1]=0,b-c},jb=a=>2*a.length,kb=(a,b)=>{for(var d=0,c="";!(d>=b/4);){var e=I[a+4*d>>2];if(e==0)break;++d,65536<=e?(e-=65536,c+=String.fromCharCode(55296|e>>10,56320|e&1023)):c+=String.fromCharCode(e)}return c},lb=(a,b,d)=>{if(d??=2147483647,4>d)return 0;var c=b;d=c+d-4;for(var e=0;e<a.length;++e){var f=a.charCodeAt(e);if(55296<=f&&57343>=f){var m=a.charCodeAt(++e);f=65536+((f&1023)<<10)|m&1023}if(I[b>>2]=f,b+=4,b+4>d)break}return I[b>>2]=0,b-c},mb=a=>{for(var b=0,d=0;d<a.length;++d){var c=a.charCodeAt(d);55296<=c&&57343>=c&&++d,b+=4}return b},nb=0,ob=[],pb=a=>{var b=ob.length;return ob.push(a),b},qb=(a,b)=>{var d=R[a];if(d===void 0)throw a=`${b} has unknown type ${ab(a)}`,new T(a);return d},rb=(a,b)=>{for(var d=Array(a),c=0;c<a;++c)d[c]=qb(J[b+4*c>>2],`parameter ${c}`);return d},sb=(a,b,d)=>{var c=[];return a=a.toWireType(c,d),c.length&&(J[b>>2]=Ka(c)),a},X={},tb=a=>{ia=a,O||0<nb||(g.onExit?.(a),E=!0),u(a,new va(a))},ub=a=>{if(!E)try{if(a(),!(O||0<nb))try{ia=a=ia,tb(a)}catch(b){b instanceof va||b=="unwind"||u(1,b)}}catch(b){b instanceof va||b=="unwind"||u(1,b)}},vb=Array(256),Y=0;256>Y;++Y)vb[Y]=String.fromCharCode(Y);Da=vb,V.push(0,1,void 0,1,null,1,!0,1,!1,1),g.count_emval_handles=()=>V.length/2-5-Ha.length,g.noExitRuntime&&(O=g.noExitRuntime),g.printErr&&(A=g.printErr),g.wasmBinary&&(C=g.wasmBinary);var Ab={u:(a,b,d)=>{var c=new Aa(a);throw J[c.I+16>>2]=0,J[c.I+4>>2]=b,J[c.I+8>>2]=d,Ba=a,Ca++,Ba},v:()=>qa(""),l:(a,b,d)=>{b=P(b),U(a,{name:b,fromWireType:c=>c,toWireType:function(c,e){if(typeof e!="bigint"&&typeof e!="number")throw e===null?e="null":(c=typeof e,e=c==="object"||c==="array"||c==="function"?e.toString():""+e),new TypeError(`Cannot convert "${e}" to ${this.name}`);return typeof e=="number"&&(e=BigInt(e)),e},H:8,readValueFromPointer:Ga(b,d,b.indexOf("u")==-1),G:null})},o:(a,b,d,c)=>{b=P(b),U(a,{name:b,fromWireType:function(e){return!!e},toWireType:function(e,f){return f?d:c},H:8,readValueFromPointer:function(e){return this.fromWireType(F[e])},G:null})},m:a=>U(a,Ma),k:(a,b,d)=>{b=P(b),U(a,{name:b,fromWireType:c=>c,toWireType:(c,e)=>e,H:8,readValueFromPointer:Na(b,d),G:null})},c:(a,b,d,c,e,f,m)=>{var h=Ua(b,d);a=P(a),a=db(a),e=Ya(c,e),Ta(a,function(){bb(`Cannot call ${a} due to unbound types`,h)},b-1),cb(h,l=>{var k=[l[0],null].concat(l.slice(1));l=a;var p=a,z=e,n=k.length;if(2>n)throw new T("argTypes array size mismatch! Must at least get return value and 'this' types!");var B=k[1]!==null&&!1,M=Pa(k),Qa=k[0].name!=="void";z=[p,Ea,z,f,Oa,k[0],k[1]];for(var x=0;x<n-2;++x)z.push(k[x+2]);if(!M)for(x=B?1:2;x<k.length;++x)k[x].G!==null&&z.push(k[x].G);M=Pa(k),x=k.length-2;var r=[],N=["fn"];for(B&&N.push("thisWired"),n=0;n<x;++n)r.push(`arg${n}`),N.push(`arg${n}Wired`);r=r.join(","),N=N.join(","),r=`return function (${r}) {
2
+ `,M&&(r+=`var destructors = [];
3
+ `);var Ra=M?"destructors":"null",oa="humanName throwBindingError invoker fn runDestructors retType classParam".split(" ");for(B&&(r+=`var thisWired = classParam['toWireType'](${Ra}, this);
4
+ `),n=0;n<x;++n)r+=`var arg${n}Wired = argType${n}['toWireType'](${Ra}, arg${n});
5
+ `,oa.push(`argType${n}`);if(r+=(Qa||m?"var rv = ":"")+`invoker(${N});
6
+ `,M)r+=`runDestructors(destructors);
7
+ `;else for(n=B?1:2;n<k.length;++n)B=n===1?"thisWired":"arg"+(n-2)+"Wired",k[n].G!==null&&(r+=`${B}_dtor(${B});
8
+ `,oa.push(`${B}_dtor`));Qa&&(r+=`var ret = retType['fromWireType'](rv);
9
+ return ret;
10
+ `);let[yb,zb]=[oa,r+`}
11
+ `];if(k=new Function(...yb,zb)(...z),p=Object.defineProperty(k,"name",{value:p}),k=b-1,!g.hasOwnProperty(l))throw new Va("Replacing nonexistent public symbol");return g[l].F!==void 0&&k!==void 0?g[l].F[k]=p:(g[l]=p,g[l].J=k),[]})},b:(a,b,d,c,e)=>{if(b=P(b),e===-1&&(e=4294967295),e=h=>h,c===0){var f=32-8*d;e=h=>h<<f>>>f}var m=b.includes("unsigned")?function(h,l){return l>>>0}:function(h,l){return l};U(a,{name:b,fromWireType:e,toWireType:m,H:8,readValueFromPointer:Ga(b,d,c!==0),G:null})},a:(a,b,d)=>{function c(f){return new e(ja.buffer,J[f+4>>2],J[f>>2])}var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array][b];d=P(d),U(a,{name:d,fromWireType:c,H:8,readValueFromPointer:c},{K:!0})},n:(a,b)=>{b=P(b),U(a,{name:b,fromWireType:function(d){for(var c=J[d>>2],e=d+4,f,m=e,h=0;h<=c;++h){var l=e+h;(h==c||F[l]==0)&&(m=m?fb(m,l-m):"",f===void 0?f=m:(f+="\0",f+=m),m=l+1)}return W(d),f},toWireType:function(d,c){c instanceof ArrayBuffer&&(c=new Uint8Array(c));var e,f=typeof c=="string";if(!(f||ArrayBuffer.isView(c)&&c.BYTES_PER_ELEMENT==1))throw new T("Cannot pass non-string to std::string");var m;if(f)for(e=m=0;e<c.length;++e){var h=c.charCodeAt(e);127>=h?m++:2047>=h?m+=2:55296<=h&&57343>=h?(m+=4,++e):m+=3}else m=c.length;if(e=m,m=wb(4+e+1),h=m+4,J[m>>2]=e,f){if(f=h,h=e+1,e=F,0<h){h=f+h-1;for(var l=0;l<c.length;++l){var k=c.charCodeAt(l);if(55296<=k&&57343>=k){var p=c.charCodeAt(++l);k=65536+((k&1023)<<10)|p&1023}if(127>=k){if(f>=h)break;e[f++]=k}else{if(2047>=k){if(f+1>=h)break;e[f++]=192|k>>6}else{if(65535>=k){if(f+2>=h)break;e[f++]=224|k>>12}else{if(f+3>=h)break;e[f++]=240|k>>18,e[f++]=128|k>>12&63}e[f++]=128|k>>6&63}e[f++]=128|k&63}}e[f]=0}}else F.set(c,h);return d!==null&&d.push(W,m),m},H:8,readValueFromPointer:La,G(d){W(d)}})},e:(a,b,d)=>{if(d=P(d),b===2)var c=hb,e=ib,f=jb,m=h=>H[h>>1];else b===4&&(c=kb,e=lb,f=mb,m=h=>J[h>>2]);U(a,{name:d,fromWireType:h=>{for(var l=J[h>>2],k,p=h+4,z=0;z<=l;++z){var n=h+4+z*b;(z==l||m(n)==0)&&(p=c(p,n-p),k===void 0?k=p:(k+="\0",k+=p),p=n+b)}return W(h),k},toWireType:(h,l)=>{if(typeof l!="string")throw new T(`Cannot pass non-string to C++ string type ${d}`);var k=f(l),p=wb(4+k+b);return J[p>>2]=k/b,e(l,p+4,k+b),h!==null&&h.push(W,p),p},H:8,readValueFromPointer:La,G(h){W(h)}})},f:a=>{U(a,Ma)},p:(a,b)=>{b=P(b),U(a,{L:!0,name:b,H:0,fromWireType:()=>{},toWireType:()=>{}})},s:()=>{O=!1,nb=0},i:(a,b,d,c)=>(a=ob[a],b=Ja(b),a(null,b,d,c)),d:Ia,h:(a,b,d)=>{b=rb(a,b);var c=b.shift();a--;var e=`return function (obj, func, destructorsRef, args) {
12
+ `,f=0,m=[];d===0&&m.push("obj");for(var h=["retType"],l=[c],k=0;k<a;++k)m.push(`arg${k}`),h.push(`argType${k}`),l.push(b[k]),e+=` var arg${k} = argType${k}.readValueFromPointer(args${f?"+"+f:""});
13
+ `,f+=b[k].H;return e+=` var rv = ${d===1?"new func":"func.call"}(${m.join(", ")});
14
+ `,c.L||(h.push("emval_returnValue"),l.push(sb),e+=` return emval_returnValue(retType, destructorsRef, rv);
15
+ `),a=new Function(...h,e+`};
16
+ `)(...l),d=`methodCaller<(${b.map(p=>p.name).join(", ")}) => ${c.name}>`,pb(Object.defineProperty(a,"name",{value:d}))},q:a=>{9<a&&(V[a+1]+=1)},g:a=>{var b=Ja(a);Oa(b),Ia(a)},j:(a,b)=>(a=qb(a,"_emval_take_value"),a=a.readValueFromPointer(b),Ka(a)),t:(a,b)=>{if(X[a]&&(clearTimeout(X[a].id),delete X[a]),!b)return 0;var d=setTimeout(()=>{delete X[a],ub(()=>xb(a,performance.now()))},b);return X[a]={id:d,M:b},0},w:a=>{var b=F.length;if(a>>>=0,2147483648<a)return!1;for(var d=1;4>=d;d*=2){var c=b*(1+.2/d);c=Math.min(c,a+100663296);a:{c=(Math.min(2147483648,65536*Math.ceil(Math.max(a,c)/65536))-D.buffer.byteLength+65535)/65536|0;try{D.grow(c),pa();var e=1;break a}catch{}e=void 0}if(e)return!0}return!1},r:tb},Z=await async function(){function a(c){return Z=c.exports,D=Z.x,pa(),Xa=Z.D,K--,g.monitorRunDependencies?.(K),K==0&&L&&(c=L,L=null,c()),Z}K++,g.monitorRunDependencies?.(K);var b={a:Ab};if(g.instantiateWasm)return new Promise(c=>{g.instantiateWasm(b,(e,f)=>{c(a(e,f))})});ra??=g.locateFile?g.locateFile?g.locateFile("silk.wasm",v):v+"silk.wasm":new URL("silk.wasm",import.meta.url).href;try{var d=await ua(b);return a(d.instance)}catch(c){return q(c),Promise.reject(c)}}(),$a=Z.z,wb=Z.A,W=Z.B,xb=Z.C;function Bb(){function a(){if(g.calledRun=!0,!E){if(Z.y(),aa(g),g.onRuntimeInitialized?.(),g.postRun)for(typeof g.postRun=="function"&&(g.postRun=[g.postRun]);g.postRun.length;){var b=g.postRun.shift();xa.push(b)}wa(xa)}}if(0<K)L=Bb;else{if(g.preRun)for(typeof g.preRun=="function"&&(g.preRun=[g.preRun]);g.preRun.length;)za();wa(ya),0<K?L=Bb:g.setStatus?(g.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>g.setStatus(""),1),a()},1)):a()}}if(g.preInit)for(typeof g.preInit=="function"&&(g.preInit=[g.preInit]);0<g.preInit.length;)g.preInit.shift()();return Bb(),moduleRtn=ba,moduleRtn},silk_default=Module;function isWavFile(fileData){try{let chunks=unpackWavFileChunks(fileData),fmt=decodeFormatChunk(chunks.get("fmt")),data=chunks.get("data");return getWavFileType(fmt),verifyDataChunkLength(data,fmt),!0}catch{return!1}}var audioEncodingNames=["int","float"],wavFileTypeAudioEncodings=[0,0,0,1];function decodeWavFile(fileData){let chunks=unpackWavFileChunks(fileData),fmt=decodeFormatChunk(chunks.get("fmt")),data=chunks.get("data"),wavFileType=getWavFileType(fmt),audioEncoding=wavFileTypeAudioEncodings[wavFileType],wavFileTypeName=audioEncodingNames[audioEncoding]+fmt.bitsPerSample;return verifyDataChunkLength(data,fmt),{channelData:decodeDataChunk(data,fmt,wavFileType),sampleRate:fmt.sampleRate,numberOfChannels:fmt.numberOfChannels,audioEncoding,bitsPerSample:fmt.bitsPerSample,wavFileTypeName}}function unpackWavFileChunks(fileData){let dataView;fileData instanceof ArrayBuffer?dataView=new DataView(fileData):dataView=new DataView(fileData.buffer,fileData.byteOffset,fileData.byteLength);let fileLength=dataView.byteLength;if(fileLength<20)throw new Error("WAV file is too short.");if(getString(dataView,0,4)!="RIFF")throw new Error("Not a valid WAV file (no RIFF header).");let mainChunkLength=dataView.getUint32(4,!0);if(8+mainChunkLength!=fileLength)throw new Error(`Main chunk length of WAV file (${8+mainChunkLength}) does not match file size (${fileLength}).`);if(getString(dataView,8,4)!="WAVE")throw new Error("RIFF file is not a WAV file.");let chunks=new Map,fileOffset=12;for(;fileOffset<fileLength;){if(fileOffset+8>fileLength)throw new Error(`Incomplete chunk prefix in WAV file at offset ${fileOffset}.`);let chunkId=getString(dataView,fileOffset,4).trim(),chunkLength=dataView.getUint32(fileOffset+4,!0);if(fileOffset+8+chunkLength>fileLength)throw new Error(`Incomplete chunk data in WAV file at offset ${fileOffset}.`);let chunkData=new DataView(dataView.buffer,dataView.byteOffset+fileOffset+8,chunkLength);chunks.set(chunkId,chunkData);let padLength=chunkLength%2;fileOffset+=8+chunkLength+padLength}return chunks}function getString(dataView,offset,length){let a=new Uint8Array(dataView.buffer,dataView.byteOffset+offset,length);return String.fromCharCode.apply(null,a)}function getInt24(dataView,offset){let b0=dataView.getInt8(offset+2)*65536,b12=dataView.getUint16(offset,!0);return b0+b12}function decodeFormatChunk(dataView){if(!dataView)throw new Error("No format chunk found in WAV file.");if(dataView.byteLength<16)throw new Error("Format chunk of WAV file is too short.");let fmt={};return fmt.formatCode=dataView.getUint16(0,!0),fmt.numberOfChannels=dataView.getUint16(2,!0),fmt.sampleRate=dataView.getUint32(4,!0),fmt.bytesPerSec=dataView.getUint32(8,!0),fmt.bytesPerFrame=dataView.getUint16(12,!0),fmt.bitsPerSample=dataView.getUint16(14,!0),fmt}function getWavFileType(fmt){if(fmt.numberOfChannels<1||fmt.numberOfChannels>999)throw new Error("Invalid number of channels in WAV file.");let bytesPerSample=Math.ceil(fmt.bitsPerSample/8),expectedBytesPerFrame=fmt.numberOfChannels*bytesPerSample;if(fmt.formatCode==1&&fmt.bitsPerSample>=1&&fmt.bitsPerSample<=8&&fmt.bytesPerFrame==expectedBytesPerFrame)return 0;if(fmt.formatCode==1&&fmt.bitsPerSample>=9&&fmt.bitsPerSample<=16&&fmt.bytesPerFrame==expectedBytesPerFrame)return 1;if(fmt.formatCode==1&&fmt.bitsPerSample>=17&&fmt.bitsPerSample<=24&&fmt.bytesPerFrame==expectedBytesPerFrame)return 2;if(fmt.formatCode==3&&fmt.bitsPerSample==32&&fmt.bytesPerFrame==expectedBytesPerFrame)return 3;throw new Error(`Unsupported WAV file type, formatCode=${fmt.formatCode}, bitsPerSample=${fmt.bitsPerSample}, bytesPerFrame=${fmt.bytesPerFrame}, numberOfChannels=${fmt.numberOfChannels}.`)}function decodeDataChunk(data,fmt,wavFileType){switch(wavFileType){case 0:return decodeDataChunk_uint8(data,fmt);case 1:return decodeDataChunk_int16(data,fmt);case 2:return decodeDataChunk_int24(data,fmt);case 3:return decodeDataChunk_float32(data,fmt);default:throw new Error("No decoder.")}}function decodeDataChunk_int16(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=data.getInt16(offs,!0)/32768;channelData[channelNo][frameNo]=sampleValueFloat,offs+=2}return channelData}function decodeDataChunk_uint8(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=(data.getUint8(offs)-128)/128;channelData[channelNo][frameNo]=sampleValueFloat,offs+=1}return channelData}function decodeDataChunk_int24(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=getInt24(data,offs)/8388608;channelData[channelNo][frameNo]=sampleValueFloat,offs+=3}return channelData}function decodeDataChunk_float32(data,fmt){let channelData=allocateChannelDataArrays(data.byteLength,fmt),numberOfChannels=fmt.numberOfChannels,numberOfFrames=channelData[0].length,offs=0;for(let frameNo=0;frameNo<numberOfFrames;frameNo++)for(let channelNo=0;channelNo<numberOfChannels;channelNo++){let sampleValueFloat=data.getFloat32(offs,!0);channelData[channelNo][frameNo]=sampleValueFloat,offs+=4}return channelData}function allocateChannelDataArrays(dataLength,fmt){let numberOfFrames=Math.floor(dataLength/fmt.bytesPerFrame),channelData=new Array(fmt.numberOfChannels);for(let channelNo=0;channelNo<fmt.numberOfChannels;channelNo++)channelData[channelNo]=new Float32Array(numberOfFrames);return channelData}function verifyDataChunkLength(data,fmt){if(!data)throw new Error("No data chunk found in WAV file.");if(data.byteLength%fmt.bytesPerFrame!=0)throw new Error("WAV file data chunk length is not a multiple of frame size.")}function getWavFileInfo(fileData){let chunks=unpackWavFileChunks(fileData),chunkInfo=getChunkInfo(chunks),fmt=decodeFormatChunk(chunks.get("fmt"));return{chunkInfo,fmt}}function getChunkInfo(chunks){let chunkInfo=[];for(let e of chunks){let ci={};ci.chunkId=e[0],ci.dataOffset=e[1].byteOffset,ci.dataLength=e[1].byteLength,chunkInfo.push(ci)}return chunkInfo.sort((e1,e2)=>e1.dataOffset-e2.dataOffset),chunkInfo}function ensureMonoPcm(channelData){let{length:numberOfChannels}=channelData;if(numberOfChannels===1)return channelData[0];let monoData=new Float32Array(channelData[0].length);for(let i=0;i<monoData.length;i++){let sum=0;for(let j=0;j<numberOfChannels;j++)sum+=channelData[j][i];monoData[i]=sum/numberOfChannels}return monoData}function ensureS16lePcm(input){let int16Array=new Int16Array(input.length);for(let offset=0;offset<input.length;offset++){let x=~~(input[offset]*32768);int16Array[offset]=x>32767?32767:x}return int16Array.buffer}function toUTF8String(input,start=0,end=input.byteLength){return new TextDecoder().decode(input.slice(start,end))}function binaryFromSource(source){return ArrayBuffer.isView(source)?source.buffer.slice(source.byteOffset,source.byteOffset+source.byteLength):source}async function encode(input,sampleRate){let instance=await silk_default(),buffer=binaryFromSource(input);if(!buffer?.byteLength)throw new Error("input data length is 0");if(isWavFile(input)){let{channelData,sampleRate:wavSampleRate}=decodeWavFile(input);sampleRate||=wavSampleRate,buffer=ensureS16lePcm(ensureMonoPcm(channelData))}let data=new Uint8Array,duration=instance.silk_encode(buffer,sampleRate,output=>{data=output.slice()});if(duration===0)throw new Error("silk encoding failure");return{data,duration}}async function decode(input,sampleRate){let instance=await silk_default(),buffer=binaryFromSource(input);if(!buffer?.byteLength)throw new Error("input data length is 0");let data=new Uint8Array,duration=instance.silk_decode(buffer,sampleRate,output=>{output.length>0&&(data=output.slice())});if(duration===0)throw new Error("silk decoding failure");return{data,duration}}function getDuration(data,frameMs=20){let buffer=binaryFromSource(data),view=new DataView(buffer),byteLength=view.byteLength,offset=view.getUint8(0)===2?10:9,blocks=0;for(;offset<byteLength;){let size=view.getUint16(offset,!0);blocks+=1,offset+=size+2}return blocks*frameMs}function isWav(data){return isWavFile(data)}function getWavFileInfo2(data){return getWavFileInfo(data)}function isSilk(data){let buffer=binaryFromSource(data);return buffer.byteLength<7?!1:toUTF8String(buffer,0,7).includes("#!SILK")}export{decode,encode,getDuration,getWavFileInfo2 as getWavFileInfo,isSilk,isWav};
@@ -0,0 +1,4 @@
1
+ export declare function ensureMonoPcm(channelData: Float32Array[]): Float32Array;
2
+ export declare function ensureS16lePcm(input: Float32Array): ArrayBuffer;
3
+ export declare function toUTF8String(input: ArrayBuffer, start?: number, end?: number): string;
4
+ export declare function binaryFromSource(source: ArrayBufferView | ArrayBuffer): ArrayBuffer;
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "silk-wasm",
3
+ "description": "Tencent silk encoder for Node.js and browser",
4
+ "version": "3.7.1",
5
+ "main": "lib/index.cjs",
6
+ "module": "lib/index.mjs",
7
+ "typings": "lib/index.d.ts",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/idranme/silk-wasm.git"
11
+ },
12
+ "license": "MIT",
13
+ "files": [
14
+ "lib"
15
+ ],
16
+ "scripts": {
17
+ "compile:cjs": "esbuild src/index.ts --outfile=lib/index.cjs --bundle --minify-whitespace --minify-syntax --platform=node --target=es2022 --inject:scripts/patch.js --define:import.meta.url=import_meta_url",
18
+ "compile:esm": "esbuild src/index.ts --outfile=lib/index.mjs --bundle --minify-whitespace --minify-syntax --platform=node --target=es2022 --format=esm",
19
+ "build": "yarn compile:cjs && yarn compile:esm && tsc"
20
+ },
21
+ "keywords": [
22
+ "silk",
23
+ "tencent",
24
+ "encoder",
25
+ "sdk",
26
+ "wasm",
27
+ "decoder",
28
+ "codec"
29
+ ],
30
+ "devDependencies": {
31
+ "esbuild": "^0.25.3",
32
+ "typescript": "^5.8.3",
33
+ "wav-file-decoder": "^1.0.3"
34
+ },
35
+ "packageManager": "yarn@4.9.1",
36
+ "engines": {
37
+ "node": ">=16.11.0"
38
+ }
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sliverp/qqbot",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,13 +19,19 @@
19
19
  "moltbot.plugin.json"
20
20
  ],
21
21
  "clawdbot": {
22
- "extensions": ["./index.ts"]
22
+ "extensions": [
23
+ "./index.ts"
24
+ ]
23
25
  },
24
26
  "moltbot": {
25
- "extensions": ["./index.ts"]
27
+ "extensions": [
28
+ "./index.ts"
29
+ ]
26
30
  },
27
31
  "openclaw": {
28
- "extensions": ["./index.ts"]
32
+ "extensions": [
33
+ "./index.ts"
34
+ ]
29
35
  },
30
36
  "scripts": {
31
37
  "build": "tsc || true",
@@ -33,9 +39,11 @@
33
39
  "prepack": "npm install --omit=dev"
34
40
  },
35
41
  "dependencies": {
42
+ "silk-wasm": "^3.7.1",
36
43
  "ws": "^8.18.0"
37
44
  },
38
45
  "bundledDependencies": [
46
+ "silk-wasm",
39
47
  "ws"
40
48
  ],
41
49
  "devDependencies": {
@@ -48,5 +56,9 @@
48
56
  "moltbot": "*",
49
57
  "openclaw": "*"
50
58
  },
51
- "homepage": "https://github.com/sliverp/qqbot"
59
+ "homepage": "https://github.com/sliverp/qqbot",
60
+ "bundleDependencies": [
61
+ "silk-wasm",
62
+ "ws"
63
+ ]
52
64
  }
package/src/gateway.ts CHANGED
@@ -9,6 +9,7 @@ import { getQQBotRuntime } from "./runtime.js";
9
9
  import { startImageServer, isImageServerRunning, downloadFile, type ImageServerConfig } from "./image-server.js";
10
10
  import { getImageSize, formatQQBotMarkdownImage, hasQQBotImageSize, DEFAULT_IMAGE_SIZE } from "./utils/image-size.js";
11
11
  import { parseQQBotPayload, encodePayloadForCron, isCronReminderPayload, isMediaPayload, type CronReminderPayload, type MediaPayload } from "./utils/payload.js";
12
+ import { convertSilkToWav, isVoiceAttachment, formatDuration } from "./utils/audio-convert.js";
12
13
 
13
14
  // QQ Bot intents - 按权限级别分组
14
15
  const INTENTS = {
@@ -124,6 +125,29 @@ function recordMessageReply(messageId: string): void {
124
125
  }
125
126
  }
126
127
 
128
+ // ============ QQ 表情标签解析 ============
129
+
130
+ /**
131
+ * 解析 QQ 表情标签,将 <faceType=1,faceId="13",ext="base64..."> 格式
132
+ * 替换为 【表情: 中文名】 格式
133
+ * ext 字段为 Base64 编码的 JSON,格式如 {"text":"呲牙"}
134
+ */
135
+ function parseFaceTags(text: string): string {
136
+ if (!text) return text;
137
+
138
+ // 匹配 <faceType=...,faceId="...",ext="..."> 格式的表情标签
139
+ return text.replace(/<faceType=\d+,faceId="[^"]*",ext="([^"]*)">/g, (_match, ext: string) => {
140
+ try {
141
+ const decoded = Buffer.from(ext, "base64").toString("utf-8");
142
+ const parsed = JSON.parse(decoded);
143
+ const faceName = parsed.text || "未知表情";
144
+ return `【表情: ${faceName}】`;
145
+ } catch {
146
+ return _match;
147
+ }
148
+ });
149
+ }
150
+
127
151
  // ============ 内部标记过滤 ============
128
152
 
129
153
  /**
@@ -401,6 +425,8 @@ export async function startGateway(ctx: GatewayContext): Promise<void> {
401
425
  groupOpenid?: string;
402
426
  attachments?: Array<{ content_type: string; url: string; filename?: string }>;
403
427
  }) => {
428
+
429
+ log?.debug?.(`[qqbot:${account.accountId}] Received message: ${JSON.stringify(event)}`);
404
430
  log?.info(`[qqbot:${account.accountId}] Processing message from ${event.senderId}: ${event.content}`);
405
431
  if (event.attachments?.length) {
406
432
  log?.info(`[qqbot:${account.accountId}] Attachments: ${event.attachments.length}`);
@@ -514,9 +540,9 @@ openclaw cron add \\
514
540
  const downloadDir = path.join(process.env.HOME || "/home/ubuntu", "clawd", "downloads");
515
541
 
516
542
  if (event.attachments?.length) {
517
- // ============ 接收图片的自然语言描述生成 ============
518
- // 根据需求 4:将图片信息转换为自然语言描述,便于 AI 理解
543
+ // ============ 接收附件描述生成(图片 / 语音 / 其他) ============
519
544
  const imageDescriptions: string[] = [];
545
+ const voiceDescriptions: string[] = [];
520
546
  const otherAttachments: string[] = [];
521
547
 
522
548
  for (const att of event.attachments) {
@@ -538,6 +564,42 @@ openclaw cron add \\
538
564
  - 发送时间:${timestamp}
539
565
 
540
566
  请根据图片内容进行回复。`);
567
+ } else if (isVoiceAttachment(att)) {
568
+ // ============ 语音消息处理:SILK → WAV ============
569
+ log?.info(`[qqbot:${account.accountId}] Voice attachment detected: ${att.filename}, converting SILK to WAV...`);
570
+ try {
571
+ const result = await convertSilkToWav(localPath, downloadDir);
572
+ if (result) {
573
+ const durationStr = formatDuration(result.duration);
574
+ log?.info(`[qqbot:${account.accountId}] Voice converted: ${result.wavPath} (duration: ${durationStr})`);
575
+
576
+ const timestamp = new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
577
+ voiceDescriptions.push(`
578
+ 用户发送了一条语音消息:
579
+ - 语音文件:${result.wavPath}
580
+ - 语音时长:${durationStr}
581
+ - 发送时间:${timestamp}`);
582
+ } else {
583
+ // SILK 解码失败,保留原始文件
584
+ log?.info(`[qqbot:${account.accountId}] Voice file is not SILK format, keeping original: ${localPath}`);
585
+ voiceDescriptions.push(`
586
+ 用户发送了一条语音消息(非SILK格式,无法转换):
587
+ - 语音文件:${localPath}
588
+ - 原始格式:${att.filename || "unknown"}
589
+ - 消息ID:${event.messageId}
590
+
591
+ 请告知用户该语音格式暂不支持解析。`);
592
+ }
593
+ } catch (convertErr) {
594
+ log?.error(`[qqbot:${account.accountId}] Voice conversion failed: ${convertErr}`);
595
+ voiceDescriptions.push(`
596
+ 用户发送了一条语音消息(转换失败):
597
+ - 原始文件:${localPath}
598
+ - 错误信息:${convertErr}
599
+ - 消息ID:${event.messageId}
600
+
601
+ 请告知用户语音处理出现问题。`);
602
+ }
541
603
  } else {
542
604
  otherAttachments.push(`[附件: ${localPath}]`);
543
605
  }
@@ -566,16 +628,21 @@ openclaw cron add \\
566
628
  }
567
629
  }
568
630
 
569
- // 组合附件信息:先图片描述,后其他附件
631
+ // 组合附件信息:先图片描述,后语音描述,后其他附件
570
632
  if (imageDescriptions.length > 0) {
571
633
  attachmentInfo += "\n" + imageDescriptions.join("\n");
572
634
  }
635
+ if (voiceDescriptions.length > 0) {
636
+ attachmentInfo += "\n" + voiceDescriptions.join("\n");
637
+ }
573
638
  if (otherAttachments.length > 0) {
574
639
  attachmentInfo += "\n" + otherAttachments.join("\n");
575
640
  }
576
641
  }
577
642
 
578
- const userContent = event.content + attachmentInfo;
643
+ // 解析 QQ 表情标签,将 <faceType=...,ext="base64"> 替换为 【表情: 中文名】
644
+ const parsedContent = parseFaceTags(event.content);
645
+ const userContent = parsedContent + attachmentInfo;
579
646
  let messageBody = `【系统提示】\n${systemPrompts.join("\n")}\n\n【用户输入】\n${userContent}`;
580
647
 
581
648
  if(userContent.startsWith("/")){ // 保留Openclaw原始命令