FEAT: cài đặt tính năng cho volume main out

This commit is contained in:
2026-07-30 09:34:36 +07:00
parent 66eef405a7
commit e64070a83e
3 changed files with 96 additions and 22 deletions
+18 -16
View File
@@ -53,11 +53,11 @@ function initMasterBus(ctx) {
masterBus.compressor.attack.value = 0.003;
masterBus.compressor.release.value = 0.25;
masterBus.output.gain.value = 1;
// Default routing: input compressor analyser output destination
// MAIN OUT routing per spec: input compressor output (MAIN OUT GAIN) analyser destination
masterBus.input.connect(masterBus.compressor);
masterBus.compressor.connect(masterBus.analyser);
masterBus.analyser.connect(masterBus.output);
masterBus.output.connect(ctx.destination);
masterBus.compressor.connect(masterBus.output);
masterBus.output.connect(masterBus.analyser);
masterBus.analyser.connect(ctx.destination);
return masterBus;
}
@@ -81,8 +81,8 @@ function toggleMasteringOnMaster(activate, nodes) {
nodes.eqMid2Filter.connect(nodes.eqHighFilter);
nodes.eqHighFilter.connect(nodes.maximizerBoostGain);
nodes.maximizerBoostGain.connect(nodes.maximizerCompressor);
nodes.maximizerCompressor.connect(masterBus.analyser);
masterBus.analyser.connect(masterBus.output);
nodes.maximizerCompressor.connect(masterBus.output);
masterBus.output.connect(masterBus.analyser);
masterBus.masteringActive = true;
masterBus.eqNodes = nodes;
} else if (!activate && masterBus.masteringActive) {
@@ -97,10 +97,10 @@ function toggleMasteringOnMaster(activate, nodes) {
try { masterBus.eqNodes.maximizerBoostGain.disconnect(); } catch(e) {}
try { masterBus.eqNodes.maximizerCompressor.disconnect(); } catch(e) {}
}
// Restore default routing
// Restore default routing: input compressor output analyser destination
masterBus.input.connect(masterBus.compressor);
masterBus.compressor.connect(masterBus.analyser);
masterBus.analyser.connect(masterBus.output);
masterBus.compressor.connect(masterBus.output);
masterBus.output.connect(masterBus.analyser);
masterBus.masteringActive = false;
masterBus.eqNodes = null;
}
@@ -18950,18 +18950,18 @@ const App = () => {
})))), /*#__PURE__*/React.createElement("div", {
className: "flex-1 flex overflow-x-auto p-1.5 gap-1.5 items-stretch"
}, /*#__PURE__*/React.createElement("div", {
className: "flex flex-col items-stretch w-16 shrink-0 bg-[#2b2b2b] border border-black/70 overflow-hidden rounded-sm"
className: "flex flex-col items-stretch w-[72px] shrink-0 bg-[#2b2b2b] border border-black/70 overflow-hidden rounded-sm"
}, /*#__PURE__*/React.createElement("div", {
className: "text-[9px] font-bold text-zinc-300 uppercase tracking-wider w-full text-center py-0.5 bg-[#222] border-b border-black/60 shrink-0"
}, "MASTER"), /*#__PURE__*/React.createElement("div", {
className: "flex-1 flex items-stretch justify-center gap-1 px-1 py-1 min-h-0"
}, /*#__PURE__*/React.createElement("div", {
className: "w-5 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60 flex flex-col items-center"
className: "w-6 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60 flex flex-col items-center"
}, /*#__PURE__*/React.createElement("input", {
type: "range",
min: "-60", max: "12", step: "0.5",
value: masterVolume,
onChange: e => { const v = parseFloat(e.target.value); setMasterVolume(v); if (masterBus) setMasterVolume(v); const linear = v <= -50 ? 0 : Math.pow(10, v / 20); if (masterBus) masterBus.output.gain.setValueAtTime(linear, getAudioContext().currentTime); },
onChange: e => { const v = parseFloat(e.target.value); setMasterVolume(v); const linear = v <= -50 ? 0 : Math.pow(10, v / 20); if (masterBus && masterBus.output) masterBus.output.gain.setValueAtTime(linear, getAudioContext().currentTime); },
className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10",
style: { writingMode: 'vertical-lr', direction: 'rtl' }
}), /*#__PURE__*/React.createElement("div", {
@@ -18971,17 +18971,19 @@ const App = () => {
className: "w-full bg-[#0d0d0d] transition-all duration-75",
style: { height: `${(1 - Math.min(1, Math.max(0, (masterVolume + 60) / 72))) * 100}%` }
}))), /*#__PURE__*/React.createElement("div", {
className: "w-2.5 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60"
className: "w-3 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60"
}, /*#__PURE__*/React.createElement("div", {
className: "absolute bottom-0 w-full transition-all duration-75",
style: { height: `${Math.min(100, masterVU * 100)}%`, background: masterVU > 0.85 ? '#ef4444' : masterVU > 0.7 ? '#f59e0b' : '#38bdf8' }
}))), /*#__PURE__*/React.createElement("div", {
className: "flex items-center gap-1 justify-center py-0.5 bg-[#222] border-t border-black/60 shrink-0"
}, /*#__PURE__*/React.createElement("button", {
className: "text-[8px] font-mono font-bold text-center py-0.5 bg-[#222] border-t border-black/60 shrink-0 flex items-center justify-center gap-1"
}, /*#__PURE__*/React.createElement("span", {
className: "text-zinc-400"
}, masterVolume > 0 ? '+' : '', masterVolume.toFixed(1), " dB"), /*#__PURE__*/React.createElement("button", {
onClick: () => setShowMasteringModal(true),
className: "px-1 py-0.5 text-[7px] font-bold uppercase bg-cyan-900 hover:bg-cyan-800 text-cyan-300 rounded transition-colors",
title: "Open Mastering Suite"
}, "Mastering")), /*#__PURE__*/React.createElement("div", {
}, "M")), /*#__PURE__*/React.createElement("div", {
className: "text-[8px] font-mono font-bold text-zinc-500 w-full text-center py-0.5 bg-[#222] border-t border-black/60 shrink-0"
}, "MAIN OUT")), activeTracks.length > 0 && /*#__PURE__*/React.createElement("div", {
className: "w-px bg-zinc-700 shrink-0 self-stretch mx-0.5"