@runanywhere/web 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +795 -0
- package/dist/Foundation/ErrorTypes.d.ts +61 -0
- package/dist/Foundation/ErrorTypes.d.ts.map +1 -0
- package/dist/Foundation/ErrorTypes.js +90 -0
- package/dist/Foundation/ErrorTypes.js.map +1 -0
- package/dist/Foundation/EventBus.d.ts +171 -0
- package/dist/Foundation/EventBus.d.ts.map +1 -0
- package/dist/Foundation/EventBus.js +113 -0
- package/dist/Foundation/EventBus.js.map +1 -0
- package/dist/Foundation/PlatformAdapter.d.ts +101 -0
- package/dist/Foundation/PlatformAdapter.d.ts.map +1 -0
- package/dist/Foundation/PlatformAdapter.js +417 -0
- package/dist/Foundation/PlatformAdapter.js.map +1 -0
- package/dist/Foundation/SDKLogger.d.ts +33 -0
- package/dist/Foundation/SDKLogger.d.ts.map +1 -0
- package/dist/Foundation/SDKLogger.js +82 -0
- package/dist/Foundation/SDKLogger.js.map +1 -0
- package/dist/Foundation/SherpaONNXBridge.d.ts +134 -0
- package/dist/Foundation/SherpaONNXBridge.d.ts.map +1 -0
- package/dist/Foundation/SherpaONNXBridge.js +332 -0
- package/dist/Foundation/SherpaONNXBridge.js.map +1 -0
- package/dist/Foundation/StructOffsets.d.ts +147 -0
- package/dist/Foundation/StructOffsets.d.ts.map +1 -0
- package/dist/Foundation/StructOffsets.js +161 -0
- package/dist/Foundation/StructOffsets.js.map +1 -0
- package/dist/Foundation/WASMBridge.d.ts +241 -0
- package/dist/Foundation/WASMBridge.d.ts.map +1 -0
- package/dist/Foundation/WASMBridge.js +393 -0
- package/dist/Foundation/WASMBridge.js.map +1 -0
- package/dist/Infrastructure/ArchiveUtility.d.ts +25 -0
- package/dist/Infrastructure/ArchiveUtility.d.ts.map +1 -0
- package/dist/Infrastructure/ArchiveUtility.js +139 -0
- package/dist/Infrastructure/ArchiveUtility.js.map +1 -0
- package/dist/Infrastructure/AudioCapture.d.ts +87 -0
- package/dist/Infrastructure/AudioCapture.d.ts.map +1 -0
- package/dist/Infrastructure/AudioCapture.js +231 -0
- package/dist/Infrastructure/AudioCapture.js.map +1 -0
- package/dist/Infrastructure/AudioPlayback.d.ts +53 -0
- package/dist/Infrastructure/AudioPlayback.d.ts.map +1 -0
- package/dist/Infrastructure/AudioPlayback.js +117 -0
- package/dist/Infrastructure/AudioPlayback.js.map +1 -0
- package/dist/Infrastructure/DeviceCapabilities.d.ts +39 -0
- package/dist/Infrastructure/DeviceCapabilities.d.ts.map +1 -0
- package/dist/Infrastructure/DeviceCapabilities.js +111 -0
- package/dist/Infrastructure/DeviceCapabilities.js.map +1 -0
- package/dist/Infrastructure/ExtensionRegistry.d.ts +30 -0
- package/dist/Infrastructure/ExtensionRegistry.d.ts.map +1 -0
- package/dist/Infrastructure/ExtensionRegistry.js +41 -0
- package/dist/Infrastructure/ExtensionRegistry.js.map +1 -0
- package/dist/Infrastructure/ModelDownloader.d.ts +98 -0
- package/dist/Infrastructure/ModelDownloader.d.ts.map +1 -0
- package/dist/Infrastructure/ModelDownloader.js +431 -0
- package/dist/Infrastructure/ModelDownloader.js.map +1 -0
- package/dist/Infrastructure/ModelLoaderTypes.d.ts +34 -0
- package/dist/Infrastructure/ModelLoaderTypes.d.ts.map +1 -0
- package/dist/Infrastructure/ModelLoaderTypes.js +12 -0
- package/dist/Infrastructure/ModelLoaderTypes.js.map +1 -0
- package/dist/Infrastructure/ModelManager.d.ts +219 -0
- package/dist/Infrastructure/ModelManager.d.ts.map +1 -0
- package/dist/Infrastructure/ModelManager.js +885 -0
- package/dist/Infrastructure/ModelManager.js.map +1 -0
- package/dist/Infrastructure/ModelRegistry.d.ts +131 -0
- package/dist/Infrastructure/ModelRegistry.d.ts.map +1 -0
- package/dist/Infrastructure/ModelRegistry.js +122 -0
- package/dist/Infrastructure/ModelRegistry.js.map +1 -0
- package/dist/Infrastructure/OPFSStorage.d.ts +143 -0
- package/dist/Infrastructure/OPFSStorage.d.ts.map +1 -0
- package/dist/Infrastructure/OPFSStorage.js +330 -0
- package/dist/Infrastructure/OPFSStorage.js.map +1 -0
- package/dist/Infrastructure/VLMWorkerBridge.d.ts +211 -0
- package/dist/Infrastructure/VLMWorkerBridge.d.ts.map +1 -0
- package/dist/Infrastructure/VLMWorkerBridge.js +264 -0
- package/dist/Infrastructure/VLMWorkerBridge.js.map +1 -0
- package/dist/Infrastructure/VLMWorkerRuntime.d.ts +38 -0
- package/dist/Infrastructure/VLMWorkerRuntime.d.ts.map +1 -0
- package/dist/Infrastructure/VLMWorkerRuntime.js +503 -0
- package/dist/Infrastructure/VLMWorkerRuntime.js.map +1 -0
- package/dist/Infrastructure/VideoCapture.d.ts +118 -0
- package/dist/Infrastructure/VideoCapture.d.ts.map +1 -0
- package/dist/Infrastructure/VideoCapture.js +207 -0
- package/dist/Infrastructure/VideoCapture.js.map +1 -0
- package/dist/Public/Extensions/DiffusionTypes.d.ts +64 -0
- package/dist/Public/Extensions/DiffusionTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/DiffusionTypes.js +28 -0
- package/dist/Public/Extensions/DiffusionTypes.js.map +1 -0
- package/dist/Public/Extensions/EmbeddingsTypes.d.ts +33 -0
- package/dist/Public/Extensions/EmbeddingsTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/EmbeddingsTypes.js +13 -0
- package/dist/Public/Extensions/EmbeddingsTypes.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+Diffusion.d.ts +44 -0
- package/dist/Public/Extensions/RunAnywhere+Diffusion.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+Diffusion.js +189 -0
- package/dist/Public/Extensions/RunAnywhere+Diffusion.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+Embeddings.d.ts +56 -0
- package/dist/Public/Extensions/RunAnywhere+Embeddings.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+Embeddings.js +240 -0
- package/dist/Public/Extensions/RunAnywhere+Embeddings.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+ModelManagement.d.ts +53 -0
- package/dist/Public/Extensions/RunAnywhere+ModelManagement.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+ModelManagement.js +153 -0
- package/dist/Public/Extensions/RunAnywhere+ModelManagement.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+STT.d.ts +95 -0
- package/dist/Public/Extensions/RunAnywhere+STT.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+STT.js +417 -0
- package/dist/Public/Extensions/RunAnywhere+STT.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+StructuredOutput.d.ts +69 -0
- package/dist/Public/Extensions/RunAnywhere+StructuredOutput.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+StructuredOutput.js +196 -0
- package/dist/Public/Extensions/RunAnywhere+StructuredOutput.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+TTS.d.ts +55 -0
- package/dist/Public/Extensions/RunAnywhere+TTS.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+TTS.js +253 -0
- package/dist/Public/Extensions/RunAnywhere+TTS.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+TextGeneration.d.ts +80 -0
- package/dist/Public/Extensions/RunAnywhere+TextGeneration.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+TextGeneration.js +436 -0
- package/dist/Public/Extensions/RunAnywhere+TextGeneration.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+ToolCalling.d.ts +82 -0
- package/dist/Public/Extensions/RunAnywhere+ToolCalling.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+ToolCalling.js +576 -0
- package/dist/Public/Extensions/RunAnywhere+ToolCalling.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VAD.d.ts +70 -0
- package/dist/Public/Extensions/RunAnywhere+VAD.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VAD.js +231 -0
- package/dist/Public/Extensions/RunAnywhere+VAD.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VLM.d.ts +58 -0
- package/dist/Public/Extensions/RunAnywhere+VLM.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VLM.js +262 -0
- package/dist/Public/Extensions/RunAnywhere+VLM.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VoiceAgent.d.ts +49 -0
- package/dist/Public/Extensions/RunAnywhere+VoiceAgent.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VoiceAgent.js +222 -0
- package/dist/Public/Extensions/RunAnywhere+VoiceAgent.js.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VoicePipeline.d.ts +63 -0
- package/dist/Public/Extensions/RunAnywhere+VoicePipeline.d.ts.map +1 -0
- package/dist/Public/Extensions/RunAnywhere+VoicePipeline.js +168 -0
- package/dist/Public/Extensions/RunAnywhere+VoicePipeline.js.map +1 -0
- package/dist/Public/Extensions/STTTypes.d.ts +53 -0
- package/dist/Public/Extensions/STTTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/STTTypes.js +16 -0
- package/dist/Public/Extensions/STTTypes.js.map +1 -0
- package/dist/Public/Extensions/TTSTypes.d.ts +31 -0
- package/dist/Public/Extensions/TTSTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/TTSTypes.js +3 -0
- package/dist/Public/Extensions/TTSTypes.js.map +1 -0
- package/dist/Public/Extensions/ToolCallingTypes.d.ts +78 -0
- package/dist/Public/Extensions/ToolCallingTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/ToolCallingTypes.js +8 -0
- package/dist/Public/Extensions/ToolCallingTypes.js.map +1 -0
- package/dist/Public/Extensions/VADTypes.d.ts +30 -0
- package/dist/Public/Extensions/VADTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/VADTypes.js +8 -0
- package/dist/Public/Extensions/VADTypes.js.map +1 -0
- package/dist/Public/Extensions/VLMTypes.d.ts +56 -0
- package/dist/Public/Extensions/VLMTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/VLMTypes.js +24 -0
- package/dist/Public/Extensions/VLMTypes.js.map +1 -0
- package/dist/Public/Extensions/VoiceAgentTypes.d.ts +42 -0
- package/dist/Public/Extensions/VoiceAgentTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/VoiceAgentTypes.js +12 -0
- package/dist/Public/Extensions/VoiceAgentTypes.js.map +1 -0
- package/dist/Public/Extensions/VoicePipelineTypes.d.ts +69 -0
- package/dist/Public/Extensions/VoicePipelineTypes.d.ts.map +1 -0
- package/dist/Public/Extensions/VoicePipelineTypes.js +9 -0
- package/dist/Public/Extensions/VoicePipelineTypes.js.map +1 -0
- package/dist/Public/RunAnywhere.d.ts +121 -0
- package/dist/Public/RunAnywhere.d.ts.map +1 -0
- package/dist/Public/RunAnywhere.js +332 -0
- package/dist/Public/RunAnywhere.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/types/LLMTypes.d.ts +48 -0
- package/dist/types/LLMTypes.d.ts.map +1 -0
- package/dist/types/LLMTypes.js +8 -0
- package/dist/types/LLMTypes.js.map +1 -0
- package/dist/types/enums.d.ts +144 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +159 -0
- package/dist/types/enums.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/models.d.ts +154 -0
- package/dist/types/models.d.ts.map +1 -0
- package/dist/types/models.js +8 -0
- package/dist/types/models.js.map +1 -0
- package/dist/workers/vlm-worker.d.ts +9 -0
- package/dist/workers/vlm-worker.d.ts.map +1 -0
- package/dist/workers/vlm-worker.js +10 -0
- package/dist/workers/vlm-worker.js.map +1 -0
- package/package.json +62 -0
- package/wasm/racommons-webgpu.js +156 -0
- package/wasm/racommons-webgpu.wasm +0 -0
- package/wasm/racommons.js +126 -0
- package/wasm/racommons.wasm +0 -0
- package/wasm/sherpa/sherpa-onnx-asr.js +1538 -0
- package/wasm/sherpa/sherpa-onnx-glue-original.js +19 -0
- package/wasm/sherpa/sherpa-onnx-glue.js +17 -0
- package/wasm/sherpa/sherpa-onnx-tts.js +657 -0
- package/wasm/sherpa/sherpa-onnx-vad.js +337 -0
- package/wasm/sherpa/sherpa-onnx-wave.js +88 -0
- package/wasm/sherpa/sherpa-onnx.wasm +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioCapture.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/AudioCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;AACjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,UAAU,CAA2C;IAC7D,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAsB;IAExC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,aAAa,CAAmC;gBAE5C,MAAM,GAAE,kBAAuB;IAQ3C,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,0EAA0E;IAC1E,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,8EAA8E;IAC9E,IAAI,qBAAqB,IAAI,MAAM,CAGlC;IAED;;;;;;OAMG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EtF;;OAEG;IACH,IAAI,IAAI,IAAI;IAYZ;;;OAGG;IACH,cAAc,IAAI,YAAY;IAY9B;;;OAGG;IACH,WAAW,IAAI,YAAY;IAM3B,yDAAyD;IACzD,WAAW,IAAI,IAAI;IAInB,wEAAwE;IACxE,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,eAAe;CAOxB"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAnywhere Web SDK - Audio Capture
|
|
3
|
+
*
|
|
4
|
+
* Captures microphone audio using Web Audio API and provides
|
|
5
|
+
* Float32Array PCM samples suitable for STT and VAD processing.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Real-time microphone capture via getUserMedia
|
|
9
|
+
* - Configurable sample rate (resampling via AudioContext)
|
|
10
|
+
* - Chunk-based callbacks for streaming STT/VAD
|
|
11
|
+
* - Buffer accumulation (getAudioBuffer, drainBuffer, clearBuffer)
|
|
12
|
+
* - Audio level monitoring via AnalyserNode (currentLevel getter)
|
|
13
|
+
*/
|
|
14
|
+
import { SDKLogger } from '../Foundation/SDKLogger';
|
|
15
|
+
const logger = new SDKLogger('AudioCapture');
|
|
16
|
+
/**
|
|
17
|
+
* AudioCapture - Captures microphone audio for STT/VAD processing.
|
|
18
|
+
*
|
|
19
|
+
* Uses Web Audio API (AudioContext + ScriptProcessorNode) to capture
|
|
20
|
+
* microphone audio, resample to target rate, and deliver Float32Array
|
|
21
|
+
* PCM chunks to the consumer.
|
|
22
|
+
*
|
|
23
|
+
* Includes buffer accumulation for batch STT and an AnalyserNode for
|
|
24
|
+
* real-time audio level metering (0-1 range).
|
|
25
|
+
*/
|
|
26
|
+
export class AudioCapture {
|
|
27
|
+
audioContext = null;
|
|
28
|
+
mediaStream = null;
|
|
29
|
+
sourceNode = null;
|
|
30
|
+
processorNode = null;
|
|
31
|
+
_analyser = null;
|
|
32
|
+
_animFrameId = null;
|
|
33
|
+
_isCapturing = false;
|
|
34
|
+
_currentLevel = 0;
|
|
35
|
+
_pcmChunks = [];
|
|
36
|
+
config;
|
|
37
|
+
chunkCallback = null;
|
|
38
|
+
levelCallback = null;
|
|
39
|
+
constructor(config = {}) {
|
|
40
|
+
this.config = {
|
|
41
|
+
sampleRate: config.sampleRate ?? 16000,
|
|
42
|
+
chunkSize: config.chunkSize ?? 1600,
|
|
43
|
+
channels: config.channels ?? 1,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
get isCapturing() {
|
|
47
|
+
return this._isCapturing;
|
|
48
|
+
}
|
|
49
|
+
/** Current normalized audio level (0..1), updated per animation frame. */
|
|
50
|
+
get currentLevel() {
|
|
51
|
+
return this._currentLevel;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the actual sample rate of the audio context.
|
|
55
|
+
* May differ from requested rate if browser doesn't support it.
|
|
56
|
+
*/
|
|
57
|
+
get actualSampleRate() {
|
|
58
|
+
return this.audioContext?.sampleRate ?? this.config.sampleRate;
|
|
59
|
+
}
|
|
60
|
+
/** Duration of collected audio in seconds based on configured sample rate. */
|
|
61
|
+
get bufferDurationSeconds() {
|
|
62
|
+
const samples = this._pcmChunks.reduce((acc, c) => acc + c.length, 0);
|
|
63
|
+
return samples / this.config.sampleRate;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start capturing microphone audio.
|
|
67
|
+
*
|
|
68
|
+
* @param onChunk - Optional callback receiving Float32Array chunks of PCM audio (streaming)
|
|
69
|
+
* @param onLevel - Optional callback invoked per animation frame with audio level 0..1
|
|
70
|
+
* @throws If microphone permission is denied
|
|
71
|
+
*/
|
|
72
|
+
async start(onChunk, onLevel) {
|
|
73
|
+
if (this._isCapturing) {
|
|
74
|
+
logger.debug('Already capturing');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.chunkCallback = onChunk ?? null;
|
|
78
|
+
this.levelCallback = onLevel ?? null;
|
|
79
|
+
this._pcmChunks = [];
|
|
80
|
+
this._currentLevel = 0;
|
|
81
|
+
logger.info(`Starting audio capture (${this.config.sampleRate}Hz, chunk=${this.config.chunkSize})`);
|
|
82
|
+
try {
|
|
83
|
+
// Request microphone access
|
|
84
|
+
this.mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
85
|
+
audio: {
|
|
86
|
+
sampleRate: { ideal: this.config.sampleRate },
|
|
87
|
+
channelCount: { exact: this.config.channels },
|
|
88
|
+
echoCancellation: true,
|
|
89
|
+
noiseSuppression: true,
|
|
90
|
+
autoGainControl: true,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
// Create AudioContext at target sample rate
|
|
94
|
+
this.audioContext = new AudioContext({
|
|
95
|
+
sampleRate: this.config.sampleRate,
|
|
96
|
+
});
|
|
97
|
+
// Connect microphone to AudioContext
|
|
98
|
+
this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
|
|
99
|
+
// --- AnalyserNode for level metering ---
|
|
100
|
+
this._analyser = this.audioContext.createAnalyser();
|
|
101
|
+
this._analyser.fftSize = 256;
|
|
102
|
+
this.sourceNode.connect(this._analyser);
|
|
103
|
+
// --- ScriptProcessorNode for chunk-based processing ---
|
|
104
|
+
// Note: ScriptProcessorNode is deprecated but AudioWorklet requires
|
|
105
|
+
// cross-origin isolation. We use ScriptProcessor as a fallback.
|
|
106
|
+
const bufferSize = this.nearestPowerOf2(this.config.chunkSize);
|
|
107
|
+
this.processorNode = this.audioContext.createScriptProcessor(bufferSize, this.config.channels, this.config.channels);
|
|
108
|
+
this.processorNode.onaudioprocess = (event) => {
|
|
109
|
+
if (!this._isCapturing)
|
|
110
|
+
return;
|
|
111
|
+
const inputData = event.inputBuffer.getChannelData(0);
|
|
112
|
+
// Copy to avoid buffer reuse issues
|
|
113
|
+
const samples = new Float32Array(inputData.length);
|
|
114
|
+
samples.set(inputData);
|
|
115
|
+
// Accumulate into internal buffer
|
|
116
|
+
this._pcmChunks.push(samples);
|
|
117
|
+
// Notify chunk callback if provided
|
|
118
|
+
this.chunkCallback?.(samples);
|
|
119
|
+
};
|
|
120
|
+
this.sourceNode.connect(this.processorNode);
|
|
121
|
+
this.processorNode.connect(this.audioContext.destination);
|
|
122
|
+
this._isCapturing = true;
|
|
123
|
+
// Start level monitoring loop
|
|
124
|
+
this.startLevelMonitoring();
|
|
125
|
+
logger.info('Audio capture started');
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
this.cleanupResources();
|
|
129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
130
|
+
logger.error(`Failed to start audio capture: ${message}`);
|
|
131
|
+
throw new Error(`Microphone access failed: ${message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Stop capturing audio and release resources.
|
|
136
|
+
*/
|
|
137
|
+
stop() {
|
|
138
|
+
if (!this._isCapturing)
|
|
139
|
+
return;
|
|
140
|
+
this._isCapturing = false;
|
|
141
|
+
this._currentLevel = 0;
|
|
142
|
+
this.chunkCallback = null;
|
|
143
|
+
this.levelCallback = null;
|
|
144
|
+
this.cleanupResources();
|
|
145
|
+
logger.info('Audio capture stopped');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get all collected PCM audio as a single Float32Array.
|
|
149
|
+
* Does NOT clear the buffer — call `clearBuffer()` separately.
|
|
150
|
+
*/
|
|
151
|
+
getAudioBuffer() {
|
|
152
|
+
if (this._pcmChunks.length === 0)
|
|
153
|
+
return new Float32Array(0);
|
|
154
|
+
const totalLength = this._pcmChunks.reduce((acc, c) => acc + c.length, 0);
|
|
155
|
+
const merged = new Float32Array(totalLength);
|
|
156
|
+
let offset = 0;
|
|
157
|
+
for (const chunk of this._pcmChunks) {
|
|
158
|
+
merged.set(chunk, offset);
|
|
159
|
+
offset += chunk.length;
|
|
160
|
+
}
|
|
161
|
+
return merged;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Drain: return the current buffer and clear it for the next segment.
|
|
165
|
+
* Useful for live mode where we transcribe segments incrementally.
|
|
166
|
+
*/
|
|
167
|
+
drainBuffer() {
|
|
168
|
+
const buffer = this.getAudioBuffer();
|
|
169
|
+
this._pcmChunks = [];
|
|
170
|
+
return buffer;
|
|
171
|
+
}
|
|
172
|
+
/** Clear collected PCM data without stopping capture. */
|
|
173
|
+
clearBuffer() {
|
|
174
|
+
this._pcmChunks = [];
|
|
175
|
+
}
|
|
176
|
+
/** Start the requestAnimationFrame loop that reads the AnalyserNode. */
|
|
177
|
+
startLevelMonitoring() {
|
|
178
|
+
const analyser = this._analyser;
|
|
179
|
+
if (!analyser)
|
|
180
|
+
return;
|
|
181
|
+
const dataArray = new Uint8Array(analyser.frequencyBinCount);
|
|
182
|
+
const tick = () => {
|
|
183
|
+
if (!this._isCapturing || !this._analyser)
|
|
184
|
+
return;
|
|
185
|
+
this._analyser.getByteFrequencyData(dataArray);
|
|
186
|
+
let sum = 0;
|
|
187
|
+
for (let i = 0; i < dataArray.length; i++)
|
|
188
|
+
sum += dataArray[i];
|
|
189
|
+
const avg = sum / dataArray.length / 255;
|
|
190
|
+
this._currentLevel = avg;
|
|
191
|
+
this.levelCallback?.(avg);
|
|
192
|
+
this._animFrameId = requestAnimationFrame(tick);
|
|
193
|
+
};
|
|
194
|
+
this._animFrameId = requestAnimationFrame(tick);
|
|
195
|
+
}
|
|
196
|
+
cleanupResources() {
|
|
197
|
+
if (this._animFrameId !== null) {
|
|
198
|
+
cancelAnimationFrame(this._animFrameId);
|
|
199
|
+
this._animFrameId = null;
|
|
200
|
+
}
|
|
201
|
+
if (this.processorNode) {
|
|
202
|
+
this.processorNode.disconnect();
|
|
203
|
+
this.processorNode.onaudioprocess = null;
|
|
204
|
+
this.processorNode = null;
|
|
205
|
+
}
|
|
206
|
+
if (this._analyser) {
|
|
207
|
+
this._analyser.disconnect();
|
|
208
|
+
this._analyser = null;
|
|
209
|
+
}
|
|
210
|
+
if (this.sourceNode) {
|
|
211
|
+
this.sourceNode.disconnect();
|
|
212
|
+
this.sourceNode = null;
|
|
213
|
+
}
|
|
214
|
+
if (this.audioContext) {
|
|
215
|
+
this.audioContext.close().catch(() => { });
|
|
216
|
+
this.audioContext = null;
|
|
217
|
+
}
|
|
218
|
+
if (this.mediaStream) {
|
|
219
|
+
this.mediaStream.getTracks().forEach((track) => track.stop());
|
|
220
|
+
this.mediaStream = null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
nearestPowerOf2(n) {
|
|
224
|
+
let power = 256;
|
|
225
|
+
while (power < n && power < 16384) {
|
|
226
|
+
power *= 2;
|
|
227
|
+
}
|
|
228
|
+
return power;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=AudioCapture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioCapture.js","sourceRoot":"","sources":["../../src/Infrastructure/AudioCapture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAnywhere Web SDK - Audio Playback
|
|
3
|
+
*
|
|
4
|
+
* Plays synthesized audio (TTS output) using Web Audio API.
|
|
5
|
+
* Accepts Float32Array PCM samples and plays them through
|
|
6
|
+
* the browser's audio output.
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - One-shot playback of PCM audio buffers
|
|
10
|
+
* - Streaming playback (queued chunks)
|
|
11
|
+
* - Playback controls (stop, pause, resume)
|
|
12
|
+
* - Completion callbacks
|
|
13
|
+
*/
|
|
14
|
+
export type PlaybackCompleteCallback = () => void;
|
|
15
|
+
export interface PlaybackConfig {
|
|
16
|
+
/** Sample rate of the audio (default: 22050 for Piper TTS) */
|
|
17
|
+
sampleRate?: number;
|
|
18
|
+
/** Volume (0.0 - 1.0, default: 1.0) */
|
|
19
|
+
volume?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* AudioPlayback - Plays synthesized audio through browser speakers.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AudioPlayback {
|
|
25
|
+
private audioContext;
|
|
26
|
+
private gainNode;
|
|
27
|
+
private currentSource;
|
|
28
|
+
private _isPlaying;
|
|
29
|
+
private config;
|
|
30
|
+
constructor(config?: PlaybackConfig);
|
|
31
|
+
get isPlaying(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Play a Float32Array of PCM audio samples.
|
|
34
|
+
*
|
|
35
|
+
* @param samples - PCM audio data (Float32Array)
|
|
36
|
+
* @param sampleRate - Sample rate (overrides config)
|
|
37
|
+
* @returns Promise that resolves when playback completes
|
|
38
|
+
*/
|
|
39
|
+
play(samples: Float32Array, sampleRate?: number): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Stop playback immediately.
|
|
42
|
+
*/
|
|
43
|
+
stop(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Set playback volume.
|
|
46
|
+
*/
|
|
47
|
+
setVolume(volume: number): void;
|
|
48
|
+
/**
|
|
49
|
+
* Release all audio resources.
|
|
50
|
+
*/
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=AudioPlayback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioPlayback.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/AudioPlayback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,MAAM,wBAAwB,GAAG,MAAM,IAAI,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,GAAE,cAAmB;IAOvC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;;;OAMG;IACG,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrE;;OAEG;IACH,IAAI,IAAI,IAAI;IAYZ;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO/B;;OAEG;IACH,OAAO,IAAI,IAAI;CAQhB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAnywhere Web SDK - Audio Playback
|
|
3
|
+
*
|
|
4
|
+
* Plays synthesized audio (TTS output) using Web Audio API.
|
|
5
|
+
* Accepts Float32Array PCM samples and plays them through
|
|
6
|
+
* the browser's audio output.
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - One-shot playback of PCM audio buffers
|
|
10
|
+
* - Streaming playback (queued chunks)
|
|
11
|
+
* - Playback controls (stop, pause, resume)
|
|
12
|
+
* - Completion callbacks
|
|
13
|
+
*/
|
|
14
|
+
import { SDKLogger } from '../Foundation/SDKLogger';
|
|
15
|
+
import { EventBus } from '../Foundation/EventBus';
|
|
16
|
+
import { SDKEventType } from '../types/enums';
|
|
17
|
+
const logger = new SDKLogger('AudioPlayback');
|
|
18
|
+
/**
|
|
19
|
+
* AudioPlayback - Plays synthesized audio through browser speakers.
|
|
20
|
+
*/
|
|
21
|
+
export class AudioPlayback {
|
|
22
|
+
audioContext = null;
|
|
23
|
+
gainNode = null;
|
|
24
|
+
currentSource = null;
|
|
25
|
+
_isPlaying = false;
|
|
26
|
+
config;
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
this.config = {
|
|
29
|
+
sampleRate: config.sampleRate ?? 22050,
|
|
30
|
+
volume: config.volume ?? 1.0,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
get isPlaying() {
|
|
34
|
+
return this._isPlaying;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Play a Float32Array of PCM audio samples.
|
|
38
|
+
*
|
|
39
|
+
* @param samples - PCM audio data (Float32Array)
|
|
40
|
+
* @param sampleRate - Sample rate (overrides config)
|
|
41
|
+
* @returns Promise that resolves when playback completes
|
|
42
|
+
*/
|
|
43
|
+
async play(samples, sampleRate) {
|
|
44
|
+
this.stop(); // Stop any current playback
|
|
45
|
+
const rate = sampleRate ?? this.config.sampleRate;
|
|
46
|
+
const durationMs = (samples.length / rate) * 1000;
|
|
47
|
+
logger.debug(`Playing ${samples.length} samples at ${rate}Hz (${(durationMs / 1000).toFixed(1)}s)`);
|
|
48
|
+
// Create or resume AudioContext
|
|
49
|
+
if (!this.audioContext || this.audioContext.state === 'closed') {
|
|
50
|
+
this.audioContext = new AudioContext({ sampleRate: rate });
|
|
51
|
+
}
|
|
52
|
+
if (this.audioContext.state === 'suspended') {
|
|
53
|
+
await this.audioContext.resume();
|
|
54
|
+
}
|
|
55
|
+
// Create gain node for volume control
|
|
56
|
+
if (!this.gainNode || this.gainNode.context !== this.audioContext) {
|
|
57
|
+
this.gainNode = this.audioContext.createGain();
|
|
58
|
+
this.gainNode.connect(this.audioContext.destination);
|
|
59
|
+
}
|
|
60
|
+
this.gainNode.gain.value = this.config.volume;
|
|
61
|
+
// Create audio buffer from samples
|
|
62
|
+
const audioBuffer = this.audioContext.createBuffer(1, samples.length, rate);
|
|
63
|
+
audioBuffer.getChannelData(0).set(samples);
|
|
64
|
+
// Create and play source node
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
const source = this.audioContext.createBufferSource();
|
|
67
|
+
source.buffer = audioBuffer;
|
|
68
|
+
source.connect(this.gainNode);
|
|
69
|
+
source.onended = () => {
|
|
70
|
+
this._isPlaying = false;
|
|
71
|
+
this.currentSource = null;
|
|
72
|
+
EventBus.shared.emit('playback.completed', SDKEventType.Voice, { durationMs });
|
|
73
|
+
resolve();
|
|
74
|
+
};
|
|
75
|
+
this.currentSource = source;
|
|
76
|
+
this._isPlaying = true;
|
|
77
|
+
EventBus.shared.emit('playback.started', SDKEventType.Voice, { durationMs, sampleRate: rate });
|
|
78
|
+
source.start();
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Stop playback immediately.
|
|
83
|
+
*/
|
|
84
|
+
stop() {
|
|
85
|
+
if (this.currentSource) {
|
|
86
|
+
try {
|
|
87
|
+
this.currentSource.stop();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Already stopped
|
|
91
|
+
}
|
|
92
|
+
this.currentSource = null;
|
|
93
|
+
}
|
|
94
|
+
this._isPlaying = false;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Set playback volume.
|
|
98
|
+
*/
|
|
99
|
+
setVolume(volume) {
|
|
100
|
+
this.config.volume = Math.max(0, Math.min(1, volume));
|
|
101
|
+
if (this.gainNode) {
|
|
102
|
+
this.gainNode.gain.value = this.config.volume;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Release all audio resources.
|
|
107
|
+
*/
|
|
108
|
+
dispose() {
|
|
109
|
+
this.stop();
|
|
110
|
+
if (this.audioContext && this.audioContext.state !== 'closed') {
|
|
111
|
+
this.audioContext.close().catch(() => { });
|
|
112
|
+
}
|
|
113
|
+
this.audioContext = null;
|
|
114
|
+
this.gainNode = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=AudioPlayback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioPlayback.js","sourceRoot":"","sources":["../../src/Infrastructure/AudioPlayback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,eAAe,CAAC,CAAC;AAW9C;;GAEG;AACH,MAAM,OAAO,aAAa;IAChB,YAAY,GAAwB,IAAI,CAAC;IACzC,QAAQ,GAAoB,IAAI,CAAC;IACjC,aAAa,GAAiC,IAAI,CAAC;IACnD,UAAU,GAAG,KAAK,CAAC;IACnB,MAAM,CAA2B;IAEzC,YAAY,SAAyB,EAAE;QACrC,IAAI,CAAC,MAAM,GAAG;YACZ,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,KAAK;YACtC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG;SAC7B,CAAC;IACJ,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,OAAqB,EAAE,UAAmB;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,4BAA4B;QAEzC,MAAM,IAAI,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAClD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAElD,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,MAAM,eAAe,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEpG,gCAAgC;QAChC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC5C,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACnC,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YAClE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAE9C,mCAAmC;QACnC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC5E,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE3C,8BAA8B;QAC9B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAa,CAAC,kBAAkB,EAAE,CAAC;YACvD,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;YAC5B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAS,CAAC,CAAC;YAE/B,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;gBACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC/E,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YAEF,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YAEvB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/F,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9D,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAgB,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAnywhere Web SDK - Device Capabilities
|
|
3
|
+
*
|
|
4
|
+
* Detects browser capabilities relevant to on-device AI inference:
|
|
5
|
+
* WebGPU, SharedArrayBuffer (for pthreads), WASM SIMD, etc.
|
|
6
|
+
*/
|
|
7
|
+
import type { DeviceInfoData } from '../types/models';
|
|
8
|
+
import type { AccelerationMode } from '../Foundation/WASMBridge';
|
|
9
|
+
export interface WebCapabilities {
|
|
10
|
+
/** WebGPU available and functional */
|
|
11
|
+
hasWebGPU: boolean;
|
|
12
|
+
/** WebGPU adapter info (if available) */
|
|
13
|
+
gpuAdapterInfo?: Record<string, string>;
|
|
14
|
+
/** The acceleration mode actually in use by the WASM module ('webgpu' | 'cpu'). */
|
|
15
|
+
activeAcceleration: AccelerationMode;
|
|
16
|
+
/** SharedArrayBuffer available (needed for pthreads/multithreaded WASM) */
|
|
17
|
+
hasSharedArrayBuffer: boolean;
|
|
18
|
+
/** Cross-Origin Isolation enabled (required for SharedArrayBuffer) */
|
|
19
|
+
isCrossOriginIsolated: boolean;
|
|
20
|
+
/** WebAssembly SIMD supported */
|
|
21
|
+
hasWASMSIMD: boolean;
|
|
22
|
+
/** Origin Private File System available */
|
|
23
|
+
hasOPFS: boolean;
|
|
24
|
+
/** Estimated device memory (GB) */
|
|
25
|
+
deviceMemoryGB: number;
|
|
26
|
+
/** Number of logical CPU cores */
|
|
27
|
+
hardwareConcurrency: number;
|
|
28
|
+
/** User agent string */
|
|
29
|
+
userAgent: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Detect all browser capabilities relevant to AI inference.
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectCapabilities(): Promise<WebCapabilities>;
|
|
35
|
+
/**
|
|
36
|
+
* Build a DeviceInfoData from detected capabilities.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getDeviceInfo(): Promise<DeviceInfoData>;
|
|
39
|
+
//# sourceMappingURL=DeviceCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCapabilities.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/DeviceCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAIjE,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,mFAAmF;IACnF,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,2EAA2E;IAC3E,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sEAAsE;IACtE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iCAAiC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,mCAAmC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,CA+CnE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC,CAY7D"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAnywhere Web SDK - Device Capabilities
|
|
3
|
+
*
|
|
4
|
+
* Detects browser capabilities relevant to on-device AI inference:
|
|
5
|
+
* WebGPU, SharedArrayBuffer (for pthreads), WASM SIMD, etc.
|
|
6
|
+
*/
|
|
7
|
+
import { SDKLogger } from '../Foundation/SDKLogger';
|
|
8
|
+
const logger = new SDKLogger('DeviceCapabilities');
|
|
9
|
+
/**
|
|
10
|
+
* Detect all browser capabilities relevant to AI inference.
|
|
11
|
+
*/
|
|
12
|
+
export async function detectCapabilities() {
|
|
13
|
+
// Import WASMBridge lazily to avoid circular imports at module level
|
|
14
|
+
const { WASMBridge } = await import('../Foundation/WASMBridge');
|
|
15
|
+
const capabilities = {
|
|
16
|
+
hasWebGPU: false,
|
|
17
|
+
activeAcceleration: WASMBridge.shared.isLoaded ? WASMBridge.shared.accelerationMode : 'cpu',
|
|
18
|
+
hasSharedArrayBuffer: typeof SharedArrayBuffer !== 'undefined',
|
|
19
|
+
isCrossOriginIsolated: typeof crossOriginIsolated !== 'undefined' ? crossOriginIsolated : false,
|
|
20
|
+
hasWASMSIMD: detectWASMSIMD(),
|
|
21
|
+
hasOPFS: typeof navigator !== 'undefined' && 'storage' in navigator && 'getDirectory' in navigator.storage,
|
|
22
|
+
deviceMemoryGB: navigator.deviceMemory ?? 4,
|
|
23
|
+
hardwareConcurrency: navigator.hardwareConcurrency ?? 4,
|
|
24
|
+
userAgent: navigator.userAgent,
|
|
25
|
+
};
|
|
26
|
+
// Detect WebGPU
|
|
27
|
+
if (typeof navigator !== 'undefined' && 'gpu' in navigator) {
|
|
28
|
+
try {
|
|
29
|
+
const gpu = navigator.gpu;
|
|
30
|
+
const adapter = await gpu?.requestAdapter();
|
|
31
|
+
if (adapter) {
|
|
32
|
+
capabilities.hasWebGPU = true;
|
|
33
|
+
try {
|
|
34
|
+
const info = await adapter.requestAdapterInfo();
|
|
35
|
+
capabilities.gpuAdapterInfo = {
|
|
36
|
+
vendor: info.vendor ?? '',
|
|
37
|
+
architecture: info.architecture ?? '',
|
|
38
|
+
description: info.description ?? '',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch { /* adapter info not available */ }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
logger.debug('WebGPU detection failed');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
logger.info(`Capabilities: WebGPU=${capabilities.hasWebGPU}, ` +
|
|
49
|
+
`SharedArrayBuffer=${capabilities.hasSharedArrayBuffer}, ` +
|
|
50
|
+
`SIMD=${capabilities.hasWASMSIMD}, ` +
|
|
51
|
+
`OPFS=${capabilities.hasOPFS}, ` +
|
|
52
|
+
`Memory=${capabilities.deviceMemoryGB}GB, ` +
|
|
53
|
+
`Cores=${capabilities.hardwareConcurrency}`);
|
|
54
|
+
return capabilities;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build a DeviceInfoData from detected capabilities.
|
|
58
|
+
*/
|
|
59
|
+
export async function getDeviceInfo() {
|
|
60
|
+
const caps = await detectCapabilities();
|
|
61
|
+
return {
|
|
62
|
+
model: 'Browser',
|
|
63
|
+
name: getBrowserName(caps.userAgent),
|
|
64
|
+
osVersion: getOSVersion(caps.userAgent),
|
|
65
|
+
totalMemory: caps.deviceMemoryGB * 1024 * 1024 * 1024,
|
|
66
|
+
architecture: 'wasm32',
|
|
67
|
+
hasWebGPU: caps.hasWebGPU,
|
|
68
|
+
hasSharedArrayBuffer: caps.hasSharedArrayBuffer,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Helpers
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
function detectWASMSIMD() {
|
|
75
|
+
try {
|
|
76
|
+
// Check for WASM SIMD support by validating a minimal SIMD module
|
|
77
|
+
const simdTest = new Uint8Array([
|
|
78
|
+
0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0,
|
|
79
|
+
10, 10, 1, 8, 0, 65, 0, 253, 15, 253, 98, 11,
|
|
80
|
+
]);
|
|
81
|
+
return WebAssembly.validate(simdTest);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function getBrowserName(ua) {
|
|
88
|
+
if (ua.includes('Firefox'))
|
|
89
|
+
return 'Firefox';
|
|
90
|
+
if (ua.includes('Edg/'))
|
|
91
|
+
return 'Edge';
|
|
92
|
+
if (ua.includes('Chrome'))
|
|
93
|
+
return 'Chrome';
|
|
94
|
+
if (ua.includes('Safari'))
|
|
95
|
+
return 'Safari';
|
|
96
|
+
return 'Unknown Browser';
|
|
97
|
+
}
|
|
98
|
+
function getOSVersion(ua) {
|
|
99
|
+
if (ua.includes('Windows'))
|
|
100
|
+
return 'Windows';
|
|
101
|
+
if (ua.includes('Mac OS X'))
|
|
102
|
+
return 'macOS';
|
|
103
|
+
if (ua.includes('Linux'))
|
|
104
|
+
return 'Linux';
|
|
105
|
+
if (ua.includes('Android'))
|
|
106
|
+
return 'Android';
|
|
107
|
+
if (ua.includes('iOS'))
|
|
108
|
+
return 'iOS';
|
|
109
|
+
return 'Unknown OS';
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=DeviceCapabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCapabilities.js","sourceRoot":"","sources":["../../src/Infrastructure/DeviceCapabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension Registry - Manages SDK extension lifecycle
|
|
3
|
+
*
|
|
4
|
+
* Provides a centralised registry so that RunAnywhere.shutdown() does not
|
|
5
|
+
* need to hard-code every extension cleanup call. Extensions are registered
|
|
6
|
+
* during SDK initialisation and cleaned up in reverse order on shutdown.
|
|
7
|
+
*/
|
|
8
|
+
/** Common interface that every SDK extension must implement. */
|
|
9
|
+
export interface SDKExtension {
|
|
10
|
+
/** Human-readable name for logging / debugging. */
|
|
11
|
+
readonly extensionName: string;
|
|
12
|
+
/** Release all resources held by this extension. */
|
|
13
|
+
cleanup(): void;
|
|
14
|
+
}
|
|
15
|
+
declare class ExtensionRegistryImpl {
|
|
16
|
+
private extensions;
|
|
17
|
+
/** Register an extension. Call in dependency order (low-level first). */
|
|
18
|
+
register(extension: SDKExtension): void;
|
|
19
|
+
/**
|
|
20
|
+
* Cleanup all registered extensions in reverse registration order.
|
|
21
|
+
* Each cleanup is individually wrapped in try-catch so one failure
|
|
22
|
+
* does not prevent the rest from being cleaned up.
|
|
23
|
+
*/
|
|
24
|
+
cleanupAll(): void;
|
|
25
|
+
/** Reset the registry (call after full shutdown). */
|
|
26
|
+
reset(): void;
|
|
27
|
+
}
|
|
28
|
+
export declare const ExtensionRegistry: ExtensionRegistryImpl;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=ExtensionRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtensionRegistry.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/ExtensionRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oDAAoD;IACpD,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD,cAAM,qBAAqB;IACzB,OAAO,CAAC,UAAU,CAAsB;IAExC,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAOvC;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAUlB,qDAAqD;IACrD,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,iBAAiB,uBAA8B,CAAC"}
|