@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.
- package/README.md +32 -1
- package/node_modules/silk-wasm/LICENSE +21 -0
- package/node_modules/silk-wasm/README.md +85 -0
- package/node_modules/silk-wasm/lib/index.cjs +16 -0
- package/node_modules/silk-wasm/lib/index.d.ts +70 -0
- package/node_modules/silk-wasm/lib/index.mjs +16 -0
- package/node_modules/silk-wasm/lib/silk.wasm +0 -0
- package/node_modules/silk-wasm/lib/utils.d.ts +4 -0
- package/node_modules/silk-wasm/package.json +39 -0
- package/package.json +17 -5
- package/src/gateway.ts +71 -4
- package/src/utils/audio-convert.ts +138 -0
- package/dist/index.d.ts +0 -17
- package/dist/index.js +0 -22
- package/dist/src/api.d.ts +0 -194
- package/dist/src/api.js +0 -555
- package/dist/src/channel.d.ts +0 -3
- package/dist/src/channel.js +0 -281
- package/dist/src/config.d.ts +0 -25
- package/dist/src/config.js +0 -156
- package/dist/src/gateway.d.ts +0 -18
- package/dist/src/gateway.js +0 -1475
- package/dist/src/image-server.d.ts +0 -62
- package/dist/src/image-server.js +0 -401
- package/dist/src/known-users.d.ts +0 -100
- package/dist/src/known-users.js +0 -264
- package/dist/src/onboarding.d.ts +0 -10
- package/dist/src/onboarding.js +0 -195
- package/dist/src/outbound.d.ts +0 -149
- package/dist/src/outbound.js +0 -476
- package/dist/src/proactive.d.ts +0 -170
- package/dist/src/proactive.js +0 -398
- package/dist/src/runtime.d.ts +0 -3
- package/dist/src/runtime.js +0 -10
- package/dist/src/session-store.d.ts +0 -49
- package/dist/src/session-store.js +0 -242
- package/dist/src/types.d.ts +0 -116
- package/dist/src/types.js +0 -1
- package/dist/src/utils/image-size.d.ts +0 -51
- package/dist/src/utils/image-size.js +0 -234
- package/dist/src/utils/payload.d.ts +0 -112
- 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
|
+
[](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};
|
|
Binary file
|
|
@@ -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.
|
|
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": [
|
|
22
|
+
"extensions": [
|
|
23
|
+
"./index.ts"
|
|
24
|
+
]
|
|
23
25
|
},
|
|
24
26
|
"moltbot": {
|
|
25
|
-
"extensions": [
|
|
27
|
+
"extensions": [
|
|
28
|
+
"./index.ts"
|
|
29
|
+
]
|
|
26
30
|
},
|
|
27
31
|
"openclaw": {
|
|
28
|
-
"extensions": [
|
|
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
|
-
|
|
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原始命令
|