FIX: chỉnh sửa hoàn thành UX/UI master strip
This commit is contained in:
+16
-56
@@ -744,7 +744,6 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
const [panText, setPanText] = React.useState('');
|
||||
|
||||
const vuCanvasRef = React.useRef(null);
|
||||
const testSourceRef = React.useRef(null);
|
||||
const animFrameRef = React.useRef(null);
|
||||
const rmsValRef = React.useRef(null);
|
||||
const peakLRef = React.useRef(null);
|
||||
@@ -792,43 +791,6 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
try { e.currentTarget.releasePointerCapture(e.pointerId); } catch(err) {}
|
||||
};
|
||||
|
||||
const startTestAudio = () => {
|
||||
ensureAudio();
|
||||
if (audioCtx.state === 'suspended') audioCtx.resume();
|
||||
stopTestAudio();
|
||||
|
||||
const sampleRate = audioCtx.sampleRate;
|
||||
const bufferSize = sampleRate * 2;
|
||||
const buffer = audioCtx.createBuffer(2, bufferSize, sampleRate);
|
||||
const left = buffer.getChannelData(0);
|
||||
const right = buffer.getChannelData(1);
|
||||
|
||||
for (let i = 0; i < bufferSize; i++) {
|
||||
const t = i / sampleRate;
|
||||
const kick = Math.sin(2 * Math.PI * (55 * Math.exp(-(t % 0.5) * 15))) * Math.max(0, 1 - (t % 0.5) * 6);
|
||||
const synth = Math.sin(2 * Math.PI * 440 * t) * 0.15;
|
||||
left[i] = kick * 0.7 + synth;
|
||||
right[i] = kick * 0.7 + synth * 0.95;
|
||||
}
|
||||
|
||||
const source = audioCtx.createBufferSource();
|
||||
source.buffer = buffer;
|
||||
source.loop = true;
|
||||
source.connect(masterBus.input);
|
||||
source.start();
|
||||
testSourceRef.current = source;
|
||||
setIsTestPlaying(true);
|
||||
};
|
||||
|
||||
const stopTestAudio = () => {
|
||||
if (testSourceRef.current) {
|
||||
try { testSourceRef.current.stop(); } catch(e) {}
|
||||
try { testSourceRef.current.disconnect(); } catch(e) {}
|
||||
testSourceRef.current = null;
|
||||
}
|
||||
setIsTestPlaying(false);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
const canvas = vuCanvasRef.current;
|
||||
if (!canvas) return;
|
||||
@@ -902,11 +864,7 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
return () => {
|
||||
if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
|
||||
};
|
||||
}, [isTestPlaying, isPlaying, masterVolume, isMuted, isMono]);
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => { stopTestAudio(); };
|
||||
}, []);
|
||||
}, [isPlaying, masterVolume, isMuted, isMono]);
|
||||
|
||||
return React.createElement("div", {
|
||||
className: "flex flex-col items-stretch w-[300px] shrink-0 strip-bg rounded-lg p-2 text-slate-300 select-none shadow-2xl relative overflow-hidden"
|
||||
@@ -936,6 +894,17 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
onPointerDown: handlePanPointerDown,
|
||||
onPointerMove: handlePanPointerMove,
|
||||
onPointerUp: handlePanPointerUp,
|
||||
onWheel: function(e) {
|
||||
e.preventDefault();
|
||||
var step = e.deltaY > 0 ? -0.05 : 0.05;
|
||||
var newPan = Math.max(-1, Math.min(1, pan + step));
|
||||
newPan = Math.round(newPan * 100) / 100;
|
||||
setPan(newPan);
|
||||
if (panPointerRef.current) panPointerRef.current.style.transform = 'rotate(' + (newPan * 120) + 'deg)';
|
||||
if (newPan === 0) setPanText('center');
|
||||
else if (newPan < 0) setPanText('L' + Math.abs(Math.round(newPan * 100)));
|
||||
else setPanText('R' + Math.round(newPan * 100));
|
||||
},
|
||||
onDoubleClick: function() { setPan(0); setPanText('center'); if (panPointerRef.current) panPointerRef.current.style.transform = 'rotate(0deg)'; }
|
||||
}, React.createElement("div", {
|
||||
ref: panPointerRef,
|
||||
@@ -960,7 +929,7 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
React.createElement("span", { className: "flex-1 flex items-center justify-end" }, "-36"), React.createElement("span", { className: "flex-1 flex items-center justify-end" }, "-42"), React.createElement("span", { className: "flex-1 flex items-center justify-end" }, "-54")
|
||||
),
|
||||
React.createElement("div", { className: "flex-1 relative bg-slate-950 rounded overflow-hidden mx-1.5 border border-slate-900" },
|
||||
React.createElement("canvas", { ref: vuCanvasRef, className: "w-full h-full block" }),
|
||||
React.createElement("canvas", { ref: vuCanvasRef, className: "w-[100px] h-full block" }),
|
||||
React.createElement("div", { className: "absolute bottom-0.5 inset-x-0 flex justify-around text-[7px] font-mono text-slate-500 font-bold pointer-events-none bg-black/60 py-0.5" },
|
||||
React.createElement("span", null, "L"), React.createElement("span", null, "R")
|
||||
)
|
||||
@@ -1051,7 +1020,7 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
}
|
||||
},
|
||||
title: "Bật/Tắt MASTERING PANEL Bypass"
|
||||
}, React.createElement("i", { className: "fa-solid fa-power-off" })),
|
||||
}, [React.createElement("i", { className: "fa-solid fa-power-off" + (isFxActive ? " text-emerald-400" : " text-slate-500"), key: "ico" }), React.createElement("span", { key: "lbl", className: "text-[7px] font-bold" + (isFxActive ? " text-emerald-300" : " text-slate-400") }, "PWR")]),
|
||||
React.createElement("button", { className: "btn-daw h-[18px] rounded text-slate-400 text-[8px]", title: "Trim Envelope" }, "TRIM"),
|
||||
React.createElement("button", { className: "btn-daw h-[18px] rounded text-slate-400 text-[9px]", title: "Session Info" },
|
||||
React.createElement("i", { className: "fa-solid fa-info" })
|
||||
@@ -1067,18 +1036,9 @@ const MasterStripConsole = ({ masterVolume, setMasterVolume, showMasteringModal,
|
||||
React.createElement("span", { ref: rmsValRef, className: "text-emerald-400 font-bold" }, "-inf")
|
||||
),
|
||||
React.createElement("div", {
|
||||
className: "w-full flex items-center justify-between bg-black/80 py-0.5 rounded border border-slate-800 text-[10px] font-extrabold tracking-widest text-slate-100 uppercase px-1"
|
||||
className: "w-full text-center bg-black/80 py-0.5 rounded border border-slate-800 text-[10px] font-extrabold tracking-widest text-slate-100 uppercase"
|
||||
},
|
||||
React.createElement("span", null, "MASTER"),
|
||||
isTestPlaying
|
||||
? React.createElement("button", {
|
||||
onClick: stopTestAudio,
|
||||
className: "text-[8px] bg-red-900 hover:bg-red-800 text-red-300 rounded px-1 py-0.5 transition-colors"
|
||||
}, "STOP TEST")
|
||||
: React.createElement("button", {
|
||||
onClick: startTestAudio,
|
||||
className: "text-[8px] bg-slate-800 hover:bg-slate-700 text-slate-300 rounded px-1 py-0.5 transition-colors"
|
||||
}, "TEST")
|
||||
React.createElement("span", null, "MAIN OUT")
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user