jevstrudel.git / website / src / jev / meter.test.mjs
1import { describe, expect, it } from 'vitest';
2import { partName, summarize, summarizeParts } from './meter.mjs';
3
4describe('meter', () => {
5  it('names parts by orbit; numbered orbits are other', () => {
6    expect(partName('riff')).toBe('riff');
7    expect(partName(1)).toBe('other');
8    expect(partName('2')).toBe('other');
9  });
10
11  it('summarizes loudness, peak and silence', () => {
12    const m = summarize([
13      { rms: 0.1, peak: 0.5 },
14      { rms: 0.1, peak: 0.25 },
15      { rms: 0, peak: 0 },
16      { rms: 0.1, peak: 0.1 },
17    ]);
18    expect(m.loudnessDbfs).toBeCloseTo(-21.2, 1);
19    expect(m.peakDbfs).toBeCloseTo(-6, 0);
20    expect(m.silentShare).toBe(0.25);
21  });
22
23  it('weighs each reading by the samples it covered', () => {
24    const m = summarize([
25      { rms: 0.2, peak: 0.2, n: 3000 },
26      { rms: 0, peak: 0, n: 1000 },
27    ]);
28    expect(m.loudnessDbfs).toBeCloseTo(20 * Math.log10(Math.sqrt(0.04 * 0.75)), 1);
29    expect(m.silentShare).toBe(0.25);
30  });
31
32  it('counts a part as silent before its orbit existed', () => {
33    const parts = summarizeParts([
34      { rms: 0.1, peak: 0.1, parts: {} },
35      { rms: 0.1, peak: 0.1, parts: { riff: { rms: 0.1, peak: 0.2 } } },
36    ]);
37    expect(parts.riff.silentShare).toBe(0.5);
38  });
39});