@spatialwalk/avatarkit 1.0.0-beta.1 → 1.0.0-beta.3

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 CHANGED
@@ -1,25 +1,25 @@
1
1
  # SPAvatarKit SDK
2
2
 
3
- 基于 3D Gaussian Splatting 的实时虚拟人物头像渲染 SDK,支持音频驱动的动画渲染和高质量 3D 渲染。
3
+ Real-time virtual avatar rendering SDK based on 3D Gaussian Splatting, supporting audio-driven animation rendering and high-quality 3D rendering.
4
4
 
5
- ## 🚀 特性
5
+ ## 🚀 Features
6
6
 
7
- - **3D Gaussian Splatting 渲染** - 基于最新的点云渲染技术,提供高质量的 3D 虚拟人物
8
- - **音频驱动的实时动画渲染** - 用户提供音频数据,SDK 负责接收动画数据并渲染
9
- - **WebGPU/WebGL 双渲染后端** - 自动选择最佳渲染后端,确保兼容性
10
- - **WASM 高性能计算** - 使用 C++ 编译的 WebAssembly 模块进行几何计算
11
- - **TypeScript 支持** - 完整的类型定义和智能提示
12
- - **模块化架构** - 清晰的组件分离,易于集成和扩展
7
+ - **3D Gaussian Splatting Rendering** - Based on the latest point cloud rendering technology, providing high-quality 3D virtual avatars
8
+ - **Audio-Driven Real-Time Animation Rendering** - Users provide audio data, SDK handles receiving animation data and rendering
9
+ - **WebGPU/WebGL Dual Rendering Backend** - Automatically selects the best rendering backend for compatibility
10
+ - **WASM High-Performance Computing** - Uses C++ compiled WebAssembly modules for geometric calculations
11
+ - **TypeScript Support** - Complete type definitions and IntelliSense
12
+ - **Modular Architecture** - Clear component separation, easy to integrate and extend
13
13
 
14
- ## 📦 安装
14
+ ## 📦 Installation
15
15
 
16
16
  ```bash
17
17
  npm install @spatialwalk/avatarkit
18
18
  ```
19
19
 
20
- ## 🎯 快速开始
20
+ ## 🎯 Quick Start
21
21
 
22
- ### 基础使用
22
+ ### Basic Usage
23
23
 
24
24
  ```typescript
25
25
  import {
@@ -30,150 +30,173 @@ import {
30
30
  Environment
31
31
  } from '@spatialwalk/avatarkit'
32
32
 
33
- // 1. 初始化 SDK
33
+ // 1. Initialize SDK
34
34
  const configuration: Configuration = {
35
35
  environment: Environment.test,
36
36
  }
37
37
 
38
38
  await AvatarKit.initialize('your-app-id', configuration)
39
39
 
40
- // 设置 sessionToken(如果需要,单独调用)
40
+ // Set sessionToken (if needed, call separately)
41
41
  // AvatarKit.setSessionToken('your-session-token')
42
42
 
43
- // 2. 加载角色
43
+ // 2. Load character
44
44
  const avatarManager = new AvatarManager()
45
45
  const avatar = await avatarManager.load('character-id', (progress) => {
46
46
  console.log(`Loading progress: ${progress.progress}%`)
47
47
  })
48
48
 
49
- // 3. 创建视图(自动创建 Canvas AvatarController
49
+ // 3. Create view (automatically creates Canvas and AvatarController)
50
50
  const container = document.getElementById('avatar-container')
51
51
  const avatarView = new AvatarView(avatar, container)
52
52
 
53
- // 4. 启动实时通信
53
+ // 4. Start real-time communication
54
54
  await avatarView.avatarController.start()
55
55
 
56
- // 5. 发送音频数据
57
- // 如果音频是 Uint8Array,可以使用 slice().buffer 转换为 ArrayBuffer
58
- const audioUint8 = new Uint8Array(1024) // 示例:音频数据
59
- const audioData = audioUint8.slice().buffer // 简化的转换方式,适用于 ArrayBuffer SharedArrayBuffer
60
- avatarView.avatarController.send(audioData, false) // 发送音频数据,积累到一定量后会自动开始播放
61
- avatarView.avatarController.send(audioData, true) // end=true 表示立即返回动画数据,不再积累
56
+ // 5. Send audio data
57
+ // If audio is Uint8Array, you can use slice().buffer to convert to ArrayBuffer
58
+ const audioUint8 = new Uint8Array(1024) // Example: audio data
59
+ const audioData = audioUint8.slice().buffer // Simplified conversion, works for ArrayBuffer and SharedArrayBuffer
60
+ avatarView.avatarController.send(audioData, false) // Send audio data, will automatically start playing after accumulating enough data
61
+ avatarView.avatarController.send(audioData, true) // end=true means immediately return animation data, no longer accumulating
62
62
  ```
63
63
 
64
- ### 完整示例
64
+ ### Complete Example
65
65
 
66
- 查看 GitHub 仓库中的示例代码了解完整的使用流程。
66
+ Check the example code in the GitHub repository for the complete usage flow.
67
67
 
68
- ## 🏗️ 架构概览
68
+ **Example Project:** [Avatarkit-web-demo](https://github.com/spatialwalk/Avatarkit-web-demo)
69
69
 
70
- ### 核心组件
70
+ This repository contains complete examples for Vanilla JS, Vue 3, and React, demonstrating how to integrate and use SPAvatarKit SDK in different frameworks.
71
71
 
72
- - **AvatarKit** - SDK 初始化和管理
73
- - **AvatarManager** - 角色资源加载和管理
74
- - **AvatarView** - 3D 渲染视图(内部包含 AvatarController)
75
- - **AvatarController** - 实时通信和数据处理
76
- - **AvatarCoreAdapter** - WASM 模块适配器
72
+ ## 🏗️ Architecture Overview
77
73
 
78
- ### 数据流
74
+ ### Core Components
75
+
76
+ - **AvatarKit** - SDK initialization and management
77
+ - **AvatarManager** - Character resource loading and management
78
+ - **AvatarView** - 3D rendering view (internally contains AvatarController)
79
+ - **AvatarController** - Real-time communication and data processing
80
+ - **AvatarCoreAdapter** - WASM module adapter
81
+
82
+ ### Data Flow
79
83
 
80
84
  ```
81
- 用户音频输入(16kHz mono PCM → AvatarController → WebSocket → 后台处理
85
+ User audio input (16kHz mono PCM) → AvatarController → WebSocket → Backend processing
82
86
 
83
- 后台返回动画数据(FLAME 关键帧) → AvatarController → AnimationPlayer
87
+ Backend returns animation data (FLAME keyframes) → AvatarController → AnimationPlayer
84
88
 
85
- FLAME 参数 → AvatarCore.computeFrameFlatFromParams() → Splat 数据
89
+ FLAME parameters → AvatarCore.computeFrameFlatFromParams() → Splat data
86
90
 
87
- Splat 数据 → RenderSystem → WebGPU/WebGL → Canvas 渲染
91
+ Splat data → RenderSystem → WebGPU/WebGL → Canvas rendering
88
92
  ```
89
93
 
90
- **注意:** 用户需要自己提供音频数据(16kHz mono PCM),SDK 负责接收动画数据并渲染。
94
+ **Note:** Users need to provide audio data themselves (16kHz mono PCM), SDK handles receiving animation data and rendering.
91
95
 
92
- ## 📚 API 参考
96
+ ## 📚 API Reference
93
97
 
94
98
  ### AvatarKit
95
99
 
96
- SDK 的核心管理类,负责初始化和全局配置。
100
+ The core management class of the SDK, responsible for initialization and global configuration.
97
101
 
98
102
  ```typescript
99
- // 初始化 SDK
103
+ // Initialize SDK
100
104
  await AvatarKit.initialize(appId: string, configuration: Configuration)
101
105
 
102
- // 检查初始化状态
106
+ // Check initialization status
103
107
  const isInitialized = AvatarKit.isInitialized
104
108
 
105
- // 清理资源(不再使用时必须调用)
109
+ // Cleanup resources (must be called when no longer in use)
106
110
  AvatarKit.cleanup()
107
111
  ```
108
112
 
109
113
  ### AvatarManager
110
114
 
111
- 角色资源管理器,负责下载、缓存和加载角色数据。
115
+ Character resource manager, responsible for downloading, caching, and loading character data.
112
116
 
113
117
  ```typescript
114
118
  const manager = new AvatarManager()
115
119
 
116
- // 加载角色
120
+ // Load character
117
121
  const avatar = await manager.load(
118
122
  characterId: string,
119
123
  onProgress?: (progress: LoadProgressInfo) => void
120
124
  )
121
125
 
122
- // 清理缓存
126
+ // Clear cache
123
127
  manager.clearCache()
124
128
  ```
125
129
 
126
130
  ### AvatarView
127
131
 
128
- 3D 渲染视图,内部自动创建和管理 AvatarController
132
+ 3D rendering view, internally automatically creates and manages AvatarController.
133
+
134
+ **⚠️ Important Limitation:** Currently, the SDK only supports one AvatarView instance at a time. If you need to switch characters, you must first call the `dispose()` method to clean up the current AvatarView, then create a new instance.
129
135
 
130
136
  ```typescript
131
- // 创建视图(Canvas 会自动添加到容器中)
137
+ // Create view (Canvas is automatically added to container)
132
138
  const avatarView = new AvatarView(avatar: Avatar, container?: HTMLElement)
133
139
 
134
- // 获取 Canvas 元素
140
+ // Get Canvas element
135
141
  const canvas = avatarView.getCanvas()
136
142
 
137
- // 设置背景
143
+ // Set background
138
144
  avatarView.setBackgroundImage('path/to/image.jpg')
139
145
  avatarView.setBackgroundOpaque(true)
140
146
 
141
- // 更新相机配置
147
+ // Update camera configuration
142
148
  avatarView.updateCameraConfig(cameraConfig: CameraConfig)
143
149
 
144
- // 清理资源
150
+ // Cleanup resources (must be called before switching characters)
145
151
  avatarView.dispose()
146
152
  ```
147
153
 
154
+ **Character Switching Example:**
155
+
156
+ ```typescript
157
+ // Before switching characters, must clean up old AvatarView first
158
+ if (currentAvatarView) {
159
+ currentAvatarView.dispose()
160
+ currentAvatarView = null
161
+ }
162
+
163
+ // Load new character
164
+ const newAvatar = await avatarManager.load('new-character-id')
165
+
166
+ // Create new AvatarView
167
+ currentAvatarView = new AvatarView(newAvatar, container)
168
+ await currentAvatarView.avatarController.start()
169
+ ```
170
+
148
171
  ### AvatarController
149
172
 
150
- 实时通信控制器,处理 WebSocket 连接和动画数据。
173
+ Real-time communication controller, handles WebSocket connections and animation data.
151
174
 
152
175
  ```typescript
153
- // 启动连接
176
+ // Start connection
154
177
  await avatarView.avatarController.start()
155
178
 
156
- // 发送音频数据
179
+ // Send audio data
157
180
  avatarView.avatarController.send(audioData: ArrayBuffer, end: boolean)
158
- // audioData: 音频数据(ArrayBuffer 格式)
159
- // end: false(默认)- 正常发送音频数据,服务端会积累音频数据,积累到一定量后会自动返回动画数据并开始同步播放动画和音频
160
- // end: true - 立即返回动画数据,不再积累,用于结束当前对话或需要立即响应的场景
181
+ // audioData: Audio data (ArrayBuffer format)
182
+ // end: false (default) - Normal audio data sending, server will accumulate audio data, automatically returns animation data and starts synchronized playback of animation and audio after accumulating enough data
183
+ // end: true - Immediately return animation data, no longer accumulating, used for ending current conversation or scenarios requiring immediate response
161
184
 
162
- // 打断对话
185
+ // Interrupt conversation
163
186
  avatarView.avatarController.interrupt()
164
187
 
165
- // 关闭连接
188
+ // Close connection
166
189
  avatarView.avatarController.close()
167
190
 
168
- // 设置事件回调
191
+ // Set event callbacks
169
192
  avatarView.avatarController.onConnectionState = (state: ConnectionState) => {}
170
193
  avatarView.avatarController.onAvatarState = (state: AvatarState) => {}
171
194
  avatarView.avatarController.onError = (error: Error) => {}
172
195
 
173
- // 注意:不支持 sendText() 方法,调用会抛出错误
196
+ // Note: sendText() method is not supported, calling it will throw an error
174
197
  ```
175
198
 
176
- ## 🔧 配置
199
+ ## 🔧 Configuration
177
200
 
178
201
  ### Configuration
179
202
 
@@ -183,14 +206,15 @@ interface Configuration {
183
206
  }
184
207
  ```
185
208
 
186
- **说明:**
187
- - `environment`: 指定环境(cn/us/test),SDK 会根据环境自动使用对应的 API 地址和 WebSocket 地址
188
- - `sessionToken`: 通过 `AvatarKit.setSessionToken()` 单独设置,而不是在 Configuration
209
+ **Description:**
210
+ - `environment`: Specifies the environment (cn/us/test), SDK will automatically use the corresponding API address and WebSocket address based on the environment
211
+ - `sessionToken`: Set separately via `AvatarKit.setSessionToken()`, not in Configuration
189
212
 
213
+ ```typescript
190
214
  enum Environment {
191
- cn = 'cn', // 中国区
192
- us = 'us', // 美国区
193
- test = 'test' // 测试环境
215
+ cn = 'cn', // China region
216
+ us = 'us', // US region
217
+ test = 'test' // Test environment
194
218
  }
195
219
  ```
196
220
 
@@ -198,17 +222,17 @@ enum Environment {
198
222
 
199
223
  ```typescript
200
224
  interface CameraConfig {
201
- position: [number, number, number] // 相机位置
202
- target: [number, number, number] // 相机目标
203
- fov: number // 视野角度
204
- near: number // 近裁剪面
205
- far: number // 远裁剪面
206
- up?: [number, number, number] // 上方向
207
- aspect?: number // 宽高比
225
+ position: [number, number, number] // Camera position
226
+ target: [number, number, number] // Camera target
227
+ fov: number // Field of view angle
228
+ near: number // Near clipping plane
229
+ far: number // Far clipping plane
230
+ up?: [number, number, number] // Up direction
231
+ aspect?: number // Aspect ratio
208
232
  }
209
233
  ```
210
234
 
211
- ## 📊 状态管理
235
+ ## 📊 State Management
212
236
 
213
237
  ### ConnectionState
214
238
 
@@ -225,77 +249,77 @@ enum ConnectionState {
225
249
 
226
250
  ```typescript
227
251
  enum AvatarState {
228
- idle = 'idle', // 空闲状态,呈现呼吸态
229
- active = 'active', // 活跃中,等待可播放内容
230
- playing = 'playing' // 播放中
252
+ idle = 'idle', // Idle state, showing breathing animation
253
+ active = 'active', // Active, waiting for playable content
254
+ playing = 'playing' // Playing
231
255
  }
232
256
  ```
233
257
 
234
- ## 🎨 渲染系统
258
+ ## 🎨 Rendering System
235
259
 
236
- SDK 支持两种渲染后端:
260
+ The SDK supports two rendering backends:
237
261
 
238
- - **WebGPU** - 现代浏览器的高性能渲染
239
- - **WebGL** - 兼容性更好的传统渲染
262
+ - **WebGPU** - High-performance rendering for modern browsers
263
+ - **WebGL** - Better compatibility traditional rendering
240
264
 
241
- 渲染系统会自动选择最佳的后端,无需手动配置。
265
+ The rendering system automatically selects the best backend, no manual configuration needed.
242
266
 
243
- ## 🔍 调试和监控
267
+ ## 🔍 Debugging and Monitoring
244
268
 
245
- ### 日志系统
269
+ ### Logging System
246
270
 
247
- SDK 内置了完整的日志系统,支持不同级别的日志输出:
271
+ The SDK has a built-in complete logging system, supporting different levels of log output:
248
272
 
249
273
  ```typescript
250
274
  import { logger } from '@spatialwalk/avatarkit'
251
275
 
252
- // 设置日志级别
276
+ // Set log level
253
277
  logger.setLevel('verbose') // 'basic' | 'verbose'
254
278
 
255
- // 手动日志输出
279
+ // Manual log output
256
280
  logger.log('Info message')
257
281
  logger.warn('Warning message')
258
282
  logger.error('Error message')
259
283
  ```
260
284
 
261
- ### 性能监控
285
+ ### Performance Monitoring
262
286
 
263
- SDK 提供了性能监控接口,可以监控渲染性能:
287
+ The SDK provides performance monitoring interfaces to monitor rendering performance:
264
288
 
265
289
  ```typescript
266
- // 获取渲染性能统计
290
+ // Get rendering performance statistics
267
291
  const stats = avatarView.getPerformanceStats()
268
292
 
269
293
  if (stats) {
270
- console.log(`渲染耗时: ${stats.renderTime.toFixed(2)}ms`)
271
- console.log(`排序耗时: ${stats.sortTime.toFixed(2)}ms`)
272
- console.log(`渲染后端: ${stats.backend}`)
294
+ console.log(`Render time: ${stats.renderTime.toFixed(2)}ms`)
295
+ console.log(`Sort time: ${stats.sortTime.toFixed(2)}ms`)
296
+ console.log(`Rendering backend: ${stats.backend}`)
273
297
 
274
- // 计算帧率
298
+ // Calculate frame rate
275
299
  const fps = 1000 / stats.renderTime
276
- console.log(`帧率: ${fps.toFixed(2)} FPS`)
300
+ console.log(`Frame rate: ${fps.toFixed(2)} FPS`)
277
301
  }
278
302
 
279
- // 定期监控性能
303
+ // Regular performance monitoring
280
304
  setInterval(() => {
281
305
  const stats = avatarView.getPerformanceStats()
282
306
  if (stats) {
283
- // 发送到监控服务或显示在 UI
307
+ // Send to monitoring service or display on UI
284
308
  console.log('Performance:', stats)
285
309
  }
286
310
  }, 1000)
287
311
  ```
288
312
 
289
- **性能统计说明**:
290
- - `renderTime`: 总渲染耗时(毫秒),包含排序和 GPU 渲染
291
- - `sortTime`: 排序耗时(毫秒),使用 Radix Sort 算法对点云进行深度排序
292
- - `backend`: 当前使用的渲染后端(`'webgpu'` | `'webgl'` | `null`)
313
+ **Performance Statistics Description:**
314
+ - `renderTime`: Total rendering time (milliseconds), includes sorting and GPU rendering
315
+ - `sortTime`: Sorting time (milliseconds), uses Radix Sort algorithm to depth-sort point cloud
316
+ - `backend`: Currently used rendering backend (`'webgpu'` | `'webgl'` | `null`)
293
317
 
294
- ## 🚨 错误处理
318
+ ## 🚨 Error Handling
295
319
 
296
320
  ### SPAvatarError
297
321
 
298
- SDK 使用自定义错误类型,提供更详细的错误信息:
322
+ The SDK uses custom error types, providing more detailed error information:
299
323
 
300
324
  ```typescript
301
325
  import { SPAvatarError } from '@spatialwalk/avatarkit'
@@ -311,65 +335,70 @@ try {
311
335
  }
312
336
  ```
313
337
 
314
- ### 错误回调
338
+ ### Error Callbacks
315
339
 
316
340
  ```typescript
317
341
  avatarView.avatarController.onError = (error: Error) => {
318
342
  console.error('AvatarController error:', error)
319
- // 处理错误,比如重连、用户提示等
343
+ // Handle error, such as reconnection, user notification, etc.
320
344
  }
321
345
  ```
322
346
 
323
- ## 🔄 资源管理
347
+ ## 🔄 Resource Management
324
348
 
325
- ### 生命周期管理
349
+ ### Lifecycle Management
326
350
 
327
351
  ```typescript
328
- // 初始化
352
+ // Initialize
329
353
  const avatarView = new AvatarView(avatar, container)
330
354
  await avatarView.avatarController.start()
331
355
 
332
- // 使用
356
+ // Use
333
357
  avatarView.avatarController.send(audioData, false)
334
358
 
335
- // 清理
336
- avatarView.dispose() // 自动清理所有资源
359
+ // Cleanup (must be called before switching characters)
360
+ avatarView.dispose() // Automatically cleans up all resources
337
361
  ```
338
362
 
339
- ### 内存优化
363
+ **⚠️ Important Notes:**
364
+ - SDK currently only supports one AvatarView instance at a time
365
+ - When switching characters, must first call `dispose()` to clean up old AvatarView, then create new instance
366
+ - Not properly cleaning up may cause resource leaks and rendering errors
367
+
368
+ ### Memory Optimization
340
369
 
341
- - SDK 自动管理 WASM 内存分配
342
- - 支持角色和动画资源的动态加载/卸载
343
- - 提供内存使用监控接口
370
+ - SDK automatically manages WASM memory allocation
371
+ - Supports dynamic loading/unloading of character and animation resources
372
+ - Provides memory usage monitoring interface
344
373
 
345
- ### 音频数据发送
374
+ ### Audio Data Sending
346
375
 
347
- `send()` 方法接收 `ArrayBuffer` 格式的音频数据:
376
+ The `send()` method receives audio data in `ArrayBuffer` format:
348
377
 
349
- **使用说明:**
350
- - `audioData`: 音频数据(ArrayBuffer 格式)
351
- - `end=false`(默认)- 正常发送音频数据,服务端会积累音频数据,积累到一定量后会自动返回动画数据并开始同步播放动画和音频
352
- - `end=true` - 立即返回动画数据,不再积累,用于结束当前对话或需要立即响应的场景
353
- - **重要**:不需要等待 `end=true` 才开始播放,积累到一定音频数据后就会自动开始播放
378
+ **Usage:**
379
+ - `audioData`: Audio data (ArrayBuffer format)
380
+ - `end=false` (default) - Normal audio data sending, server will accumulate audio data, automatically returns animation data and starts synchronized playback of animation and audio after accumulating enough data
381
+ - `end=true` - Immediately return animation data, no longer accumulating, used for ending current conversation or scenarios requiring immediate response
382
+ - **Important**: No need to wait for `end=true` to start playing, it will automatically start playing after accumulating enough audio data
354
383
 
355
- ## 🌐 浏览器兼容性
384
+ ## 🌐 Browser Compatibility
356
385
 
357
- - **Chrome/Edge** 90+ (推荐 WebGPU)
386
+ - **Chrome/Edge** 90+ (WebGPU recommended)
358
387
  - **Firefox** 90+ (WebGL)
359
388
  - **Safari** 14+ (WebGL)
360
- - **移动端** iOS 14+, Android 8+
389
+ - **Mobile** iOS 14+, Android 8+
361
390
 
362
- ## 📝 许可证
391
+ ## 📝 License
363
392
 
364
393
  MIT License
365
394
 
366
- ## 🤝 贡献
395
+ ## 🤝 Contributing
367
396
 
368
- 欢迎提交 Issue Pull Request!
397
+ Issues and Pull Requests are welcome!
369
398
 
370
- ## 📞 支持
399
+ ## 📞 Support
371
400
 
372
- 如有问题,请联系:
373
- - 邮箱:support@spavatar.com
374
- - 文档:https://docs.spavatar.com
375
- - GitHubhttps://github.com/spavatar/sdk
401
+ For questions, please contact:
402
+ - Email: support@spavatar.com
403
+ - Documentation: https://docs.spavatar.com
404
+ - GitHub: https://github.com/spavatar/sdk
@@ -1,7 +1,7 @@
1
1
  var c = Object.defineProperty;
2
2
  var g = (h, t, e) => t in h ? c(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
3
  var s = (h, t, e) => g(h, typeof t != "symbol" ? t + "" : t, e);
4
- import { l as r } from "./index-DwhR9l52.js";
4
+ import { l } from "./index-NmYXWJnL.js";
5
5
  class k {
6
6
  constructor(t) {
7
7
  // AudioContext is managed internally
@@ -48,7 +48,7 @@ class k {
48
48
  */
49
49
  addChunk(t, e = !1) {
50
50
  if (!this.audioContext) {
51
- r.error("AudioContext not initialized");
51
+ l.error("AudioContext not initialized");
52
52
  return;
53
53
  }
54
54
  this.audioChunks.push({ data: t, isLast: e }), this.log(`Added chunk ${this.audioChunks.length}`, {
@@ -117,9 +117,9 @@ class k {
117
117
  this.scheduledChunks++;
118
118
  return;
119
119
  }
120
- const l = e.data, d = e.isLast, n = this.pcmToAudioBuffer(l);
120
+ const r = e.data, d = e.isLast, n = this.pcmToAudioBuffer(r);
121
121
  if (!n) {
122
- r.error("Failed to create AudioBuffer from PCM data");
122
+ l.error("Failed to create AudioBuffer from PCM data");
123
123
  return;
124
124
  }
125
125
  try {
@@ -135,7 +135,7 @@ class k {
135
135
  activeSources: this.activeSources.length
136
136
  });
137
137
  } catch (i) {
138
- r.errorWithError("Failed to schedule audio chunk:", i);
138
+ l.errorWithError("Failed to schedule audio chunk:", i);
139
139
  }
140
140
  }
141
141
  /**
@@ -155,7 +155,7 @@ class k {
155
155
  a.getChannelData(o).fill(0);
156
156
  return a;
157
157
  }
158
- const e = new Uint8Array(t), l = new Int16Array(e.buffer, 0, e.length / 2), d = l.length / this.channelCount, n = this.audioContext.createBuffer(
158
+ const e = new Uint8Array(t), r = new Int16Array(e.buffer, 0, e.length / 2), d = r.length / this.channelCount, n = this.audioContext.createBuffer(
159
159
  this.channelCount,
160
160
  d,
161
161
  this.sampleRate
@@ -164,7 +164,7 @@ class k {
164
164
  const u = n.getChannelData(i);
165
165
  for (let a = 0; a < d; a++) {
166
166
  const o = a * this.channelCount + i;
167
- u[a] = l[o] / 32768;
167
+ u[a] = r[o] / 32768;
168
168
  }
169
169
  }
170
170
  return n;
@@ -205,12 +205,7 @@ class k {
205
205
  */
206
206
  stop() {
207
207
  if (this.audioContext) {
208
- this.log("[StreamingAudioPlayer] Stopping playback", {
209
- isPlaying: this.isPlaying,
210
- audioChunks: this.audioChunks.length,
211
- scheduledChunks: this.scheduledChunks,
212
- activeSources: this.activeSources.length
213
- }), this.isPlaying = !1, this.isPaused = !1, this.sessionStartTime = 0, this.scheduledTime = 0;
208
+ this.isPlaying = !1, this.isPaused = !1, this.sessionStartTime = 0, this.scheduledTime = 0;
214
209
  for (const t of this.activeSources) {
215
210
  t.onended = null;
216
211
  try {
@@ -284,10 +279,10 @@ class k {
284
279
  * Debug logging
285
280
  */
286
281
  log(t, e) {
287
- this.debug && r.log(`[StreamingAudioPlayer] ${t}`, e || "");
282
+ this.debug && l.log(`[StreamingAudioPlayer] ${t}`, e || "");
288
283
  }
289
284
  }
290
285
  export {
291
286
  k as StreamingAudioPlayer
292
287
  };
293
- //# sourceMappingURL=StreamingAudioPlayer-C2TfYsO8.js.map
288
+ //# sourceMappingURL=StreamingAudioPlayer-BeLlDiwE.js.map