@vunk/plus 1.7.3 → 1.7.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/components/broadcasting-markdown/index.mjs +101 -238
- package/components/broadcasting-markdown/src/ctx.d.ts +1 -4
- package/components/broadcasting-markdown/src/howler-speech.vue.d.ts +49 -88
- package/components/broadcasting-markdown/src/index.vue.d.ts +44 -103
- package/components/broadcasting-markdown/src/types.d.ts +1 -1
- package/components/broadcasting-markdown/src/use.d.ts +6 -8
- package/components/bubble-templates/index.css +4 -0
- package/components/bubble-templates/index.mjs +1 -1
- package/components/metahuman-broadcasting/index.mjs +8 -5
- package/components/metahuman-broadcasting/src/index.vue.d.ts +62 -114
- package/components/pixi-frame/src/apng.vue.d.ts +3 -3
- package/components/pixi-frame/src/bitmap.vue.d.ts +5 -5
- package/components/pixi-frame/src/core.vue.d.ts +5 -5
- package/components/pixi-frame/src/index.vue.d.ts +12 -12
- package/components/pixi-frame/src/video.vue.d.ts +3 -3
- package/components/typing-markdown/index.mjs +4 -7
- package/components/vditor/src/ctx.d.ts +1 -1
- package/components/vditor/src/index.vue.d.ts +1 -1
- package/index.css +5 -0
- package/package.json +4 -1
- package/shared/StreamingInferenceService.mjs +4 -1
- package/shared/audioToFrames/index.mjs +2 -5
- package/shared/audioToFrames/src/audio/StreamingFeatureExtractorService.d.ts +20 -4
- package/shared/audioToFrames/src/audio/index.d.ts +0 -2
- package/shared/audioToFrames/src/audio/index.mjs +84 -157
- package/shared/audioToFrames/src/core/constants.d.ts +0 -22
- package/shared/audioToFrames/src/core/index.mjs +16 -2643
- package/shared/audioToFrames/src/core/utils.d.ts +1 -68
- package/shared/audioToFrames/src/inference/StreamingInferenceService.d.ts +43 -0
- package/shared/audioToFrames/src/media/index.d.ts +0 -5
- package/shared/audioToFrames/src/media/index.mjs +180 -610
- package/shared/constants.mjs +1 -12
- package/shared/PredictiveFrameLoader.mjs +0 -367
- package/shared/audioToFrames/src/audio/AudioProcessor.d.ts +0 -25
- package/shared/audioToFrames/src/audio/FeatureExtractorService.d.ts +0 -31
- package/shared/audioToFrames/src/inference/types.d.ts +0 -102
- package/shared/audioToFrames/src/media/ImageBitmapPool.d.ts +0 -63
- package/shared/audioToFrames/src/media/ImageProcessor.d.ts +0 -47
- package/shared/audioToFrames/src/media/PlaybackService.d.ts +0 -56
- package/shared/audioToFrames/src/media/WebGLPlaybackService.d.ts +0 -74
- package/shared/audioToFrames/src/media/WebGLRenderer.d.ts +0 -66
- package/shared/utils.mjs +0 -123
|
@@ -1,111 +1,5 @@
|
|
|
1
|
-
import { W as WINDOW_NUM_CHUNKS, d as WINDOW_NUM_CHUNKS_HALF, C as CHUNK_DURATION_SECONDS, a as NUM_SEQUENCE_FRAMES, N as NUM_MEL_BINS } from '../../../constants.mjs';
|
|
2
1
|
import { w as workerConfig } from '../../../config.mjs';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
function getAudioWindow(allAudioFeatures, allAudioDims, centerChunkIndex) {
|
|
6
|
-
if (allAudioDims.length !== 3) {
|
|
7
|
-
throw new Error(
|
|
8
|
-
"Invalid dimensions array provided to getAudioWindow. Expected length 3."
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
const [numChunks, chunkSize, melBins] = allAudioDims;
|
|
12
|
-
const finalWindowData = new Float32Array(
|
|
13
|
-
WINDOW_NUM_CHUNKS * chunkSize * melBins
|
|
14
|
-
);
|
|
15
|
-
const chunkTotalSize = chunkSize * melBins;
|
|
16
|
-
for (let j = 0; j < WINDOW_NUM_CHUNKS; j++) {
|
|
17
|
-
const sourceChunkIndex = centerChunkIndex - WINDOW_NUM_CHUNKS_HALF + j;
|
|
18
|
-
const clampedSourceIndex = Math.max(
|
|
19
|
-
0,
|
|
20
|
-
Math.min(sourceChunkIndex, numChunks - 1)
|
|
21
|
-
);
|
|
22
|
-
const sourceChunkStart = clampedSourceIndex * chunkTotalSize;
|
|
23
|
-
const sourceChunkEnd = sourceChunkStart + chunkTotalSize;
|
|
24
|
-
const chunkData = allAudioFeatures.subarray(
|
|
25
|
-
sourceChunkStart,
|
|
26
|
-
sourceChunkEnd
|
|
27
|
-
);
|
|
28
|
-
const destChunkStart = j * chunkTotalSize;
|
|
29
|
-
finalWindowData.set(chunkData, destChunkStart);
|
|
30
|
-
}
|
|
31
|
-
return finalWindowData;
|
|
32
|
-
}
|
|
33
|
-
async function createAudioContext() {
|
|
34
|
-
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
|
|
35
|
-
if (!AudioContextClass) {
|
|
36
|
-
throw new Error("\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301Web Audio API");
|
|
37
|
-
}
|
|
38
|
-
const audioContext = new AudioContextClass();
|
|
39
|
-
if (audioContext.state === "suspended") {
|
|
40
|
-
await audioContext.resume();
|
|
41
|
-
}
|
|
42
|
-
return audioContext;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
class FeatureExtractorService {
|
|
46
|
-
constructor() {
|
|
47
|
-
this.errorHandler = createErrorHandler("FeatureExtractorService");
|
|
48
|
-
this.worker = new Worker(
|
|
49
|
-
/* @vite-ignore */
|
|
50
|
-
`${workerConfig.path}/feature.worker.js`,
|
|
51
|
-
{ type: "module" }
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* 处理 AudioBuffer,在后台线程中提取特征。
|
|
56
|
-
* @param audioBuffer Web Audio API 的 AudioBuffer 对象。
|
|
57
|
-
* @returns 一个 Promise,成功时解析为特征结果,失败时拒绝并返回错误信息。
|
|
58
|
-
*/
|
|
59
|
-
async process(audioBuffer) {
|
|
60
|
-
try {
|
|
61
|
-
const leftChannel = audioBuffer.getChannelData(0);
|
|
62
|
-
const rightChannel = audioBuffer.numberOfChannels > 1 ? audioBuffer.getChannelData(1) : void 0;
|
|
63
|
-
const message = {
|
|
64
|
-
leftChannel,
|
|
65
|
-
rightChannel,
|
|
66
|
-
sampleRate: audioBuffer.sampleRate
|
|
67
|
-
};
|
|
68
|
-
const transferList = [leftChannel.buffer, rightChannel?.buffer].filter(Boolean);
|
|
69
|
-
const result = await this.createWorkerPromise(
|
|
70
|
-
message,
|
|
71
|
-
transferList
|
|
72
|
-
);
|
|
73
|
-
return result;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
throw this.errorHandler(error);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* 创建Worker Promise,直接处理消息传递
|
|
80
|
-
*/
|
|
81
|
-
createWorkerPromise(message, transferList) {
|
|
82
|
-
return new Promise((resolve, reject) => {
|
|
83
|
-
const handleMessage = (event) => {
|
|
84
|
-
this.worker.removeEventListener("message", handleMessage);
|
|
85
|
-
this.worker.removeEventListener("error", handleError);
|
|
86
|
-
if (event.data.status === "success") {
|
|
87
|
-
resolve(event.data.payload);
|
|
88
|
-
} else {
|
|
89
|
-
reject(new Error(event.data.error || "Unknown worker error"));
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
function handleError(error) {
|
|
93
|
-
this.worker.removeEventListener("message", handleMessage);
|
|
94
|
-
this.worker.removeEventListener("error", handleError);
|
|
95
|
-
reject(error);
|
|
96
|
-
}
|
|
97
|
-
this.worker.addEventListener("message", handleMessage);
|
|
98
|
-
this.worker.addEventListener("error", handleError);
|
|
99
|
-
this.worker.postMessage(message, transferList);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* 终止Worker
|
|
104
|
-
*/
|
|
105
|
-
terminate() {
|
|
106
|
-
this.worker.terminate();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
2
|
+
import { C as CHUNK_DURATION_SECONDS, a as NUM_SEQUENCE_FRAMES, N as NUM_MEL_BINS } from '../../../constants.mjs';
|
|
109
3
|
|
|
110
4
|
var __defProp = Object.defineProperty;
|
|
111
5
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -239,13 +133,22 @@ var _AsyncQueue = class _AsyncQueue {
|
|
|
239
133
|
__name(_AsyncQueue, "AsyncQueue");
|
|
240
134
|
var AsyncQueue = _AsyncQueue;
|
|
241
135
|
|
|
136
|
+
async function createAudioContext() {
|
|
137
|
+
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
|
|
138
|
+
if (!AudioContextClass) {
|
|
139
|
+
throw new Error("\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301Web Audio API");
|
|
140
|
+
}
|
|
141
|
+
const audioContext = new AudioContextClass();
|
|
142
|
+
if (audioContext.state === "suspended") {
|
|
143
|
+
await audioContext.resume();
|
|
144
|
+
}
|
|
145
|
+
return audioContext;
|
|
146
|
+
}
|
|
242
147
|
class StreamingFeatureExtractorService {
|
|
243
148
|
constructor() {
|
|
244
149
|
this.queue = new AsyncQueue();
|
|
245
150
|
/** 回调函数集合 */
|
|
246
151
|
this.callbacks = {};
|
|
247
|
-
/** 性能计时器 */
|
|
248
|
-
this.timer = new PerformanceTimer();
|
|
249
152
|
/** 存储每个chunk的处理结果,用于最终合并 */
|
|
250
153
|
this.chunkResults = [];
|
|
251
154
|
/** 音频总chunk数 */
|
|
@@ -260,8 +163,8 @@ class StreamingFeatureExtractorService {
|
|
|
260
163
|
this.audioBuffer = null;
|
|
261
164
|
/** 音频上下文实例,用于创建AudioBuffer */
|
|
262
165
|
this.audioContext = null;
|
|
263
|
-
/**
|
|
264
|
-
this.
|
|
166
|
+
/** 复用的Worker实例,以提高性能 */
|
|
167
|
+
this.worker = null;
|
|
265
168
|
}
|
|
266
169
|
/**
|
|
267
170
|
* 创建AudioBuffer的兼容方法,处理Safari的限制。
|
|
@@ -289,6 +192,47 @@ class StreamingFeatureExtractorService {
|
|
|
289
192
|
);
|
|
290
193
|
}
|
|
291
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* 使用Worker处理AudioBuffer,提取特征
|
|
197
|
+
* @param audioBuffer 输入的AudioBuffer
|
|
198
|
+
* @returns Promise<FeatureExtractionResult>
|
|
199
|
+
*/
|
|
200
|
+
async processWithWorker(audioBuffer) {
|
|
201
|
+
if (!this.worker) {
|
|
202
|
+
throw new Error("Worker not initialized");
|
|
203
|
+
}
|
|
204
|
+
return new Promise((resolve, reject) => {
|
|
205
|
+
const cleanup = () => {
|
|
206
|
+
if (this.worker) {
|
|
207
|
+
this.worker.removeEventListener("message", handleMessage);
|
|
208
|
+
this.worker.removeEventListener("error", handleError);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
function handleMessage(event) {
|
|
212
|
+
cleanup();
|
|
213
|
+
if (event.data.status === "success") {
|
|
214
|
+
resolve(event.data.payload);
|
|
215
|
+
} else {
|
|
216
|
+
reject(new Error(event.data.error || "Unknown worker error"));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function handleError(error) {
|
|
220
|
+
cleanup();
|
|
221
|
+
reject(error);
|
|
222
|
+
}
|
|
223
|
+
this.worker.addEventListener("message", handleMessage);
|
|
224
|
+
this.worker.addEventListener("error", handleError);
|
|
225
|
+
const leftChannel = audioBuffer.getChannelData(0);
|
|
226
|
+
const rightChannel = audioBuffer.numberOfChannels > 1 ? audioBuffer.getChannelData(1) : void 0;
|
|
227
|
+
const message = {
|
|
228
|
+
leftChannel,
|
|
229
|
+
rightChannel,
|
|
230
|
+
sampleRate: audioBuffer.sampleRate
|
|
231
|
+
};
|
|
232
|
+
const transferList = [leftChannel.buffer, rightChannel?.buffer].filter(Boolean);
|
|
233
|
+
this.worker.postMessage(message, transferList);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
292
236
|
/**
|
|
293
237
|
* 启动流式音频特征提取。
|
|
294
238
|
* @param audioBuffer 输入的音频缓冲区。
|
|
@@ -305,22 +249,24 @@ class StreamingFeatureExtractorService {
|
|
|
305
249
|
this.chunkResults = [];
|
|
306
250
|
this.completedChunks = 0;
|
|
307
251
|
this.totalFramesProcessed = 0;
|
|
308
|
-
this.
|
|
252
|
+
if (!this.worker) {
|
|
253
|
+
this.worker = new Worker(
|
|
254
|
+
/* @vite-ignore */
|
|
255
|
+
`${workerConfig.path}/feature.worker.js`,
|
|
256
|
+
{ type: "module" }
|
|
257
|
+
);
|
|
258
|
+
}
|
|
309
259
|
const durationSeconds = audioBuffer.duration;
|
|
310
260
|
this.totalChunks = Math.ceil(durationSeconds / CHUNK_DURATION_SECONDS);
|
|
311
261
|
try {
|
|
312
|
-
this.timer.start("totalProcessing");
|
|
313
262
|
for (let chunkIndex = 0; chunkIndex < this.totalChunks; chunkIndex++) {
|
|
314
263
|
if (!this.isRunning)
|
|
315
264
|
break;
|
|
316
|
-
this.timer.start(`chunk_${chunkIndex}`);
|
|
317
265
|
await this.processChunk(chunkIndex);
|
|
318
|
-
this.timer.end(`chunk_${chunkIndex}`);
|
|
319
266
|
}
|
|
320
267
|
if (this.isRunning) {
|
|
321
268
|
await this.finalize();
|
|
322
269
|
}
|
|
323
|
-
this.timer.end("totalProcessing");
|
|
324
270
|
} catch (error) {
|
|
325
271
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
326
272
|
this.callbacks.onError?.(errorMessage);
|
|
@@ -334,7 +280,7 @@ class StreamingFeatureExtractorService {
|
|
|
334
280
|
* @param chunkIndex chunk的索引(从0开始)。
|
|
335
281
|
*/
|
|
336
282
|
async processChunk(chunkIndex) {
|
|
337
|
-
if (!this.audioBuffer || !this.
|
|
283
|
+
if (!this.audioBuffer || !this.worker)
|
|
338
284
|
return;
|
|
339
285
|
const startTimeSeconds = chunkIndex * CHUNK_DURATION_SECONDS;
|
|
340
286
|
const endTimeSeconds = Math.min(
|
|
@@ -346,11 +292,6 @@ class StreamingFeatureExtractorService {
|
|
|
346
292
|
);
|
|
347
293
|
const endSample = Math.floor(endTimeSeconds * this.audioBuffer.sampleRate);
|
|
348
294
|
const chunkLength = endSample - startSample;
|
|
349
|
-
console.log(
|
|
350
|
-
`\u5904\u7406chunk ${chunkIndex}: ${startTimeSeconds.toFixed(
|
|
351
|
-
2
|
|
352
|
-
)}s - ${endTimeSeconds.toFixed(2)}s`
|
|
353
|
-
);
|
|
354
295
|
const chunkBuffer = await this.createAudioBuffer(
|
|
355
296
|
this.audioBuffer.numberOfChannels,
|
|
356
297
|
chunkLength,
|
|
@@ -361,36 +302,25 @@ class StreamingFeatureExtractorService {
|
|
|
361
302
|
const chunkData = chunkBuffer.getChannelData(channel);
|
|
362
303
|
chunkData.set(sourceData.subarray(startSample, endSample));
|
|
363
304
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
console.log(
|
|
379
|
-
`Chunk ${chunkIndex} \u5B8C\u6210\uFF0C\u7279\u5F81\u7EF4\u5EA6: [${result.dimensions.join(", ")}]`
|
|
380
|
-
);
|
|
381
|
-
this.callbacks.onChunkComplete?.(chunkResult);
|
|
382
|
-
this.callbacks.onProgress?.(this.completedChunks, this.totalChunks);
|
|
383
|
-
this.chunkResults[chunkIndex] = null;
|
|
384
|
-
} catch (error) {
|
|
385
|
-
console.error(`\u5904\u7406chunk ${chunkIndex} \u65F6\u53D1\u751F\u9519\u8BEF:`, error);
|
|
386
|
-
throw error;
|
|
387
|
-
}
|
|
305
|
+
const result = await this.processWithWorker(chunkBuffer);
|
|
306
|
+
const chunkResult = {
|
|
307
|
+
chunkIndex,
|
|
308
|
+
features: result.features,
|
|
309
|
+
dimensions: result.dimensions,
|
|
310
|
+
startTimeSeconds,
|
|
311
|
+
endTimeSeconds
|
|
312
|
+
};
|
|
313
|
+
this.totalFramesProcessed += chunkResult.dimensions[0];
|
|
314
|
+
this.chunkResults[chunkIndex] = chunkResult;
|
|
315
|
+
this.completedChunks++;
|
|
316
|
+
this.callbacks.onChunkComplete?.(chunkResult);
|
|
317
|
+
this.callbacks.onProgress?.(this.completedChunks, this.totalChunks);
|
|
318
|
+
this.chunkResults[chunkIndex] = null;
|
|
388
319
|
}
|
|
389
320
|
/**
|
|
390
321
|
* 所有chunk处理完成后,合并特征并调用onComplete。
|
|
391
322
|
*/
|
|
392
323
|
async finalize() {
|
|
393
|
-
console.log("\u6700\u7EC8\u786E\u5B9A\u6240\u6709chunk\u7684\u5904\u7406...");
|
|
394
324
|
if (this.completedChunks === 0) {
|
|
395
325
|
this.callbacks.onError?.("No chunks were processed.");
|
|
396
326
|
return;
|
|
@@ -400,7 +330,6 @@ class StreamingFeatureExtractorService {
|
|
|
400
330
|
NUM_SEQUENCE_FRAMES,
|
|
401
331
|
NUM_MEL_BINS
|
|
402
332
|
];
|
|
403
|
-
console.log(`\u7279\u5F81\u5904\u7406\u5B8C\u6210, \u603B\u7EF4\u5EA6: [${totalDimensions.join(", ")}]`);
|
|
404
333
|
this.callbacks.onComplete?.(totalDimensions);
|
|
405
334
|
}
|
|
406
335
|
/**
|
|
@@ -409,9 +338,9 @@ class StreamingFeatureExtractorService {
|
|
|
409
338
|
cleanup() {
|
|
410
339
|
this.isRunning = false;
|
|
411
340
|
this.audioBuffer = null;
|
|
412
|
-
if (this.
|
|
413
|
-
this.
|
|
414
|
-
this.
|
|
341
|
+
if (this.worker) {
|
|
342
|
+
this.worker.terminate();
|
|
343
|
+
this.worker = null;
|
|
415
344
|
}
|
|
416
345
|
this.chunkResults.forEach((chunk) => {
|
|
417
346
|
if (chunk && chunk.features) {
|
|
@@ -423,18 +352,16 @@ class StreamingFeatureExtractorService {
|
|
|
423
352
|
this.completedChunks = 0;
|
|
424
353
|
this.totalChunks = 0;
|
|
425
354
|
this.totalFramesProcessed = 0;
|
|
426
|
-
this.timer.reset();
|
|
427
355
|
}
|
|
428
356
|
/**
|
|
429
357
|
* 停止当前的流式处理。
|
|
430
358
|
*/
|
|
431
359
|
stop() {
|
|
432
360
|
if (this.isRunning) {
|
|
433
|
-
console.log("\u505C\u6B62\u6D41\u5F0F\u97F3\u9891\u5904\u7406");
|
|
434
361
|
this.isRunning = false;
|
|
435
|
-
if (this.
|
|
436
|
-
this.
|
|
437
|
-
this.
|
|
362
|
+
if (this.worker) {
|
|
363
|
+
this.worker.terminate();
|
|
364
|
+
this.worker = null;
|
|
438
365
|
}
|
|
439
366
|
this.callbacks = {};
|
|
440
367
|
this.chunkResults = [];
|
|
@@ -445,4 +372,4 @@ class StreamingFeatureExtractorService {
|
|
|
445
372
|
}
|
|
446
373
|
}
|
|
447
374
|
|
|
448
|
-
export {
|
|
375
|
+
export { StreamingFeatureExtractorService, createAudioContext };
|
|
@@ -11,29 +11,7 @@ export declare const NUM_MEL_BINS = 80;
|
|
|
11
11
|
export declare const NUM_SEQUENCE_FRAMES = 4;
|
|
12
12
|
/** 每个chunk的时长(秒) */
|
|
13
13
|
export declare const CHUNK_DURATION_SECONDS = 5;
|
|
14
|
-
/** 目标帧率 (FPS) */
|
|
15
|
-
export declare const TARGET_FPS = 25;
|
|
16
|
-
/** 每帧之间的间隔时间 (毫秒) */
|
|
17
|
-
export declare const FRAME_INTERVAL_MS: number;
|
|
18
|
-
/** 音频采样率 (Hz) */
|
|
19
|
-
export declare const SAMPLE_RATE = 16000;
|
|
20
|
-
/** 音频帧长度 (毫秒) */
|
|
21
|
-
export declare const FRAME_LENGTH_MS = 25;
|
|
22
|
-
/** 音频帧移 (毫秒) */
|
|
23
|
-
export declare const FRAME_SHIFT_MS = 10;
|
|
24
|
-
/** 能量下限,用于防止在对数计算中出现 log(0) 的情况 */
|
|
25
|
-
export declare const ENERGY_FLOOR = 1e-10;
|
|
26
|
-
/** 预加重系数 */
|
|
27
|
-
export declare const PREEMPH_COEFF = 0.97;
|
|
28
14
|
/** 上下文窗口中的总块数 */
|
|
29
15
|
export declare const WINDOW_NUM_CHUNKS = 32;
|
|
30
16
|
/** 上下文窗口的单边块数(半径) */
|
|
31
17
|
export declare const WINDOW_NUM_CHUNKS_HALF: number;
|
|
32
|
-
/** 批处理大小,用于批量推理以提高吞吐量 */
|
|
33
|
-
export declare const BATCH_SIZE = 32;
|
|
34
|
-
/** 默认的低频截止频率 (Hz) */
|
|
35
|
-
export declare const DEFAULT_LOW_FREQ = 20;
|
|
36
|
-
/** 是否移除直流分量(DC offset) */
|
|
37
|
-
export declare const REMOVE_DC_OFFSET = true;
|
|
38
|
-
/** FFT 计算大小是否向上舍入到最近的2的幂 */
|
|
39
|
-
export declare const ROUND_TO_POWER_OF_TWO = true;
|