import assert from 'node:assert/strict'; import test from 'node:test'; import { collectEffects } from '../src/lib/parsers'; import { TarFile } from '../src/lib/untar'; function effectsFile(length: number) { const data = new Uint8Array(length); data[4] = 6; return { data, file: new TarFile('fx_settings', data.length, data), view: new DataView(data.buffer), }; } test('preserves selected FX parsing for short files without extended state', () => { const fixture = effectsFile(100); fixture.view.setFloat32(32, 0.25, true); fixture.view.setFloat32(96, 0.75, true); const effects = collectEffects([fixture.file]); assert.equal(effects.effectType, 6); assert.equal(effects.param1, 0.25); assert.equal(effects.param2, 0.75); assert.equal(effects.rawData, fixture.data); assert.equal(effects.outputCompressor, undefined); assert.equal(effects.sidechain, undefined); }); test('parses output compressor state from a 144-byte file without sidechain state', () => { const fixture = effectsFile(144); fixture.view.setFloat32(136, 0.25, true); fixture.view.setFloat32(140, 0.75, true); const effects = collectEffects([fixture.file]); assert.deepEqual(effects.outputCompressor, { drive: 0.25, speed: 0.75 }); assert.equal(effects.sidechain, undefined); }); test('parses sidechain controls from a 152-byte file without inventing routing', () => { const fixture = effectsFile(152); fixture.view.setFloat32(144, 0.25, true); fixture.view.setFloat32(148, 0.75, true); const effects = collectEffects([fixture.file]); assert.deepEqual(effects.sidechain, { length: 0.25, shape: 0.75, routing: undefined }); }); test('parses P07-like output dynamics and sidechain state from a 160-byte file', () => { const fixture = effectsFile(160); fixture.view.setFloat32(32, 0.5, true); fixture.view.setFloat32(96, 0.5, true); fixture.view.setFloat32(136, 0.5, true); fixture.view.setFloat32(140, 0.5, true); fixture.view.setFloat32(144, 0, true); fixture.view.setFloat32(148, 0.5, true); fixture.view.setUint16(152, 0x0600, true); fixture.view.setUint16(154, 0x8000, true); fixture.view.setUint16(156, 0x8000, true); fixture.view.setUint16(158, 0x8000, true); const effects = collectEffects([fixture.file]); assert.deepEqual(effects.outputCompressor, { drive: 0.5, speed: 0.5 }); assert.deepEqual(effects.sidechain, { length: 0, shape: 0.5, routing: { a: { rawValue: 0x0600, sourcePadMask: 0x0600, duckedDestination: false }, b: { rawValue: 0x8000, sourcePadMask: 0, duckedDestination: true }, c: { rawValue: 0x8000, sourcePadMask: 0, duckedDestination: true }, d: { rawValue: 0x8000, sourcePadMask: 0, duckedDestination: true }, }, }); });