fix(loudness): target sync, effective pre-analysis trim, and queue/settings copy (#333)

* fix(loudness): target sync, -14 pre-analysis ref, queue UI, and reseed

- Front: coalesce loudness refresh by target LUFS; replay-gain IPC dedupe keys
  include norm target and effective pre-attenuation so TGT changes apply.
- Rust: placeholder gain before integrated LUFS uses pivot at -14 LUFS; UI gain
  from effective trim; reseed loudness after delete when waveform cache would skip.
- Pre-analysis: store attenuation relative to -14 LUFS; engine and UI use an
  offset for other targets; migrate legacy absolute values on rehydrate.
- Queue/Settings: Loudness/TGT labels vs value buttons; styles; i18n for help.

* fix(i18n): simplify loudness pre-analysis helper copy

Remove reference-target wording from loudness pre-analysis helper text and keep
only the effective adjustment shown for the current LUFS target in all locales.
This commit is contained in:
cucadmuh
2026-04-27 02:54:58 +03:00
committed by GitHub
parent cf09fd4bd3
commit 87373edb17
18 changed files with 299 additions and 69 deletions
+15
View File
@@ -0,0 +1,15 @@
/**
* Before SQLite has integrated LUFS, match Rust `loudness_gain_placeholder_until_cache`:
* pivot at -14 LUFS, `true_peak = 0` (no EBU headroom cap), then add pre-attenuation from settings.
*/
const PLACEHOLDER_INTEGRATED_LUFS = -14;
export function loudnessGainPlaceholderUntilCacheDb(
targetLufs: number,
preAnalysisAttenuationDb: number,
): number {
const pre = Math.min(0, Math.max(-24, preAnalysisAttenuationDb));
let pivot = targetLufs - PLACEHOLDER_INTEGRATED_LUFS;
pivot = Math.max(-24, Math.min(24, pivot));
return Math.max(-24, Math.min(24, pivot + pre));
}
+21
View File
@@ -0,0 +1,21 @@
/** Pre-analysis level is defined relative to a 14 LUFS target; engine uses an offset for other targets. */
export const LOUDNESS_PRE_ANALYSIS_REF_TARGET_LUFS = -14 as const;
/**
* dB actually applied by the engine (and placeholder math) for the current target.
* Example: ref 4.5 dB at 14, at 12 → 2.5 dB.
*/
export function effectiveLoudnessPreAnalysisAttenuationDb(
storedDbRelativeToRef: number,
targetLufs: number,
): number {
const stepped = Math.round(storedDbRelativeToRef * 2) / 2;
const effective = stepped + (targetLufs - LOUDNESS_PRE_ANALYSIS_REF_TARGET_LUFS);
return Math.max(-24, Math.min(0, effective));
}
/** Stored [24, 0] dB, meaning “at 14 LUFS target”. */
export function clampStoredLoudnessPreAnalysisAttenuationRefDb(v: number): number {
const n = Math.round(v * 2) / 2;
return Math.max(-24, Math.min(0, n));
}