Sonora: local 3D audio visualizer (initial import)
Three.js + Web Audio FFT visualizer with Constellation, Texture, Frequency and Modulation views. Vite build, node --test suite. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JABXBRLs9T6nqHKUVwoTHJ
This commit is contained in:
30
tests/analysis.test.js
Normal file
30
tests/analysis.test.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { analyzeSpectrum } from '../src/analysis.js';
|
||||
|
||||
test('silence produces finite zero features and no peaks', () => {
|
||||
const f = analyzeSpectrum(new Float32Array(32).fill(-Infinity), new Float32Array(64), 48000);
|
||||
for (const key of ['rms', 'centroid', 'spread', 'entropy', 'flatness']) assert.equal(f[key], 0);
|
||||
assert.deepEqual(f.peaks, []);
|
||||
});
|
||||
test('a single spectral tone has its exact frequency and zero spread and entropy', () => {
|
||||
const db = new Float32Array(32).fill(-Infinity); db[4] = -6;
|
||||
const f = analyzeSpectrum(db, new Float32Array([0.5, -0.5]), 48000);
|
||||
assert.equal(f.centroid, 3000); assert.equal(f.spread, 0); assert.equal(f.entropy, 0);
|
||||
assert.equal(f.rms, 0.5); assert.equal(f.peaks[0].frequency, 3000);
|
||||
});
|
||||
test('uniform spectral power has maximum normalized entropy and flatness', () => {
|
||||
const f = analyzeSpectrum(new Float32Array(32).fill(-20), new Float32Array(64), 48000);
|
||||
assert.ok(Math.abs(f.entropy - 1) < 1e-10);
|
||||
assert.ok(Math.abs(f.flatness - 1) < 1e-10);
|
||||
assert.ok(Math.abs(f.centroid - 11625) < 1e-8);
|
||||
});
|
||||
test('centroid weights spectral power, not decibel values', () => {
|
||||
const db = new Float32Array(4).fill(-Infinity); db[1] = 0; db[3] = -10;
|
||||
const f = analyzeSpectrum(db, new Float32Array(8), 8000);
|
||||
assert.ok(Math.abs(f.centroid - 1300 / 1.1) < 1e-7);
|
||||
});
|
||||
test('nonfinite inputs cannot contaminate 3D coordinates', () => {
|
||||
const f = analyzeSpectrum(new Float32Array([NaN, Infinity, -Infinity, -30]), new Float32Array([NaN, 0]), 48000);
|
||||
for (const key of ['rms', 'centroid', 'spread', 'entropy', 'flatness']) assert.ok(Number.isFinite(f[key]));
|
||||
});
|
||||
Reference in New Issue
Block a user