@vib3code/sdk 2.0.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.
Files changed (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,505 @@
1
+ /**
2
+ * AudioReactivity.js - Audio Input Visualization System
3
+ *
4
+ * Provides audio-reactive features:
5
+ * - Microphone input capture
6
+ * - Audio file playback analysis
7
+ * - FFT frequency analysis
8
+ * - Beat detection
9
+ * - Mapping audio features to 6D rotation parameters
10
+ */
11
+
12
+ import { EventEmitter } from 'events';
13
+
14
+ /**
15
+ * Audio source types
16
+ */
17
+ export const AudioSource = {
18
+ MICROPHONE: 'microphone',
19
+ FILE: 'file',
20
+ ELEMENT: 'element',
21
+ STREAM: 'stream'
22
+ };
23
+
24
+ /**
25
+ * Frequency band definitions (Hz)
26
+ */
27
+ export const FrequencyBand = {
28
+ SUB_BASS: { min: 20, max: 60 },
29
+ BASS: { min: 60, max: 250 },
30
+ LOW_MID: { min: 250, max: 500 },
31
+ MID: { min: 500, max: 2000 },
32
+ HIGH_MID: { min: 2000, max: 4000 },
33
+ PRESENCE: { min: 4000, max: 6000 },
34
+ BRILLIANCE: { min: 6000, max: 20000 }
35
+ };
36
+
37
+ /**
38
+ * AudioReactivity - Audio input visualization system
39
+ */
40
+ export class AudioReactivity extends EventEmitter {
41
+ constructor(options = {}) {
42
+ super();
43
+
44
+ this.audioContext = null;
45
+ this.analyser = null;
46
+ this.source = null;
47
+ this.mediaStream = null;
48
+
49
+ // Configuration
50
+ this.config = {
51
+ fftSize: options.fftSize || 2048,
52
+ smoothingTimeConstant: options.smoothing || 0.8,
53
+ minDecibels: options.minDecibels || -90,
54
+ maxDecibels: options.maxDecibels || -10,
55
+ beatThreshold: options.beatThreshold || 0.8,
56
+ beatCooldown: options.beatCooldown || 100
57
+ };
58
+
59
+ // Analysis data
60
+ this.frequencyData = null;
61
+ this.timeDomainData = null;
62
+ this.bandLevels = {};
63
+
64
+ // Beat detection
65
+ this.beatHistory = [];
66
+ this.beatHistorySize = 43; // ~1 second at 60fps
67
+ this.lastBeatTime = 0;
68
+ this.bpm = 0;
69
+ this.isBeat = false;
70
+
71
+ // Feature extraction
72
+ this.features = {
73
+ volume: 0,
74
+ bass: 0,
75
+ mid: 0,
76
+ treble: 0,
77
+ energy: 0,
78
+ centroid: 0,
79
+ flatness: 0
80
+ };
81
+
82
+ // 6D rotation mapping
83
+ this.rotationMapping = {
84
+ xy: { feature: 'bass', scale: 0.5, offset: 0 },
85
+ xz: { feature: 'mid', scale: 0.3, offset: 0 },
86
+ yz: { feature: 'treble', scale: 0.2, offset: 0 },
87
+ xw: { feature: 'energy', scale: 0.4, offset: 0 },
88
+ yw: { feature: 'centroid', scale: 0.3, offset: 0 },
89
+ zw: { feature: 'flatness', scale: 0.2, offset: 0 }
90
+ };
91
+
92
+ // State
93
+ this.isActive = false;
94
+ this.sourceType = null;
95
+ this._animationFrame = null;
96
+
97
+ // Bind methods
98
+ this._analyze = this._analyze.bind(this);
99
+ }
100
+
101
+ /**
102
+ * Initialize audio context
103
+ */
104
+ async initialize() {
105
+ try {
106
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
107
+ this.analyser = this.audioContext.createAnalyser();
108
+
109
+ this.analyser.fftSize = this.config.fftSize;
110
+ this.analyser.smoothingTimeConstant = this.config.smoothingTimeConstant;
111
+ this.analyser.minDecibels = this.config.minDecibels;
112
+ this.analyser.maxDecibels = this.config.maxDecibels;
113
+
114
+ // Initialize data arrays
115
+ const bufferLength = this.analyser.frequencyBinCount;
116
+ this.frequencyData = new Uint8Array(bufferLength);
117
+ this.timeDomainData = new Uint8Array(bufferLength);
118
+
119
+ this.emit('initialized');
120
+ return true;
121
+ } catch (err) {
122
+ console.error('Failed to initialize audio context:', err);
123
+ this.emit('error', err);
124
+ return false;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Connect to microphone
130
+ */
131
+ async connectMicrophone() {
132
+ if (!this.audioContext) {
133
+ await this.initialize();
134
+ }
135
+
136
+ try {
137
+ this.mediaStream = await navigator.mediaDevices.getUserMedia({
138
+ audio: {
139
+ echoCancellation: false,
140
+ noiseSuppression: false,
141
+ autoGainControl: false
142
+ }
143
+ });
144
+
145
+ this.source = this.audioContext.createMediaStreamSource(this.mediaStream);
146
+ this.source.connect(this.analyser);
147
+
148
+ this.sourceType = AudioSource.MICROPHONE;
149
+ this.isActive = true;
150
+ this._startAnalysis();
151
+
152
+ this.emit('connected', { source: AudioSource.MICROPHONE });
153
+ return true;
154
+ } catch (err) {
155
+ console.error('Microphone access denied:', err);
156
+ this.emit('error', err);
157
+ return false;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Connect to audio element
163
+ */
164
+ connectElement(audioElement) {
165
+ if (!this.audioContext) {
166
+ this.initialize();
167
+ }
168
+
169
+ try {
170
+ this.source = this.audioContext.createMediaElementSource(audioElement);
171
+ this.source.connect(this.analyser);
172
+ this.analyser.connect(this.audioContext.destination);
173
+
174
+ this.sourceType = AudioSource.ELEMENT;
175
+ this.isActive = true;
176
+ this._startAnalysis();
177
+
178
+ this.emit('connected', { source: AudioSource.ELEMENT });
179
+ return true;
180
+ } catch (err) {
181
+ console.error('Failed to connect audio element:', err);
182
+ this.emit('error', err);
183
+ return false;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Load and connect audio file
189
+ */
190
+ async connectFile(file) {
191
+ if (!this.audioContext) {
192
+ await this.initialize();
193
+ }
194
+
195
+ try {
196
+ const arrayBuffer = await file.arrayBuffer();
197
+ const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
198
+
199
+ this.source = this.audioContext.createBufferSource();
200
+ this.source.buffer = audioBuffer;
201
+ this.source.connect(this.analyser);
202
+ this.analyser.connect(this.audioContext.destination);
203
+
204
+ this.sourceType = AudioSource.FILE;
205
+ this.isActive = true;
206
+ this._startAnalysis();
207
+
208
+ this.source.start(0);
209
+ this.source.onended = () => {
210
+ this.emit('ended');
211
+ };
212
+
213
+ this.emit('connected', { source: AudioSource.FILE, duration: audioBuffer.duration });
214
+ return true;
215
+ } catch (err) {
216
+ console.error('Failed to load audio file:', err);
217
+ this.emit('error', err);
218
+ return false;
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Disconnect current source
224
+ */
225
+ disconnect() {
226
+ this._stopAnalysis();
227
+
228
+ if (this.source) {
229
+ this.source.disconnect();
230
+ this.source = null;
231
+ }
232
+
233
+ if (this.mediaStream) {
234
+ this.mediaStream.getTracks().forEach(track => track.stop());
235
+ this.mediaStream = null;
236
+ }
237
+
238
+ this.isActive = false;
239
+ this.sourceType = null;
240
+
241
+ this.emit('disconnected');
242
+ }
243
+
244
+ /**
245
+ * Dispose and cleanup
246
+ */
247
+ dispose() {
248
+ this.disconnect();
249
+
250
+ if (this.audioContext) {
251
+ this.audioContext.close();
252
+ this.audioContext = null;
253
+ }
254
+
255
+ this.emit('disposed');
256
+ }
257
+
258
+ /**
259
+ * Resume audio context (required after user interaction)
260
+ */
261
+ async resume() {
262
+ if (this.audioContext?.state === 'suspended') {
263
+ await this.audioContext.resume();
264
+ this.emit('resumed');
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Start analysis loop
270
+ */
271
+ _startAnalysis() {
272
+ if (this._animationFrame) return;
273
+ this._analyze();
274
+ }
275
+
276
+ /**
277
+ * Stop analysis loop
278
+ */
279
+ _stopAnalysis() {
280
+ if (this._animationFrame) {
281
+ cancelAnimationFrame(this._animationFrame);
282
+ this._animationFrame = null;
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Main analysis loop
288
+ */
289
+ _analyze() {
290
+ if (!this.isActive) return;
291
+
292
+ // Get frequency and time domain data
293
+ this.analyser.getByteFrequencyData(this.frequencyData);
294
+ this.analyser.getByteTimeDomainData(this.timeDomainData);
295
+
296
+ // Extract features
297
+ this._extractFeatures();
298
+
299
+ // Detect beats
300
+ this._detectBeat();
301
+
302
+ // Calculate band levels
303
+ this._calculateBandLevels();
304
+
305
+ // Calculate 6D rotation
306
+ const rotation = this.get6DRotation();
307
+
308
+ // Emit analysis data
309
+ this.emit('analysis', {
310
+ features: { ...this.features },
311
+ bands: { ...this.bandLevels },
312
+ beat: this.isBeat,
313
+ bpm: this.bpm,
314
+ rotation
315
+ });
316
+
317
+ this._animationFrame = requestAnimationFrame(this._analyze);
318
+ }
319
+
320
+ /**
321
+ * Extract audio features
322
+ */
323
+ _extractFeatures() {
324
+ const binCount = this.frequencyData.length;
325
+
326
+ // Calculate overall volume (RMS)
327
+ let sum = 0;
328
+ for (let i = 0; i < this.timeDomainData.length; i++) {
329
+ const val = (this.timeDomainData[i] - 128) / 128;
330
+ sum += val * val;
331
+ }
332
+ this.features.volume = Math.sqrt(sum / this.timeDomainData.length);
333
+
334
+ // Calculate frequency band levels
335
+ const bassEnd = Math.floor(binCount * 0.1);
336
+ const midEnd = Math.floor(binCount * 0.5);
337
+
338
+ let bassSum = 0, midSum = 0, trebleSum = 0;
339
+
340
+ for (let i = 0; i < binCount; i++) {
341
+ const val = this.frequencyData[i] / 255;
342
+ if (i < bassEnd) {
343
+ bassSum += val;
344
+ } else if (i < midEnd) {
345
+ midSum += val;
346
+ } else {
347
+ trebleSum += val;
348
+ }
349
+ }
350
+
351
+ this.features.bass = bassSum / bassEnd;
352
+ this.features.mid = midSum / (midEnd - bassEnd);
353
+ this.features.treble = trebleSum / (binCount - midEnd);
354
+
355
+ // Calculate energy (sum of all frequency magnitudes)
356
+ let energy = 0;
357
+ for (let i = 0; i < binCount; i++) {
358
+ energy += this.frequencyData[i] / 255;
359
+ }
360
+ this.features.energy = energy / binCount;
361
+
362
+ // Calculate spectral centroid (brightness)
363
+ let weightedSum = 0;
364
+ let magnitudeSum = 0;
365
+ for (let i = 0; i < binCount; i++) {
366
+ const magnitude = this.frequencyData[i] / 255;
367
+ weightedSum += i * magnitude;
368
+ magnitudeSum += magnitude;
369
+ }
370
+ this.features.centroid = magnitudeSum > 0 ? (weightedSum / magnitudeSum) / binCount : 0;
371
+
372
+ // Calculate spectral flatness (tonality vs noise)
373
+ let geometricMean = 0;
374
+ let arithmeticMean = 0;
375
+ const epsilon = 0.001;
376
+
377
+ for (let i = 0; i < binCount; i++) {
378
+ const val = Math.max(this.frequencyData[i] / 255, epsilon);
379
+ geometricMean += Math.log(val);
380
+ arithmeticMean += val;
381
+ }
382
+
383
+ geometricMean = Math.exp(geometricMean / binCount);
384
+ arithmeticMean = arithmeticMean / binCount;
385
+
386
+ this.features.flatness = arithmeticMean > 0 ? geometricMean / arithmeticMean : 0;
387
+ }
388
+
389
+ /**
390
+ * Detect beats
391
+ */
392
+ _detectBeat() {
393
+ const now = performance.now();
394
+ const energy = this.features.energy;
395
+
396
+ // Add to history
397
+ this.beatHistory.push(energy);
398
+ if (this.beatHistory.length > this.beatHistorySize) {
399
+ this.beatHistory.shift();
400
+ }
401
+
402
+ // Calculate average energy
403
+ const avgEnergy = this.beatHistory.reduce((a, b) => a + b, 0) / this.beatHistory.length;
404
+
405
+ // Calculate variance
406
+ const variance = this.beatHistory.reduce((acc, val) => acc + Math.pow(val - avgEnergy, 2), 0) / this.beatHistory.length;
407
+
408
+ // Dynamic threshold based on variance
409
+ const threshold = avgEnergy + (Math.sqrt(variance) * this.config.beatThreshold);
410
+
411
+ // Check for beat
412
+ const wasInCooldown = (now - this.lastBeatTime) < this.config.beatCooldown;
413
+ this.isBeat = energy > threshold && !wasInCooldown;
414
+
415
+ if (this.isBeat) {
416
+ // Update BPM calculation
417
+ const timeSinceLastBeat = now - this.lastBeatTime;
418
+ if (timeSinceLastBeat > 200 && timeSinceLastBeat < 2000) {
419
+ const instantBPM = 60000 / timeSinceLastBeat;
420
+ this.bpm = this.bpm === 0 ? instantBPM : this.bpm * 0.9 + instantBPM * 0.1;
421
+ }
422
+
423
+ this.lastBeatTime = now;
424
+ this.emit('beat', { energy, bpm: this.bpm });
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Calculate frequency band levels
430
+ */
431
+ _calculateBandLevels() {
432
+ const binCount = this.frequencyData.length;
433
+ const nyquist = this.audioContext?.sampleRate / 2 || 22050;
434
+ const binWidth = nyquist / binCount;
435
+
436
+ for (const [name, band] of Object.entries(FrequencyBand)) {
437
+ const startBin = Math.floor(band.min / binWidth);
438
+ const endBin = Math.min(Math.floor(band.max / binWidth), binCount - 1);
439
+
440
+ let sum = 0;
441
+ for (let i = startBin; i <= endBin; i++) {
442
+ sum += this.frequencyData[i] / 255;
443
+ }
444
+
445
+ this.bandLevels[name] = sum / (endBin - startBin + 1);
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Get 6D rotation values based on audio features
451
+ */
452
+ get6DRotation() {
453
+ const rotation = {};
454
+
455
+ for (const [plane, mapping] of Object.entries(this.rotationMapping)) {
456
+ const featureValue = this.features[mapping.feature] || 0;
457
+ rotation[plane] = (featureValue * mapping.scale + mapping.offset) * Math.PI * 2;
458
+ }
459
+
460
+ return rotation;
461
+ }
462
+
463
+ /**
464
+ * Set rotation mapping for a plane
465
+ */
466
+ setRotationMapping(plane, feature, scale = 1, offset = 0) {
467
+ if (this.rotationMapping[plane]) {
468
+ this.rotationMapping[plane] = { feature, scale, offset };
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Get current frequency data (for visualization)
474
+ */
475
+ getFrequencyData() {
476
+ return this.frequencyData ? Array.from(this.frequencyData) : [];
477
+ }
478
+
479
+ /**
480
+ * Get current waveform data (for visualization)
481
+ */
482
+ getWaveformData() {
483
+ return this.timeDomainData ? Array.from(this.timeDomainData) : [];
484
+ }
485
+
486
+ /**
487
+ * Serialize configuration
488
+ */
489
+ toJSON() {
490
+ return {
491
+ config: this.config,
492
+ rotationMapping: this.rotationMapping
493
+ };
494
+ }
495
+
496
+ /**
497
+ * Restore from serialized state
498
+ */
499
+ fromJSON(data) {
500
+ if (data.config) Object.assign(this.config, data.config);
501
+ if (data.rotationMapping) Object.assign(this.rotationMapping, data.rotationMapping);
502
+ }
503
+ }
504
+
505
+ export default AudioReactivity;