Files
multiverse/xcom-ultra/xcu-command-center/src/components/modules/M44ResonanceAudio.jsx
T

184 lines
6.5 KiB
React

import React, { useEffect, useRef, useState } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import * as THREE from 'three';
// --- Komponen 3D: Biomechanical Audio Sphere ---
function ResonanceSphere({ analyser }) {
const meshRef = useRef();
const materialRef = useRef();
// Buffer untuk memuat data frekuensi audio
const dataArray = useRef(new Uint8Array(64));
useFrame((state, delta) => {
if (!meshRef.current || !analyser) return;
// Menarik data frekuensi mutakhir (Real-Time)
analyser.getByteFrequencyData(dataArray.current);
// Hitung rata-rata frekuensi (Bass/Mid) untuk denyut ukuran
let sum = 0;
for (let i = 0; i < dataArray.current.length; i++) {
sum += dataArray.current[i];
}
const average = sum / dataArray.current.length;
// Normalisasi skala denyut (Scale Pulsing)
const scale = 1 + (average / 255) * 1.5;
// Terapkan ke Mesh secara halus menggunakan Lerp
meshRef.current.scale.lerp(new THREE.Vector3(scale, scale, scale), 0.2);
// Rotasi konstan ala Sci-Fi
meshRef.current.rotation.x += delta * 0.5;
meshRef.current.rotation.y += delta * 0.8;
// Reaktivitas Warna: Semakin keras, merah semakin meradang
if (materialRef.current) {
const redIntensity = average / 255;
materialRef.current.emissive.setRGB(redIntensity + 0.2, 0, 0);
materialRef.current.emissiveIntensity = 1 + (redIntensity * 3);
}
});
return (
<mesh ref={meshRef}>
<icosahedronGeometry args={[1.5, 2]} />
<meshStandardMaterial
ref={materialRef}
color={0x110000}
emissive={new THREE.Color(0xff0000)}
emissiveIntensity={1}
wireframe={true}
transparent={true}
opacity={0.8}
/>
</mesh>
);
}
export default function M44ResonanceAudio() {
const [engineStatus, setEngineStatus] = useState('OFFLINE');
const [bitrate, setBitrate] = useState('0 kbps');
const audioContextRef = useRef(null);
const analyserRef = useRef(null);
const mediaStreamRef = useRef(null);
const sourceRef = useRef(null);
useEffect(() => {
setEngineStatus('BOOTING RESONANCE...');
async function initAudio() {
try {
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
throw new Error("Web Audio API / MediaDevices tidak didukung.");
}
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
mediaStreamRef.current = stream;
// Inisialisasi Kuantum Audio Engine
audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
analyserRef.current = audioContextRef.current.createAnalyser();
// Konfigurasi presisi pembedahan frekuensi
analyserRef.current.fftSize = 128; // Ringan namun cukup detail untuk visual
analyserRef.current.smoothingTimeConstant = 0.8;
sourceRef.current = audioContextRef.current.createMediaStreamSource(stream);
sourceRef.current.connect(analyserRef.current);
setEngineStatus('VOCAL TRACT SYNTHESIS ENGAGED');
// Simulasi kalkulasi ekstrim ke 3kbps (menyesuaikan frekuensi suara)
setInterval(() => {
if(analyserRef.current) {
const data = new Uint8Array(analyserRef.current.frequencyBinCount);
analyserRef.current.getByteFrequencyData(data);
let activity = data.reduce((a,b)=>a+b, 0);
if(activity > 500) {
setBitrate((2.5 + Math.random()).toFixed(2) + ' kbps');
} else {
setBitrate('0.00 kbps (VAD Active)');
}
}
}, 500);
} catch (err) {
console.error("Resonance Audio Error:", err);
setEngineStatus('MICROPHONE ACCESS DENIED');
}
}
initAudio();
return () => {
// Protokol Pembersihan Memori (Zero Error)
if (mediaStreamRef.current) {
mediaStreamRef.current.getTracks().forEach(track => track.stop());
}
if (audioContextRef.current && audioContextRef.current.state !== 'closed') {
audioContextRef.current.close();
}
};
}, []);
return (
<div style={{animation: 'fadeIn 0.5s ease-out', height: '100%', display: 'flex', flexDirection: 'column'}}>
{/* UI Overlay */}
<div className="glass-panel" style={{
padding: '15px', marginBottom: '15px', display: 'flex', justifyContent: 'space-between',
alignItems: 'center', borderColor: '#ff003c'
}}>
<div>
<h2 style={{margin: 0, color: '#ff003c', letterSpacing: '2px', textTransform: 'uppercase'}}>M44: The Resonance Matrix</h2>
<div style={{color: 'var(--text-muted)', fontSize: '0.8rem', fontFamily: 'monospace', marginTop: '5px'}}>
Biomechanical Vocal Tract Synthesis. Bypassing Opus codec.
</div>
</div>
<div style={{textAlign: 'right'}}>
<div style={{color: '#888', fontSize: '0.7rem', letterSpacing: '2px'}}>SYNTHESIS STATUS</div>
<div style={{color: engineStatus.includes('ENGAGED') ? '#ff003c' : 'var(--accent-yellow)', fontWeight: 'bold', fontFamily: 'monospace'}}>
{engineStatus}
</div>
</div>
</div>
{/* 3D WebGL Audio Environment */}
<div style={{flex: 1, borderRadius: '8px', overflow: 'hidden', border: '1px solid #330000', background: '#050000', position: 'relative'}}>
{/* Holographic grid UI overlay */}
<div style={{
position: 'absolute', top: '20px', left: '20px', zIndex: 10,
background: 'rgba(255, 0, 60, 0.1)', padding: '10px', borderLeft: '2px solid #ff003c',
fontFamily: 'monospace', fontSize: '0.8rem', color: '#ff003c', pointerEvents: 'none'
}}>
<div>VOCAL TENSION: DYNAMIC</div>
<div>CODEC: RESONANCE WASM (PHASE 44)</div>
<div>REAL-TIME BITRATE: {bitrate}</div>
</div>
<Canvas camera={{ position: [0, 0, 6], fov: 60 }}>
<ambientLight intensity={0.2} />
<pointLight position={[10, 10, 10]} intensity={1} color="#ff0000" />
<pointLight position={[-10, -10, -10]} intensity={0.5} color="#550000" />
<ResonanceSphere analyser={analyserRef.current} />
<OrbitControls
enablePan={false}
maxPolarAngle={Math.PI / 1.5}
minPolarAngle={Math.PI / 3}
autoRotate={true}
autoRotateSpeed={0.5}
/>
</Canvas>
</div>
</div>
);
}