RD5 GOLD WEB EDITOR
📄
📄 2-RB4-3CC.HTML
📄 222.JPG
📄 3CC-BASIC1.HTML
📄 Microsoft Paint.exe
📄 R2C-3.HTML
📄 R2C-4.HTML
📄 RB4-3C.HTML
📄 RB4-3CC.HTML
📄 RB4-RETRO.HTML
📄 RB4-RETRO.html
📄 RD5-3CC.html
📄 RL-4.html
📄 TARS.html
📄 TES10.mp3
📄 TES11.mp3
📄 TRISHA-OK.html
📄 TRISHA-WIN.HTML
📄 Tiny-demo.html
📄 Tinybj7-blindado.html
📄 Tinybj7-publica.html
📄 aplicaciones-rd5.html
📄 app1.html
📄 app2.html
📄 app3.html
📄 appb1.html
📄 appb2.html
📄 appb3.html
📄 appb4.html
📄 appb5.html
📄 appb6.html
📄 c-julio.JPG
📄 caratula.gif
📄 caratula02.gif
📄 caratula2.gif
📄 chokurei2.jpg
📄 columna-julio.html
📄 columna-stella.html
📄 columna-stellab.html
📄 demos.html
📄 df3.html
📄 dni.gif
📄 donaciones.gif
📄 ecualizador.html
📄 ed-podcast.JPG
📄 ed-radio.JPG
📄 editorv.html
📄 editorv1.html
📄 editorv2.html
📄 fondo5d.jpg
📄 fresi-clip.html
📄 gold.php
📄 gold62.php
📄 gold93.php
📄 googlefd161ffccea5f6ab.html
📄 gw.php
📄 index-anterior.html
📄 index.html
📄 index2.html
📄 logo.png
📄 logo.webp
📄 magazine.html
📄 manager3.php
📄 mic2.jpg
📄 mini1.html
📄 minib2a.html
📄 mn.php
📄 muestra.JPG
📄 p.html
📄 pm.html
📄 pm2.html
📄 pod-rd5.html
📄 podcast-stops.gif
📄 podcast2.mp3
📄 pp.html
📄 promo-tinybj7.html
📄 radio.html
📄 radio_gold.html
📄 rd5-fresia-4 canvashtml
📄 rd5-fresia-ok.html
📄 rd5-fresia.html
📄 rd5-plus-anterior.html
📄 rd5-plus.html
📄 rd5-plus2.html
📄 rd5-radioplayer.html
📄 rd5-tv.html
📄 rd5.html
📄 sst.html
📄 st.html
📄 starclip.html
📄 stella-2.JPG
📄 stella.JPG
📄 stt.html
📄 t-rd5.html.html
📄 t-rd6.html
📄 t-rd7.html
📄 t-tiny.html
📄 tes0.jpg
📄 tes1.jpg
📄 tes2.jpg
📄 tes4.jpg
📄 tes4.mp3
📄 tes5.jpg
📄 tes7.jpg
📄 tes8.jpg
📄 tienda.html
📄 tiendaaps.html
📄 tiendapps.html
📄 tiny-bj6.html
📄 tiny-bj7-full.html
📄 tiny-bj7.html
📄 tiny3-bj2.html
📄 tinybj7-blindado.html
📄 tinydemo.html
📄 titulo.jpg
📄 tnw2.html
📄 trisha-basic.html
📄 trisha-cafe.html
📄 trisha-mini.html
📄 tv-pantalla.php
📄 tv.html
📄 xdni.html
CÓDIGO (OSCURO GOLD)
VISTA PREVIA
💾 GUARDAR
Tema: Monokai
Tema: Dracula
Tema: Material
Tema: Blackboard
Tema: Abyss
Monospace
Courier
12px
14px
16px
18px
20px
22px
24px
26px
28px
30px
32px
↷ Rehacer
↶ Deshacer
🔍 BUSCAR
+ REPRO RADIO
SIG.
X
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Trisha TINY-BJ2 - 8 Band EQ ARMOURED</title> <style> :root { --accent: orange; --bg-panel: #1a110f; --bg-body: #231815; --border: #3a2c28; --text-muted: #888; --text-main: #ccc; } body { background: var(--bg-body); color:white; font-family:Arial, sans-serif; margin:15px; overflow-x: hidden; transition: background 0.3s; } #contador { font-size: 20px; margin-top:10px; color:white; font-family: monospace; border-top: 1px solid var(--border); padding-top: 10px; } .linea { display:flex; align-items:flex-start; gap:15px; flex-wrap:wrap; } .cont-sliders { display: flex; gap: 8px; align-items: flex-end; background: var(--bg-panel); padding: 10px; border-radius: 8px; border: 1px solid var(--border); box-shadow: inset 0 0 10px #000; } .control-vertical { display: flex; flex-direction: column; align-items: center; gap: 5px; width: 42px; } .slider-v { -webkit-appearance: slider-vertical; width: 8px; height: 60px; background: var(--border); outline: none; cursor: pointer; } .val-pct { font-size: 9px; color: var(--accent); font-family: monospace; min-height: 11px; } label { font-size: 8px; text-transform: uppercase; color: var(--text-muted); font-weight: bold; } canvas.vu { background:black; border:4px solid #888; border-radius:50%; box-shadow: 0 0 5px #000; } #lista { margin-top:10px; max-height:259px; overflow-y:auto; list-style:none; padding-left:0; user-select: none; border: 1px solid var(--border); background: var(--bg-panel); border-radius: 4px; } #lista li { padding:8px 12px; border-bottom: 1px solid #333; font-size: 13px; color: var(--text-main); cursor: grab; transition: background 0.2s; } #lista li:active { cursor: grabbing; } #lista li.dragging { opacity: 0.5; background: #444; } #lista li.active { background:#42322f; color: var(--accent); font-weight: bold; border-left: 4px solid var(--accent); } #prog { -webkit-appearance:none; appearance:none; width:100%; height:8px; background: var(--border); border-radius:5px; margin: 15px 0; cursor: pointer; } #prog::-webkit-slider-thumb { -webkit-appearance:none; width:14px; height:14px; background: var(--accent); border-radius:50%; border:2px solid black; } #btnLimpiar { padding: 5px; background: #e3a465; color: black; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; writing-mode: vertical-lr; text-transform: uppercase; height: 105px; font-size: 11px; } .librero { display: flex; gap: 4px; } .btnTema { width: 25px; height: 105px; border: none; border-radius: 2px; cursor: pointer; font-weight: bold; writing-mode: vertical-lr; font-size: 9px; text-transform: uppercase; color: white; transition: 0.2s; display: flex; align-items: center; justify-content: center; } .btnTema:hover { transform: translateY(-3px); filter: brightness(1.2); } .t-azul { background: #2980b9; } .t-verde { background: #27ae60; } .t-rojo { background: #c0392b; } .t-custom { background: #444; position: relative; overflow: hidden; } #colorCustom { position: absolute; width: 150%; height: 150%; cursor: pointer; border: none; padding: 0; } </style> </head> <body> <div class="linea"> <div style="display:flex; flex-direction:column; gap:10px;"> <input type="file" id="archivos" multiple accept="audio/*"> <div style="display:flex; gap:10px;"> <canvas id="btnPlay" class="vu" width="70" height="70" style="cursor:pointer;"></canvas> <canvas id="vuL" class="vu" width="70" height="70"></canvas> <canvas id="vuR" class="vu" width="70" height="70"></canvas> <canvas id="vuECG" class="vu" width="70" height="70"></canvas> <canvas id="vuSpectrum" class="vu" width="70" height="70"></canvas> </div> </div> <div class="cont-sliders"> <div class="control-vertical"><label>VOL</label><input type="range" id="vol" class="slider-v" min="0" max="1" step="0.01" value="0.7"><span id="v-vol" class="val-pct">70%</span></div> <div class="control-vertical"><label>32Hz</label><input type="range" id="eq1" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq1" class="val-pct">0</span></div> <div class="control-vertical"><label>64Hz</label><input type="range" id="eq2" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq2" class="val-pct">0</span></div> <div class="control-vertical"><label>125Hz</label><input type="range" id="eq3" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq3" class="val-pct">0</span></div> <div class="control-vertical"><label>500Hz</label><input type="range" id="eq4" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq4" class="val-pct">0</span></div> <div class="control-vertical"><label>1kHz</label><input type="range" id="eq5" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq5" class="val-pct">0</span></div> <div class="control-vertical"><label>4kHz</label><input type="range" id="eq6" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq6" class="val-pct">0</span></div> <div class="control-vertical"><label>8kHz</label><input type="range" id="eq7" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq7" class="val-pct">0</span></div> <div class="control-vertical"><label>16kHz</label><input type="range" id="eq8" class="slider-v" min="-15" max="15" step="1" value="0"><span id="v-eq8" class="val-pct">0</span></div> <button id="btnLimpiar">Limpiar Lista</button> <div class="librero"> <button class="btnTema t-azul" onclick="cambiarTema('#3498db', '#1a1c2c', '#0d1117')"></button> <button class="btnTema t-verde" onclick="cambiarTema('#2ecc71', '#0f1a11', '#0d140f')"></button> <button class="btnTema t-rojo" onclick="cambiarTema('#e74c3c', '#1a0f0f', '#140d0d')"></button> <div class="btnTema t-custom"> <span style="pointer-events:none; z-index:1;">Custom</span> <input type="color" id="colorCustom" value="#ff8800"> </div> </div> </div> </div> <input type="range" id="prog" min="0" max="100" step="0.1" value="0"> <div id="contador">00:00 / 00:00 • <span id="currentTrack" style="font-weight:bold; color:var(--accent);">esperando motor...</span></div> <ul id="lista"></ul> <script> let audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const player = document.createElement('audio'); const archivos = document.getElementById('archivos'), lista = document.getElementById('lista'), prog = document.getElementById('prog'), contador = document.getElementById('contador'), btnLimpiar = document.getElementById('btnLimpiar'); let playlist = [], index = 0, sourceNode, gainNode, filters = [], splitter, anaL, anaR; // --- TEMA Y COLORES --- function cambiarTema(color, bgPanel, bgBody) { document.documentElement.style.setProperty('--accent', color); if(bgPanel) document.documentElement.style.setProperty('--bg-panel', bgPanel); if(bgBody) document.documentElement.style.setProperty('--bg-body', bgBody); dibujarBtn(); } document.getElementById('colorCustom').oninput = (e) => cambiarTema(e.target.value); // --- NAVEGACIÓN Y TECLADO --- window.addEventListener('keydown', (e) => { if (playlist.length === 0) return; if (e.code === "Space") { e.preventDefault(); togglePlay(); } if (e.code === "ArrowDown") { e.preventDefault(); moverSeleccion(1); } if (e.code === "ArrowUp") { e.preventDefault(); moverSeleccion(-1); } if (e.code === "Enter") { cargar(); player.play(); } }); function moverSeleccion(dir) { index = (index + dir + playlist.length) % playlist.length; actualizarLista(); const activo = lista.querySelector('.active'); if (activo) activo.scrollIntoView({ block: "nearest", behavior: "smooth" }); } function togglePlay() { if (!player.src && playlist.length > 0) cargar(); if (player.src) player.paused ? player.play() : player.pause(); } // --- DRAG & DROP --- lista.addEventListener('dragstart', e => { if(e.target.tagName==='LI') e.target.classList.add('dragging'); }); lista.addEventListener('dragend', e => { if(e.target.tagName==='LI') { e.target.classList.remove('dragging'); reordenarPlaylist(); } }); lista.addEventListener('dragover', e => { e.preventDefault(); const dragging = document.querySelector('.dragging'); if (!dragging) return; const afterElement = getDragAfterElement(lista, e.clientY); if (afterElement == null) lista.appendChild(dragging); else lista.insertBefore(dragging, afterElement); }); function getDragAfterElement(container, y) { const elements = [...container.querySelectorAll('li:not(.dragging)')]; return elements.reduce((closest, child) => { const box = child.getBoundingClientRect(); const offset = y - box.top - box.height / 2; if (offset < 0 && offset > closest.offset) return { offset: offset, element: child }; else return closest; }, { offset: Number.NEGATIVE_INFINITY }).element; } function reordenarPlaylist() { const items = [...lista.querySelectorAll('li')]; const cancionActual = playlist[index]; const nuevaPlaylist = items.map(li => playlist[parseInt(li.getAttribute('data-id'))]); playlist = nuevaPlaylist; index = playlist.indexOf(cancionActual); renderLista(); // Refresca IDs } // --- AUDIO CORE --- player.onplay = () => { if(audioCtx.state === "suspended") audioCtx.resume(); initAudio(); dibujarBtn(); }; player.onpause = () => dibujarBtn(); function initAudio(){ if(sourceNode) return; sourceNode = audioCtx.createMediaElementSource(player); gainNode = audioCtx.createGain(); gainNode.gain.value = document.getElementById('vol').value; const freqs = [32, 64, 125, 500, 1000, 4000, 8000, 16000]; let lastNode = sourceNode; freqs.forEach((freq, i) => { const f = audioCtx.createBiquadFilter(); f.type = (i===0)?"lowshelf":(i===7)?"highshelf":"peaking"; f.frequency.value = freq; f.Q.value = 1.4; f.gain.value = document.getElementById('eq'+(i+1)).value; filters.push(f); lastNode.connect(f); lastNode = f; }); lastNode.connect(gainNode); gainNode.connect(audioCtx.destination); splitter = audioCtx.createChannelSplitter(2); anaL = audioCtx.createAnalyser(); anaR = audioCtx.createAnalyser(); anaL.fftSize = 256; anaR.fftSize = 256; gainNode.connect(splitter); splitter.connect(anaL,0); splitter.connect(anaR,1); } archivos.onchange = e => { const nuevos = [...e.target.files].filter(f=>f.type.startsWith("audio/")); if(!nuevos.length) return; playlist = playlist.concat(nuevos); renderLista(); if(!player.src) { index = 0; cargar(); } }; function renderLista(){ lista.innerHTML = ""; playlist.forEach((f,i)=>{ const li = document.createElement("li"); li.textContent = f.name; li.draggable = true; li.setAttribute('data-id', i); li.onclick = () => { index = i; cargar(); player.play(); }; lista.appendChild(li); }); actualizarLista(); } function actualizarLista(){ [...lista.children].forEach((li, i) => li.classList.toggle("active", i === index)); } function cargar(){ if(!playlist[index]) return; if(player.src) URL.revokeObjectURL(player.src); player.src = URL.createObjectURL(playlist[index]); player.load(); actualizarLista(); } // Sliders vol.oninput = e => { if(gainNode) gainNode.gain.value = e.target.value; document.getElementById('v-vol').textContent = Math.round(e.target.value*100)+'%'; }; [1,2,3,4,5,6,7,8].forEach(n => { document.getElementById('eq'+n).oninput = e => { if(filters[n-1]) filters[n-1].gain.value = e.target.value; document.getElementById('v-eq'+n).textContent = e.target.value; }; }); player.onended = () => { index = (index + 1) % playlist.length; cargar(); player.play(); }; player.ontimeupdate = () => { if(player.duration){ prog.max = player.duration; prog.value = player.currentTime; let m1=Math.floor(player.currentTime/60), s1=Math.floor(player.currentTime%60).toString().padStart(2,0); let m2=Math.floor(player.duration/60), s2=Math.floor(player.duration%60).toString().padStart(2,0); contador.innerHTML = `${m1}:${s1} / ${m2}:${s2} • <span style="color:var(--accent);">${playlist[index].name}</span>`; } }; prog.oninput = () => player.currentTime = prog.value; btnLimpiar.onclick = () => { playlist=[]; index=0; player.pause(); player.src=""; lista.innerHTML=""; }; // --- VISUALIZADORES --- const ctxL = document.getElementById("vuL").getContext("2d"), ctxR = document.getElementById("vuR").getContext("2d"), ctxECG = document.getElementById("vuECG").getContext("2d"), ctxSpec = document.getElementById("vuSpectrum").getContext("2d"), btnC = document.getElementById("btnPlay"), ctxBtn = btnC.getContext("2d"); let aL = -Math.PI, aR = -Math.PI; function aguja(ctx, ang){ ctx.clearRect(0,0,70,70); ctx.beginPath(); ctx.arc(35,35,28,-Math.PI,0,false); ctx.strokeStyle="#1a110f"; ctx.lineWidth=30; ctx.stroke(); ctx.save(); ctx.translate(35,35); ctx.rotate(ang); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(32,0); ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--accent'); ctx.lineWidth=4; ctx.stroke(); ctx.restore(); } function dibujarBtn(){ const acc = getComputedStyle(document.documentElement).getPropertyValue('--accent'); ctxBtn.clearRect(0,0,70,70); ctxBtn.beginPath(); ctxBtn.arc(35,35,30,0,Math.PI*2); ctxBtn.fillStyle = !player.paused?acc:"#42322f"; ctxBtn.fill(); ctxBtn.fillStyle="black"; if(player.paused){ ctxBtn.beginPath(); ctxBtn.moveTo(28,22); ctxBtn.lineTo(28,48); ctxBtn.lineTo(48,35); ctxBtn.fill(); } else { ctxBtn.fillRect(28,22,6,26); ctxBtn.fillRect(40,22,6,26); } } function animar(){ if(anaL){ let dE = new Uint8Array(anaL.fftSize); anaL.getByteTimeDomainData(dE); ctxECG.clearRect(0,0,70,70); ctxECG.beginPath(); ctxECG.moveTo(0,35); for(let i=0;i<dE.length;i++) ctxECG.lineTo(i/dE.length*70, 35+(dE[i]-128)/128*30); ctxECG.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--accent'); ctxECG.stroke(); let dS = new Uint8Array(anaR.frequencyBinCount); anaR.getByteFrequencyData(dS); ctxSpec.clearRect(0,0,70,70); for(let i=0;i<dS.length;i++) { ctxSpec.fillStyle=`hsl(${i/dS.length*360},100%,50%)`; ctxSpec.fillRect(i*(70/dS.length),70-dS[i]/255*70,70/dS.length,dS[i]/255*70); } let L=new Uint8Array(anaL.frequencyBinCount), R=new Uint8Array(anaR.frequencyBinCount); anaL.getByteFrequencyData(L); anaR.getByteFrequencyData(R); aL += ((-1.57 + L.reduce((a,b)=>a+b,0)/L.length/255*3.14) - aL)*0.1; aR += ((-1.57 + R.reduce((a,b)=>a+b,0)/R.length/255*3.14) - aR)*0.1; aguja(ctxL,aL); aguja(ctxR,aR); } requestAnimationFrame(animar); } btnC.onclick = togglePlay; dibujarBtn(); animar(); </script> <div id="armoured-final-row" style="width:100%; margin-top:5px; background:#1a110f; border:1px solid #3a2c28; border-radius:4px; padding:8px; display:flex; align-items:center; gap:10px; box-shadow:inset 0 0 5px #000; box-sizing:border-box;"> <button id="z-mic" style="background:#c0392b; color:white; border:none; padding:6px 10px; border-radius:3px; font-weight:bold; cursor:pointer; font-size:9px;">🔴 MIC</button> <input type="range" id="z-l" min="-15" max="15" value="0" style="width:80px; height:4px; cursor:pointer; accent-color:orange;">low <input type="range" id="z-m" min="-15" max="15" value="0" style="width:80px; height:4px; cursor:pointer; accent-color:orange;">mid <input type="range" id="z-h" min="-15" max="15" value="0" style="width:80px; height:4px; cursor:pointer; accent-color:orange;">hi <div style="width:50px; height:10px; background:#000; border:1px solid #333; border-radius:2px; overflow:hidden;"> <div id="z-vu" style="height:100%; width:0%; background:linear-gradient(90deg, #27ae60, #f1c40f, #e74c3c); transition:width 0.05s;"></div> </div> <button id="z-pv" style="background:#333; color:#aaa; border:none; padding:6px 8px; border-radius:3px; font-size:9px; cursor:pointer;">OÍR</button> <div style="width:1px; height:20px; background:#333;"></div> <button id="z-cp" style="background:#e67e22; color:white; border:none; padding:6px 10px; border-radius:3px; font-weight:bold; cursor:pointer; font-size:9px;">🟠 COMPILAR</button> <button id="z-pp" style="background:#333; color:#aaa; border:none; padding:6px 8px; border-radius:3px; font-size:9px; cursor:pointer;">PREVIEW</button> <div style="width:100px; height:10px; background:#000; border:1px solid #333; border-radius:2px; overflow:hidden;"> <div id="z-vu-p" style="height:100%; width:0%; background:linear-gradient(90deg, #3498db, #9b59b6, #e74c3c); transition:width 0.05s;"></div> </div> <button id="z-dl" style="background:#27ae60; color:white; border:none; padding:6px 12px; border-radius:3px; font-weight:bold; cursor:pointer; font-size:9px; flex-grow:1;">💾 DESCARGAR MP3</button><h1 style="color:var(--accent); font-size: 12px; margin-top:20px; font-weight: bold; text-shadow: 2px 2px 5px black;">Trisha TINY podcaster-BJ7</h1><font color="#3a2c28">............. <audio id="z-am" style="display:none"></audio> <audio id="z-ac" style="display:none"></audio> <script> (function() { let s, r, ch = [], ctx, an, fl = [], micNode, pAn; const bM = document.getElementById('z-mic'), aM = document.getElementById('z-am'), vM = document.getElementById('z-vu'), vP = document.getElementById('z-vu-p'), aC = document.getElementById('z-ac'), btnOir = document.getElementById('z-pv'), btnPreview = document.getElementById('z-pp'); // --- Mic bM.onclick = async () => { if (!s) { try { s = await navigator.mediaDevices.getUserMedia({ audio: true }); ctx = (typeof audioCtx !== 'undefined') ? audioCtx : new AudioContext(); let src = ctx.createMediaStreamSource(s), n = src; an = ctx.createAnalyser(); [250, 1200, 5000].forEach((f,i)=>{ let flt = ctx.createBiquadFilter(); flt.type = i==1?'peaking':i==0?'lowshelf':'highshelf'; flt.frequency.value = f; fl[i] = flt; n.connect(flt); n = flt; }); micNode = n; const d = ctx.createMediaStreamDestination(); n.connect(an); n.connect(d); r = new MediaRecorder(d.stream); ch = []; r.ondataavailable = e => ch.push(e.data); r.onstop = () => aM.src = URL.createObjectURL(new Blob(ch, {type:'audio/mp3'})); r.start(); bM.textContent = "⏹ STOP"; // Vúmetro Mic const lp = () => { if(!s) { vM.style.width="0%"; return; } const dt = new Uint8Array(an.frequencyBinCount); an.getByteFrequencyData(dt); vM.style.width = (dt.reduce((a,b)=>a+b)/dt.length)*2.5 + "%"; requestAnimationFrame(lp); }; lp(); } catch(e){ console.error(e); } } else { r.stop(); s.getTracks().forEach(t=>t.stop()); s=null; bM.textContent="🔴 MIC"; vM.style.width="0%"; } }; // --- Compilar let rC, chC = []; document.getElementById('z-cp').onclick = function() { if(!rC || rC.state === "inactive") { if(typeof gainNode === 'undefined') return; const d = gainNode.context.createMediaStreamDestination(); gainNode.connect(d); if(s && micNode) micNode.connect(d); rC = new MediaRecorder(d.stream); chC=[]; rC.ondataavailable = e => chC.push(e.data); rC.onstop = () => aC.src = URL.createObjectURL(new Blob(chC, {type:'audio/mp3'})); rC.start(); this.textContent="⏹ STOP"; } else { rC.stop(); this.textContent="🟠 COMPILAR"; if(micNode) try{micNode.disconnect();}catch(e){} } }; // --- OÍR Mic Playback con Vúmetro btnOir.onclick = () => { if(!aM.src) return; if(aM.paused) aM.play(); else aM.pause(); btnOir.textContent = aM.paused ? "OÍR" : "⏹ STOP"; const updateVU = () => { if(aM.paused){ vM.style.width="0%"; return; } if(!ctx) ctx = (typeof audioCtx !== 'undefined') ? audioCtx : new AudioContext(); if(!an) { an = ctx.createAnalyser(); const src = ctx.createMediaElementSource(aM); src.connect(an); an.connect(ctx.destination); } const data = new Uint8Array(an.frequencyBinCount); an.getByteFrequencyData(data); vM.style.width = (data.reduce((a,b)=>a+b)/data.length)*2.5 + "%"; requestAnimationFrame(updateVU); }; updateVU(); }; // --- Preview Compilado con Vúmetro btnPreview.onclick = () => { if(!aC.src) return; if(aC.paused) aC.play(); else aC.pause(); btnPreview.textContent = aC.paused ? "PREVIEW" : "⏹ STOP"; if(!pAn) { const pCtx = (typeof audioCtx !== 'undefined') ? audioCtx : new AudioContext(); pAn = pCtx.createAnalyser(); const pSrc = pCtx.createMediaElementSource(aC); pSrc.connect(pAn); pAn.connect(pCtx.destination); } const loopVU = () => { if(aC.paused){ vP.style.width="0%"; return; } const data = new Uint8Array(pAn.frequencyBinCount); pAn.getByteFrequencyData(data); vP.style.width = (data.reduce((a,b)=>a+b)/data.length)*2.5 + "%"; requestAnimationFrame(loopVU); }; loopVU(); }; // --- Descargar document.getElementById('z-dl').onclick = () => { if(!aC.src) return; const a = document.createElement('a'); a.href=aC.src; a.download='mix_final.mp3'; a.click(); }; // --- EQ Mic ['z-l','z-m','z-h'].forEach((id,i)=> document.getElementById(id).oninput = e => fl[i] && (fl[i].gain.value = e.target.value)); })(); </script> <button id="btn-bj8-final" style="background:#2a2a2a; color:#fff; border:1px solid orange; padding:8px 15px; border-radius:4px; font-weight:bold; cursor:pointer; font-size:10px; text-transform:uppercase; transition: 0.2s;"> 📟 MONITOR BJ8 </button> </div> <style> #evo-panel { display: none; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: #000; z-index: 20000; padding: 20px; box-sizing: border-box; } .evo-container { display: flex; flex-direction: column; height: 100%; gap: 10px; max-width: 1400px; margin: 0 auto; } .evo-header { display: flex; justify-content: space-between; color: #0f0; background: #111; padding: 8px 15px; border: 1px solid #333; font-family: monospace; } /* Canvas del Mapeo (Scrolling) */ #evo-canvas-wave { width: 100%; height: 50%; background: #000500; border: 1px solid #004400; border-radius: 4px; image-rendering: pixelated; /* Para que se vea nítido como el software viejo */ } /* Canvas del EQ */ #evo-canvas-bars { width: 100%; height: 40%; background: #000; border: 1px solid #333; border-radius: 4px; } .evo-close { cursor: pointer; color: #fff; background: #c0392b; padding: 0 10px; border-radius: 3px; } </style> <script> document.addEventListener("DOMContentLoaded", function() { const row = document.getElementById('armoured-final-row'); const btn = document.createElement('button'); btn.className = 'btn-evo'; btn.style = "background:#333; color:#0f0; border:1px solid #0f0; padding:6px 12px; border-radius:3px; font-weight:bold; cursor:pointer; font-size:9px;"; btn.innerHTML = '📟 GOLDWAVE MAP'; btn.onclick = toggleEvoPanel; row.insertBefore(btn, document.getElementById('z-dl')); }); let evoAnalyser, waveCtx, barsCtx, waveCanvas; let xScroll = 0; function toggleEvoPanel() { const panel = document.getElementById('evo-panel'); panel.style.display = (panel.style.display === 'block') ? 'none' : 'block'; if (panel.style.display === 'block') setupEvoLogic(); } function setupEvoLogic() { if (evoAnalyser) return; if (typeof audioCtx === 'undefined') return; evoAnalyser = audioCtx.createAnalyser(); evoAnalyser.fftSize = 512; if (typeof gainNode !== 'undefined') gainNode.connect(evoAnalyser); waveCanvas = document.getElementById('evo-canvas-wave'); waveCtx = waveCanvas.getContext('2d'); barsCtx = document.getElementById('evo-canvas-bars').getContext('2d'); // Limpiamos fondo inicial waveCtx.fillStyle = '#000500'; waveCtx.fillRect(0, 0, waveCanvas.width, waveCanvas.height); function render() { requestAnimationFrame(render); const bufferLength = evoAnalyser.frequencyBinCount; const dataFreq = new Uint8Array(bufferLength); const dataWave = new Uint8Array(bufferLength); evoAnalyser.getByteFrequencyData(dataFreq); evoAnalyser.getByteTimeDomainData(dataWave); // --- 1. MAPEO SCROLLING (ESTILO GOLDWAVE) --- // Desplazamos lo dibujado 2 píxeles a la izquierda const imageData = waveCtx.getImageData(2, 0, waveCanvas.width - 2, waveCanvas.height); waveCtx.putImageData(imageData, 0, 0); // Limpiamos la franja nueva a la derecha waveCtx.fillStyle = '#000500'; waveCtx.fillRect(waveCanvas.width - 2, 0, 2, waveCanvas.height); // Dibujamos el pico de audio actual en el borde derecho let min = 255, max = 0; for(let i=0; i<bufferLength; i++) { if(dataWave[i] < min) min = dataWave[i]; if(dataWave[i] > max) max = dataWave[i]; } const yMin = (min / 255) * waveCanvas.height; const yMax = (max / 255) * waveCanvas.height; waveCtx.strokeStyle = '#00ff00'; waveCtx.lineWidth = 2; waveCtx.beginPath(); waveCtx.moveTo(waveCanvas.width - 1, yMin); waveCtx.lineTo(waveCanvas.width - 1, yMax); waveCtx.stroke(); // --- 2. EQ ARCOIRIS (BARRAS GRUESAS) --- const bC = document.getElementById('evo-canvas-bars'); barsCtx.fillStyle = '#000'; barsCtx.fillRect(0, 0, bC.width, bC.height); let barWidth = (bC.width / (bufferLength/2)); let xB = 0; for(let i = 0; i < bufferLength/2; i++) { let barHeight = (dataFreq[i] / 255) * bC.height; let hue = (i / (bufferLength/2)) * 300; barsCtx.fillStyle = `hsl(${hue}, 100%, 50%)`; barsCtx.fillRect(xB, bC.height - barHeight, barWidth - 2, barHeight); xB += barWidth; } } render(); } </script> <div id="evo-panel"> <div class="evo-container"> <div class="evo-header"> <span>GOLDWAVE REAL-TIME MAPPING // TINY-BJ7</span> <span class="evo-close" onclick="toggleEvoPanel()">EXIT [X]</span> </div> <label style="color:#0f0; font-size:10px; margin-left:5px;">SCROLLING WAVEFORM ANALYZER</label> <canvas id="evo-canvas-wave" width="1200" height="100"></canvas> <label style="color:#0f0; font-size:10px; margin-left:5px;">COLOR SPECTRUM BARS</label> <canvas id="evo-canvas-bars" width="1200" height="150"></canvas> </div> <style> #evo-transport{ position:absolute; bottom:0; left:0; width:100%; background:#000; display:flex; align-items:center; justify-content:center; gap:14px; padding:10px; border-top:2px solid #111; z-index:9999; } /* BOTONES */ #evo-transport button{ width:46px; height:46px; background:#000; border:2px solid #fff; border-radius:50%; color:#fff; font-size:18px; display:flex; align-items:center; justify-content:center; cursor:pointer; } #evo-transport button:hover{ background:#111; } /* SLIDERS */ .eq-h{ width:90px; accent-color:white; } .eq-label{ color:white; font-size:10px; font-family:monospace; } </style> <div id="evo-transport"> <button id="ev-prev">⏮</button> <button id="ev-play">▶</button> <button id="ev-pause">⏸</button> <button id="ev-next">⏭</button> <span class="eq-label">VOL</span> <input class="eq-h" id="ev-vol" type="range" min="0" max="1" step="0.01" value="0.7"> <span class="eq-label">LOW</span> <input class="eq-h" id="ev-low" type="range" min="-15" max="15" value="0"> <span class="eq-label">MID</span> <input class="eq-h" id="ev-mid" type="range" min="-15" max="15" value="0"> <span class="eq-label">HIGH</span> <input class="eq-h" id="ev-high" type="range" min="-15" max="15" value="0"> </div> <script> let eqLow, eqMid, eqHigh; function initMiniEQ(){ if(!audioCtx || !gainNode) return; eqLow = audioCtx.createBiquadFilter(); eqLow.type="lowshelf"; eqLow.frequency.value=200; eqMid = audioCtx.createBiquadFilter(); eqMid.type="peaking"; eqMid.frequency.value=1200; eqMid.Q.value=1; eqHigh = audioCtx.createBiquadFilter(); eqHigh.type="highshelf"; eqHigh.frequency.value=6000; gainNode.disconnect(); gainNode.connect(eqLow); eqLow.connect(eqMid); eqMid.connect(eqHigh); eqHigh.connect(audioCtx.destination); } setTimeout(initMiniEQ,1000); /* CONTROLES PLAYER */ document.getElementById("ev-play").onclick=()=>{ if(!player.src && playlist.length>0) cargar(); player.play(); } document.getElementById("ev-pause").onclick=()=>{ player.pause(); } document.getElementById("ev-prev").onclick=()=>{ if(playlist.length===0)return; index=(index-1+playlist.length)%playlist.length; cargar(); player.play(); } document.getElementById("ev-next").onclick=()=>{ if(playlist.length===0)return; index=(index+1)%playlist.length; cargar(); player.play(); } /* VOLUMEN */ document.getElementById("ev-vol").oninput=(e)=>{ player.volume=e.target.value; } /* EQ 3 BANDAS */ document.getElementById("ev-low").oninput=(e)=>{ if(eqLow) eqLow.gain.value=e.target.value; } document.getElementById("ev-mid").oninput=(e)=>{ if(eqMid) eqMid.gain.value=e.target.value; } document.getElementById("ev-high").oninput=(e)=>{ if(eqHigh) eqHigh.gain.value=e.target.value; } </script> </div> <style> #bj8-overlay { display: none; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: #000; /* NEGRO AFUERA */ z-index: 999999; padding: 25px; box-sizing: border-box; font-family: 'Courier New', monospace; } .bj8-main { display: flex; flex-direction: column; height: 100%; max-width: 1200px; margin: 0 auto; gap: 15px; } /* CONTENEDORES GRIS LISO (COMO LA FOTO) */ .bj8-box { background: #333; /* GRIS LISO ADENTRO */ border: 1px solid #444; flex: 1; position: relative; overflow: hidden; border-radius: 5px; } .bj8-label { position: absolute; top: 10px; left: 15px; color: #fff; font-size: 11px; background: rgba(0,0,0,0.6); padding: 4px 8px; border-radius: 3px; font-weight: bold; z-index: 5; } canvas.bj8-canvas { width: 100%; height: 100%; display: block; } .bj8-footer { display: grid; grid-template-columns: repeat(4, 1fr); background: #111; padding: 15px; border: 1px solid #222; border-radius: 5px; color: #666; font-size: 11px; } </style> <div id="bj8-overlay"> <div class="bj8-main"> <div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; padding-bottom: 10px;"> <span style="color: orange; font-weight: bold; letter-spacing: 2px;">SYSTEM: BJ8-ARMORED // MONITOR ACTIVE</span> <button onclick="document.getElementById('bj8-overlay').style.display='none'" style="background: #c0392b; color: white; border: none; padding: 8px 16px; cursor: pointer; font-weight: bold; border-radius: 4px;">EXIT [X]</button> </div> <div class="bj8-box"> <div class="bj8-label">CH 1 - LEFT SIDE</div> <canvas id="bj8-cv-l" class="bj8-canvas"></canvas> </div> <div class="bj8-box"> <div class="bj8-label">CH 2 - RIGHT SIDE</div> <canvas id="bj8-cv-r" class="bj8-canvas"></canvas> </div> <div class="bj8-footer"> <div>MODE: <span style="color:white">REAL_TIME</span></div> <div>SYNC: <span style="color:#0f0">LOCKED</span></div> <div>BUFFER: <span style="color:white">1024 SMPL</span></div> <div>ENGINE: <span style="color:orange">TRISHA-BJ8</span></div> </div> </div> </div> <script> (function() { let bj8Analizador, ctxL, ctxR, cL, cR; const scrollX = 4; document.getElementById('btn-bj8-final').onclick = function() { document.getElementById('bj8-overlay').style.display = 'block'; if (!bj8Analizador) arrancarBJ8(); }; function arrancarBJ8() { // BUSCAMOS TU MOTOR EXISTENTE if (typeof audioCtx === 'undefined') { console.error("No se detectó el Contexto de Audio."); return; } // Creamos un analizador nuevo bj8Analizador = audioCtx.createAnalyser(); bj8Analizador.fftSize = 2048; // SE CONECTA AL gainNode SIN DESCONECTAR EL VOLUMEN // El audio sigue saliendo por tus parlantes, pero le enviamos una "copia" al monitor if (typeof gainNode !== 'undefined') { gainNode.connect(bj8Analizador); } cL = document.getElementById('bj8-cv-l'); cR = document.getElementById('bj8-cv-r'); cL.width = cL.offsetWidth; cL.height = cL.offsetHeight; cR.width = cR.offsetWidth; cR.height = cR.offsetHeight; ctxL = cL.getContext('2d', { alpha: false }); ctxR = cR.getContext('2d', { alpha: false }); // Pintamos el gris liso inicial ctxL.fillStyle = ctxR.fillStyle = '#333'; ctxL.fillRect(0, 0, cL.width, cL.height); ctxR.fillRect(0, 0, cR.width, cR.height); dibujarBJ8(); } function dibujarBJ8() { requestAnimationFrame(dibujarBJ8); if (document.getElementById('bj8-overlay').style.display === 'none') return; const data = new Uint8Array(bj8Analizador.frequencyBinCount); bj8Analizador.getByteTimeDomainData(data); // Efecto Scroll [ctxL, ctxR].forEach(ctx => { const tempImg = ctx.getImageData(scrollX, 0, cL.width - scrollX, cL.height); ctx.putImageData(tempImg, 0, 0); ctx.fillStyle = '#333'; // Gris liso tapa el rastro ctx.fillRect(cL.width - scrollX, 0, scrollX, cL.height); }); // Buscar picos para la onda let min = 255, max = 0; for(let i=0; i < data.length; i++) { if(data[i] < min) min = data[i]; if(data[i] > max) max = data[i]; } const yMin = (min / 255) * cL.height; const yMax = (max / 255) * cL.height; // Dibujo de la línea Blanca (como en la foto) [ctxL, ctxR].forEach(ctx => { ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(cL.width - 2, yMin); ctx.lineTo(cL.width - 2, yMax); ctx.stroke(); }); } })(); </script> </div></div> </body> </html>