55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
|
|
/**
|
||
|
|
* MLP mode manager — switches between unified and dual MLP operation.
|
||
|
|
*
|
||
|
|
* Unified: single MLP, outputs partitioned between timbre and sequence.
|
||
|
|
* Dual: separate MLPs for timbre and sequence, independent training.
|
||
|
|
*/
|
||
|
|
|
||
|
|
export const MLP_MODES = Object.freeze({ UNIFIED: 'unified', DUAL: 'dual' });
|
||
|
|
|
||
|
|
export class MLPModeManager {
|
||
|
|
constructor() {
|
||
|
|
this._mode = MLP_MODES.DUAL; // default to dual (current architecture)
|
||
|
|
this._unifiedSliceStart = 0; // where sequence outputs start in unified mode
|
||
|
|
this._unifiedSliceCount = 16; // how many outputs go to sequence in unified mode
|
||
|
|
}
|
||
|
|
|
||
|
|
get mode() { return this._mode; }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Configure unified mode: which slice of the timbre MLP outputs feeds the sequencer.
|
||
|
|
* @param {number} start - first output index for sequence
|
||
|
|
* @param {number} count - number of outputs for sequence
|
||
|
|
*/
|
||
|
|
setUnifiedConfig(start, count) {
|
||
|
|
this._unifiedSliceStart = start;
|
||
|
|
this._unifiedSliceCount = count;
|
||
|
|
}
|
||
|
|
|
||
|
|
get unifiedSliceStart() { return this._unifiedSliceStart; }
|
||
|
|
get unifiedSliceCount() { return this._unifiedSliceCount; }
|
||
|
|
|
||
|
|
setMode(mode) {
|
||
|
|
if (mode !== MLP_MODES.UNIFIED && mode !== MLP_MODES.DUAL) {
|
||
|
|
throw new TypeError('Invalid MLP mode: ' + mode);
|
||
|
|
}
|
||
|
|
this._mode = mode;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Extract sequence params from a timbre MLP's outputs (unified mode).
|
||
|
|
* @param {Float32Array} timbreOutputs - full output array from the timbre MLP
|
||
|
|
* @returns {Float32Array} slice for the sequence engine
|
||
|
|
*/
|
||
|
|
extractSequenceOutputs(timbreOutputs) {
|
||
|
|
const start = this._unifiedSliceStart;
|
||
|
|
const count = this._unifiedSliceCount;
|
||
|
|
const result = new Float32Array(count);
|
||
|
|
for (let i = 0; i < count; i++) {
|
||
|
|
const idx = start + i;
|
||
|
|
result[i] = idx < timbreOutputs.length ? timbreOutputs[idx] : 0.5;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|