@chat21/chat21-web-widget 5.1.32-rc4 → 5.1.33
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/.github/workflows/docker-community-push-latest.yml +13 -23
- package/.github/workflows/docker-image-tag-community-tag-push.yml +12 -22
- package/CHANGELOG.md +7 -50
- package/Dockerfile +5 -4
- package/angular.json +2 -5
- package/deploy_amazon_beta.sh +7 -17
- package/deploy_amazon_prod.sh +41 -0
- package/docs/changelog/this-branch.md +0 -36
- package/nginx.conf +2 -22
- package/package.json +1 -4
- package/src/app/app.component.ts +9 -10
- package/src/app/app.module.ts +0 -9
- package/src/app/component/conversation-detail/conversation/conversation.component.html +2 -8
- package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -12
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +5 -45
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +1 -1
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -10
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +0 -1
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +79 -146
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +13 -140
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +7 -124
- package/src/app/component/last-message/last-message.component.ts +1 -4
- package/src/app/component/message/audio/audio.component.ts +5 -0
- package/src/app/component/message/bubble-message/bubble-message.component.html +1 -6
- package/src/app/component/message/bubble-message/bubble-message.component.ts +1 -2
- package/src/app/providers/global-settings.service.ts +0 -21
- package/src/app/providers/translator.service.ts +0 -2
- package/src/app/sass/_variables.scss +0 -3
- package/src/app/utils/globals.ts +1 -7
- package/src/assets/i18n/en.json +0 -1
- package/src/assets/i18n/es.json +0 -1
- package/src/assets/i18n/fr.json +0 -1
- package/src/assets/i18n/it.json +0 -1
- package/src/chat21-core/models/message.ts +1 -2
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +2 -3
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +0 -12
- package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
- package/src/chat21-core/utils/utils-message.ts +0 -7
- package/src/chat21-core/utils/utils.ts +2 -5
- package/src/launch.js +41 -32
- package/src/launch_template.js +41 -32
- package/tsconfig.json +0 -5
- package/src/app/component/message/audio-sync/audio-sync.component.html +0 -19
- package/src/app/component/message/audio-sync/audio-sync.component.scss +0 -65
- package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +0 -23
- package/src/app/component/message/audio-sync/audio-sync.component.ts +0 -197
- package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +0 -12
- package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +0 -171
- package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +0 -39
- package/src/app/providers/voice/audio.types.ts +0 -34
- package/src/app/providers/voice/vad.service.spec.ts +0 -28
- package/src/app/providers/voice/vad.service.ts +0 -70
- package/src/app/providers/voice/voice.service.spec.ts +0 -60
- package/src/app/providers/voice/voice.service.ts +0 -294
- package/src/app/shims/onnxruntime-web-wasm.ts +0 -4
- package/src/assets/onnx/ort-wasm-simd-threaded.mjs +0 -59
- package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
- package/src/assets/vad/silero_vad_legacy.onnx +0 -0
- package/src/assets/vad/vad.worklet.bundle.min.js +0 -1
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Location } from '@angular/common';
|
|
2
|
-
import { TestBed } from '@angular/core/testing';
|
|
3
|
-
|
|
4
|
-
import { VadService } from './vad.service';
|
|
5
|
-
|
|
6
|
-
describe('VadService', () => {
|
|
7
|
-
let service: VadService;
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
TestBed.configureTestingModule({
|
|
11
|
-
providers: [
|
|
12
|
-
VadService,
|
|
13
|
-
{
|
|
14
|
-
provide: Location,
|
|
15
|
-
useValue: {
|
|
16
|
-
prepareExternalUrl: (url: string) => `/${url}`,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
});
|
|
21
|
-
service = TestBed.inject(VadService);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should expose VAD and ONNX WASM base URLs with trailing slash', () => {
|
|
25
|
-
expect(service.getVadAssetBaseUrl()).toBe('/assets/vad/');
|
|
26
|
-
expect(service.getOnnxWasmBaseUrl()).toBe('/assets/onnx/');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { Location } from '@angular/common';
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import { MicVAD, getDefaultRealTimeVADOptions } from '@ricky0123/vad-web';
|
|
4
|
-
import type { RealTimeVADOptions } from '@ricky0123/vad-web';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* MicVAD (@ricky0123/vad-web): modelli in assets/vad/, WASM ONNX in assets/onnx/
|
|
8
|
-
* (allineato a ort.env.wasm.wasmPaths = "/assets/onnx/").
|
|
9
|
-
*/
|
|
10
|
-
@Injectable({ providedIn: 'root' })
|
|
11
|
-
export class VadService {
|
|
12
|
-
private onnxRuntimeEnvPromise: Promise<void> | null = null;
|
|
13
|
-
|
|
14
|
-
constructor(private readonly location: Location) {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Base URL per silero_vad_legacy.onnx / vad.worklet.bundle.min.js
|
|
18
|
-
* (MicVAD usa baseAssetPath + nome file interno, non modelURL singolo).
|
|
19
|
-
*/
|
|
20
|
-
getVadAssetBaseUrl(): string {
|
|
21
|
-
return this.ensureTrailingSlash(this.location.prepareExternalUrl('assets/vad/'));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Base URL per ort-wasm-*.mjs / .wasm (es. /assets/onnx/). */
|
|
25
|
-
getOnnxWasmBaseUrl(): string {
|
|
26
|
-
return this.ensureTrailingSlash(this.location.prepareExternalUrl('assets/onnx/'));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Pre-configura il modulo onnxruntime-web/wasm (stesso usato da MicVAD):
|
|
31
|
-
* wasmPaths + numThreads prima del primo MicVAD.new.
|
|
32
|
-
*/
|
|
33
|
-
ensureOnnxRuntimeEnv(): Promise<void> {
|
|
34
|
-
if (!this.onnxRuntimeEnvPromise) {
|
|
35
|
-
this.onnxRuntimeEnvPromise = (async () => {
|
|
36
|
-
const ort = await import('onnxruntime-web/wasm');
|
|
37
|
-
const wasmBase = this.getOnnxWasmBaseUrl();
|
|
38
|
-
ort.env.wasm.wasmPaths = wasmBase;
|
|
39
|
-
ort.env.wasm.numThreads = 1;
|
|
40
|
-
ort.env.logLevel = 'error';
|
|
41
|
-
})();
|
|
42
|
-
}
|
|
43
|
-
return this.onnxRuntimeEnvPromise;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async createMicVad(overrides: Partial<RealTimeVADOptions>): Promise<MicVAD> {
|
|
47
|
-
await this.ensureOnnxRuntimeEnv();
|
|
48
|
-
const base = getDefaultRealTimeVADOptions('legacy');
|
|
49
|
-
const vadBase = this.getVadAssetBaseUrl();
|
|
50
|
-
const ortWasmBase = this.getOnnxWasmBaseUrl();
|
|
51
|
-
|
|
52
|
-
return MicVAD.new({
|
|
53
|
-
...base,
|
|
54
|
-
startOnLoad: false,
|
|
55
|
-
baseAssetPath: vadBase,
|
|
56
|
-
onnxWASMBasePath: ortWasmBase,
|
|
57
|
-
ortConfig: (ort) => {
|
|
58
|
-
base.ortConfig?.(ort);
|
|
59
|
-
ort.env.wasm.wasmPaths = ortWasmBase;
|
|
60
|
-
ort.env.wasm.numThreads = 1;
|
|
61
|
-
ort.env.logLevel = 'error';
|
|
62
|
-
},
|
|
63
|
-
...overrides,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private ensureTrailingSlash(path: string): string {
|
|
68
|
-
return path.endsWith('/') ? path : `${path}/`;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { VoiceService } from './voice.service';
|
|
4
|
-
import { VadService } from './vad.service';
|
|
5
|
-
|
|
6
|
-
describe('VoiceService', () => {
|
|
7
|
-
let service: VoiceService;
|
|
8
|
-
let vadService: jasmine.SpyObj<VadService>;
|
|
9
|
-
|
|
10
|
-
let mockVad: { start: jasmine.Spy; pause: jasmine.Spy; destroy: jasmine.Spy };
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
mockVad = {
|
|
14
|
-
start: jasmine.createSpy('start').and.returnValue(Promise.resolve()),
|
|
15
|
-
pause: jasmine.createSpy('pause').and.returnValue(Promise.resolve()),
|
|
16
|
-
destroy: jasmine.createSpy('destroy').and.returnValue(Promise.resolve()),
|
|
17
|
-
};
|
|
18
|
-
vadService = jasmine.createSpyObj('VadService', ['ensureOnnxRuntimeEnv', 'createMicVad']);
|
|
19
|
-
vadService.ensureOnnxRuntimeEnv.and.returnValue(Promise.resolve());
|
|
20
|
-
vadService.createMicVad.and.returnValue(Promise.resolve(mockVad as any));
|
|
21
|
-
|
|
22
|
-
TestBed.configureTestingModule({
|
|
23
|
-
providers: [VoiceService, { provide: VadService, useValue: vadService }],
|
|
24
|
-
});
|
|
25
|
-
service = TestBed.inject(VoiceService);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('startSession should call ensureOnnxRuntimeEnv', async () => {
|
|
29
|
-
const stream = new MediaStream();
|
|
30
|
-
spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
|
|
31
|
-
|
|
32
|
-
await service.startSession({});
|
|
33
|
-
|
|
34
|
-
expect(vadService.ensureOnnxRuntimeEnv).toHaveBeenCalled();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('startSession should request mic, create MicVAD, and start', async () => {
|
|
38
|
-
const stream = new MediaStream();
|
|
39
|
-
spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
|
|
40
|
-
|
|
41
|
-
await service.startSession({
|
|
42
|
-
onRecordingComplete: () => {},
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
expect(navigator.mediaDevices.getUserMedia).toHaveBeenCalled();
|
|
46
|
-
expect(vadService.createMicVad).toHaveBeenCalled();
|
|
47
|
-
expect(mockVad.start).toHaveBeenCalled();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('stopSession should destroy VAD and stop tracks', async () => {
|
|
51
|
-
const track = jasmine.createSpyObj<MediaStreamTrack>('MediaStreamTrack', ['stop']);
|
|
52
|
-
const stream = new MediaStream([track]);
|
|
53
|
-
spyOn(navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream));
|
|
54
|
-
|
|
55
|
-
await service.startSession({ onRecordingComplete: () => {} });
|
|
56
|
-
await service.stopSession();
|
|
57
|
-
|
|
58
|
-
expect(track.stop).toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
});
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import { Inject, Injectable, Optional } from '@angular/core';
|
|
2
|
-
import type { MicVAD } from '@ricky0123/vad-web';
|
|
3
|
-
import { getDefaultRealTimeVADOptions } from '@ricky0123/vad-web';
|
|
4
|
-
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
|
5
|
-
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
6
|
-
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS,
|
|
10
|
-
VoiceSegmentPayload,
|
|
11
|
-
VoiceSessionStartOptions,
|
|
12
|
-
} from './audio.types';
|
|
13
|
-
import { SpeechToTextProvider } from './STT&TTS/speech-provider.abstract';
|
|
14
|
-
import { VadService } from './vad.service';
|
|
15
|
-
|
|
16
|
-
const VOICE_RECORDING_MIME = 'audio/webm';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Voce: VadService (ONNX WASM) → MicVAD → MediaRecorder su ogni segmento parlato.
|
|
20
|
-
* Opzionalmente STT (`SpeechToTextProvider`) arricchisce il payload con `transcript`.
|
|
21
|
-
*/
|
|
22
|
-
@Injectable({ providedIn: 'root' })
|
|
23
|
-
export class VoiceService {
|
|
24
|
-
private vad?: MicVAD;
|
|
25
|
-
private stream?: MediaStream;
|
|
26
|
-
private mediaRecorder?: MediaRecorder;
|
|
27
|
-
private audioChunks: Blob[] = [];
|
|
28
|
-
private sessionConstraints: MediaStreamConstraints = DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS;
|
|
29
|
-
private onRecordingComplete?: (result: VoiceSegmentPayload) => void;
|
|
30
|
-
private enableTranscription = true;
|
|
31
|
-
|
|
32
|
-
private readonly audioSegmentSubject = new Subject<VoiceSegmentPayload>();
|
|
33
|
-
/** Emesso a ogni fine segmento parlato: audio WebM + opzionalmente `transcript` / `transcriptionError`. */
|
|
34
|
-
readonly audioSegment$: Observable<VoiceSegmentPayload> = this.audioSegmentSubject.asObservable();
|
|
35
|
-
|
|
36
|
-
// 🔊 REALTIME VOLUME STREAM
|
|
37
|
-
private readonly volumeSubject = new BehaviorSubject<number>(0);
|
|
38
|
-
readonly volume$: Observable<number> = this.volumeSubject.asObservable();
|
|
39
|
-
|
|
40
|
-
// 🎧 AUDIO ANALYSER
|
|
41
|
-
private audioContext?: AudioContext;
|
|
42
|
-
private analyser?: AnalyserNode;
|
|
43
|
-
/** Buffer dedicato (`ArrayBuffer`) per compatibilità con `getByteFrequencyData`. */
|
|
44
|
-
private dataArray?: Uint8Array;
|
|
45
|
-
|
|
46
|
-
private readonly logger: LoggerService = LoggerInstance.getInstance();
|
|
47
|
-
|
|
48
|
-
constructor(
|
|
49
|
-
private readonly vadService: VadService,
|
|
50
|
-
@Optional() @Inject(SpeechToTextProvider) private readonly speechToText: SpeechToTextProvider | null,
|
|
51
|
-
) {}
|
|
52
|
-
|
|
53
|
-
get isSessionActive(): boolean {
|
|
54
|
-
return !!this.vad || !!this.stream;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Richiede il microfono, avvia VAD in ascolto (inizio/fine parlato) e registra in WebM per segmento.
|
|
59
|
-
*/
|
|
60
|
-
async startSession(options: VoiceSessionStartOptions = {}): Promise<void> {
|
|
61
|
-
await this.stopSession();
|
|
62
|
-
|
|
63
|
-
this.sessionConstraints = options.constraints ?? DEFAULT_VOICE_MEDIA_STREAM_CONSTRAINTS;
|
|
64
|
-
this.onRecordingComplete = options.onRecordingComplete;
|
|
65
|
-
this.enableTranscription = options.enableTranscription !== false;
|
|
66
|
-
|
|
67
|
-
await this.vadService.ensureOnnxRuntimeEnv();
|
|
68
|
-
|
|
69
|
-
this.stream = await navigator.mediaDevices.getUserMedia(this.sessionConstraints);
|
|
70
|
-
|
|
71
|
-
// 🎧 AUDIO ANALYSER INIT
|
|
72
|
-
this.initAudioAnalyser(this.stream);
|
|
73
|
-
|
|
74
|
-
const vadDefaults = getDefaultRealTimeVADOptions('legacy');
|
|
75
|
-
|
|
76
|
-
this.vad = await this.vadService.createMicVad({
|
|
77
|
-
getStream: async () => this.stream as MediaStream,
|
|
78
|
-
pauseStream: vadDefaults.pauseStream,
|
|
79
|
-
resumeStream: async () => {
|
|
80
|
-
this.stream = await navigator.mediaDevices.getUserMedia(this.sessionConstraints);
|
|
81
|
-
this.initAudioAnalyser(this.stream);
|
|
82
|
-
return this.stream;
|
|
83
|
-
},
|
|
84
|
-
onSpeechStart: () => {
|
|
85
|
-
this.logger.log('[VoiceService] speech start');
|
|
86
|
-
this.startMediaRecorderSegment();
|
|
87
|
-
},
|
|
88
|
-
onSpeechEnd: () => {
|
|
89
|
-
this.logger.log('[VoiceService] speech end');
|
|
90
|
-
this.stopMediaRecorderSegment();
|
|
91
|
-
},
|
|
92
|
-
minSpeechMs: 480,
|
|
93
|
-
redemptionMs: 1920,
|
|
94
|
-
preSpeechPadMs: 960,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
await this.vad.start();
|
|
98
|
-
|
|
99
|
-
// 🔁 start volume loop
|
|
100
|
-
this.startVolumeLoop();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @param options.discardInProgressSegment — non inviare STT/upload per il segmento WebM corrente (es. interruzione da messaggio in arrivo).
|
|
105
|
-
*/
|
|
106
|
-
async stopSession(options?: { discardInProgressSegment?: boolean }): Promise<void> {
|
|
107
|
-
const discard = options?.discardInProgressSegment === true;
|
|
108
|
-
|
|
109
|
-
if (this.mediaRecorder) {
|
|
110
|
-
if (discard) {
|
|
111
|
-
this.mediaRecorder.onstop = null;
|
|
112
|
-
this.mediaRecorder.ondataavailable = null;
|
|
113
|
-
}
|
|
114
|
-
if (this.mediaRecorder.state === 'recording') {
|
|
115
|
-
this.mediaRecorder.stop();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
this.mediaRecorder = undefined;
|
|
120
|
-
this.audioChunks = [];
|
|
121
|
-
|
|
122
|
-
if (this.vad) {
|
|
123
|
-
try {
|
|
124
|
-
await this.vad.pause();
|
|
125
|
-
await this.vad.destroy();
|
|
126
|
-
} catch (e) {
|
|
127
|
-
this.logger.log('[VoiceService] stopSession VAD cleanup', e);
|
|
128
|
-
}
|
|
129
|
-
this.vad = undefined;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (this.stream) {
|
|
133
|
-
this.stream.getTracks().forEach((t) => t.stop());
|
|
134
|
-
this.stream = undefined;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 🎧 cleanup audio context
|
|
138
|
-
this.audioContext?.close();
|
|
139
|
-
this.audioContext = undefined;
|
|
140
|
-
this.analyser = undefined;
|
|
141
|
-
this.dataArray = undefined;
|
|
142
|
-
|
|
143
|
-
this.volumeSubject.next(0);
|
|
144
|
-
|
|
145
|
-
this.onRecordingComplete = undefined;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Scarta il segmento WebM in corso (nessun upload/STT) senza chiudere VAD, mic o sessione.
|
|
150
|
-
* Lo stream resta in ascolto per il prossimo `onSpeechStart`.
|
|
151
|
-
*/
|
|
152
|
-
discardCurrentRecordingSegment(): void {
|
|
153
|
-
if (this.mediaRecorder) {
|
|
154
|
-
this.mediaRecorder.onstop = null;
|
|
155
|
-
this.mediaRecorder.ondataavailable = null;
|
|
156
|
-
if (this.mediaRecorder.state === 'recording') {
|
|
157
|
-
this.mediaRecorder.stop();
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
this.mediaRecorder = undefined;
|
|
161
|
-
this.audioChunks = [];
|
|
162
|
-
this.logger.log('[VoiceService] discarded in-progress segment; VAD session unchanged');
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* 🎧 AUDIO ANALYSER INIT
|
|
167
|
-
*/
|
|
168
|
-
private initAudioAnalyser(stream: MediaStream): void {
|
|
169
|
-
this.audioContext = new AudioContext();
|
|
170
|
-
|
|
171
|
-
const source = this.audioContext.createMediaStreamSource(stream);
|
|
172
|
-
|
|
173
|
-
this.analyser = this.audioContext.createAnalyser();
|
|
174
|
-
this.analyser.fftSize = 256;
|
|
175
|
-
|
|
176
|
-
const bins = this.analyser.frequencyBinCount;
|
|
177
|
-
this.dataArray = new Uint8Array(new ArrayBuffer(bins));
|
|
178
|
-
|
|
179
|
-
source.connect(this.analyser);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* 🔁 VOLUME LOOP
|
|
184
|
-
*/
|
|
185
|
-
private startVolumeLoop(): void {
|
|
186
|
-
const tick = () => {
|
|
187
|
-
if (!this.analyser || !this.dataArray) {
|
|
188
|
-
requestAnimationFrame(tick);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
this.analyser.getByteFrequencyData(
|
|
193
|
-
this.dataArray as Parameters<AnalyserNode['getByteFrequencyData']>[0],
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
let sum = 0;
|
|
197
|
-
for (let i = 0; i < this.dataArray.length; i++) {
|
|
198
|
-
sum += this.dataArray[i];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const volume = sum / this.dataArray.length;
|
|
202
|
-
|
|
203
|
-
this.volumeSubject.next(volume);
|
|
204
|
-
|
|
205
|
-
requestAnimationFrame(tick);
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
tick();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* 🎙️ RECORD SEGMENT START
|
|
213
|
-
*/
|
|
214
|
-
private startMediaRecorderSegment(): void {
|
|
215
|
-
if (this.mediaRecorder?.state === 'recording') return;
|
|
216
|
-
if (!this.stream) return;
|
|
217
|
-
|
|
218
|
-
this.audioChunks = [];
|
|
219
|
-
|
|
220
|
-
this.mediaRecorder = new MediaRecorder(this.stream, {
|
|
221
|
-
mimeType: VOICE_RECORDING_MIME,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
this.mediaRecorder.ondataavailable = (event) => {
|
|
225
|
-
if (event.data.size > 0) {
|
|
226
|
-
this.audioChunks.push(event.data);
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
this.mediaRecorder.start();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* 🛑 RECORD SEGMENT STOP
|
|
235
|
-
*/
|
|
236
|
-
private stopMediaRecorderSegment(): void {
|
|
237
|
-
if (!this.mediaRecorder) return;
|
|
238
|
-
|
|
239
|
-
this.mediaRecorder.stop();
|
|
240
|
-
|
|
241
|
-
this.mediaRecorder.onstop = () => {
|
|
242
|
-
const blob = new Blob(this.audioChunks, {
|
|
243
|
-
type: VOICE_RECORDING_MIME,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
void this.finalizeSegment(blob, VOICE_RECORDING_MIME);
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* 🧠 FINALIZE SEGMENT (STT optional)
|
|
252
|
-
*/
|
|
253
|
-
private async finalizeSegment(blob: Blob, mimeType: string): Promise<void> {
|
|
254
|
-
const base: VoiceSegmentPayload = { blob, mimeType };
|
|
255
|
-
|
|
256
|
-
const runStt =
|
|
257
|
-
this.enableTranscription &&
|
|
258
|
-
!!this.speechToText &&
|
|
259
|
-
blob.size > 0;
|
|
260
|
-
|
|
261
|
-
if (!runStt) {
|
|
262
|
-
this.emitSegmentPayload(base);
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
try {
|
|
267
|
-
const { text } = await this.speechToText.transcribe({
|
|
268
|
-
audio: blob,
|
|
269
|
-
mimeType,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
this.emitSegmentPayload({ ...base, transcript: text });
|
|
273
|
-
} catch (e) {
|
|
274
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
275
|
-
this.logger.log('[VoiceService] transcription failed', msg);
|
|
276
|
-
|
|
277
|
-
this.emitSegmentPayload({
|
|
278
|
-
...base,
|
|
279
|
-
transcriptionError: msg,
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* 📡 EMIT RESULT
|
|
286
|
-
*/
|
|
287
|
-
private emitSegmentPayload(payload: VoiceSegmentPayload): void {
|
|
288
|
-
this.logger.log( '[VoiceService] segment ready', payload.transcript ?? payload.transcriptionError ?? payload.blob.size);
|
|
289
|
-
|
|
290
|
-
this.audioSegmentSubject.next(payload);
|
|
291
|
-
|
|
292
|
-
this.onRecordingComplete?.(payload);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
async function ortWasmThreaded(moduleArg={}){var moduleRtn;var h=moduleArg,aa=!!globalThis.window,k=!!globalThis.WorkerGlobalScope,m=globalThis.process?.versions?.node&&"renderer"!=globalThis.process?.type,n=k&&self.name?.startsWith("em-pthread");if(m){const {createRequire:a}=await import("module");var require=a(import.meta.url),ba=require("worker_threads");global.Worker=ba.Worker;n=(k=!ba.ic)&&"em-pthread"==ba.workerData}h.mountExternalData=(a,b)=>{a.startsWith("./")&&(a=a.substring(2));(h.Sb||(h.Sb=new Map)).set(a,b)};
|
|
2
|
-
h.unmountExternalData=()=>{delete h.Sb};var SharedArrayBuffer=globalThis.SharedArrayBuffer??(new WebAssembly.Memory({initial:0,maximum:0,kc:!0})).buffer.constructor,ca="./this.program",da=(a,b)=>{throw b;},ea=import.meta.url,fa="",ha,ia;
|
|
3
|
-
if(m){var fs=require("fs");ea.startsWith("file:")&&(fa=require("path").dirname(require("url").fileURLToPath(ea))+"/");ia=a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a)};ha=async a=>{a=ja(a)?new URL(a):a;return fs.readFileSync(a,void 0)};1<process.argv.length&&(ca=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);da=(a,b)=>{process.exitCode=a;throw b;}}else if(aa||k){try{fa=(new URL(".",ea)).href}catch{}m||(k&&(ia=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";
|
|
4
|
-
b.send(null);return new Uint8Array(b.response)}),ha=async a=>{if(ja(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&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);})}var ka=console.log.bind(console),la=console.error.bind(console);
|
|
5
|
-
if(m){var ma=require("util"),na=a=>"object"==typeof a?ma.inspect(a):a;ka=(...a)=>fs.writeSync(1,a.map(na).join(" ")+"\n");la=(...a)=>fs.writeSync(2,a.map(na).join(" ")+"\n")}var oa=ka,p=la,q,r,pa=!1,t,ja=a=>a.startsWith("file://");function v(){x.buffer!=z.buffer&&qa()}var ra,sa;
|
|
6
|
-
if(m&&n){var ta=ba.parentPort;ta.on("message",a=>global.onmessage?.({data:a}));Object.assign(globalThis,{self:global,postMessage:a=>ta.postMessage(a)});process.on("uncaughtException",a=>{postMessage({Qb:"uncaughtException",error:a});process.exit(1)})}var ua;
|
|
7
|
-
if(n){var va=!1;self.onunhandledrejection=b=>{throw b.reason||b;};function a(b){try{var d=b.data,c=d.Qb;if("load"===c){let e=[];self.onmessage=f=>e.push(f);ua=()=>{postMessage({Qb:"loaded"});for(let f of e)a(f);self.onmessage=a};for(const f of d.$b)if(!h[f]||h[f].proxy)h[f]=(...g)=>{postMessage({Qb:"callHandler",Zb:f,args:g})},"print"==f&&(oa=h[f]),"printErr"==f&&(p=h[f]);x=d.ec;qa();r=d.fc;wa();xa()}else if("run"===c){ya(d.Pb);za(d.Pb,0,0,1,0,0);Aa();Ba(d.Pb);va||=!0;try{Ca(d.cc,d.Ub)}catch(e){if("unwind"!=
|
|
8
|
-
e)throw e;}}else"setimmediate"!==d.target&&("checkMailbox"===c?va&&Da():c&&(p(`worker: received unknown command ${c}`),p(d)))}catch(e){throw Ea(),e;}}self.onmessage=a}var z,A,Fa,C,D,Ga,G,H,Ha=!1;function qa(){var a=x.buffer;h.HEAP8=z=new Int8Array(a);Fa=new Int16Array(a);h.HEAPU8=A=new Uint8Array(a);new Uint16Array(a);h.HEAP32=C=new Int32Array(a);h.HEAPU32=D=new Uint32Array(a);Ga=new Float32Array(a);G=new Float64Array(a);H=new BigInt64Array(a);new BigUint64Array(a)}
|
|
9
|
-
function Ia(){Ha=!0;n?ua():I.Ua()}function J(a){a="Aborted("+a+")";p(a);pa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");sa?.(a);throw a;}var Ja;async function Ka(a){if(!q)try{var b=await ha(a);return new Uint8Array(b)}catch{}if(a==Ja&&q)a=new Uint8Array(q);else if(ia)a=ia(a);else throw"both async and sync fetching of the wasm failed";return a}
|
|
10
|
-
async function La(a,b){try{var d=await Ka(a);return await WebAssembly.instantiate(d,b)}catch(c){p(`failed to asynchronously prepare wasm: ${c}`),J(c)}}async function Na(a){var b=Ja;if(!q&&!ja(b)&&!m)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){p(`wasm streaming compile failed: ${c}`),p("falling back to ArrayBuffer instantiation")}return La(b,a)}
|
|
11
|
-
function Oa(){Pa={S:Qa,f:Ra,w:Sa,e:Ta,j:Ua,g:Va,T:Wa,b:Xa,G:Ya,ua:Za,k:$a,K:ab,Ka:bb,qa:cb,sa:db,La:eb,Ia:fb,Ba:gb,Ha:hb,Z:ib,ra:jb,oa:kb,Ja:lb,pa:mb,Qa:nb,Ea:ob,ma:pb,va:qb,ja:rb,U:sb,Da:Ba,Na:tb,ya:ub,za:vb,Aa:wb,wa:xb,xa:yb,ka:zb,Sa:Ab,Pa:Bb,W:Cb,V:Db,Oa:Eb,F:Fb,Ma:Gb,na:Hb,u:Ib,H:Jb,R:Kb,la:Lb,da:Mb,Ta:Nb,Fa:Ob,Ga:Pb,ta:Qb,L:Rb,Y:Sb,Ca:Tb,X:Ub,$:Vb,M:Wb,aa:Xb,N:Yb,v:Zb,c:$b,m:ac,n:bc,r:cc,ea:dc,x:ec,o:fc,O:gc,D:hc,I:ic,ba:jc,ca:kc,Q:lc,P:mc,fa:nc,z:oc,E:pc,d:qc,q:rc,i:sc,_:tc,l:uc,p:vc,s:wc,t:xc,
|
|
12
|
-
y:yc,ga:zc,B:Ac,J:Bc,C:Cc,ha:Dc,ia:Ec,A:Fc,h:Gc,a:x,Ra:Hc};return{a:Pa}}
|
|
13
|
-
async function wa(){function a(c,e){I=c.exports;I=Ic();Jc.push(I.wb);c=I;h._OrtInit=c.Va;h._OrtGetLastError=c.Wa;h._OrtCreateSessionOptions=c.Xa;h._OrtAppendExecutionProvider=c.Ya;h._OrtAddFreeDimensionOverride=c.Za;h._OrtAddSessionConfigEntry=c._a;h._OrtReleaseSessionOptions=c.$a;h._OrtCreateSession=c.ab;h._OrtReleaseSession=c.bb;h._OrtGetInputOutputCount=c.cb;h._OrtGetInputOutputMetadata=c.db;h._OrtFree=c.eb;h._OrtCreateTensor=c.fb;h._OrtGetTensorData=c.gb;h._OrtReleaseTensor=c.hb;h._OrtCreateRunOptions=
|
|
14
|
-
c.ib;h._OrtAddRunConfigEntry=c.jb;h._OrtReleaseRunOptions=c.kb;h._OrtCreateBinding=c.lb;h._OrtBindInput=c.mb;h._OrtBindOutput=c.nb;h._OrtClearBoundOutputs=c.ob;h._OrtReleaseBinding=c.pb;h._OrtRunWithBinding=c.qb;h._OrtRun=c.rb;h._OrtEndProfiling=c.sb;Kc=c.tb;Lc=h._free=c.ub;Mc=h._malloc=c.vb;za=c.yb;Ea=c.zb;Nc=c.Ab;Oc=c.Bb;Pc=c.Cb;Qc=c.Db;Rc=c.Eb;K=c.Fb;L=c.Gb;Sc=c.Hb;M=c.Ib;Tc=c.Jb;N=c.Kb;Uc=c.Lb;Vc=c.Mb;Wc=c.Nb;Xc=c.Ob;Yc=c.xb;r=e;return I}var b=Oa();if(h.instantiateWasm)return new Promise(c=>{h.instantiateWasm(b,
|
|
15
|
-
(e,f)=>{c(a(e,f))})});if(n){var d=new WebAssembly.Instance(r,Oa());return a(d,r)}Ja??=h.locateFile?h.locateFile?h.locateFile("ort-wasm-simd-threaded.wasm",fa):fa+"ort-wasm-simd-threaded.wasm":(new URL("ort-wasm-simd-threaded.wasm",import.meta.url)).href;return function(c){return a(c.instance,c.module)}(await Na(b))}class Zc{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
|
|
16
|
-
var $c=a=>{a.terminate();a.onmessage=()=>{}},ad=[],O=0,P=null,dd=a=>{0==Q.length&&(bd(),cd(Q[0]));var b=Q.pop();if(!b)return 6;R.push(b);S[a.Pb]=b;b.Pb=a.Pb;var d={Qb:"run",cc:a.bc,Ub:a.Ub,Pb:a.Pb};m&&b.unref();b.postMessage(d,a.Yb);return 0},T=0,U=(a,b,...d)=>{var c=16*d.length,e=N(),f=Tc(c),g=f>>>3,l;for(l of d)"bigint"==typeof l?((v(),H)[g++>>>0]=1n,(v(),H)[g++>>>0]=l):((v(),H)[g++>>>0]=0n,(v(),G)[g++>>>0]=l);a=Nc(a,0,c,f,b);M(e);return a};
|
|
17
|
-
function Hc(a){if(n)return U(0,1,a);t=a;if(!(0<T)){for(var b of R)$c(b);for(b of Q)$c(b);Q=[];R=[];S={};pa=!0}da(a,new Zc(a))}function ed(a){if(n)return U(1,0,a);Qb(a)}var Qb=a=>{t=a;if(n)throw ed(a),"unwind";Hc(a)},Q=[],R=[],Jc=[],S={};function fd(){for(var a=h.numThreads-1;a--;)bd();ad.push(async()=>{var b=gd();O++;await b;O--;0==O&&P&&(b=P,P=null,b())})}var hd=a=>{var b=a.Pb;delete S[b];Q.push(a);R.splice(R.indexOf(a),1);a.Pb=0;Oc(b)};function Aa(){Jc.forEach(a=>a())}
|
|
18
|
-
var cd=a=>new Promise(b=>{a.onmessage=f=>{var g=f.data;f=g.Qb;if(g.Tb&&g.Tb!=Kc()){var l=S[g.Tb];l?l.postMessage(g,g.Yb):p(`Internal error! Worker sent a message "${f}" to target pthread ${g.Tb}, but that thread no longer exists!`)}else if("checkMailbox"===f)Da();else if("spawnThread"===f)dd(g);else if("cleanupThread"===f)jd(()=>{hd(S[g.dc])});else if("loaded"===f)a.loaded=!0,m&&!a.Pb&&a.unref(),b(a);else if("setimmediate"===g.target)a.postMessage(g);else if("uncaughtException"===f)a.onerror(g.error);
|
|
19
|
-
else if("callHandler"===f)h[g.Zb](...g.args);else f&&p(`worker sent an unknown command ${f}`)};a.onerror=f=>{p(`${"worker sent an error!"} ${f.filename}:${f.lineno}: ${f.message}`);throw f;};m&&(a.on("message",f=>a.onmessage({data:f})),a.on("error",f=>a.onerror(f)));var d=[],c=[],e;for(e of c)h.propertyIsEnumerable(e)&&d.push(e);a.postMessage({Qb:"load",$b:d,ec:x,fc:r})});async function gd(){if(!n)return Promise.all(Q.map(cd))}
|
|
20
|
-
function bd(){var a=new Worker(new URL(import.meta.url),{type:"module",workerData:"em-pthread",name:"em-pthread"});Q.push(a)}function ya(a){var b=(v(),D)[a+52>>>2>>>0];a=(v(),D)[a+56>>>2>>>0];Sc(b,b-a);M(b)}var kd=[],V=a=>{var b=kd[a];b||(kd[a]=b=Yc.get(a));return b},Ca=(a,b)=>{T=0;a=V(a)(b);0<T?t=a:Pc(a)},x,ld=[],md=0;function Ra(a){a>>>=0;var b=new nd(a);0==(v(),z)[b.Rb+12>>>0]&&(od(b,!0),md--);pd(b,!1);ld.push(b);return Xc(a)}
|
|
21
|
-
var W=0,Sa=()=>{K(0,0);var a=ld.pop();Uc(a.Vb);W=0};function od(a,b){b=b?1:0;(v(),z)[a.Rb+12>>>0]=b}function pd(a,b){b=b?1:0;(v(),z)[a.Rb+13>>>0]=b}class nd{constructor(a){this.Vb=a;this.Rb=a-24}}var qd=a=>{var b=W;if(!b)return L(0),0;var d=new nd(b);(v(),D)[d.Rb+16>>>2>>>0]=b;var c=(v(),D)[d.Rb+4>>>2>>>0];if(!c)return L(0),b;for(var e of a){if(0===e||e===c)break;if(Wc(e,c,d.Rb+16))return L(e),b}L(c);return b};function Ta(){return qd([])}function Ua(a){return qd([a>>>0])}
|
|
22
|
-
function Va(a,b,d,c){return qd([a>>>0,b>>>0,d>>>0,c>>>0])}var Wa=()=>{var a=ld.pop();a||J("no exception to throw");var b=a.Vb;0==(v(),z)[a.Rb+13>>>0]&&(ld.push(a),pd(a,!0),od(a,!1),md++);Vc(b);W=b;throw W;};function Xa(a,b,d){a>>>=0;var c=new nd(a);b>>>=0;d>>>=0;(v(),D)[c.Rb+16>>>2>>>0]=0;(v(),D)[c.Rb+4>>>2>>>0]=b;(v(),D)[c.Rb+8>>>2>>>0]=d;Vc(a);W=a;md++;throw W;}var Ya=()=>md;function rd(a,b,d,c){return n?U(2,1,a,b,d,c):Za(a,b,d,c)}
|
|
23
|
-
function Za(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;if(!globalThis.SharedArrayBuffer)return 6;var e=[];if(n&&0===e.length)return rd(a,b,d,c);a={bc:d,Pb:a,Ub:c,Yb:e};return n?(a.Qb="spawnThread",postMessage(a,e),0):dd(a)}function $a(a){W||=a>>>0;throw W;}
|
|
24
|
-
var sd=globalThis.TextDecoder&&new TextDecoder,td=(a,b=0,d,c)=>{b>>>=0;var e=b;d=e+d;if(c)c=d;else{for(;a[e]&&!(e>=d);)++e;c=e}if(16<c-b&&a.buffer&&sd)return sd.decode(a.buffer instanceof ArrayBuffer?a.subarray(b,c):a.slice(b,c));for(e="";b<c;)if(d=a[b++],d&128){var f=a[b++]&63;if(192==(d&224))e+=String.fromCharCode((d&31)<<6|f);else{var g=a[b++]&63;d=224==(d&240)?(d&15)<<12|f<<6|g:(d&7)<<18|f<<12|g<<6|a[b++]&63;65536>d?e+=String.fromCharCode(d):(d-=65536,e+=String.fromCharCode(55296|d>>10,56320|
|
|
25
|
-
d&1023))}}else e+=String.fromCharCode(d);return e},ud=(a,b,d)=>(a>>>=0)?td((v(),A),a,b,d):"";function ab(a,b,d){return n?U(3,1,a,b,d):0}function bb(a,b){if(n)return U(4,1,a,b)}function cb(a,b){if(n)return U(5,1,a,b)}function db(a,b,d){if(n)return U(6,1,a,b,d)}function eb(a,b,d){return n?U(7,1,a,b,d):0}function fb(a,b){if(n)return U(8,1,a,b)}function gb(a,b,d){if(n)return U(9,1,a,b,d)}function hb(a,b,d,c){if(n)return U(10,1,a,b,d,c)}function ib(a,b,d,c){if(n)return U(11,1,a,b,d,c)}
|
|
26
|
-
function jb(a,b,d,c){if(n)return U(12,1,a,b,d,c)}function kb(a){if(n)return U(13,1,a)}function lb(a,b){if(n)return U(14,1,a,b)}function mb(a,b,d){if(n)return U(15,1,a,b,d)}var nb=()=>J("");function ob(a){za(a>>>0,!k,1,!aa,131072,!1);Aa()}
|
|
27
|
-
var jd=a=>{if(!pa)try{if(a(),!(0<T))try{n?Kc()&&Pc(t):Qb(t)}catch(b){b instanceof Zc||"unwind"==b||da(1,b)}}catch(b){b instanceof Zc||"unwind"==b||da(1,b)}},vd=!Atomics.waitAsync||globalThis.navigator?.userAgent&&91>Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)||[])[2]);function Ba(a){a>>>=0;vd||(Atomics.waitAsync((v(),C),a>>>2,a).value.then(Da),a+=128,Atomics.store((v(),C),a>>>2,1))}var Da=()=>jd(()=>{var a=Kc();a&&(Ba(a),Rc())});
|
|
28
|
-
function pb(a,b){a>>>=0;a==b>>>0?setTimeout(Da):n?postMessage({Tb:a,Qb:"checkMailbox"}):(a=S[a])&&a.postMessage({Qb:"checkMailbox"})}var wd=[];function qb(a,b,d,c,e){b>>>=0;e>>>=0;wd.length=0;d=e>>>3;for(c=e+c>>>3;d<c;){var f;(v(),H)[d++>>>0]?f=(v(),H)[d++>>>0]:f=(v(),G)[d++>>>0];wd.push(f)}return(b?xd[b]:yd[a])(...wd)}var rb=()=>{T=0};function sb(a){a>>>=0;n?postMessage({Qb:"cleanupThread",dc:a}):hd(S[a])}function tb(a){m&&S[a>>>0].ref()}
|
|
29
|
-
function ub(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getUTCSeconds();(v(),C)[b+4>>>2>>>0]=a.getUTCMinutes();(v(),C)[b+8>>>2>>>0]=a.getUTCHours();(v(),C)[b+12>>>2>>>0]=a.getUTCDate();(v(),C)[b+16>>>2>>>0]=a.getUTCMonth();(v(),C)[b+20>>>2>>>0]=a.getUTCFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;(v(),C)[b+28>>>2>>>0]=a}
|
|
30
|
-
var zd=a=>0===a%4&&(0!==a%100||0===a%400),Ad=[0,31,60,91,121,152,182,213,244,274,305,335],Bd=[0,31,59,90,120,151,181,212,243,273,304,334];
|
|
31
|
-
function vb(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);b>>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getSeconds();(v(),C)[b+4>>>2>>>0]=a.getMinutes();(v(),C)[b+8>>>2>>>0]=a.getHours();(v(),C)[b+12>>>2>>>0]=a.getDate();(v(),C)[b+16>>>2>>>0]=a.getMonth();(v(),C)[b+20>>>2>>>0]=a.getFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getDay();var d=(zd(a.getFullYear())?Ad:Bd)[a.getMonth()]+a.getDate()-1|0;(v(),C)[b+28>>>2>>>0]=d;(v(),C)[b+36>>>2>>>0]=-(60*a.getTimezoneOffset());d=(new Date(a.getFullYear(),
|
|
32
|
-
6,1)).getTimezoneOffset();var c=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;(v(),C)[b+32>>>2>>>0]=a}
|
|
33
|
-
function wb(a){a>>>=0;var b=new Date((v(),C)[a+20>>>2>>>0]+1900,(v(),C)[a+16>>>2>>>0],(v(),C)[a+12>>>2>>>0],(v(),C)[a+8>>>2>>>0],(v(),C)[a+4>>>2>>>0],(v(),C)[a>>>2>>>0],0),d=(v(),C)[a+32>>>2>>>0],c=b.getTimezoneOffset(),e=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),f=(new Date(b.getFullYear(),0,1)).getTimezoneOffset(),g=Math.min(f,e);0>d?(v(),C)[a+32>>>2>>>0]=Number(e!=f&&g==c):0<d!=(g==c)&&(e=Math.max(f,e),b.setTime(b.getTime()+6E4*((0<d?g:e)-c)));(v(),C)[a+24>>>2>>>0]=b.getDay();d=(zd(b.getFullYear())?
|
|
34
|
-
Ad:Bd)[b.getMonth()]+b.getDate()-1|0;(v(),C)[a+28>>>2>>>0]=d;(v(),C)[a>>>2>>>0]=b.getSeconds();(v(),C)[a+4>>>2>>>0]=b.getMinutes();(v(),C)[a+8>>>2>>>0]=b.getHours();(v(),C)[a+12>>>2>>>0]=b.getDate();(v(),C)[a+16>>>2>>>0]=b.getMonth();(v(),C)[a+20>>>2>>>0]=b.getYear();a=b.getTime();return BigInt(isNaN(a)?-1:a/1E3)}function xb(a,b,d,c,e,f,g){return n?U(16,1,a,b,d,c,e,f,g):-52}function yb(a,b,d,c,e,f){if(n)return U(17,1,a,b,d,c,e,f)}var X={},Ib=()=>performance.timeOrigin+performance.now();
|
|
35
|
-
function zb(a,b){if(n)return U(18,1,a,b);X[a]&&(clearTimeout(X[a].id),delete X[a]);if(!b)return 0;var d=setTimeout(()=>{delete X[a];jd(()=>Qc(a,performance.timeOrigin+performance.now()))},b);X[a]={id:d,lc:b};return 0}
|
|
36
|
-
var Y=(a,b,d)=>{var c=(v(),A);b>>>=0;if(0<d){var e=b;d=b+d-1;for(var f=0;f<a.length;++f){var g=a.codePointAt(f);if(127>=g){if(b>=d)break;c[b++>>>0]=g}else if(2047>=g){if(b+1>=d)break;c[b++>>>0]=192|g>>6;c[b++>>>0]=128|g&63}else if(65535>=g){if(b+2>=d)break;c[b++>>>0]=224|g>>12;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63}else{if(b+3>=d)break;c[b++>>>0]=240|g>>18;c[b++>>>0]=128|g>>12&63;c[b++>>>0]=128|g>>6&63;c[b++>>>0]=128|g&63;f++}}c[b>>>0]=0;a=b-e}else a=0;return a};
|
|
37
|
-
function Ab(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;var e=(new Date).getFullYear(),f=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();var g=Math.max(f,e);(v(),D)[a>>>2>>>0]=60*g;(v(),C)[b>>>2>>>0]=Number(f!=e);b=l=>{var u=Math.abs(l);return`UTC${0<=l?"-":"+"}${String(Math.floor(u/60)).padStart(2,"0")}${String(u%60).padStart(2,"0")}`};a=b(f);b=b(e);e<f?(Y(a,d,17),Y(b,c,17)):(Y(a,c,17),Y(b,d,17))}var Eb=()=>Date.now(),Cd=1;
|
|
38
|
-
function Bb(a,b,d){d>>>=0;if(!(0<=a&&3>=a))return 28;if(0===a)a=Date.now();else if(Cd)a=performance.timeOrigin+performance.now();else return 52;a=Math.round(1E6*a);(v(),H)[d>>>3>>>0]=BigInt(a);return 0}var Dd=[];function Cb(a,b,d){a>>>=0;b>>>=0;d>>>=0;Dd.length=0;for(var c;c=(v(),A)[b++>>>0];){var e=105!=c;e&=112!=c;d+=e&&d%8?4:0;Dd.push(112==c?(v(),D)[d>>>2>>>0]:106==c?(v(),H)[d>>>3>>>0]:105==c?(v(),C)[d>>>2>>>0]:(v(),G)[d>>>3>>>0]);d+=e?8:4}return xd[a](...Dd)}var Db=()=>{};
|
|
39
|
-
function Fb(a,b){return p(ud(a>>>0,b>>>0))}var Gb=()=>{T+=1;throw"unwind";};function Hb(){return 4294901760}var Jb=()=>m?require("os").cpus().length:navigator.hardwareConcurrency,Z={},Ed=a=>{for(var b=0,d=0;d<a.length;++d){var c=a.charCodeAt(d);127>=c?b++:2047>=c?b+=2:55296<=c&&57343>=c?(b+=4,++d):b+=3}return b},Fd=a=>{var b;return(b=/\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(a))?+b[1]:(b=/:(\d+):\d+(?:\)|$)/.exec(a))?2147483648|+b[1]:0},Gd=a=>{for(var b of a)(a=Fd(b))&&(Z[a]=b)};
|
|
40
|
-
function Mb(){var a=Error().stack.toString().split("\n");"Error"==a[0]&&a.shift();Gd(a);Z.Wb=Fd(a[3]);Z.ac=a;return Z.Wb}function Kb(a){a=Z[a>>>0];if(!a)return 0;var b;if(b=/^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^\s+at (.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^(.+?)@/.exec(a))a=b[1];else return 0;Lc(Kb.Xb??0);b=Ed(a)+1;var d=Mc(b);d&&Y(a,d,b);Kb.Xb=d;return Kb.Xb}
|
|
41
|
-
function Lb(a){a>>>=0;var b=(v(),A).length;if(a<=b||4294901760<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(4294901760,65536*Math.ceil(Math.max(a,c)/65536))-x.buffer.byteLength+65535)/65536|0;try{x.grow(c);qa();var e=1;break a}catch(f){}e=void 0}if(e)return!0}return!1}
|
|
42
|
-
function Nb(a,b,d){a>>>=0;b>>>=0;if(Z.Wb==a)var c=Z.ac;else c=Error().stack.toString().split("\n"),"Error"==c[0]&&c.shift(),Gd(c);for(var e=3;c[e]&&Fd(c[e])!=a;)++e;for(a=0;a<d&&c[a+e];++a)(v(),C)[b+4*a>>>2>>>0]=Fd(c[a+e]);return a}
|
|
43
|
-
var Hd={},Jd=()=>{if(!Id){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8",_:ca||"./this.program"},b;for(b in Hd)void 0===Hd[b]?delete a[b]:a[b]=Hd[b];var d=[];for(b in a)d.push(`${b}=${a[b]}`);Id=d}return Id},Id;function Ob(a,b){if(n)return U(19,1,a,b);a>>>=0;b>>>=0;var d=0,c=0,e;for(e of Jd()){var f=b+d;(v(),D)[a+c>>>2>>>0]=f;d+=Y(e,f,Infinity)+1;c+=4}return 0}
|
|
44
|
-
function Pb(a,b){if(n)return U(20,1,a,b);a>>>=0;b>>>=0;var d=Jd();(v(),D)[a>>>2>>>0]=d.length;a=0;for(var c of d)a+=Ed(c)+1;(v(),D)[b>>>2>>>0]=a;return 0}function Rb(a){return n?U(21,1,a):52}function Sb(a,b,d,c){return n?U(22,1,a,b,d,c):52}function Tb(a,b,d,c){return n?U(23,1,a,b,d,c):70}var Kd=[null,[],[]];
|
|
45
|
-
function Ub(a,b,d,c){if(n)return U(24,1,a,b,d,c);b>>>=0;d>>>=0;c>>>=0;for(var e=0,f=0;f<d;f++){var g=(v(),D)[b>>>2>>>0],l=(v(),D)[b+4>>>2>>>0];b+=8;for(var u=0;u<l;u++){var w=a,y=(v(),A)[g+u>>>0],B=Kd[w];0===y||10===y?((1===w?oa:p)(td(B)),B.length=0):B.push(y)}e+=l}(v(),D)[c>>>2>>>0]=e;return 0}function Gc(a){return a>>>0}n||fd();n||(x=new WebAssembly.Memory({initial:256,maximum:65536,shared:!0}),qa());h.wasmBinary&&(q=h.wasmBinary);h.stackSave=()=>N();h.stackRestore=a=>M(a);h.stackAlloc=a=>Tc(a);
|
|
46
|
-
h.setValue=function(a,b,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":(v(),z)[a>>>0]=b;break;case "i8":(v(),z)[a>>>0]=b;break;case "i16":(v(),Fa)[a>>>1>>>0]=b;break;case "i32":(v(),C)[a>>>2>>>0]=b;break;case "i64":(v(),H)[a>>>3>>>0]=BigInt(b);break;case "float":(v(),Ga)[a>>>2>>>0]=b;break;case "double":(v(),G)[a>>>3>>>0]=b;break;case "*":(v(),D)[a>>>2>>>0]=b;break;default:J(`invalid type for setValue: ${d}`)}};
|
|
47
|
-
h.getValue=function(a,b="i8"){b.endsWith("*")&&(b="*");switch(b){case "i1":return(v(),z)[a>>>0];case "i8":return(v(),z)[a>>>0];case "i16":return(v(),Fa)[a>>>1>>>0];case "i32":return(v(),C)[a>>>2>>>0];case "i64":return(v(),H)[a>>>3>>>0];case "float":return(v(),Ga)[a>>>2>>>0];case "double":return(v(),G)[a>>>3>>>0];case "*":return(v(),D)[a>>>2>>>0];default:J(`invalid type for getValue: ${b}`)}};h.UTF8ToString=ud;h.stringToUTF8=Y;h.lengthBytesUTF8=Ed;
|
|
48
|
-
var yd=[Hc,ed,rd,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb,mb,xb,yb,zb,Ob,Pb,Rb,Sb,Tb,Ub],xd={887900:(a,b,d,c,e)=>{if("undefined"==typeof h||!h.Sb)return 1;a=ud(Number(a>>>0));a.startsWith("./")&&(a=a.substring(2));a=h.Sb.get(a);if(!a)return 2;b=Number(b>>>0);d=Number(d>>>0);c=Number(c>>>0);if(b+d>a.byteLength)return 3;try{const f=a.subarray(b,b+d);switch(e){case 0:(v(),A).set(f,c>>>0);break;case 1:h.hc?h.hc(c,f):h.jc(c,f);break;default:return 4}return 0}catch{return 4}},888724:()=>"undefined"!==typeof wasmOffsetConverter};
|
|
49
|
-
function Qa(){return"undefined"!==typeof wasmOffsetConverter}var Kc,Lc,Mc,za,Ea,Nc,Oc,Pc,Qc,Rc,K,L,Sc,M,Tc,N,Uc,Vc,Wc,Xc,Yc,Pa;function bc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function ac(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function sc(a,b,d){var c=N();try{V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function $b(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}
|
|
50
|
-
function qc(a){var b=N();try{V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function fc(a,b,d,c,e,f,g){var l=N();try{return V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function rc(a,b){var d=N();try{V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0)}}function wc(a,b,d,c,e,f){var g=N();try{V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function uc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}
|
|
51
|
-
function vc(a,b,d,c,e){var f=N();try{V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}function xc(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Ec(a,b,d,c,e,f,g){var l=N();try{V(a)(b,d,c,e,f,g)}catch(u){M(l);if(u!==u+0)throw u;K(1,0)}}function Dc(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function cc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
|
|
52
|
-
function yc(a,b,d,c,e,f,g,l){var u=N();try{V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}function Bc(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}function ec(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function oc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0);return 0n}}
|
|
53
|
-
function zc(a,b,d,c,e,f,g,l,u){var w=N();try{V(a)(b,d,c,e,f,g,l,u)}catch(y){M(w);if(y!==y+0)throw y;K(1,0)}}function Zb(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0)}}function lc(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function nc(a,b){var d=N();try{return V(a)(b)}catch(c){M(d);if(c!==c+0)throw c;K(1,0);return 0n}}function Fc(a,b,d,c,e){var f=N();try{V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
|
|
54
|
-
function mc(a){var b=N();try{return V(a)()}catch(d){M(b);if(d!==d+0)throw d;K(1,0);return 0n}}function ic(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function dc(a,b,d,c,e,f){var g=N();try{return V(a)(b,d,c,e,f)}catch(l){M(g);if(l!==l+0)throw l;K(1,0)}}function gc(a,b,d,c,e,f,g,l){var u=N();try{return V(a)(b,d,c,e,f,g,l)}catch(w){M(u);if(w!==w+0)throw w;K(1,0)}}
|
|
55
|
-
function pc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0);return 0n}}function Yb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function Wb(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function hc(a,b,d,c,e,f,g,l,u,w,y,B){var E=N();try{return V(a)(b,d,c,e,f,g,l,u,w,y,B)}catch(F){M(E);if(F!==F+0)throw F;K(1,0)}}
|
|
56
|
-
function Ac(a,b,d,c,e,f,g,l,u,w,y){var B=N();try{V(a)(b,d,c,e,f,g,l,u,w,y)}catch(E){M(B);if(E!==E+0)throw E;K(1,0)}}function Cc(a,b,d,c,e,f,g,l,u,w,y,B,E,F,Ld,Md){var Nd=N();try{V(a)(b,d,c,e,f,g,l,u,w,y,B,E,F,Ld,Md)}catch(Ma){M(Nd);if(Ma!==Ma+0)throw Ma;K(1,0)}}function kc(a,b,d,c){var e=N();try{return V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function jc(a,b,d,c,e){var f=N();try{return V(a)(b,d,c,e)}catch(g){M(f);if(g!==g+0)throw g;K(1,0)}}
|
|
57
|
-
function Xb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function Vb(a,b,d){var c=N();try{return V(a)(b,d)}catch(e){M(c);if(e!==e+0)throw e;K(1,0)}}function tc(a,b,d,c){var e=N();try{V(a)(b,d,c)}catch(f){M(e);if(f!==f+0)throw f;K(1,0)}}function Ic(){var a=I;a=Object.assign({},a);var b=c=>()=>c()>>>0,d=c=>e=>c(e)>>>0;a.tb=b(a.tb);a.vb=d(a.vb);a.Jb=d(a.Jb);a.Kb=b(a.Kb);a.Ob=d(a.Ob);return a}
|
|
58
|
-
function xa(){if(0<O)P=xa;else if(n)ra?.(h),Ia();else{for(var a=ad;0<a.length;)a.shift()(h);0<O?P=xa:(h.calledRun=!0,pa||(Ia(),ra?.(h)))}}var I;n||(I=await (wa()),xa());h.PTR_SIZE=4;Ha?moduleRtn=h:moduleRtn=new Promise((a,b)=>{ra=a;sa=b});
|
|
59
|
-
;return moduleRtn}export default ortWasmThreaded;var isPthread=globalThis.self?.name?.startsWith("em-pthread");var isNode=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(isNode)isPthread=(await import("worker_threads")).workerData==="em-pthread";isPthread&&ortWasmThreaded();
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(()=>{"use strict";var e={710:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.log=void 0;const s=e=>t=>{console.log(`VAD | ${e} >`,t)};t.log={error:s("error"),debug:s("debug"),warn:s("warn")}},954:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.Message=void 0,function(e){e.AudioFrame="AUDIO_FRAME",e.SpeechStart="SPEECH_START",e.VADMisfire="VAD_MISFIRE",e.SpeechEnd="SPEECH_END",e.SpeechStop="SPEECH_STOP",e.SpeechRealStart="SPEECH_REAL_START",e.FrameProcessed="FRAME_PROCESSED"}(s||(t.Message=s={}))},825:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Resampler=void 0;const r=s(710);t.Resampler=class{constructor(e){this.options=e,this.process=e=>{const t=[];for(const s of e)for(this.inputBuffer.push(s);this.hasEnoughDataForFrame();){const e=this.generateOutputFrame();t.push(e)}return t},e.nativeSampleRate<16e3&&r.log.error("nativeSampleRate is too low. Should have 16000 = targetSampleRate <= nativeSampleRate"),this.inputBuffer=[]}async*stream(e){for(const t of e)for(this.inputBuffer.push(t);this.hasEnoughDataForFrame();){const e=this.generateOutputFrame();yield e}}hasEnoughDataForFrame(){return this.inputBuffer.length*this.options.targetSampleRate/this.options.nativeSampleRate>=this.options.targetFrameSize}generateOutputFrame(){const e=new Float32Array(this.options.targetFrameSize);let t=0,s=0;for(;t<this.options.targetFrameSize;){let r=0,o=0;for(;s<Math.min(this.inputBuffer.length,(t+1)*this.options.nativeSampleRate/this.options.targetSampleRate);){const e=this.inputBuffer[s];void 0!==e&&(r+=e,o++),s++}e[t]=r/o,t++}return this.inputBuffer=this.inputBuffer.slice(s),e}}}},t={};function s(r){var o=t[r];if(void 0!==o)return o.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,s),a.exports}(()=>{const e=s(710),t=s(954),r=s(825);class o extends AudioWorkletProcessor{constructor(s){super(),this._stopProcessing=!1,this.options=s.processorOptions,this.port.onmessage=s=>{s.data===t.Message.SpeechStop&&(e.log.debug("Worklet received speech stop message"),this._stopProcessing=!0)},this.resampler=new r.Resampler({nativeSampleRate:sampleRate,targetSampleRate:16e3,targetFrameSize:this.options.frameSamples})}process(e){if(this._stopProcessing)return!1;const s=e[0];if(void 0===s)return!0;const r=s[0];if(void 0===r)return!0;const o=this.resampler.process(r);for(const e of o)this.port.postMessage({message:t.Message.AudioFrame,data:e.buffer},[e.buffer]);return!0}}registerProcessor("vad-helper-worklet",o)})()})();
|