Keep RTW profile for all octave resolutions

This commit is contained in:
Mikei386
2026-07-21 20:17:02 +02:00
parent e318647d3b
commit 0347a5f946
6 changed files with 14 additions and 29 deletions
+6 -5
View File
@@ -8,7 +8,9 @@ assert.ok(functionSource, 'buildRtaRuntimeConfig must remain testable');
const context = vm.createContext({ const context = vm.createContext({
Number, Number,
getRtwCenters(mode) { getRtwCenters(mode) {
return mode === '1_3' ? new Array(31).fill(0) : []; if (mode === '1_12') return new Array(121).fill(0);
if (mode === '1_6') return new Array(61).fill(0);
return new Array(31).fill(0);
}, },
}); });
vm.runInContext(functionSource.replace('export function', 'function'), context); vm.runInContext(functionSource.replace('export function', 'function'), context);
@@ -24,10 +26,10 @@ const forced = context.buildRtaRuntimeConfig({
XY_POINTS: 256, XY_POINTS: 256,
}); });
assert.equal(forced.engine, 'iir'); assert.equal(forced.engine, 'iir');
assert.equal(forced.bpo, '1_3'); assert.equal(forced.bpo, '1_12');
assert.equal(forced.freqRange, 'norm'); assert.equal(forced.freqRange, 'norm');
assert.equal(forced.order, 6); assert.equal(forced.order, 6);
assert.equal(forced.rtwCenters.length, 31); assert.equal(forced.rtwCenters.length, 121);
assert.equal(forced.correlationResponseS, 2.5); assert.equal(forced.correlationResponseS, 2.5);
assert.equal(forced.correlationResetToken, 7); assert.equal(forced.correlationResetToken, 7);
assert.equal(forced.xyPoints, 256); assert.equal(forced.xyPoints, 256);
@@ -54,8 +56,7 @@ const selectionContext = vm.createContext({
vm.runInContext(selectionSource, selectionContext); vm.runInContext(selectionSource, selectionContext);
assert.equal(selectionContext.applyRtaBpoSelection('1_6'), '1_6'); assert.equal(selectionContext.applyRtaBpoSelection('1_6'), '1_6');
assert.equal(selectionContext.CONFIG.RTA_BPO_MODE, '1_6'); assert.equal(selectionContext.CONFIG.RTA_BPO_MODE, '1_6');
assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'iec'); assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'rtw');
selectionContext.CONFIG.RTA_BAR_LAYOUT = 'rtw';
assert.equal(selectionContext.applyRtaBpoSelection('1_3'), '1_3'); assert.equal(selectionContext.applyRtaBpoSelection('1_3'), '1_3');
assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'rtw'); assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'rtw');
+4 -8
View File
@@ -368,7 +368,6 @@ fn normalize_rta_config(mut config: PhoenixRtaConfig) -> PhoenixRtaConfig {
} }
if config.layout == "rtw" { if config.layout == "rtw" {
config.engine = "iir".to_string(); config.engine = "iir".to_string();
config.bpo = "1_3".to_string();
config.order = 6; config.order = 6;
config.freq_range = "norm".to_string(); config.freq_range = "norm".to_string();
} }
@@ -663,9 +662,6 @@ fn apply_global_to_rta(
) -> PhoenixRtaConfig { ) -> PhoenixRtaConfig {
config.fft_size = global.fft_size; config.fft_size = global.fft_size;
config.bpo = global.rta_bpo_mode.clone(); config.bpo = global.rta_bpo_mode.clone();
if config.bpo != "1_3" && config.layout == "rtw" {
config.layout = "iec".to_string();
}
config.input_offset_db_l = global.input_offset_db_l; config.input_offset_db_l = global.input_offset_db_l;
config.input_offset_db_r = global.input_offset_db_r; config.input_offset_db_r = global.input_offset_db_r;
config.mono_input = global.mono_input; config.mono_input = global.mono_input;
@@ -715,7 +711,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn rtw_profile_is_always_iir_third_octave() { fn rtw_profile_is_iir_and_retains_selected_resolution() {
let config = normalize_rta_config(PhoenixRtaConfig { let config = normalize_rta_config(PhoenixRtaConfig {
engine: "fft".to_string(), engine: "fft".to_string(),
bpo: "1_12".to_string(), bpo: "1_12".to_string(),
@@ -725,7 +721,7 @@ mod tests {
..PhoenixRtaConfig::default() ..PhoenixRtaConfig::default()
}); });
assert_eq!(config.engine, "iir"); assert_eq!(config.engine, "iir");
assert_eq!(config.bpo, "1_3"); assert_eq!(config.bpo, "1_12");
assert_eq!(config.order, 6); assert_eq!(config.order, 6);
assert_eq!(config.freq_range, "norm"); assert_eq!(config.freq_range, "norm");
} }
@@ -749,11 +745,11 @@ mod tests {
} }
#[test] #[test]
fn non_third_octave_global_selection_leaves_locked_rtw_profile() { fn non_third_octave_global_selection_retains_rtw_profile() {
let mut global = PhoenixGlobalConfig::default(); let mut global = PhoenixGlobalConfig::default();
global.rta_bpo_mode = "1_12".to_string(); global.rta_bpo_mode = "1_12".to_string();
let config = apply_global_to_rta(PhoenixRtaConfig::default(), &global); let config = apply_global_to_rta(PhoenixRtaConfig::default(), &global);
assert_eq!(config.layout, "iec"); assert_eq!(config.layout, "rtw");
assert_eq!(config.bpo, "1_12"); assert_eq!(config.bpo, "1_12");
assert_eq!(config.engine, "iir"); assert_eq!(config.engine, "iir");
} }
+1 -1
View File
@@ -868,7 +868,7 @@ export function buildRtaRuntimeConfig(CONFIG = {}) {
const bpoMode = CONFIG.RTA_BPO_MODE || '1_3'; const bpoMode = CONFIG.RTA_BPO_MODE || '1_3';
const layout = CONFIG.RTA_BAR_LAYOUT === 'rtw' ? 'rtw' : 'iec'; const layout = CONFIG.RTA_BAR_LAYOUT === 'rtw' ? 'rtw' : 'iec';
const rtwProfile = layout === 'rtw'; const rtwProfile = layout === 'rtw';
const runtimeBpoMode = rtwProfile ? '1_3' : bpoMode; const runtimeBpoMode = bpoMode;
return { return {
engine: rtwProfile ? 'iir' : (CONFIG.RTA_ENGINE || 'iir'), engine: rtwProfile ? 'iir' : (CONFIG.RTA_ENGINE || 'iir'),
fftSize: CONFIG.FFT_SIZE || 4096, fftSize: CONFIG.FFT_SIZE || 4096,
-10
View File
@@ -285,11 +285,6 @@ const CONFIG_DEFAULTS = JSON.parse(JSON.stringify(CONFIG));
function applyRtaBpoSelection(value) { function applyRtaBpoSelection(value) {
const mode = ['1_3', '1_6', '1_12'].includes(String(value)) ? String(value) : '1_3'; const mode = ['1_3', '1_6', '1_12'].includes(String(value)) ? String(value) : '1_3';
CONFIG.RTA_BPO_MODE = mode; CONFIG.RTA_BPO_MODE = mode;
// RTW remains the original 31-band third-octave reference profile. Finer
// resolutions are Phoenix extensions and switch visibly to the IEC profile.
if (mode !== '1_3' && CONFIG.RTA_BAR_LAYOUT === 'rtw') {
CONFIG.RTA_BAR_LAYOUT = 'iec';
}
return mode; return mode;
} }
const SOFTWARE_PRESET_IDS = Object.freeze(['default', 'claus', 'michael']); const SOFTWARE_PRESET_IDS = Object.freeze(['default', 'claus', 'michael']);
@@ -789,12 +784,8 @@ function loadConfig(opts = {}) {
if (typeof saved.PPM_DIN_DECAY_DB_PER_S === 'number') CONFIG.PPM_DIN_DECAY_DB_PER_S = saved.PPM_DIN_DECAY_DB_PER_S; if (typeof saved.PPM_DIN_DECAY_DB_PER_S === 'number') CONFIG.PPM_DIN_DECAY_DB_PER_S = saved.PPM_DIN_DECAY_DB_PER_S;
if (typeof saved.PPM_DIN_HOLD_MS === 'number') CONFIG.PPM_DIN_HOLD_MS = saved.PPM_DIN_HOLD_MS; if (typeof saved.PPM_DIN_HOLD_MS === 'number') CONFIG.PPM_DIN_HOLD_MS = saved.PPM_DIN_HOLD_MS;
if (CONFIG.RTA_BAR_LAYOUT === 'classic') CONFIG.RTA_BAR_LAYOUT = 'rtw'; if (CONFIG.RTA_BAR_LAYOUT === 'classic') CONFIG.RTA_BAR_LAYOUT = 'rtw';
if (CONFIG.RTA_BAR_LAYOUT === 'rtw' && CONFIG.RTA_BPO_MODE !== '1_3') {
CONFIG.RTA_BAR_LAYOUT = 'iec';
}
if (CONFIG.RTA_BAR_LAYOUT === 'rtw') { if (CONFIG.RTA_BAR_LAYOUT === 'rtw') {
CONFIG.RTA_ENGINE = 'iir'; CONFIG.RTA_ENGINE = 'iir';
CONFIG.RTA_BPO_MODE = '1_3';
CONFIG.RTA_IIR_ORDER = 6; CONFIG.RTA_IIR_ORDER = 6;
CONFIG.RTA_FREQ_RANGE = 'norm'; CONFIG.RTA_FREQ_RANGE = 'norm';
const hold = Number(CONFIG.RTA_PEAK_HOLD_SEC); const hold = Number(CONFIG.RTA_PEAK_HOLD_SEC);
@@ -1126,7 +1117,6 @@ function applyPhoenixGlobalConfig(payload = {}) {
} }
if (CONFIG.RTA_BAR_LAYOUT === 'rtw') { if (CONFIG.RTA_BAR_LAYOUT === 'rtw') {
CONFIG.RTA_ENGINE = 'iir'; CONFIG.RTA_ENGINE = 'iir';
CONFIG.RTA_BPO_MODE = '1_3';
CONFIG.RTA_IIR_ORDER = 6; CONFIG.RTA_IIR_ORDER = 6;
CONFIG.RTA_FREQ_RANGE = 'norm'; CONFIG.RTA_FREQ_RANGE = 'norm';
} }
+3 -3
View File
@@ -310,7 +310,7 @@
<option value="1_6">1/6 Oktave</option> <option value="1_6">1/6 Oktave</option>
<option value="1_12">1/12 Oktave</option> <option value="1_12">1/12 Oktave</option>
</select> </select>
<small>RTW verwendet fest 1/3; 1/6 und 1/12 wechseln automatisch zum IEC-/Phoenix-Profil.</small> <small>Im RTW-Profil stehen 1/3, 1/6 und 1/12 Oktave mit der IIR-Filterbank zur Verfügung.</small>
</div> </div>
<div class="opt"><label>IIR Ordnung</label> <div class="opt"><label>IIR Ordnung</label>
<input id="opt_rtaOrder" type="number" min="2" max="8" step="2" style="width:110px"> <input id="opt_rtaOrder" type="number" min="2" max="8" step="2" style="width:110px">
@@ -1258,9 +1258,9 @@
<li><strong>Browserlast:</strong> Single-Slot-Puffer und Sequenzprüfung für Mess-, Spektrogramm- und Visualisierungsdaten ergänzt. Große Rohsamplefelder werden nicht mehr in jedem JSON-Messpaket wiederholt.</li> <li><strong>Browserlast:</strong> Single-Slot-Puffer und Sequenzprüfung für Mess-, Spektrogramm- und Visualisierungsdaten ergänzt. Große Rohsamplefelder werden nicht mehr in jedem JSON-Messpaket wiederholt.</li>
<li><strong>Spektrogramm:</strong> Langzeitstillstand und stotterndes Nachholen beseitigt. Inkrementelles Spaltenzeichnen, Worker-ACK, Watchdog/Neustart und begrenztes Überspringen veralteter Spalten ergänzt. 0,5×, 1×, 2×, 4× und 6× besitzen nun eine feste, FFT- und DPI-unabhängige Zeitbasis.</li> <li><strong>Spektrogramm:</strong> Langzeitstillstand und stotterndes Nachholen beseitigt. Inkrementelles Spaltenzeichnen, Worker-ACK, Watchdog/Neustart und begrenztes Überspringen veralteter Spalten ergänzt. 0,5×, 1×, 2×, 4× und 6× besitzen nun eine feste, FFT- und DPI-unabhängige Zeitbasis.</li>
<li><strong>DIN-/EBU-PPM:</strong> Blockunabhängige Quasi-Peak-Detektoren mit bandbegrenzter Interpolation, korrekter Attack- und Rücklaufballistik sowie automatischen Tonburst-, Frequenzgang- und Polaritätstests implementiert. Eine zweite Browser-Anstiegsballistik wurde entfernt.</li> <li><strong>DIN-/EBU-PPM:</strong> Blockunabhängige Quasi-Peak-Detektoren mit bandbegrenzter Interpolation, korrekter Attack- und Rücklaufballistik sowie automatischen Tonburst-, Frequenzgang- und Polaritätstests implementiert. Eine zweite Browser-Anstiegsballistik wurde entfernt.</li>
<li><strong>RTW-RTA:</strong> RTW-Profil verbindlich auf die IIR-Dritteloktav-Filterbank festgelegt. Die Filterbank verwendet vollständige Butterworth-Bandpässe sechster Ordnung aus unterschiedlichen SOS-Sektionen, interne f64-Rechnung sowie exakte IEC-Basis-10-Mitten und -Bandkanten bei vertrauten Nominalbeschriftungen.</li> <li><strong>RTW-RTA:</strong> RTW-Profil verbindlich auf die IIR-Oktavteilband-Filterbank festgelegt. Die Filterbank verwendet vollständige Butterworth-Bandpässe sechster Ordnung aus unterschiedlichen SOS-Sektionen, interne f64-Rechnung sowie exakte IEC-Basis-10-Mitten und -Bandkanten bei vertrauten Nominalbeschriftungen.</li>
<li><strong>RTA-Bewertung und Integration:</strong> A-, C- und Z-Bewertung sampleweise vor der Filterbank ergänzt. Fast, Medium, Slow, Impulse, Average und Peak rechnen im Leistungsbereich und unabhängig von der ALSA-Periodengröße.</li> <li><strong>RTA-Bewertung und Integration:</strong> A-, C- und Z-Bewertung sampleweise vor der Filterbank ergänzt. Fast, Medium, Slow, Impulse, Average und Peak rechnen im Leistungsbereich und unabhängig von der ALSA-Periodengröße.</li>
<li><strong>RTA-Auflösung:</strong> Umschaltung zwischen 1/3, 1/6 und 1/12 repariert. 1/6 und 1/12 wechseln sichtbar in das IEC-/Phoenix-Erweiterungsprofil; das originale RTW-Profil bleibt korrekt auf 1/3 verriegelt.</li> <li><strong>RTA-Auflösung:</strong> Umschaltung zwischen 1/3, 1/6 und 1/12 repariert. Alle drei Auflösungen bleiben im RTW-Profil aktiv und verwenden dessen IIR-Filterbank, Darstellung und Ballistik.</li>
<li><strong>Hardwareparameter:</strong> Tatsächlich von ALSA ausgehandelte Samplerate, Perioden- und Puffergröße werden nun durch DSP, Aufnahme, Status und Browser verwendet; die feste 48-kHz-Annahme wurde entfernt.</li> <li><strong>Hardwareparameter:</strong> Tatsächlich von ALSA ausgehandelte Samplerate, Perioden- und Puffergröße werden nun durch DSP, Aufnahme, Status und Browser verwendet; die feste 48-kHz-Annahme wurde entfernt.</li>
<li><strong>Goniometer:</strong> Nur neue XY-Samplepaare werden mit einer periodengrößenunabhängigen mittleren Rate von 60 Hz übertragen. Punktbegrenzung wirkt bereits auf den Transport; begrenzte und wiederverwendbare Spurpuffer reduzieren Speicher- und Zeichenlast.</li> <li><strong>Goniometer:</strong> Nur neue XY-Samplepaare werden mit einer periodengrößenunabhängigen mittleren Rate von 60 Hz übertragen. Punktbegrenzung wirkt bereits auf den Transport; begrenzte und wiederverwendbare Spurpuffer reduzieren Speicher- und Zeichenlast.</li>
<li><strong>Goniometer-Persistenz:</strong> Reproduzierbare Fast-, Medium- und Slow-Profile sowie ein freies Phoenix-Fade ergänzt. Künstliche Bézier-Verformung der Messspur entfernt; AGC und Silence-Gate arbeiten zeit- beziehungsweise fensterbasiert.</li> <li><strong>Goniometer-Persistenz:</strong> Reproduzierbare Fast-, Medium- und Slow-Profile sowie ein freies Phoenix-Fade ergänzt. Künstliche Bézier-Verformung der Messspur entfernt; AGC und Silence-Gate arbeiten zeit- beziehungsweise fensterbasiert.</li>
-2
View File
@@ -1104,12 +1104,10 @@ function wireHandlers(env) {
CONFIG.RTA_BAR_LAYOUT = val; CONFIG.RTA_BAR_LAYOUT = val;
if (val === 'rtw') { if (val === 'rtw') {
CONFIG.RTA_ENGINE = 'iir'; CONFIG.RTA_ENGINE = 'iir';
CONFIG.RTA_BPO_MODE = '1_3';
CONFIG.RTA_IIR_ORDER = 6; CONFIG.RTA_IIR_ORDER = 6;
CONFIG.RTA_FREQ_RANGE = 'norm'; CONFIG.RTA_FREQ_RANGE = 'norm';
const forced = { const forced = {
opt_rtaEngine: 'iir', opt_rtaEngine: 'iir',
opt_rtaBpo: '1_3',
opt_rtaOrder: '6', opt_rtaOrder: '6',
opt_rtaFreq: 'norm', opt_rtaFreq: 'norm',
}; };