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:
marcuspaico
2026-09-08 15:57:51 +10:00
commit ab748bfb9d
18 changed files with 2282 additions and 0 deletions

28
tests/color.test.js Normal file
View File

@@ -0,0 +1,28 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { colorStyle } from '../src/color.js';
test('each spatial axis changes the color at equal loudness', () => {
const base = colorStyle(0, 3.5, 0, 0.5, 'spectrum', 'position');
for (const position of [[3, 3.5, 0], [0, 6, 0], [0, 3.5, 4]]) {
const next = colorStyle(...position, 0.5, 'spectrum', 'position');
assert.notEqual(next.h, base.h);
}
});
test('loudness changes brightness without moving spatial hue', () => {
const quiet = colorStyle(0, 3.5, 0, 0.1, 'spectrum', 'position');
const loud = colorStyle(0, 3.5, 0, 0.9, 'spectrum', 'position');
assert.equal(quiet.h, loud.h);
assert.ok(loud.energy > quiet.energy);
});
test('loudness mapping is independent of spatial position', () => {
assert.deepEqual(colorStyle(-6, 0, -6, 0.4, 'ember', 'amplitude'), colorStyle(6, 7, 6, 0.4, 'ember', 'amplitude'));
});
test('all palette values remain finite and bounded at plot extremes', () => {
for (const palette of ['ember', 'spectrum', 'glacier', 'orchid']) {
for (const x of [-6, 0, 6]) for (const y of [0, 7]) for (const z of [-6, 6]) {
const c = colorStyle(x, y, z, 1, palette, 'position');
for (const key of ['h', 's', 'l']) assert.ok(c[key] >= 0 && c[key] <= 1);
}
}
});