Add 3.8 changelog and fix RTA octave selection
This commit is contained in:
@@ -44,4 +44,19 @@ assert.equal(extension.bpo, '1_12');
|
|||||||
assert.equal(extension.freqRange, 'lf');
|
assert.equal(extension.freqRange, 'lf');
|
||||||
assert.equal(extension.order, 8);
|
assert.equal(extension.order, 8);
|
||||||
|
|
||||||
|
const configSource = fs.readFileSync(new URL('../www/core/config.js', import.meta.url), 'utf8');
|
||||||
|
const selectionSource = configSource.match(/function applyRtaBpoSelection[\s\S]*?\n\}/)?.[0];
|
||||||
|
assert.ok(selectionSource, 'RTA BPO selection policy must remain testable');
|
||||||
|
const selectionContext = vm.createContext({
|
||||||
|
String,
|
||||||
|
CONFIG: { RTA_BPO_MODE: '1_3', RTA_BAR_LAYOUT: 'rtw' },
|
||||||
|
});
|
||||||
|
vm.runInContext(selectionSource, selectionContext);
|
||||||
|
assert.equal(selectionContext.applyRtaBpoSelection('1_6'), '1_6');
|
||||||
|
assert.equal(selectionContext.CONFIG.RTA_BPO_MODE, '1_6');
|
||||||
|
assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'iec');
|
||||||
|
selectionContext.CONFIG.RTA_BAR_LAYOUT = 'rtw';
|
||||||
|
assert.equal(selectionContext.applyRtaBpoSelection('1_3'), '1_3');
|
||||||
|
assert.equal(selectionContext.CONFIG.RTA_BAR_LAYOUT, 'rtw');
|
||||||
|
|
||||||
console.log('RTA profile regression tests passed');
|
console.log('RTA profile regression tests passed');
|
||||||
|
|||||||
@@ -663,6 +663,9 @@ 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;
|
||||||
@@ -744,4 +747,14 @@ mod tests {
|
|||||||
assert_eq!(config.freq_range, "lf");
|
assert_eq!(config.freq_range, "lf");
|
||||||
assert_eq!(config.integration, "medium");
|
assert_eq!(config.integration, "medium");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_third_octave_global_selection_leaves_locked_rtw_profile() {
|
||||||
|
let mut global = PhoenixGlobalConfig::default();
|
||||||
|
global.rta_bpo_mode = "1_12".to_string();
|
||||||
|
let config = apply_global_to_rta(PhoenixRtaConfig::default(), &global);
|
||||||
|
assert_eq!(config.layout, "iec");
|
||||||
|
assert_eq!(config.bpo, "1_12");
|
||||||
|
assert_eq!(config.engine, "iir");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-1
@@ -281,6 +281,17 @@ const CONFIG = {
|
|||||||
SOFTWARE_PRESET: 'default',
|
SOFTWARE_PRESET: 'default',
|
||||||
};
|
};
|
||||||
const CONFIG_DEFAULTS = JSON.parse(JSON.stringify(CONFIG));
|
const CONFIG_DEFAULTS = JSON.parse(JSON.stringify(CONFIG));
|
||||||
|
|
||||||
|
function applyRtaBpoSelection(value) {
|
||||||
|
const mode = ['1_3', '1_6', '1_12'].includes(String(value)) ? String(value) : '1_3';
|
||||||
|
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;
|
||||||
|
}
|
||||||
const SOFTWARE_PRESET_IDS = Object.freeze(['default', 'claus', 'michael']);
|
const SOFTWARE_PRESET_IDS = Object.freeze(['default', 'claus', 'michael']);
|
||||||
const LAYOUT_PRESET_IDS = Object.freeze(['1', '2', '3', '4']);
|
const LAYOUT_PRESET_IDS = Object.freeze(['1', '2', '3', '4']);
|
||||||
const LAYOUT_PRESET_KEYS = Object.freeze([
|
const LAYOUT_PRESET_KEYS = Object.freeze([
|
||||||
@@ -778,6 +789,9 @@ 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_BPO_MODE = '1_3';
|
||||||
@@ -1108,7 +1122,7 @@ function applyPhoenixGlobalConfig(payload = {}) {
|
|||||||
}
|
}
|
||||||
if ('rtaBpoMode' in payload) {
|
if ('rtaBpoMode' in payload) {
|
||||||
const mode = String(payload.rtaBpoMode || '').trim();
|
const mode = String(payload.rtaBpoMode || '').trim();
|
||||||
CONFIG.RTA_BPO_MODE = (mode === '1_3' || mode === '1_6' || mode === '1_12') ? mode : '1_6';
|
applyRtaBpoSelection(mode);
|
||||||
}
|
}
|
||||||
if (CONFIG.RTA_BAR_LAYOUT === 'rtw') {
|
if (CONFIG.RTA_BAR_LAYOUT === 'rtw') {
|
||||||
CONFIG.RTA_ENGINE = 'iir';
|
CONFIG.RTA_ENGINE = 'iir';
|
||||||
@@ -1278,6 +1292,7 @@ export {
|
|||||||
saveConfig,
|
saveConfig,
|
||||||
buildPhoenixGlobalConfigPayload,
|
buildPhoenixGlobalConfigPayload,
|
||||||
applyPhoenixGlobalConfig,
|
applyPhoenixGlobalConfig,
|
||||||
|
applyRtaBpoSelection,
|
||||||
applyBroadcastStandard,
|
applyBroadcastStandard,
|
||||||
applySoftwarePreset,
|
applySoftwarePreset,
|
||||||
loadSoftwarePreset,
|
loadSoftwarePreset,
|
||||||
|
|||||||
+25
-1
@@ -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>Filterauflösung – Anzahl Bänder</small>
|
<small>RTW verwendet fest 1/3; 1/6 und 1/12 wechseln automatisch zum IEC-/Phoenix-Profil.</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">
|
||||||
@@ -1246,6 +1246,30 @@
|
|||||||
<details style="margin:20px 0 0 5px">
|
<details style="margin:20px 0 0 5px">
|
||||||
<summary>Version / Änderungen</summary>
|
<summary>Version / Änderungen</summary>
|
||||||
<div class="opt-group">
|
<div class="opt-group">
|
||||||
|
<details style="margin-left:12px" open>
|
||||||
|
<summary>3.8 (Phoenix 1.0)</summary>
|
||||||
|
<div class="opt-group">
|
||||||
|
<div class="opt">
|
||||||
|
<p style="margin:0; color:#8fd3d4;">Veröffentlichung: 21.07.2026</p>
|
||||||
|
<p style="margin:4px 0 0 12px; color:#8fd3d4;">Änderungen:</p>
|
||||||
|
<ul style="margin:2px 0 0 24px; color:#b2c7d9;">
|
||||||
|
<li><strong>Analysegrundlage:</strong> Die tiefgehende Code- und DSP-Prüfung, durch die die nachfolgenden Fehler und Verbesserungsmöglichkeiten gefunden werden konnten, wurde durch den Umstieg auf das LLM-Modell GPT-5.6 SOL ermöglicht.</li>
|
||||||
|
<li><strong>Echtzeit-Datenweg:</strong> WebSocket-Verarbeitung auf „latest value wins“ umgestellt. Messwerte, Spektrogramm sowie Goniometer/Waveform verwenden getrennte, begrenzte Datenwege; alte Frames können keine anwachsende Anzeigeverzögerung mehr bilden.</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>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>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>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-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>Korrelation:</strong> Kontinuierliche DSP-Messung aus L², R² und L·R mit wählbaren 1,0/2,5 Sekunden ergänzt. Bildratenabhängige Doppelglättung entfernt; Negative-Peak-Memory, Marker und manueller Reset hinzugefügt.</li>
|
||||||
|
<li><strong>Qualitätssicherung:</strong> Automatische Regressionstests für PPM, RTA, A/C/Z, mehrere Sampleraten, Korrelationssignale, Goniometertaktung, Binärprotokolle sowie Spektrogramm-Zeitbasis und Langlauf ergänzt.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
<details style="margin-left:12px" open>
|
<details style="margin-left:12px" open>
|
||||||
<summary>3.3.5 (Phoenix 1.0)</summary>
|
<summary>3.3.5 (Phoenix 1.0)</summary>
|
||||||
<div class="opt-group">
|
<div class="opt-group">
|
||||||
|
|||||||
+3
-2
@@ -20,7 +20,7 @@ try {
|
|||||||
}
|
}
|
||||||
} catch(_) {}
|
} catch(_) {}
|
||||||
|
|
||||||
import { CONFIG, loadConfig, saveConfig, loadLayoutPreset } from './core/config.js';
|
import { CONFIG, applyRtaBpoSelection, loadConfig, saveConfig, loadLayoutPreset } from './core/config.js';
|
||||||
import * as utils from './core/utils.js';
|
import * as utils from './core/utils.js';
|
||||||
import { meterFacade, registerMeter } from './core/registry.js';
|
import { meterFacade, registerMeter } from './core/registry.js';
|
||||||
import { initAudio, audioLost, reloadAudio } from './core/audio.js';
|
import { initAudio, audioLost, reloadAudio } from './core/audio.js';
|
||||||
@@ -2152,7 +2152,7 @@ function handlePeakHistScrollSelection(value){
|
|||||||
|
|
||||||
function handleRtaBpoSelection(value){
|
function handleRtaBpoSelection(value){
|
||||||
const mode = normalizeRtaBpo(value);
|
const mode = normalizeRtaBpo(value);
|
||||||
CONFIG.RTA_BPO_MODE = mode;
|
applyRtaBpoSelection(mode);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
if (rtaBpoSel) {
|
if (rtaBpoSel) {
|
||||||
rtaBpoSel.value = mode;
|
rtaBpoSel.value = mode;
|
||||||
@@ -2162,6 +2162,7 @@ function handleRtaBpoSelection(value){
|
|||||||
select.value = mode;
|
select.value = mode;
|
||||||
}
|
}
|
||||||
try { env.audio.updateRtaConfig?.(); } catch (_) {}
|
try { env.audio.updateRtaConfig?.(); } catch (_) {}
|
||||||
|
try { env.audio.updatePhoenixGlobalConfig?.(); } catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNearestWaveWindow(value){
|
function getNearestWaveWindow(value){
|
||||||
|
|||||||
+4
-5
@@ -1,7 +1,7 @@
|
|||||||
// ui/options.js — bindet das Options-Panel an CONFIG (lesen/schreiben), Presets, Export/Import
|
// ui/options.js — bindet das Options-Panel an CONFIG (lesen/schreiben), Presets, Export/Import
|
||||||
// Erwartet vorhandenes DOM aus index.html. Nutzt localStorage-Key 'analyzer_config'.
|
// Erwartet vorhandenes DOM aus index.html. Nutzt localStorage-Key 'analyzer_config'.
|
||||||
|
|
||||||
import { CONFIG, saveConfig, loadConfig, applyAlignmentProfile, applySoftwarePreset, loadSoftwarePreset, saveSoftwarePreset, loadLayoutPreset, saveLayoutPreset, exportSoftwarePreset, importSoftwarePreset, updateVuReference, resetConfigToDefaults, updateInputOffsetGain } from '../core/config.js';
|
import { CONFIG, saveConfig, loadConfig, applyAlignmentProfile, applyRtaBpoSelection, applySoftwarePreset, loadSoftwarePreset, saveSoftwarePreset, loadLayoutPreset, saveLayoutPreset, exportSoftwarePreset, importSoftwarePreset, updateVuReference, resetConfigToDefaults, updateInputOffsetGain } from '../core/config.js';
|
||||||
import { clamp, clampPow2 } from '../core/utils.js';
|
import { clamp, clampPow2 } from '../core/utils.js';
|
||||||
|
|
||||||
// DOM helper
|
// DOM helper
|
||||||
@@ -1075,10 +1075,9 @@ function wireHandlers(env) {
|
|||||||
return CONFIG.RTA_ENGINE;
|
return CONFIG.RTA_ENGINE;
|
||||||
});
|
});
|
||||||
h('opt_rtaBpo', v => {
|
h('opt_rtaBpo', v => {
|
||||||
const allowed = new Set(['1_3', '1_6', '1_12']);
|
applyRtaBpoSelection(v);
|
||||||
CONFIG.RTA_BPO_MODE = CONFIG.RTA_BAR_LAYOUT === 'rtw'
|
const layoutControl = E('opt_rtaLayout');
|
||||||
? '1_3'
|
if (layoutControl) layoutControl.value = CONFIG.RTA_BAR_LAYOUT;
|
||||||
: (allowed.has(v) ? v : '1_6');
|
|
||||||
notifyPhoenixGlobalConfig();
|
notifyPhoenixGlobalConfig();
|
||||||
return CONFIG.RTA_BPO_MODE;
|
return CONFIG.RTA_BPO_MODE;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user