27 lines
1.1 KiB
JavaScript
27 lines
1.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
||
import { buildBandBinMapping, computeBandLevels } from '../www/core/utils.js';
|
||
|
||
const band = [{ center: 1000, fLo: 875, fHi: 1125 }];
|
||
|
||
for (const binCount of [2048, 4096, 8192, 16384]) {
|
||
const nyquist = 24000;
|
||
const binWidth = nyquist / binCount;
|
||
const mapping = buildBandBinMapping(band, nyquist, binCount);
|
||
const totalWeight = mapping[0].bins.reduce((sum, bin) => sum + bin.weight, 0);
|
||
assert.ok(
|
||
Math.abs(totalWeight * binWidth - 250) < 1e-6,
|
||
`bin overlaps must cover the complete band at FFT size ${binCount * 2}`,
|
||
);
|
||
|
||
// Constant power density: every bin contains density × bin width. The
|
||
// integrated band level must therefore be independent of FFT resolution.
|
||
const binPower = binWidth * 1e-6;
|
||
const binsDb = new Float32Array(binCount);
|
||
binsDb.fill(10 * Math.log10(binPower));
|
||
const level = computeBandLevels(mapping, binsDb)[0];
|
||
const expected = 10 * Math.log10(250e-6);
|
||
assert.ok(Math.abs(level - expected) < 1e-5, `FFT size ${binCount * 2}: ${level} vs ${expected}`);
|
||
}
|
||
|
||
console.log('FFT band-energy regression tests passed');
|