+
Local Separator Mode
+
+ Only Vocal and Instrument (Medium Accuracy) is available while not integrated with K.G.One Music Studio server.
+ Processing in local may take long time depending on your hardware. When fallback to CPU happens, the webpage may
+ temporarily hang with little or no UI response until processing advances.
+
+
+
Provider: {localProviderLabel}
+
Model: {isLocalModelCached ? 'downloaded' : 'not downloaded'}
+
+ {(localProgressText || isCheckingLocalModel) && (
+
+
+
+ {isCheckingLocalModel ? 'Checking local model cache...' : localProgressText}
+
+
+ )}
+
+ {!isLocalModelCached ? (
+ void handleDownloadLocalModel()}
+ >
+ {isDownloadingLocalModel ? 'Downloading Model...' : 'Download Model'}
+
+ ) : (
+ <>
+ void handleDownloadLocalModel()}
+ >
+ {isDownloadingLocalModel ? 'Redownloading...' : 'Redownload Model'}
+
+ void handleDeleteLocalModel()}
+ >
+ {isDeletingLocalModel ? 'Deleting...' : 'Delete Cached Model'}
+
+ >
+ )}
+
+
+ )}
+
{selectedAudioRegion ? (
<>
@@ -1139,14 +1430,44 @@ const SeparatorTab: React.FC = () => {
Separation Model
- setModel(e.target.value as typeof SEPARATOR_MODELS[number]['value'])}>
-
- {SEPARATOR_MODELS.map(m => (
+ setModel(e.target.value as typeof SERVER_SEPARATOR_MODELS[number]['value'])}>
+ {availableSeparatorModels.map(m => (
{m.label}
))}
+ {localOnlyMode && (
+
+
+ Optional audio chunk duration (seconds)
+ setLocalChunkDurationSeconds(e.target.value)}
+ placeholder="Leave blank to process the full region"
+ />
+
+
+ MDX overlap
+ setLocalOverlap(e.target.value)}
+ />
+
+
+ )}
+
{/* Stem audio players — shown once separation is complete */}
{stemAudioUrls.length > 0 && (
@@ -1156,7 +1477,7 @@ const SeparatorTab: React.FC = () => {
@@ -1195,7 +1516,7 @@ const SeparatorTab: React.FC = () => {
{isGenerating && }
@@ -1203,18 +1524,23 @@ const SeparatorTab: React.FC = () => {
{/* Status hint below button */}
- {genHint &&
{genHint}
}
+ {(localOnlyMode ? localProgressText : genHint) && (
+
{localOnlyMode ? localProgressText : genHint}
+ )}
>
) : (
- Select an audio region on the timeline to extract stems from it.
- Only audio regions are supported — MIDI regions cannot be separated.
+ {localOnlyMode && !isLocalModelCached
+ ? 'Download the local separator model, then select an audio region on the timeline to extract stems from it.'
+ : 'Select an audio region on the timeline to extract stems from it. Only audio regions are supported — MIDI regions cannot be separated.'}
)}
-
+ {!localOnlyMode && (
+
+ )}
>
);
};
@@ -2228,8 +2554,21 @@ interface KGOnePanelProps {
}
const KGOnePanel: React.FC
= ({ isVisible }) => {
- const [activeTab, setActiveTab] = useState('fullsong');
+ const mode = getKGOneMode();
+ const [activeTab, setActiveTab] = useState(getDefaultKGOneTab(mode));
const { bpm, keySignature } = useProjectStore();
+ const disabledTabs = mode === 'local-separator'
+ ? new Set(['fullsong', 'remix', 'repaint'])
+ : new Set();
+
+ useEffect(() => {
+ setActiveTab(current => {
+ if (disabledTabs.has(current)) {
+ return 'separator';
+ }
+ return getDefaultKGOneTab(mode) === 'separator' ? 'separator' : current;
+ });
+ }, [mode]);
return (
@@ -2239,16 +2578,17 @@ const KGOnePanel: React.FC
= ({ isVisible }) => {
{/* Clip tab temporarily disabled, will enable in the future */}
- {(['fullsong', 'remix', 'repaint', 'separator'] as const).map(tab => (
+ {KGONE_TABS.map(tab => (
setActiveTab(tab)}
+ className={`kgone-tab${activeTab === tab ? ' active' : ''}${disabledTabs.has(tab) ? ' is-disabled' : ''}`}
+ onClick={() => {
+ if (disabledTabs.has(tab)) return;
+ setActiveTab(tab);
+ }}
+ disabled={disabledTabs.has(tab)}
>
- {tab === 'fullsong' ? 'Full Song'
- : tab === 'remix' ? 'Remix'
- : tab === 'repaint' ? 'Repaint'
- : 'Separator'}
+ {formatKGOneTabLabel(tab)}
))}
@@ -2259,7 +2599,7 @@ const KGOnePanel: React.FC = ({ isVisible }) => {
{activeTab === 'fullsong' && }
{activeTab === 'remix' && }
{activeTab === 'repaint' && }
- {activeTab === 'separator' && }
+ {activeTab === 'separator' && }
);
diff --git a/src/components/Toolbar.tsx b/src/components/Toolbar.tsx
index af37e84..b4279be 100644
--- a/src/components/Toolbar.tsx
+++ b/src/components/Toolbar.tsx
@@ -961,8 +961,6 @@ const Toolbar: React.FC = () => {
};
// K.G.One panel toggle
- const isKGOneEnabled = ConfigManager.instance().get('general.kgone.enabled') as boolean ?? false;
-
const handleKGOneClick = () => {
if (DEBUG_MODE.TOOLBAR) {
console.log("K.G.One button clicked");
@@ -1241,11 +1239,9 @@ const Toolbar: React.FC = () => {