refactor: move all localSeparator*.ts into a subfolder

This commit is contained in:
Xiaohan-Tian
2026-05-27 17:32:13 -07:00
parent 7340f7f8f6
commit e2a7d1c285
14 changed files with 52 additions and 52 deletions
@@ -1,4 +1,4 @@
import type { LocalSeparatorModelConfig } from './localSeparatorTypes';
import type { LocalSeparatorModelConfig } from './types';
export const LOCAL_SEPARATOR_DEFAULT_MODEL_URL =
'https://huggingface.co/notabilia/uvr5-models/resolve/main/UVR-MDX-NET-Inst_HQ_3.onnx';
@@ -1,5 +1,5 @@
import type { LocalSeparatorModelConfig, StereoChannels } from './localSeparatorTypes';
import { FFT, createWindowCache, getHannPeriodic, index4d, reflectPad } from './localSeparatorShared';
import type { LocalSeparatorModelConfig, StereoChannels } from './types';
import { FFT, createWindowCache, getHannPeriodic, index4d, reflectPad } from './shared';
interface SpectrogramPayload {
data: Float32Array;
@@ -1,8 +1,8 @@
import type { LocalSeparatorModelConfig } from './localSeparatorTypes';
import { LocalSeparatorCpuDsp } from './localSeparatorCpuDsp';
import { reflectPad } from './localSeparatorShared';
import type { LocalSeparatorModelConfig } from './types';
import { LocalSeparatorCpuDsp } from './cpuDsp';
import { reflectPad } from './shared';
function localSeparatorLog(message: string, payload?: unknown): void {
function log(message: string, payload?: unknown): void {
if (payload === undefined) {
console.log(`[localSeparator] ${message}`);
return;
@@ -145,22 +145,22 @@ export class LocalSeparatorGpuDsp {
throw new Error('WebGPU is not available for GPU DSP.');
}
localSeparatorLog('Requesting WebGPU adapter for GPU DSP.');
log('Requesting WebGPU adapter for GPU DSP.');
const adapter = await (navigator as NavigatorWithGpu).gpu?.requestAdapter({
powerPreference: 'high-performance',
});
if (!adapter) {
throw new Error('No WebGPU adapter was available for GPU DSP.');
}
localSeparatorLog('WebGPU adapter acquired for GPU DSP.', {
log('WebGPU adapter acquired for GPU DSP.', {
features: typeof adapter.features?.values === 'function' ? Array.from(adapter.features.values()) : undefined,
limits: adapter.limits,
info: typeof adapter.info === 'object' ? adapter.info : undefined,
});
localSeparatorLog('Requesting WebGPU device for GPU DSP.');
log('Requesting WebGPU device for GPU DSP.');
const device = await adapter.requestDevice();
localSeparatorLog('WebGPU device acquired for GPU DSP.');
log('WebGPU device acquired for GPU DSP.');
return new LocalSeparatorGpuDsp(config, device);
}
@@ -170,7 +170,7 @@ export class LocalSeparatorGpuDsp {
this.nFft = config.metadata.mdx_n_fft_scale_set;
this.hopLength = config.defaults.hopLength;
this.trim = Math.floor(this.nFft / 2);
localSeparatorLog('Creating GPU DSP compute pipeline.');
log('Creating GPU DSP compute pipeline.');
this.pipeline = device.createComputePipeline({
layout: 'auto',
compute: {
@@ -178,7 +178,7 @@ export class LocalSeparatorGpuDsp {
entryPoint: 'main',
},
});
localSeparatorLog('GPU DSP compute pipeline created.');
log('GPU DSP compute pipeline created.');
}
public async forwardStereo(leftChunk: Float32Array, rightChunk: Float32Array): Promise<{
@@ -1,8 +1,8 @@
import {
LOCAL_SEPARATOR_MODEL_EXPECTED_SIZE_BYTES,
LOCAL_SEPARATOR_MODEL_FILENAME,
} from './localSeparatorConfig';
import { OpfsModelCache, type ModelDownloadProgress } from './opfsModelCache';
} from './config';
import { OpfsModelCache, type ModelDownloadProgress } from '../opfsModelCache';
const cache = new OpfsModelCache({ directoryName: 'models' });
@@ -1,13 +1,13 @@
import * as ort from 'onnxruntime-web/webgpu';
import { LocalSeparatorCpuDsp } from './localSeparatorCpuDsp';
import { LocalSeparatorGpuDsp } from './localSeparatorGpuDsp';
import { LocalSeparatorTimingCollector } from './localSeparatorTiming';
import { LocalSeparatorCpuDsp } from './cpuDsp';
import { LocalSeparatorGpuDsp } from './gpuDsp';
import { LocalSeparatorTimingCollector } from './timing';
import type {
LocalRuntimeProvider,
LocalSeparatorModelConfig,
LocalSeparatorProgress,
StereoChannels,
} from './localSeparatorTypes';
} from './types';
import {
concatFloat32,
createWindowCache,
@@ -16,11 +16,11 @@ import {
normalizeChannels,
scaleChannels,
sliceChannels,
} from './localSeparatorShared';
} from './shared';
const SAMPLE_RATE = 44100;
function localSeparatorLog(message: string, payload?: unknown): void {
function log(message: string, payload?: unknown): void {
if (payload === undefined) {
console.log(`[localSeparator] ${message}`);
return;
@@ -108,11 +108,11 @@ class BrowserMdxSeparator {
try {
dsp = await timing.measureAsync('dspInit', () => LocalSeparatorGpuDsp.create(config));
dspMode = 'gpu-hybrid';
localSeparatorLog('GPU DSP initialized successfully.');
log('GPU DSP initialized successfully.');
} catch (error) {
console.warn('[localSeparator] GPU DSP initialization failed, using CPU DSP.', error);
options.onProviderChange?.('webgpu + cpu dsp fallback');
localSeparatorLog(
log(
'GPU DSP initialization failed. Inference session may still use WebGPU, but DSP will fall back to CPU.',
error,
);
@@ -122,9 +122,9 @@ class BrowserMdxSeparator {
if (!dsp) {
dsp = new LocalSeparatorCpuDsp(config);
if (runtimeProvider === 'webgpu') {
localSeparatorLog('Using CPU DSP while keeping the WebGPU inference provider.');
log('Using CPU DSP while keeping the WebGPU inference provider.');
} else {
localSeparatorLog('Using CPU DSP because the active inference provider is CPU/wasm.');
log('Using CPU DSP because the active inference provider is CPU/wasm.');
}
}
@@ -376,7 +376,7 @@ class BrowserMdxSeparator {
} catch (error) {
if (payloads.length > 1 && this.runtimeBatchSize > 1) {
console.warn('[localSeparator] Batched inference failed, falling back to batch size 1.', error);
localSeparatorLog('Batched inference failed. Falling back to batch size 1.', error);
log('Batched inference failed. Falling back to batch size 1.', error);
this.runtimeBatchSize = 1;
const singleResults: SpectrogramPayload[] = [];
for (const payload of payloads) {
@@ -486,7 +486,7 @@ export async function runLocalSeparator(options: {
}> {
const timing = new LocalSeparatorTimingCollector('local-separation');
const decoded = await timing.measureAsync('decode', () => decodeAudioToStereo(options.audioBuffer));
localSeparatorLog(`Running browser MDX separation on ${options.runtimeProvider === 'webgpu' ? 'GPU/WebGPU' : 'CPU/wasm'}...`);
log(`Running browser MDX separation on ${options.runtimeProvider === 'webgpu' ? 'GPU/WebGPU' : 'CPU/wasm'}...`);
const separator = await BrowserMdxSeparator.create(
options.session,
@@ -522,7 +522,7 @@ export async function runLocalSeparator(options: {
debugSummary: separator.getDebugSummary({ model: options.modelConfig.filename }),
};
} finally {
localSeparatorLog('Separation timing summary', separator.getDebugSummary({ model: options.modelConfig.filename }));
log('Separation timing summary', separator.getDebugSummary({ model: options.modelConfig.filename }));
separator.dispose();
}
}
@@ -1,8 +1,8 @@
import * as ort from 'onnxruntime-web/webgpu';
import ortWasmAsyncifyUrl from 'onnxruntime-web/ort-wasm-simd-threaded.asyncify.wasm?url';
import type { LocalRuntimeState, LocalRuntimeSupport, LocalSeparatorModelConfig } from './localSeparatorTypes';
import type { LocalRuntimeState, LocalRuntimeSupport, LocalSeparatorModelConfig } from './types';
function localSeparatorLog(message: string, payload?: unknown): void {
function log(message: string, payload?: unknown): void {
if (payload === undefined) {
console.log(`[localSeparator] ${message}`);
return;
@@ -15,9 +15,9 @@ export function detectLocalRuntimeSupport(): LocalRuntimeSupport {
webgpuExposed: typeof navigator !== 'undefined' && 'gpu' in navigator,
};
if (support.webgpuExposed) {
localSeparatorLog('WebGPU API is exposed by this browser.');
log('WebGPU API is exposed by this browser.');
} else {
localSeparatorLog('WebGPU API is not exposed by this browser. CPU/wasm will be used.');
log('WebGPU API is not exposed by this browser. CPU/wasm will be used.');
}
return support;
}
@@ -46,16 +46,16 @@ export class LocalOrtRuntimeManager {
ort.env.wasm.wasmPaths = {
wasm: ortWasmAsyncifyUrl,
};
localSeparatorLog('Configured ONNX Runtime wasm paths.', ort.env.wasm.wasmPaths);
log('Configured ONNX Runtime wasm paths.', ort.env.wasm.wasmPaths);
LocalOrtRuntimeManager.wasmPathsConfigured = true;
}
const providersToTry: Array<'webgpu' | 'wasm'> = [];
if (typeof navigator !== 'undefined' && 'gpu' in navigator) {
providersToTry.push('webgpu');
localSeparatorLog('navigator.gpu is available, trying WebGPU first.');
log('navigator.gpu is available, trying WebGPU first.');
} else {
localSeparatorLog('navigator.gpu is not available. Falling back to CPU/wasm.');
log('navigator.gpu is not available. Falling back to CPU/wasm.');
}
providersToTry.push('wasm');
@@ -64,7 +64,7 @@ export class LocalOrtRuntimeManager {
try {
if (provider === 'webgpu' && ort.env?.webgpu) {
ort.env.webgpu.powerPreference = 'high-performance';
localSeparatorLog('Using WebGPU power preference high-performance.');
log('Using WebGPU power preference high-performance.');
}
const session = await ort.InferenceSession.create(modelData, {
@@ -75,15 +75,15 @@ export class LocalOrtRuntimeManager {
this.runtime = { provider, session };
this.currentModel = modelConfig.filename;
this.onProviderChange(provider === 'wasm' ? 'cpu/wasm' : provider);
localSeparatorLog(`Using provider: ${provider}`);
log(`Using provider: ${provider}`);
return this.runtime;
} catch (error) {
lastError = error;
if (provider === 'webgpu') {
localSeparatorLog('WebGPU session creation failed. Falling back to CPU/wasm.', error);
log('WebGPU session creation failed. Falling back to CPU/wasm.', error);
this.onProviderChange('cpu/wasm fallback');
} else {
localSeparatorLog(`Provider failed: ${provider}`, error);
log(`Provider failed: ${provider}`, error);
}
}
}
@@ -1,4 +1,4 @@
import type { StereoChannels } from './localSeparatorTypes';
import type { StereoChannels } from './types';
export function index4d(dims: number[], i0: number, i1: number, i2: number, i3: number): number {
return (((i0 * dims[1] + i1) * dims[2] + i2) * dims[3]) + i3;