Refactoring round 11: drop what only tests asked of the EQ (#85)
game-maker / gate (push) Successful in 3m48s
game-maker / suite (push) Successful in 14m58s

Refactoring round 11 covers what came since round 10 (25084f8): one
commit, 6873776, the curve in the EQ's node and the spectrum in its
tab (#375, #374). Behaviour is unchanged.

Duplicate code (jscpd 4.3.0 over src, 50 tokens, TypeScript only, as
in round 10, measured on 25084f8 and here alike): 33 clones / 249
lines before and after. The two issues brought none.

Dead code (TS language service, references per export and member):

- eqBandDb was called by tests only. It goes, and the tests ask
  eqBandResponse, which works out the curves the tab and the node
  draw.
- eqPictureShapes and SPECTRUM_SIZE were used only in their own file
  and lose their `export`.
- Kept on purpose: the members of EqCurve are called by the tab class
  in the same file, and the processors' render, process and cut are
  the worklet's own, as in round 10. StageNodes is a type, and types
  stay exported.

Comments and docs: no comment of the two issues tells history or
runs past the line width. README and wiki were brought up to date in
6873776, and every path they name exists.

Tests:

  Bundle                  md5 identical before and after
  Gate (melektaus-atx)    275 files, 4247 tests, CHECK EXIT 0
  Unit, touched areas     2 files, 14 tests

No check was added or changed, the e2e sum stays at 1921.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-09 16:08:53 +02:00
1 parent 687377682c
commit 41af1a6e51
3 files changed
+18 -20

No files matched your search

+2 -7
View File
@@ -189,7 +189,7 @@ function biquadDb(filter: Biquad, frequency: number, rate: number): number {
/**
* What one band does, in dB at any frequency – its filters in a row, only the last with its Q. The
* coefficients are worked out once, so a curve of many points asks this rather than `eqBandDb`.
* coefficients are worked out once, for a curve of many points.
*/
export function eqBandResponse(band: EqBand, rate = EQ_SAMPLE_RATE): (frequency: number) => number {
const stages = eqStagesOf(band);
@@ -203,11 +203,6 @@ export function eqBandResponse(band: EqBand, rate = EQ_SAMPLE_RATE): (frequency:
};
}
/** What one band does at a frequency, in dB. */
export function eqBandDb(band: EqBand, frequency: number, rate = EQ_SAMPLE_RATE): number {
return eqBandResponse(band, rate)(frequency);
}
/**
* What each band does at every one of `frequencies`, in dB, and what the bands that are heard do
* together: the lines the EQ tab draws. Each band's coefficients are worked out once.
@@ -296,7 +291,7 @@ const PICTURE_HEIGHT = 60;
const PICTURE_STEPS = 96;
/** The sum of the bands in the node (#375): the 0 dB line, the area to the curve, and the curve. */
export function eqPictureShapes(bands: readonly EqBand[], area: EqArea): PictureShape[] {
function eqPictureShapes(bands: readonly EqBand[], area: EqArea): PictureShape[] {
const { xs, sum } = eqCurvePoints(bands, area, PICTURE_STEPS);
const zero = dbToY(0, area);
return [
+1 -1
View File
@@ -6,7 +6,7 @@
import type { FxTap } from '../core/soundfx/nodes';
/** Points of one analysis: about 6 Hz apart at 48 kHz, close enough for a bass. */
export const SPECTRUM_SIZE = 8192;
const SPECTRUM_SIZE = 8192;
type Side = FxTap['at'];
const SIDES: readonly Side[] = ['in', 'out'];
+15 -12
View File
@@ -10,7 +10,7 @@ import { fxChainOf, SoundFxParametricEq, tapId } from '../../src/core/soundfx/no
import {
dbToY,
type EqBand,
eqBandDb,
eqBandResponse,
eqBandsOf,
eqCurves,
fillShapes,
@@ -30,6 +30,9 @@ const band = (change: Partial<EqBand>): EqBand => ({
...change,
});
/** What one band does at a frequency, in dB, as the curves are worked out. */
const bandDb = (of: EqBand, frequency: number) => eqBandResponse(of)(frequency);
function eqLine(bands: unknown) {
const f = makeProject();
const command = new CreateAssetCommand('soundfx', 'EQ');
@@ -95,28 +98,28 @@ describe('the bands of a Parametric EQ', () => {
it('draw the curve Web Audio plays', () => {
const peak = band({ gain: 6 });
expect(eqBandDb(peak, 1000)).toBeCloseTo(6, 3);
expect(Math.abs(eqBandDb(peak, 20))).toBeLessThan(0.1);
expect(bandDb(peak, 1000)).toBeCloseTo(6, 3);
expect(Math.abs(bandDb(peak, 20))).toBeLessThan(0.1);
// A cut with no bump is 3 dB down at its frequency and falls 12 dB an octave below it.
const cut = band({ type: 'highpass', frequency: 200, q: Math.SQRT1_2 });
expect(eqBandDb(cut, 200)).toBeCloseTo(-3.01, 1);
expect(eqBandDb(cut, 50) - eqBandDb(cut, 25)).toBeCloseTo(12, 0);
expect(bandDb(cut, 200)).toBeCloseTo(-3.01, 1);
expect(bandDb(cut, 50) - bandDb(cut, 25)).toBeCloseTo(12, 0);
const steeper = { ...cut, slope: 48 as const };
expect(eqBandDb(steeper, 50) - eqBandDb(steeper, 25)).toBeCloseTo(48, 0);
expect(bandDb(steeper, 50) - bandDb(steeper, 25)).toBeCloseTo(48, 0);
const shelf = band({ type: 'lowshelf', frequency: 200, gain: 6 });
expect(eqBandDb(shelf, 20)).toBeCloseTo(6, 1);
expect(eqBandDb(shelf, 200)).toBeCloseTo(3, 1);
expect(eqBandDb(band({ type: 'notch' }), 1000)).toBeLessThan(-60);
expect(bandDb(shelf, 20)).toBeCloseTo(6, 1);
expect(bandDb(shelf, 200)).toBeCloseTo(3, 1);
expect(bandDb(band({ type: 'notch' }), 1000)).toBeLessThan(-60);
// Together they add up in dB; a band that does nothing is drawn but not counted.
const flat = band({ type: 'peaking', frequency: 300, gain: 0 });
const curves = eqCurves([peak, flat, shelf], [300, 3000]);
expect(curves.bands[1]).toHaveLength(2);
expect(curves.bands[2]![0]).toBeCloseTo(eqBandDb(shelf, 300), 6);
expect(curves.sum[0]).toBeCloseTo(eqBandDb(peak, 300) + eqBandDb(shelf, 300), 6);
expect(curves.sum[1]).toBeCloseTo(eqBandDb(peak, 3000) + eqBandDb(shelf, 3000), 6);
expect(curves.bands[2]![0]).toBeCloseTo(bandDb(shelf, 300), 6);
expect(curves.sum[0]).toBeCloseTo(bandDb(peak, 300) + bandDb(shelf, 300), 6);
expect(curves.sum[1]).toBeCloseTo(bandDb(peak, 3000) + bandDb(shelf, 3000), 6);
});
it('fills a curve that crosses 0 dB with one shape for each side, meeting on the line', () => {