From 19172275a9781bf1e836af66dc9be1470fb6a269 Mon Sep 17 00:00:00 2001 From: eafonyang Date: Fri, 11 Sep 2026 19:30:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E4=BA=A4=E5=8F=89=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/lib/luxsinApi.ts | 6 +++ client/src/locales/data-de.json | 5 +- client/src/locales/data-en.json | 5 +- client/src/locales/data-es.json | 5 +- client/src/locales/data-fr.json | 5 +- client/src/locales/data-zh-HK.json | 5 +- client/src/locales/data-zh.json | 5 +- client/src/pages/EffectsPage.tsx | 77 ++++++++++++++++++++++++++++++ 8 files changed, 107 insertions(+), 6 deletions(-) diff --git a/client/src/lib/luxsinApi.ts b/client/src/lib/luxsinApi.ts index 55dd541..1d94d9d 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -105,6 +105,10 @@ export interface DeviceState { scene_value: number; crossfeed_enable: number; crossfeed_value: number; + /** Custom crossfeed cut-off frequency in Hz (500–1000, step 1). */ + crossfeed_custom_fc: number; + /** Custom crossfeed attenuation, stored as dB×10 (1.0 dB=10 … 15.0 dB=150). */ + crossfeed_custom_gain: number; subwoofer_enable: number; subwoofer_value: number; subwoofer_rate: number; @@ -573,6 +577,8 @@ export const MOCK_DEVICE_STATE: DeviceState = { scene_value: 0, crossfeed_enable: 0, crossfeed_value: 0, + crossfeed_custom_fc: 700, + crossfeed_custom_gain: 45, subwoofer_enable: 0, subwoofer_value: 80, subwoofer_rate: 0, diff --git a/client/src/locales/data-de.json b/client/src/locales/data-de.json index 152bba2..bfc070c 100644 --- a/client/src/locales/data-de.json +++ b/client/src/locales/data-de.json @@ -111,7 +111,10 @@ "BS2B Populär (700 Hz, 6 dB)", "BS2B Entspannt (650 Hz, 9,5 dB)", "Custom" - ] + ], + "customTitle": "Benutzerdefinierte Einstellungen", + "freqLabel": "Frequence", + "attenuationLabel": "Attenuation" }, "hearing": { "label": "Hörkompensation", diff --git a/client/src/locales/data-en.json b/client/src/locales/data-en.json index a414693..e2208a9 100644 --- a/client/src/locales/data-en.json +++ b/client/src/locales/data-en.json @@ -111,7 +111,10 @@ "BS2B popular (700 Hz, 6 dB)", "BS2B relax (650 Hz, 9.5 dB)", "Custom" - ] + ], + "customTitle": "Custom Settings", + "freqLabel": "Frequence", + "attenuationLabel": "Attenuation" }, "hearing": { "label": "Hearing compensation", diff --git a/client/src/locales/data-es.json b/client/src/locales/data-es.json index 2f1f2b6..db97a05 100644 --- a/client/src/locales/data-es.json +++ b/client/src/locales/data-es.json @@ -111,7 +111,10 @@ "BS2B popular (700 Hz, 6 dB)", "BS2B relajado (650 Hz, 9,5 dB)", "Custom" - ] + ], + "customTitle": "Configuración personalizada", + "freqLabel": "Frequence", + "attenuationLabel": "Attenuation" }, "hearing": { "label": "Compensación auditiva", diff --git a/client/src/locales/data-fr.json b/client/src/locales/data-fr.json index 3a3bcd5..438edf2 100644 --- a/client/src/locales/data-fr.json +++ b/client/src/locales/data-fr.json @@ -111,7 +111,10 @@ "BS2B populaire (700 Hz, 6 dB)", "BS2B relax (650 Hz, 9,5 dB)", "Custom" - ] + ], + "customTitle": "Réglages personnalisés", + "freqLabel": "Frequence", + "attenuationLabel": "Attenuation" }, "hearing": { "label": "Compensation auditive", diff --git a/client/src/locales/data-zh-HK.json b/client/src/locales/data-zh-HK.json index 0c97204..9696d0d 100644 --- a/client/src/locales/data-zh-HK.json +++ b/client/src/locales/data-zh-HK.json @@ -104,7 +104,10 @@ "BS2B polular(700Hz,6dB)", "BS2B relax(650Hz,9.5dB)", "Custom" - ] + ], + "customTitle": "自訂設置", + "freqLabel": "截止頻率", + "attenuationLabel": "衰減量" }, "hearing": { "label": "聽力補償", diff --git a/client/src/locales/data-zh.json b/client/src/locales/data-zh.json index cbcfb7f..4b4d97f 100644 --- a/client/src/locales/data-zh.json +++ b/client/src/locales/data-zh.json @@ -104,7 +104,10 @@ "BS2B polular(700Hz,6dB)", "BS2B relax(650Hz,9.5dB)", "Custom" - ] + ], + "customTitle": "自定义设置", + "freqLabel": "截止频率", + "attenuationLabel": "衰减量" }, "hearing": { "label": "听力补偿", diff --git a/client/src/pages/EffectsPage.tsx b/client/src/pages/EffectsPage.tsx index eddd9e3..7c0a05a 100644 --- a/client/src/pages/EffectsPage.tsx +++ b/client/src/pages/EffectsPage.tsx @@ -408,6 +408,20 @@ export default function EffectsPage() { const sceneDisplay = sceneLabels[sceneIdx] ?? ""; const crossIdx = clampPickIndex(crossfeedVal, crossfeedLabels.length); const crossfeedDisplay = crossfeedLabels[crossIdx] ?? ""; + // Custom crossfeed values: fc in Hz, gain stored as dB×10 + const crossfeedCustomFc = ds?.crossfeed_custom_fc ?? 700; + const crossfeedCustomGain = (ds?.crossfeed_custom_gain ?? 45) / 10; + + const [localCrossfeedFc, setLocalCrossfeedFc] = useState(() => crossfeedCustomFc); + const [localCrossfeedGain, setLocalCrossfeedGain] = useState(() => crossfeedCustomGain); + const isDraggingCrossfeedFc = useRef(false); + const isDraggingCrossfeedGain = useRef(false); + + useEffect(() => { + if (!isDraggingCrossfeedFc.current) setLocalCrossfeedFc(crossfeedCustomFc); + if (!isDraggingCrossfeedGain.current) setLocalCrossfeedGain(crossfeedCustomGain); + }, [crossfeedCustomFc, crossfeedCustomGain]); + const hearingIdx = clampPickIndex(hearingSelect, hearingLabels.length); const hearingDisplay = hearingLabels[hearingIdx] ?? effectText.hearing?.emptyProfile ?? "—"; @@ -527,6 +541,69 @@ export default function EffectsPage() { {crossfeedDisplay} + + {/* ── Custom crossfeed sub-module (shown when Custom / index 3 selected) ── */} + {crossfeedOn && crossIdx === 3 && ( +
+
+ {effectText.crossfeed?.customTitle ?? "自定义设置"} +
+ + {/* Frequence — cut-off frequency 500–1000 Hz */} +
+
+ + {effectText.crossfeed?.freqLabel ?? "Frequence"} + + + {Math.round(localCrossfeedFc)} Hz + +
+ { + isDraggingCrossfeedFc.current = true; + setLocalCrossfeedFc(Math.round(v)); + }} + onRelease={(v) => { + isDraggingCrossfeedFc.current = false; + const fc = Math.round(v); + setLocalCrossfeedFc(fc); + updateSetting({ crossfeed_custom_fc: fc }); + }} + /> +
+ + {/* Attenuation — 1.0–15.0 dB, sent as value×10 */} +
+
+ + {effectText.crossfeed?.attenuationLabel ?? "Attenuation"} + + + {localCrossfeedGain.toFixed(1)} dB + +
+ { + isDraggingCrossfeedGain.current = true; + setLocalCrossfeedGain(v); + }} + onRelease={(v) => { + isDraggingCrossfeedGain.current = false; + updateSetting({ crossfeed_custom_gain: Math.round(v * 10) }); + }} + /> +
+
+ )} {/* ── 音调 ── */}