@shogo-ai/voice 1.10.0 → 2.4.2

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.
Files changed (68) hide show
  1. package/README.md +89 -0
  2. package/dist/{chunk-S3S2RNO6.js → chunk-BI6SL35K.js} +1 -184
  3. package/dist/chunk-IOFWML5L.js +1078 -0
  4. package/dist/chunk-KMSL5PWK.js +540 -0
  5. package/dist/chunk-ME3SIZZU.js +581 -0
  6. package/dist/{chunk-T3T4EBWY.js → chunk-RALZRMFL.js} +6 -2
  7. package/dist/chunk-TQOBJMEK.js +17 -0
  8. package/dist/chunk-U5UC7ZVS.js +988 -0
  9. package/dist/chunk-UW7VQ3S6.js +148 -0
  10. package/dist/chunk-ZAW6F3YT.js +172 -0
  11. package/dist/index.cjs +748 -25
  12. package/dist/index.d.cts +396 -3
  13. package/dist/index.d.ts +396 -3
  14. package/dist/index.js +63 -3
  15. package/dist/live/client.cjs +173 -0
  16. package/dist/live/client.d.cts +132 -0
  17. package/dist/live/client.d.ts +132 -0
  18. package/dist/live/client.js +9 -0
  19. package/dist/native/index.d.cts +5 -2
  20. package/dist/native/index.d.ts +5 -2
  21. package/dist/native/index.js +15 -11
  22. package/dist/{organicParticlesShaders-DIva0vBO.d.ts → organicParticlesShaders-seZq7jYX.d.cts} +1 -421
  23. package/dist/{organicParticlesShaders-DIva0vBO.d.cts → organicParticlesShaders-seZq7jYX.d.ts} +1 -421
  24. package/dist/particlesConfig-0YbdPOdY.d.cts +223 -0
  25. package/dist/particlesConfig-0YbdPOdY.d.ts +223 -0
  26. package/dist/react/conversation.cjs +789 -0
  27. package/dist/react/conversation.d.cts +134 -0
  28. package/dist/react/conversation.d.ts +134 -0
  29. package/dist/react/conversation.js +13 -0
  30. package/dist/react/index.cjs +374 -36
  31. package/dist/react/index.d.cts +10 -141
  32. package/dist/react/index.d.ts +10 -141
  33. package/dist/react/index.js +23 -770
  34. package/dist/react/visuals.cjs +1048 -0
  35. package/dist/react/visuals.d.cts +70 -0
  36. package/dist/react/visuals.d.ts +70 -0
  37. package/dist/react/visuals.js +10 -0
  38. package/dist/route/agent.cjs +1047 -85
  39. package/dist/route/agent.js +3 -3
  40. package/dist/route/audio-tags.cjs +1047 -85
  41. package/dist/route/audio-tags.js +3 -3
  42. package/dist/route/index.cjs +1051 -85
  43. package/dist/route/index.d.cts +19 -3
  44. package/dist/route/index.d.ts +19 -3
  45. package/dist/route/index.js +3 -3
  46. package/dist/route/music.cjs +1047 -85
  47. package/dist/route/music.js +3 -3
  48. package/dist/route/op.cjs +2127 -0
  49. package/dist/route/op.d.cts +43 -0
  50. package/dist/route/op.d.ts +43 -0
  51. package/dist/route/op.js +27 -0
  52. package/dist/route/signed-url.cjs +1047 -85
  53. package/dist/route/signed-url.js +3 -3
  54. package/dist/route/tts-preview.cjs +1047 -85
  55. package/dist/route/tts-preview.d.cts +6 -4
  56. package/dist/route/tts-preview.d.ts +6 -4
  57. package/dist/route/tts-preview.js +3 -3
  58. package/dist/server.cjs +1047 -85
  59. package/dist/server.d.cts +40 -8
  60. package/dist/server.d.ts +40 -8
  61. package/dist/server.js +2 -2
  62. package/dist/types-Bfhu-aQH.d.cts +199 -0
  63. package/dist/types-Bfhu-aQH.d.ts +199 -0
  64. package/dist/{types-W9y6eMj3.d.ts → types-CadjTXNH.d.cts} +193 -12
  65. package/dist/{types-W9y6eMj3.d.cts → types-CadjTXNH.d.ts} +193 -12
  66. package/package.json +21 -1
  67. package/dist/chunk-B4JC3DK2.js +0 -529
  68. package/dist/chunk-O362EJQR.js +0 -524
@@ -0,0 +1,540 @@
1
+ import {
2
+ ORGANIC_PARTICLES_FRAGMENT_SHADER,
3
+ ORGANIC_PARTICLES_VERTEX_SHADER,
4
+ ORGANIC_SPHERE_FRAGMENT_SHADER,
5
+ ORGANIC_SPHERE_VERTEX_SHADER,
6
+ resolveOrganicParticlesConfig,
7
+ resolveOrganicSphereConfig
8
+ } from "./chunk-BI6SL35K.js";
9
+
10
+ // src/react/OrganicSphere.tsx
11
+ import { useEffect, useMemo, useRef } from "react";
12
+ import * as THREE from "three";
13
+ import { jsx } from "react/jsx-runtime";
14
+ function seededUnit(seed, salt) {
15
+ const s = Math.sin((seed + salt * 7919) * 12.9898 + salt * 78.233) * 43758.5453;
16
+ return s - Math.floor(s);
17
+ }
18
+ function OrganicSphere({
19
+ getFrequencyData,
20
+ active = true,
21
+ config: configProp,
22
+ lightAColor,
23
+ lightBColor,
24
+ rimColor,
25
+ rimThreshold,
26
+ rimPower,
27
+ backgroundColor,
28
+ subdivisions,
29
+ maxPixelRatio,
30
+ className,
31
+ style
32
+ }) {
33
+ const containerRef = useRef(null);
34
+ const resolvedConfig = useMemo(() => {
35
+ const base = resolveOrganicSphereConfig(configProp);
36
+ const overrides = {};
37
+ if (lightAColor !== void 0) overrides.lightAColor = lightAColor;
38
+ if (lightBColor !== void 0) overrides.lightBColor = lightBColor;
39
+ if (rimColor !== void 0) overrides.rimColor = rimColor;
40
+ if (rimThreshold !== void 0) overrides.rimThreshold = rimThreshold;
41
+ if (rimPower !== void 0) overrides.rimPower = rimPower;
42
+ if (backgroundColor !== void 0) overrides.backgroundColor = backgroundColor;
43
+ if (subdivisions !== void 0) overrides.subdivisions = subdivisions;
44
+ if (maxPixelRatio !== void 0) overrides.maxPixelRatio = maxPixelRatio;
45
+ return { ...base, ...overrides };
46
+ }, [
47
+ configProp,
48
+ lightAColor,
49
+ lightBColor,
50
+ rimColor,
51
+ rimThreshold,
52
+ rimPower,
53
+ backgroundColor,
54
+ subdivisions,
55
+ maxPixelRatio
56
+ ]);
57
+ const configRef = useRef(resolvedConfig);
58
+ useEffect(() => {
59
+ configRef.current = resolvedConfig;
60
+ }, [resolvedConfig]);
61
+ const getFrequencyDataRef = useRef(getFrequencyData);
62
+ const activeRef = useRef(active);
63
+ useEffect(() => {
64
+ getFrequencyDataRef.current = getFrequencyData;
65
+ }, [getFrequencyData]);
66
+ useEffect(() => {
67
+ activeRef.current = active;
68
+ }, [active]);
69
+ const initSubdivisions = resolvedConfig.subdivisions;
70
+ const initMaxPixelRatio = resolvedConfig.maxPixelRatio;
71
+ const initBackgroundColor = resolvedConfig.backgroundColor;
72
+ useEffect(() => {
73
+ const container = containerRef.current;
74
+ if (!container) return;
75
+ const cfg0 = configRef.current;
76
+ const width = container.clientWidth || 1;
77
+ const height = container.clientHeight || 1;
78
+ const pixelRatio = Math.min(
79
+ initMaxPixelRatio ?? (typeof window !== "undefined" ? window.devicePixelRatio : 1),
80
+ 2
81
+ );
82
+ const scene = new THREE.Scene();
83
+ if (initBackgroundColor) scene.background = new THREE.Color(initBackgroundColor);
84
+ const camera = new THREE.PerspectiveCamera(cfg0.fov, width / height, 0.1, 100);
85
+ camera.position.set(0, 0, cfg0.cameraZ);
86
+ scene.add(camera);
87
+ const renderer = new THREE.WebGLRenderer({
88
+ antialias: true,
89
+ alpha: initBackgroundColor === null,
90
+ powerPreference: "high-performance"
91
+ });
92
+ renderer.setSize(width, height, false);
93
+ renderer.setPixelRatio(pixelRatio);
94
+ renderer.setClearColor(0, initBackgroundColor === null ? 0 : 1);
95
+ container.appendChild(renderer.domElement);
96
+ renderer.domElement.style.display = "block";
97
+ renderer.domElement.style.width = "100%";
98
+ renderer.domElement.style.height = "100%";
99
+ const geometry = new THREE.SphereGeometry(1, initSubdivisions, initSubdivisions);
100
+ geometry.computeTangents();
101
+ const lightAPos = new THREE.Vector3().setFromSpherical(
102
+ new THREE.Spherical(1, 0.615, 2.049)
103
+ );
104
+ const lightBPos = new THREE.Vector3().setFromSpherical(
105
+ new THREE.Spherical(1, 2.561, -1.844)
106
+ );
107
+ const lightAColorObj = new THREE.Color(cfg0.lightAColor);
108
+ const lightBColorObj = new THREE.Color(cfg0.lightBColor);
109
+ const rimColorObj = new THREE.Color(cfg0.rimColor ?? cfg0.lightBColor);
110
+ const material = new THREE.ShaderMaterial({
111
+ uniforms: {
112
+ uLightAColor: { value: lightAColorObj },
113
+ uLightAPosition: { value: lightAPos },
114
+ uLightAIntensity: { value: cfg0.lightAIntensity },
115
+ uLightBColor: { value: lightBColorObj },
116
+ uLightBPosition: { value: lightBPos },
117
+ uLightBIntensity: { value: cfg0.lightBIntensity },
118
+ uSubdivision: {
119
+ value: new THREE.Vector2(initSubdivisions, initSubdivisions)
120
+ },
121
+ uOffset: { value: new THREE.Vector3() },
122
+ uDistortionFrequency: { value: cfg0.distortionFrequency },
123
+ uDistortionStrength: { value: cfg0.high.idle },
124
+ uDisplacementFrequency: { value: cfg0.displacementFrequency },
125
+ uDisplacementStrength: { value: cfg0.volume.idle },
126
+ uFresnelOffset: { value: cfg0.fresnelOffset },
127
+ uFresnelMultiplier: { value: cfg0.medium.idle },
128
+ uFresnelPower: { value: cfg0.fresnelPower },
129
+ uRimColor: { value: rimColorObj },
130
+ uRimThreshold: { value: cfg0.rimThreshold },
131
+ uRimPower: { value: cfg0.rimPower },
132
+ uTime: { value: 0 }
133
+ },
134
+ defines: { USE_TANGENT: "" },
135
+ vertexShader: ORGANIC_SPHERE_VERTEX_SHADER,
136
+ fragmentShader: ORGANIC_SPHERE_FRAGMENT_SHADER
137
+ });
138
+ const mesh = new THREE.Mesh(geometry, material);
139
+ scene.add(mesh);
140
+ const seedInitialPhase = (seed) => ({
141
+ phi: seededUnit(seed, 1) * Math.PI,
142
+ theta: seededUnit(seed, 2) * Math.PI * 2
143
+ });
144
+ const initialPhase = seedInitialPhase(cfg0.seed);
145
+ const offsetSpherical = new THREE.Spherical(1, initialPhase.phi, initialPhase.theta);
146
+ const offsetDirection = new THREE.Vector3().setFromSpherical(offsetSpherical);
147
+ const variations = {
148
+ volume: { target: 0, current: cfg0.volume.idle },
149
+ medium: { target: 0, current: cfg0.medium.idle },
150
+ high: { target: 0, current: cfg0.high.idle },
151
+ low: { target: 0, current: cfg0.low.idle }
152
+ };
153
+ const resetAnimationState = (cfg) => {
154
+ material.uniforms.uTime.value = 0;
155
+ material.uniforms.uOffset.value.set(0, 0, 0);
156
+ const phase = seedInitialPhase(cfg.seed);
157
+ offsetSpherical.radius = 1;
158
+ offsetSpherical.phi = phase.phi;
159
+ offsetSpherical.theta = phase.theta;
160
+ variations.volume.current = cfg.volume.idle;
161
+ variations.medium.current = cfg.medium.idle;
162
+ variations.high.current = cfg.high.idle;
163
+ variations.low.current = cfg.low.idle;
164
+ variations.volume.target = cfg.volume.idle;
165
+ variations.medium.target = cfg.medium.idle;
166
+ variations.high.target = cfg.high.idle;
167
+ variations.low.target = cfg.low.idle;
168
+ };
169
+ const LEVEL_COUNT = 8;
170
+ function computeLevels(buf) {
171
+ const bins = Math.floor(buf.length / LEVEL_COUNT);
172
+ const levels = new Array(LEVEL_COUNT).fill(0);
173
+ if (bins <= 0) return levels;
174
+ for (let i = 0; i < LEVEL_COUNT; i++) {
175
+ let sum = 0;
176
+ for (let j = 0; j < bins; j++) sum += buf[i * bins + j];
177
+ levels[i] = sum / bins / 256;
178
+ }
179
+ return levels;
180
+ }
181
+ function bandTarget(reactivity, levels, sourceLevel) {
182
+ if (!levels) return reactivity.idle;
183
+ return Math.max(reactivity.floor, reactivity.floor + sourceLevel * reactivity.gain);
184
+ }
185
+ let rafId = 0;
186
+ let lastTs = performance.now();
187
+ let disposed = false;
188
+ let wasActive = activeRef.current;
189
+ let lastSeed = cfg0.seed;
190
+ const render = () => {
191
+ if (disposed) return;
192
+ const now = performance.now();
193
+ const delta = Math.min(now - lastTs, 100);
194
+ lastTs = now;
195
+ const cfg = configRef.current;
196
+ lightAColorObj.set(cfg.lightAColor);
197
+ lightBColorObj.set(cfg.lightBColor);
198
+ rimColorObj.set(cfg.rimColor ?? cfg.lightBColor);
199
+ material.uniforms.uLightAIntensity.value = cfg.lightAIntensity;
200
+ material.uniforms.uLightBIntensity.value = cfg.lightBIntensity;
201
+ material.uniforms.uDistortionFrequency.value = cfg.distortionFrequency;
202
+ material.uniforms.uDisplacementFrequency.value = cfg.displacementFrequency;
203
+ material.uniforms.uFresnelOffset.value = cfg.fresnelOffset;
204
+ material.uniforms.uFresnelPower.value = cfg.fresnelPower;
205
+ material.uniforms.uRimThreshold.value = cfg.rimThreshold;
206
+ material.uniforms.uRimPower.value = cfg.rimPower;
207
+ if (camera.position.z !== cfg.cameraZ) camera.position.z = cfg.cameraZ;
208
+ if (camera.fov !== cfg.fov) {
209
+ camera.fov = cfg.fov;
210
+ camera.updateProjectionMatrix();
211
+ }
212
+ const isActive = activeRef.current;
213
+ if (isActive && !wasActive || cfg.seed !== lastSeed) {
214
+ resetAnimationState(cfg);
215
+ lastSeed = cfg.seed;
216
+ }
217
+ wasActive = isActive;
218
+ if (isActive) {
219
+ let levels = null;
220
+ if (getFrequencyDataRef.current) {
221
+ try {
222
+ const buf = getFrequencyDataRef.current();
223
+ if (buf && buf.length > 0) levels = computeLevels(buf);
224
+ } catch {
225
+ levels = null;
226
+ }
227
+ }
228
+ const l0 = levels ? levels[0] || 0 : 0;
229
+ const l1 = levels ? levels[1] || 0 : 0;
230
+ const l2 = levels ? levels[2] || 0 : 0;
231
+ const loudest = Math.max(l0, l1, l2);
232
+ const update = (variation, reactivity, sourceLevel) => {
233
+ variation.target = bandTarget(reactivity, levels, sourceLevel);
234
+ const easing = variation.target > variation.current ? reactivity.attack : reactivity.decay;
235
+ variation.current += (variation.target - variation.current) * easing * delta;
236
+ };
237
+ update(variations.volume, cfg.volume, loudest);
238
+ update(variations.medium, cfg.medium, l1);
239
+ update(variations.high, cfg.high, l2);
240
+ update(variations.low, cfg.low, l0);
241
+ const timeFrequency = variations.low.current;
242
+ const elapsed = delta * timeFrequency;
243
+ material.uniforms.uDisplacementStrength.value = variations.volume.current;
244
+ material.uniforms.uDistortionStrength.value = variations.high.current;
245
+ material.uniforms.uFresnelMultiplier.value = variations.medium.current;
246
+ const offsetTime = (material.uniforms.uTime.value + elapsed) * 0.3;
247
+ offsetSpherical.phi = (Math.sin(offsetTime * 1e-3) * Math.sin(offsetTime * 321e-5) * 0.5 + 0.5) * Math.PI;
248
+ offsetSpherical.theta = (Math.sin(offsetTime * 1e-4) * Math.sin(offsetTime * 321e-6) * 0.5 + 0.5) * Math.PI * 2;
249
+ offsetDirection.setFromSpherical(offsetSpherical);
250
+ offsetDirection.multiplyScalar(timeFrequency * 2);
251
+ material.uniforms.uOffset.value.add(offsetDirection);
252
+ material.uniforms.uTime.value += elapsed;
253
+ }
254
+ renderer.render(scene, camera);
255
+ rafId = requestAnimationFrame(render);
256
+ };
257
+ rafId = requestAnimationFrame(render);
258
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
259
+ const w = container.clientWidth || 1;
260
+ const h = container.clientHeight || 1;
261
+ camera.aspect = w / h;
262
+ camera.updateProjectionMatrix();
263
+ renderer.setSize(w, h, false);
264
+ }) : null;
265
+ resizeObserver?.observe(container);
266
+ return () => {
267
+ disposed = true;
268
+ cancelAnimationFrame(rafId);
269
+ resizeObserver?.disconnect();
270
+ geometry.dispose();
271
+ material.dispose();
272
+ renderer.dispose();
273
+ if (renderer.domElement.parentNode === container) {
274
+ container.removeChild(renderer.domElement);
275
+ }
276
+ };
277
+ }, [initSubdivisions, initMaxPixelRatio, initBackgroundColor]);
278
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className, style });
279
+ }
280
+
281
+ // src/react/OrganicParticles.tsx
282
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
283
+ import * as THREE2 from "three";
284
+ import { jsx as jsx2 } from "react/jsx-runtime";
285
+ function seededUnit2(seed, salt) {
286
+ const s = Math.sin((seed + salt * 7919) * 12.9898 + salt * 78.233) * 43758.5453;
287
+ return s - Math.floor(s);
288
+ }
289
+ function buildParticleAttributes(count, innerRadius, outerRadius, seed) {
290
+ const positions = new Float32Array(count * 3);
291
+ const seeds = new Float32Array(count);
292
+ for (let i = 0; i < count; i++) {
293
+ const u = seededUnit2(seed, i * 4 + 1);
294
+ const v = seededUnit2(seed, i * 4 + 2);
295
+ const w = seededUnit2(seed, i * 4 + 3);
296
+ const s = seededUnit2(seed, i * 4 + 4);
297
+ const theta = v * Math.PI * 2;
298
+ const phi = Math.acos(2 * w - 1);
299
+ const r = innerRadius + u * Math.max(0, outerRadius - innerRadius);
300
+ const sinPhi = Math.sin(phi);
301
+ positions[i * 3 + 0] = r * sinPhi * Math.cos(theta);
302
+ positions[i * 3 + 1] = r * sinPhi * Math.sin(theta);
303
+ positions[i * 3 + 2] = r * Math.cos(phi);
304
+ seeds[i] = s;
305
+ }
306
+ return { positions, seeds };
307
+ }
308
+ function OrganicParticles({
309
+ getFrequencyData,
310
+ active = true,
311
+ config: configProp,
312
+ className,
313
+ style
314
+ }) {
315
+ const containerRef = useRef2(null);
316
+ const resolvedConfig = useMemo2(
317
+ () => resolveOrganicParticlesConfig(configProp),
318
+ [configProp]
319
+ );
320
+ const configRef = useRef2(resolvedConfig);
321
+ useEffect2(() => {
322
+ configRef.current = resolvedConfig;
323
+ }, [resolvedConfig]);
324
+ const getFrequencyDataRef = useRef2(getFrequencyData);
325
+ const activeRef = useRef2(active);
326
+ useEffect2(() => {
327
+ getFrequencyDataRef.current = getFrequencyData;
328
+ }, [getFrequencyData]);
329
+ useEffect2(() => {
330
+ activeRef.current = active;
331
+ }, [active]);
332
+ const initCount = resolvedConfig.count;
333
+ const initInnerRadius = resolvedConfig.innerRadius;
334
+ const initOuterRadius = resolvedConfig.outerRadius;
335
+ const initSeed = resolvedConfig.seed;
336
+ const initMaxPixelRatio = resolvedConfig.maxPixelRatio;
337
+ const initBackgroundColor = resolvedConfig.backgroundColor;
338
+ useEffect2(() => {
339
+ const container = containerRef.current;
340
+ if (!container) return;
341
+ const cfg0 = configRef.current;
342
+ const width = container.clientWidth || 1;
343
+ const height = container.clientHeight || 1;
344
+ const pixelRatio = Math.min(
345
+ initMaxPixelRatio ?? (typeof window !== "undefined" ? window.devicePixelRatio : 1),
346
+ 2
347
+ );
348
+ const scene = new THREE2.Scene();
349
+ if (initBackgroundColor) scene.background = new THREE2.Color(initBackgroundColor);
350
+ const camera = new THREE2.PerspectiveCamera(cfg0.fov, width / height, 0.1, 100);
351
+ camera.position.set(0, 0, cfg0.cameraZ);
352
+ scene.add(camera);
353
+ const renderer = new THREE2.WebGLRenderer({
354
+ antialias: true,
355
+ alpha: initBackgroundColor === null,
356
+ powerPreference: "high-performance"
357
+ });
358
+ renderer.setSize(width, height, false);
359
+ renderer.setPixelRatio(pixelRatio);
360
+ renderer.setClearColor(0, initBackgroundColor === null ? 0 : 1);
361
+ container.appendChild(renderer.domElement);
362
+ renderer.domElement.style.display = "block";
363
+ renderer.domElement.style.width = "100%";
364
+ renderer.domElement.style.height = "100%";
365
+ const { positions, seeds } = buildParticleAttributes(
366
+ initCount,
367
+ initInnerRadius,
368
+ initOuterRadius,
369
+ initSeed
370
+ );
371
+ const geometry = new THREE2.BufferGeometry();
372
+ geometry.setAttribute("aBasePosition", new THREE2.BufferAttribute(positions, 3));
373
+ geometry.setAttribute("aSeed", new THREE2.BufferAttribute(seeds, 1));
374
+ geometry.setAttribute("position", new THREE2.BufferAttribute(positions, 3));
375
+ const colorCoolObj = new THREE2.Color(cfg0.colorCool);
376
+ const colorHotObj = new THREE2.Color(cfg0.colorHot);
377
+ const material = new THREE2.ShaderMaterial({
378
+ uniforms: {
379
+ uTime: { value: 0 },
380
+ uNoiseFrequency: { value: cfg0.noiseFrequency },
381
+ uNoiseStrength: { value: cfg0.noiseStrength },
382
+ uDisplacement: { value: cfg0.volume.idle },
383
+ uSwirl: { value: cfg0.high.idle },
384
+ uSwirlTimeRate: { value: cfg0.swirlTimeRate },
385
+ uSizeBase: { value: cfg0.sizeBase },
386
+ uSizeAudio: { value: cfg0.medium.idle },
387
+ uPixelRatio: { value: pixelRatio },
388
+ uColorCool: { value: colorCoolObj },
389
+ uColorHot: { value: colorHotObj },
390
+ uOpacity: { value: cfg0.opacity },
391
+ uSoftness: { value: cfg0.softness }
392
+ },
393
+ vertexShader: ORGANIC_PARTICLES_VERTEX_SHADER,
394
+ fragmentShader: ORGANIC_PARTICLES_FRAGMENT_SHADER,
395
+ transparent: true,
396
+ depthWrite: false,
397
+ blending: THREE2.AdditiveBlending
398
+ });
399
+ const points = new THREE2.Points(geometry, material);
400
+ scene.add(points);
401
+ const variations = {
402
+ volume: { target: 0, current: cfg0.volume.idle },
403
+ medium: { target: 0, current: cfg0.medium.idle },
404
+ high: { target: 0, current: cfg0.high.idle },
405
+ low: { target: 0, current: cfg0.low.idle }
406
+ };
407
+ const LEVEL_COUNT = 8;
408
+ function computeLevels(buf) {
409
+ const bins = Math.floor(buf.length / LEVEL_COUNT);
410
+ const levels = new Array(LEVEL_COUNT).fill(0);
411
+ if (bins <= 0) return levels;
412
+ for (let i = 0; i < LEVEL_COUNT; i++) {
413
+ let sum = 0;
414
+ for (let j = 0; j < bins; j++) sum += buf[i * bins + j];
415
+ levels[i] = sum / bins / 256;
416
+ }
417
+ return levels;
418
+ }
419
+ function bandTarget(reactivity, levels, sourceLevel) {
420
+ if (!levels) return reactivity.idle;
421
+ return Math.max(
422
+ reactivity.floor,
423
+ reactivity.floor + sourceLevel * reactivity.gain
424
+ );
425
+ }
426
+ const rotationState = { y: 0 };
427
+ const resetAnimationState = (cfg) => {
428
+ material.uniforms.uTime.value = 0;
429
+ rotationState.y = 0;
430
+ points.rotation.set(0, 0, 0);
431
+ variations.volume.current = cfg.volume.idle;
432
+ variations.medium.current = cfg.medium.idle;
433
+ variations.high.current = cfg.high.idle;
434
+ variations.low.current = cfg.low.idle;
435
+ variations.volume.target = cfg.volume.idle;
436
+ variations.medium.target = cfg.medium.idle;
437
+ variations.high.target = cfg.high.idle;
438
+ variations.low.target = cfg.low.idle;
439
+ };
440
+ let rafId = 0;
441
+ let lastTs = performance.now();
442
+ let disposed = false;
443
+ let wasActive = activeRef.current;
444
+ const render = () => {
445
+ if (disposed) return;
446
+ const now = performance.now();
447
+ const delta = Math.min(now - lastTs, 100);
448
+ lastTs = now;
449
+ const cfg = configRef.current;
450
+ colorCoolObj.set(cfg.colorCool);
451
+ colorHotObj.set(cfg.colorHot);
452
+ material.uniforms.uNoiseFrequency.value = cfg.noiseFrequency;
453
+ material.uniforms.uNoiseStrength.value = cfg.noiseStrength;
454
+ material.uniforms.uSwirlTimeRate.value = cfg.swirlTimeRate;
455
+ material.uniforms.uSizeBase.value = cfg.sizeBase;
456
+ material.uniforms.uOpacity.value = cfg.opacity;
457
+ material.uniforms.uSoftness.value = cfg.softness;
458
+ if (camera.position.z !== cfg.cameraZ) camera.position.z = cfg.cameraZ;
459
+ if (camera.fov !== cfg.fov) {
460
+ camera.fov = cfg.fov;
461
+ camera.updateProjectionMatrix();
462
+ }
463
+ const isActive = activeRef.current;
464
+ if (isActive && !wasActive) {
465
+ resetAnimationState(cfg);
466
+ }
467
+ wasActive = isActive;
468
+ if (isActive) {
469
+ let levels = null;
470
+ if (getFrequencyDataRef.current) {
471
+ try {
472
+ const buf = getFrequencyDataRef.current();
473
+ if (buf && buf.length > 0) levels = computeLevels(buf);
474
+ } catch {
475
+ levels = null;
476
+ }
477
+ }
478
+ const l0 = levels ? levels[0] || 0 : 0;
479
+ const l1 = levels ? levels[1] || 0 : 0;
480
+ const l2 = levels ? levels[2] || 0 : 0;
481
+ const loudest = Math.max(l0, l1, l2);
482
+ const update = (variation, reactivity, sourceLevel) => {
483
+ variation.target = bandTarget(reactivity, levels, sourceLevel);
484
+ const easing = variation.target > variation.current ? reactivity.attack : reactivity.decay;
485
+ variation.current += (variation.target - variation.current) * easing * delta;
486
+ };
487
+ update(variations.volume, cfg.volume, loudest);
488
+ update(variations.medium, cfg.medium, l1);
489
+ update(variations.high, cfg.high, l2);
490
+ update(variations.low, cfg.low, l0);
491
+ const timeFrequency = variations.low.current;
492
+ const elapsed = delta * timeFrequency;
493
+ material.uniforms.uDisplacement.value = variations.volume.current;
494
+ material.uniforms.uSizeAudio.value = variations.medium.current;
495
+ material.uniforms.uSwirl.value = variations.high.current;
496
+ material.uniforms.uTime.value += elapsed;
497
+ rotationState.y += delta * cfg.rotationBias + variations.high.current * delta * 8e-4;
498
+ points.rotation.y = rotationState.y;
499
+ } else {
500
+ material.uniforms.uTime.value += delta * cfg.idleNoiseRate;
501
+ }
502
+ renderer.render(scene, camera);
503
+ rafId = requestAnimationFrame(render);
504
+ };
505
+ rafId = requestAnimationFrame(render);
506
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
507
+ const w = container.clientWidth || 1;
508
+ const h = container.clientHeight || 1;
509
+ camera.aspect = w / h;
510
+ camera.updateProjectionMatrix();
511
+ renderer.setSize(w, h, false);
512
+ }) : null;
513
+ resizeObserver?.observe(container);
514
+ return () => {
515
+ disposed = true;
516
+ cancelAnimationFrame(rafId);
517
+ resizeObserver?.disconnect();
518
+ geometry.dispose();
519
+ material.dispose();
520
+ renderer.dispose();
521
+ if (renderer.domElement.parentNode === container) {
522
+ container.removeChild(renderer.domElement);
523
+ }
524
+ };
525
+ }, [
526
+ initCount,
527
+ initInnerRadius,
528
+ initOuterRadius,
529
+ initSeed,
530
+ initMaxPixelRatio,
531
+ initBackgroundColor
532
+ ]);
533
+ return /* @__PURE__ */ jsx2("div", { ref: containerRef, className, style });
534
+ }
535
+
536
+ export {
537
+ OrganicSphere,
538
+ OrganicParticles
539
+ };
540
+ //# sourceMappingURL=chunk-KMSL5PWK.js.map