Files
controller-v2/client/src/pages/eq/eqFormatters.ts
T

112 lines
3.0 KiB
TypeScript
Raw Normal View History

import { getFilterShortName } from "@/lib/peqAudio";
import {
BAND_FREQ_MAX,
BAND_FREQ_MIN,
BAND_GAIN_MAX,
BAND_GAIN_MIN,
BAND_Q_MAX,
BAND_Q_MIN,
} from "./eqConstants";
import type { BandParamKind } from "./types";
export function eqInterp(template: string | undefined, vars: Record<string, string | number>): string {
if (!template) return "";
let s = template;
for (const [k, v] of Object.entries(vars)) {
s = s.split(`{{${k}}}`).join(String(v));
}
return s;
}
export function formatBandFreqDisplay(freq: number) {
return freq >= 1000
? `${(freq / 1000).toFixed(2).replace(/\.?0+$/, "")} kHz`
: `${freq} Hz`;
}
export function formatBandParamForInput(
kind: BandParamKind,
band: { freq: number; gain: number; q: number },
) {
switch (kind) {
case "freq":
return String(band.freq);
case "gain":
return band.gain.toFixed(1);
case "q":
return band.q.toFixed(2);
}
}
export function parseBandParamInput(
kind: BandParamKind,
raw: string,
messages: { invalid: string; outOfRange: string },
): { ok: true; value: number } | { ok: false; message: string } {
const trimmed = raw.trim();
if (!trimmed) return { ok: false, message: messages.invalid };
if (kind === "freq") {
let s = trimmed.replace(/\s+/g, "").toLowerCase().replace(/hz$/, "");
const kHz = /k(hz)?$/.test(s);
if (kHz) s = s.replace(/k(hz)?$/, "");
const num = Number.parseFloat(s);
if (!Number.isFinite(num)) return { ok: false, message: messages.invalid };
const hz = Math.round(kHz ? num * 1000 : num);
if (hz < BAND_FREQ_MIN || hz > BAND_FREQ_MAX) {
return { ok: false, message: messages.outOfRange };
}
return { ok: true, value: hz };
}
if (kind === "gain") {
const s = trimmed.replace(/\s*dB\s*$/i, "").trim();
const num = Number.parseFloat(s);
if (!Number.isFinite(num)) return { ok: false, message: messages.invalid };
const gain = Number(num.toFixed(1));
if (gain < BAND_GAIN_MIN || gain > BAND_GAIN_MAX) {
return { ok: false, message: messages.outOfRange };
}
return { ok: true, value: gain };
}
const num = Number.parseFloat(trimmed);
if (!Number.isFinite(num)) return { ok: false, message: messages.invalid };
const q = Number(num.toFixed(2));
if (q < BAND_Q_MIN || q > BAND_Q_MAX) {
return { ok: false, message: messages.outOfRange };
}
return { ok: true, value: q };
}
export function normalizeFilterType(type: string | number | undefined): string {
if (type === undefined || type === null) return "PEAK";
if (typeof type === "number") {
switch (type) {
case 0:
return "LPF";
case 1:
return "HPF";
case 2:
return "BPF";
case 3:
return "NOTCH";
case 4:
return "PEAK";
case 5:
return "LSHELF";
case 6:
return "HSHELF";
case 7:
return "APF";
default:
return "PEAK";
}
}
return getFilterShortName(type);
}
export function freqLabel(f: number) {
return f >= 1000 ? `${(f / 1000).toFixed(1)}K` : `${f}`;
}