fix(mastering): empty chain by default, allow removing all modules
MASTERING PANEL auto-seeded 3 modules (Dynamic EQ/Imager/Maximizer) and removeChainModule re-added them when the chain hit zero. Chain now starts empty everywhere (init, restore fallback, migration, graph fallback) and can be removed down to empty; activeModule guards empty chain (null). Cache-bust precompiled.js ?v= bump.
This commit is contained in:
+10
-18
@@ -1330,12 +1330,6 @@ const MASTER_MODULE_IO = {
|
||||
rebalance: { input: 'rebalInput', output: 'rebalOutput' }
|
||||
};
|
||||
|
||||
const DEFAULT_MASTER_CHAIN = [
|
||||
{ id: 'mod_eq', type: 'eq', name: 'Dynamic EQ', active: true },
|
||||
{ id: 'mod_imager', type: 'imager', name: 'Imager', active: true },
|
||||
{ id: 'mod_maximizer', type: 'maximizer', name: 'Maximizer', active: true }
|
||||
];
|
||||
|
||||
function chainSignature(chainArray) {
|
||||
return (chainArray || []).map(m => (m.type || '') + (m.active ? '1' : '0')).join(',');
|
||||
}
|
||||
@@ -1950,7 +1944,7 @@ function toggleMasteringOnMaster(activate, isBypassed) {
|
||||
if (!masterBus) return;
|
||||
|
||||
const active = !!(activate && !isBypassed);
|
||||
const chain = (window.currentMasteringSettings && window.currentMasteringSettings.chain) || DEFAULT_MASTER_CHAIN;
|
||||
const chain = (window.currentMasteringSettings && window.currentMasteringSettings.chain) || [];
|
||||
const cSig = chainSignature(chain);
|
||||
// Idempotent: don't rebuild unless active state OR chain layout changed.
|
||||
if (_lastMasteringActive === active && masterBus.masteringActive === active && _lastChainSig === cSig) return;
|
||||
@@ -7179,7 +7173,7 @@ const ProfileModal = ({
|
||||
} else {
|
||||
setMasteringSettings({
|
||||
masterConnected: false,
|
||||
activeModule: 'eq',
|
||||
activeModule: null,
|
||||
eqActive: true,
|
||||
imagerActive: true,
|
||||
maximizerActive: true,
|
||||
@@ -7198,7 +7192,7 @@ const ProfileModal = ({
|
||||
maxTransient: 25,
|
||||
ceiling: -0.1,
|
||||
isBypassed: false,
|
||||
chain: DEFAULT_MASTER_CHAIN.map(m => ({ ...m })),
|
||||
chain: [],
|
||||
compActive: false, compThreshold: -16, compRatio: 3, compMakeup: 0,
|
||||
limActive: false, limThreshold: -1.0,
|
||||
excActive: false, excDrive: 40,
|
||||
@@ -11610,7 +11604,7 @@ const deserializeProjectFromSchema = (schemaObj) => {
|
||||
};
|
||||
// mastering_expand.md: extension modules + dynamic chain (default = old chain order)
|
||||
if (!Array.isArray(migrated.chain)) {
|
||||
migrated.chain = DEFAULT_MASTER_CHAIN.map(m => ({ ...m }));
|
||||
migrated.chain = [];
|
||||
}
|
||||
if (migrated.compActive === undefined) migrated.compActive = false;
|
||||
if (migrated.compThreshold === undefined) migrated.compThreshold = -16;
|
||||
@@ -13638,8 +13632,7 @@ const addMasterVst = (path) => { const fx = (masterFxList || []).find(f => f.pat
|
||||
if (removedMod && removedMod.type === 'vst3' && masterGuiOpen && masterGuiOpen.path === removedMod.path) closeMasterGui();
|
||||
setOzState(prev => {
|
||||
const removed = prev.chain.find(m => m.id === modId);
|
||||
let chain = prev.chain.filter(m => m.id !== modId);
|
||||
if (chain.length === 0) chain = DEFAULT_MASTER_CHAIN.map(m => ({ ...m })); // keep ≥1
|
||||
const chain = prev.chain.filter(m => m.id !== modId);
|
||||
const flags = {};
|
||||
chain.forEach(m => { flags[chainFlag(m.type)] = !!m.active; });
|
||||
const activeModule = prev.activeModule;
|
||||
@@ -13648,7 +13641,7 @@ const addMasterVst = (path) => { const fx = (masterFxList || []).find(f => f.pat
|
||||
const vi = vstFxChain.findIndex(s => s.path === removed.path);
|
||||
if (vi >= 0) vstFxChain = [...vstFxChain.slice(0, vi), ...vstFxChain.slice(vi + 1)];
|
||||
}
|
||||
return { ...prev, chain, ...flags, vstFxChain, activeModule: chain.some(m => m.type === activeModule) ? activeModule : chain[chain.length - 1].type };
|
||||
return { ...prev, chain, ...flags, vstFxChain, activeModule: chain.length ? (chain.some(m => m.type === activeModule) ? activeModule : chain[chain.length - 1].type) : null };
|
||||
});
|
||||
};
|
||||
const reorderChain = (fromIdx, toIdx) => {
|
||||
@@ -18765,8 +18758,7 @@ const App = () => {
|
||||
};
|
||||
const [masteringSettings, setMasteringSettings] = useState({
|
||||
masterConnected: true, // ⚠️ FIX: bật ON mặc định — MIDI item/preview PHẢI được xử lí qua mastering FX ngay khi chạy app (không cần bật/tắt power)
|
||||
activeModule: 'eq',
|
||||
eqActive: true,
|
||||
activeModule: null,
|
||||
imagerActive: true,
|
||||
maximizerActive: true,
|
||||
eqLowGain: 1.5,
|
||||
@@ -18784,7 +18776,7 @@ const App = () => {
|
||||
maxTransient: 25,
|
||||
ceiling: -0.1,
|
||||
isBypassed: false,
|
||||
chain: DEFAULT_MASTER_CHAIN.map(m => ({ ...m })),
|
||||
chain: [],
|
||||
compActive: false, compThreshold: -16, compRatio: 3, compMakeup: 0,
|
||||
limActive: false, limThreshold: -1.0,
|
||||
excActive: false, excDrive: 40,
|
||||
@@ -19192,7 +19184,7 @@ const App = () => {
|
||||
} else {
|
||||
setMasteringSettings({
|
||||
masterConnected: false,
|
||||
activeModule: 'eq',
|
||||
activeModule: null,
|
||||
eqActive: true,
|
||||
imagerActive: true,
|
||||
maximizerActive: true,
|
||||
@@ -19211,7 +19203,7 @@ const App = () => {
|
||||
maxTransient: 25,
|
||||
ceiling: -0.1,
|
||||
isBypassed: false,
|
||||
chain: DEFAULT_MASTER_CHAIN.map(m => ({ ...m })),
|
||||
chain: [],
|
||||
compActive: false, compThreshold: -16, compRatio: 3, compMakeup: 0,
|
||||
limActive: false, limThreshold: -1.0,
|
||||
excActive: false, excDrive: 40,
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
|
||||
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
|
||||
<script src="/static/js/services/chordTheory.js?v=202608211300"></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608220330" defer></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608181030" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||
<style>
|
||||
:root {
|
||||
|
||||
Reference in New Issue
Block a user