Correct audio metering and realtime displays
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// Nutzt die bestehenden VU-Werte (inkl. Offsets/Kalibrierung) und zeichnet
|
||||
// zwei kompakte, horizontale Nadelinstrumente (L/R) mit Slot-Auswahl.
|
||||
import { drawCachedStaticLayer } from './static_layer.js';
|
||||
import { TRUE_PEAK_MINOR_TICKS, TRUE_PEAK_SCALE } from '../meters/true_peak_scale.js';
|
||||
|
||||
export const id = 'classic-needles';
|
||||
|
||||
@@ -47,22 +48,6 @@ const DIN_SCALE = [
|
||||
{ db: +5, pos: 1.0000 },
|
||||
];
|
||||
|
||||
const TP_PERCENT_SCALE = [
|
||||
{ db: -60, frac: 0.0000 },
|
||||
{ db: -50, frac: 0.0373 },
|
||||
{ db: -40, frac: 0.1429 },
|
||||
{ db: -35, frac: 0.2112 },
|
||||
{ db: -30, frac: 0.2857 },
|
||||
{ db: -25, frac: 0.3851 },
|
||||
{ db: -20, frac: 0.4783 },
|
||||
{ db: -15, frac: 0.6087 },
|
||||
{ db: -10, frac: 0.7391 },
|
||||
{ db: -5, frac: 0.8696 },
|
||||
{ db: 0, frac: 1.0000 },
|
||||
];
|
||||
|
||||
const TP_EXTRA_MINOR_TICKS = [-47, -19, -18, -17, -16, -14, -13, -12, -11, -9, -8, -7, -6, -4, -3, -2, -1];
|
||||
|
||||
const PPM_EBU_MAJOR_TICKS = [-12, -8, -4, 0, +4, +8, +12];
|
||||
const PPM_EBU_MINOR_TICKS = [-10, -6, -2, +2, +6, +9, +10];
|
||||
|
||||
@@ -122,7 +107,19 @@ export async function render(env, state) {
|
||||
const raw = readMeterDisplayLR(meterId, meterState, CONFIG, scale, audio);
|
||||
const targets = { L: scale.valueToNorm(raw.L), R: scale.valueToNorm(raw.R) };
|
||||
const now = (typeof performance !== 'undefined' ? performance.now() : Date.now());
|
||||
smoothNeedle(state, targets, now);
|
||||
if (meterId === 'rms') {
|
||||
// RMS ballistics are already measured sample-continuously in the backend.
|
||||
// A second spring model here would add view-dependent delay and values.
|
||||
state.smooth.L = targets.L;
|
||||
state.smooth.R = targets.R;
|
||||
state.goal.L = targets.L;
|
||||
state.goal.R = targets.R;
|
||||
state.vel.L = 0;
|
||||
state.vel.R = 0;
|
||||
state.lastTs = now;
|
||||
} else {
|
||||
smoothNeedle(state, targets, now);
|
||||
}
|
||||
// Box-Abmessungen an den Real-Time-Analyzer anlehnen (gleiche Offsets)
|
||||
const BOX_LEFT = 0;
|
||||
const BOX_TOP = Number.isFinite(env?.topInset) ? Number(env.topInset) : 70;
|
||||
@@ -425,24 +422,24 @@ function getNeedleScaleDescriptor(meterId, CONFIG) {
|
||||
|
||||
if (meterId === 'tp') {
|
||||
const bottom = -60;
|
||||
const top = 0;
|
||||
const top = 6;
|
||||
const redStart = Number.isFinite(CONFIG?.TP_RED_START) ? CONFIG.TP_RED_START : -1;
|
||||
const warnColor = CONFIG?.TP_COLOR_WARN || '#ff3b3b';
|
||||
const normalColor = CONFIG?.TP_COLOR_NORMAL || '#ffe066';
|
||||
const mapRaw = (db) => {
|
||||
const clamped = clamp(db, bottom, top);
|
||||
if (clamped <= TP_PERCENT_SCALE[0].db) return TP_PERCENT_SCALE[0].frac;
|
||||
if (clamped >= TP_PERCENT_SCALE[TP_PERCENT_SCALE.length - 1].db) return TP_PERCENT_SCALE[TP_PERCENT_SCALE.length - 1].frac;
|
||||
for (let i = 1; i < TP_PERCENT_SCALE.length; i++) {
|
||||
const prev = TP_PERCENT_SCALE[i - 1];
|
||||
const curr = TP_PERCENT_SCALE[i];
|
||||
if (clamped <= TRUE_PEAK_SCALE[0].db) return TRUE_PEAK_SCALE[0].frac;
|
||||
if (clamped >= TRUE_PEAK_SCALE[TRUE_PEAK_SCALE.length - 1].db) return TRUE_PEAK_SCALE[TRUE_PEAK_SCALE.length - 1].frac;
|
||||
for (let i = 1; i < TRUE_PEAK_SCALE.length; i++) {
|
||||
const prev = TRUE_PEAK_SCALE[i - 1];
|
||||
const curr = TRUE_PEAK_SCALE[i];
|
||||
if (clamped <= curr.db) {
|
||||
const span = curr.db - prev.db || 1;
|
||||
const t = (clamped - prev.db) / span;
|
||||
return prev.frac + t * (curr.frac - prev.frac);
|
||||
}
|
||||
}
|
||||
return TP_PERCENT_SCALE[TP_PERCENT_SCALE.length - 1].frac;
|
||||
return TRUE_PEAK_SCALE[TRUE_PEAK_SCALE.length - 1].frac;
|
||||
};
|
||||
const valueToNorm = (v) => clamp01(mapRaw(v));
|
||||
return {
|
||||
@@ -454,11 +451,10 @@ function getNeedleScaleDescriptor(meterId, CONFIG) {
|
||||
warnColor,
|
||||
normalColor,
|
||||
unitLabel: 'dBTP',
|
||||
majorTicks: TP_PERCENT_SCALE.map((p) => p.db),
|
||||
minorTicks: TP_EXTRA_MINOR_TICKS,
|
||||
majorTicks: TRUE_PEAK_SCALE.map((p) => p.db),
|
||||
minorTicks: TRUE_PEAK_MINOR_TICKS,
|
||||
formatMajor: (db) => {
|
||||
const v = Math.abs(db);
|
||||
return Number.isInteger(v) ? String(v) : v.toFixed(1);
|
||||
return db > 0 ? `+${db}` : String(db);
|
||||
},
|
||||
valueToNorm,
|
||||
};
|
||||
@@ -633,7 +629,7 @@ function readMeterDisplayLR(meterId, shared, CONFIG, scale, audio) {
|
||||
const isDBU = (mode === 'dbu');
|
||||
if (isDBU) {
|
||||
const refDbfs = Number.isFinite(CONFIG?.RMS_REF_DBFS_FOR_REF_DBU) ? CONFIG.RMS_REF_DBFS_FOR_REF_DBU : -18;
|
||||
const refDbu = Number.isFinite(CONFIG?.RMS_REF_DBU) ? CONFIG.RMS_REF_DBU : +4;
|
||||
const refDbu = Number.isFinite(CONFIG?.RMS_REF_DBU) ? CONFIG.RMS_REF_DBU : 0;
|
||||
rawL = (rawL - refDbfs) + refDbu;
|
||||
rawR = (rawR - refDbfs) + refDbu;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user