diff --git a/client/public/changelog.md b/client/public/changelog.md index cff6f4f..f1422f8 100644 --- a/client/public/changelog.md +++ b/client/public/changelog.md @@ -2,6 +2,12 @@ > This document records feature updates and bug fixes for the Luxsin X9 controller. Entries are listed in reverse chronological order — the newest release appears first. +## v2026.09.22 + +### New Features +- Added a dedicated "Headphone settings" section on the Audio page, grouping headphone gain and automatic headphone impedance detection. +- Added maximum headphone volume and headphone startup volume settings. These two settings are shown only on firmware version 2.0.11.0 (build 2011) or later. + ## v2026.09.01 ### Bug Fixes diff --git a/client/src/config/firmwareFeatures.ts b/client/src/config/firmwareFeatures.ts index 8594bb3..66a6560 100644 --- a/client/src/config/firmwareFeatures.ts +++ b/client/src/config/firmwareFeatures.ts @@ -13,6 +13,8 @@ export const FIRMWARE_FEATURE_MIN_VERSION = { hearingCompensation: 2007, /** PEQ preset rename (peqRename) and reorder (peqSoft) in manage dialog. */ peqPresetRenameAndSort: 2008, + /** Audio 页面耳机最大音量和耳机启动音量设置。 */ + hpVolumeSettings: 2011, } as const; export type FirmwareFeatureKey = keyof typeof FIRMWARE_FEATURE_MIN_VERSION; @@ -32,3 +34,7 @@ export function getBootSoundMaxIndex(firmwareVersion: number): number { export function supportsPeqPresetRenameAndSort(firmwareVersion: number): boolean { return isFirmwareFeatureAvailable("peqPresetRenameAndSort", firmwareVersion); } + +export function supportsHpVolumeSettings(firmwareVersion: number): boolean { + return isFirmwareFeatureAvailable("hpVolumeSettings", firmwareVersion); +} diff --git a/client/src/lib/luxsinApi.ts b/client/src/lib/luxsinApi.ts index 4118e32..ec9d374 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -95,6 +95,10 @@ export interface DeviceState { dacGain: number; dacArc: number; dacImpedance: number; + /** 耳机最大音量:0 = 0dB,1 = -5dB … 10 = -50dB;旧固件可能不返回。 */ + hpMaxVolume?: number; + /** 耳机启动音量:0 = 默认,1 = -20dB … 7 = -50dB;旧固件可能不返回。 */ + hpStartupVolume?: number; dacVolumeDirect: number; analogGain: number; effect_enable: number; @@ -590,6 +594,8 @@ export const MOCK_DEVICE_STATE: DeviceState = { dacGain: 0, dacArc: 0, dacImpedance: 0, + hpMaxVolume: 0, + hpStartupVolume: 0, dacVolumeDirect: 0, analogGain: 0, effect_enable: 0, diff --git a/client/src/locales/data-de.json b/client/src/locales/data-de.json index 49261fa..e325b1f 100644 --- a/client/src/locales/data-de.json +++ b/client/src/locales/data-de.json @@ -389,6 +389,7 @@ "dac": { "sectionBalanceSensitivity": "Balance & Empfindlichkeit", "sectionOutput": "Ausgangsmerkmale", + "sectionHpSettings": "Kopfhörer-Einstellungen", "sectionIisSettings": "IIS-Einstellungen", "sectionSystemInterface": "System & Schnittstelle", "balance": "Links-Rechts-Balance", @@ -435,6 +436,35 @@ ] }, "volumeStep": "Lautstärkestufe", + "hpMaxVolume": { + "label": "Max. Kopfhörerlautstärke", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "Kopfhörer-Startlautstärke", + "options": [ + { "index": 0, "label": "Standard" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "Startlautstärke", "options": [ diff --git a/client/src/locales/data-en.json b/client/src/locales/data-en.json index 379699d..b3e04bb 100644 --- a/client/src/locales/data-en.json +++ b/client/src/locales/data-en.json @@ -389,6 +389,7 @@ "dac": { "sectionBalanceSensitivity": "Balance & sensitivity", "sectionOutput": "Output characteristics", + "sectionHpSettings": "Headphone settings", "sectionIisSettings": "IIS settings", "sectionSystemInterface": "System & interface", "balance": "Left-right balance", @@ -435,6 +436,35 @@ ] }, "volumeStep": "Volume step", + "hpMaxVolume": { + "label": "Max headphone volume", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "Headphone startup volume", + "options": [ + { "index": 0, "label": "Default" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "Boot volume", "options": [ diff --git a/client/src/locales/data-es.json b/client/src/locales/data-es.json index 7ba82a5..1c77799 100644 --- a/client/src/locales/data-es.json +++ b/client/src/locales/data-es.json @@ -389,6 +389,7 @@ "dac": { "sectionBalanceSensitivity": "Balance y sensibilidad", "sectionOutput": "Características de salida", + "sectionHpSettings": "Ajustes de auriculares", "sectionIisSettings": "Configuración IIS", "sectionSystemInterface": "Sistema e interfaz", "balance": "Balance izquierda-derecha", @@ -435,6 +436,35 @@ ] }, "volumeStep": "Paso de volumen", + "hpMaxVolume": { + "label": "Volumen máx. de auriculares", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "Volumen de inicio de auriculares", + "options": [ + { "index": 0, "label": "Predeterminado" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "Volumen de inicio", "options": [ diff --git a/client/src/locales/data-fr.json b/client/src/locales/data-fr.json index 88d7742..d85bf7a 100644 --- a/client/src/locales/data-fr.json +++ b/client/src/locales/data-fr.json @@ -389,6 +389,7 @@ "dac": { "sectionBalanceSensitivity": "Balance et sensibilité", "sectionOutput": "Caractéristiques de sortie", + "sectionHpSettings": "Réglages du casque", "sectionIisSettings": "Paramètres IIS", "sectionSystemInterface": "Système et interface", "balance": "Balance gauche-droite", @@ -435,6 +436,35 @@ ] }, "volumeStep": "Pas de volume", + "hpMaxVolume": { + "label": "Volume max. du casque", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "Volume de démarrage du casque", + "options": [ + { "index": 0, "label": "Par défaut" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "Volume de démarrage", "options": [ diff --git a/client/src/locales/data-zh-HK.json b/client/src/locales/data-zh-HK.json index 1a66c40..5903658 100644 --- a/client/src/locales/data-zh-HK.json +++ b/client/src/locales/data-zh-HK.json @@ -383,6 +383,7 @@ "dac": { "sectionBalanceSensitivity": "平衡與靈敏度", "sectionOutput": "輸出特性", + "sectionHpSettings": "耳機設定", "sectionIisSettings": "IIS設定", "sectionSystemInterface": "系統與介面", "balance": "左右平衡", @@ -429,6 +430,35 @@ ] }, "volumeStep": "音量級距", + "hpMaxVolume": { + "label": "耳機最大音量", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "耳機啟動音量", + "options": [ + { "index": 0, "label": "預設" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "開機音量", "options": [ diff --git a/client/src/locales/data-zh.json b/client/src/locales/data-zh.json index ca8f053..ef4e698 100644 --- a/client/src/locales/data-zh.json +++ b/client/src/locales/data-zh.json @@ -383,6 +383,7 @@ "dac": { "sectionBalanceSensitivity": "平衡与灵敏度", "sectionOutput": "输出特性", + "sectionHpSettings": "耳机设定", "sectionIisSettings": "IIS设置", "sectionSystemInterface": "系统与接口", "balance": "左右平衡", @@ -429,6 +430,35 @@ ] }, "volumeStep": "音量幅度", + "hpMaxVolume": { + "label": "耳机最大音量", + "options": [ + { "index": 0, "label": "0dB" }, + { "index": 1, "label": "-5dB" }, + { "index": 2, "label": "-10dB" }, + { "index": 3, "label": "-15dB" }, + { "index": 4, "label": "-20dB" }, + { "index": 5, "label": "-25dB" }, + { "index": 6, "label": "-30dB" }, + { "index": 7, "label": "-35dB" }, + { "index": 8, "label": "-40dB" }, + { "index": 9, "label": "-45dB" }, + { "index": 10, "label": "-50dB" } + ] + }, + "hpStartupVolume": { + "label": "耳机启动音量", + "options": [ + { "index": 0, "label": "默认" }, + { "index": 1, "label": "-20dB" }, + { "index": 2, "label": "-25dB" }, + { "index": 3, "label": "-30dB" }, + { "index": 4, "label": "-35dB" }, + { "index": 5, "label": "-40dB" }, + { "index": 6, "label": "-45dB" }, + { "index": 7, "label": "-50dB" } + ] + }, "bootVolume": { "label": "开机音量", "options": [ diff --git a/client/src/pages/AudioPage.tsx b/client/src/pages/AudioPage.tsx index e46941f..076f04d 100644 --- a/client/src/pages/AudioPage.tsx +++ b/client/src/pages/AudioPage.tsx @@ -3,7 +3,8 @@ Design: Reference luxsin_x8_音频设置.png Sections: - 平衡与灵敏度: 左右平衡, VU灵敏度, 模拟输入增益 sliders - - 输出特性: 滤波特性, 耳机增益, 音量幅度 + - 输出特性: 滤波特性, 前级输出音量直通模式, ARC模式, 音量幅度 + - 耳机设定: 耳机增益, 自动检测耳机阻抗, 耳机最大音量, 耳机启动音量(后两项 version >= 2011 才显示) - 系统与接口: 开机音量, XLR极性 All list rows → navigate to /select page ============================================================ */ @@ -13,6 +14,7 @@ import { useLocation } from "wouter"; import { useState, useEffect, useRef } from "react"; import BottomNav from "@/components/BottomNav"; import { navigateToSelect } from "./SelectPage"; +import { supportsHpVolumeSettings } from "@/config/firmwareFeatures"; import { getBootSoundMaxIndex, normalizeBootSound, @@ -107,6 +109,7 @@ type LocaleDac = { dac?: { sectionBalanceSensitivity?: string; sectionOutput?: string; + sectionHpSettings?: string; sectionSystemInterface?: string; balance?: string; sensitivity?: string; @@ -114,6 +117,8 @@ type LocaleDac = { autoImpedanceDetection?: string; filters?: { label?: string; options?: Array<{ index: number; label: string }> }; dacGain?: { label?: string; options?: Array<{ index: number; label: string }> }; + hpMaxVolume?: { label?: string; options?: Array<{ index: number; label: string }> }; + hpStartupVolume?: { label?: string; options?: Array<{ index: number; label: string }> }; dacVolumeDirect?: { label?: string; options?: Array<{ index: number; label: string }> }; dacArc?: { label?: string; options?: Array<{ index: number; label: string }> }; volumeStep?: string; @@ -217,6 +222,8 @@ export default function AudioPage() { const gainIdx = ds?.dacGain ?? 0; const autoImpedanceOn = (ds?.dacImpedance ?? 0) === 1; + const hpMaxVolumeIdx = Math.min(Math.max(ds?.hpMaxVolume ?? 0, 0), 10); + const hpStartupVolumeIdx = Math.min(Math.max(ds?.hpStartupVolume ?? 0, 0), 7); const dacVolumeDirectIdx = ds?.dacVolumeDirect ?? 0; const dacArcIdx = ds?.dacArc ?? 0; const stepIdx = ds?.soundStep ?? 1; @@ -224,6 +231,7 @@ export default function AudioPage() { const xlrIdx = ds?.xlr ?? 0; const bootSoundVal = normalizeBootSound(localBootSound); const firmwareVersion = parseFirmwareVersion(ds?.version); + const showHpVolumeSettings = supportsHpVolumeSettings(firmwareVersion); const bootSoundMaxIdx = getBootSoundMaxIndex(firmwareVersion); const bootSoundSelectIdx = Math.min(bootSoundVal, bootSoundMaxIdx); const BOOT_VOLUME_OPTIONS = bootVolumeOptions(dacText, bootSoundMaxIdx); @@ -233,6 +241,12 @@ export default function AudioPage() { const DAC_VOLUME_DIRECT_OPTIONS = optionLabels(dacText.dacVolumeDirect?.options, ["关闭", "0dB", "-12dB"]); const DAC_ARC_OPTIONS = optionLabels(dacText.dacArc?.options, ["ARC", "EARC"]); const XLR_OPTIONS = optionLabels(dacText.xlr?.options, ["正常", "反转"]); + const HP_MAX_VOLUME_OPTIONS = optionLabels(dacText.hpMaxVolume?.options, [ + "0dB", "-5dB", "-10dB", "-15dB", "-20dB", "-25dB", "-30dB", "-35dB", "-40dB", "-45dB", "-50dB", + ]); + const HP_STARTUP_VOLUME_OPTIONS = optionLabels(dacText.hpStartupVolume?.options, [ + "默认", "-20dB", "-25dB", "-30dB", "-35dB", "-40dB", "-45dB", "-50dB", + ]); const pageTitle = usePageTitleWithConnection(localeData.home?.audioSet ?? "Audio"); @@ -338,17 +352,6 @@ export default function AudioPage() { value={FILTER_OPTIONS[filterIdx] ?? FILTER_OPTIONS[0] ?? "—"} onClick={() => goSelect(dacText.filters?.label ?? "选择滤波特性", FILTER_OPTIONS, filterIdx, "filterCharacteristic")} /> - goSelect(dacText.dacGain?.label ?? "选择耳机增益", GAIN_OPTIONS, gainIdx, "dacGain")} - /> - updateSetting({ dacImpedance: v ? 1 : 0 })} - /> + {/* ── 耳机设定 ── */} + +
+ goSelect(dacText.dacGain?.label ?? "选择耳机增益", GAIN_OPTIONS, gainIdx, "dacGain")} + /> + updateSetting({ dacImpedance: v ? 1 : 0 })} + /> + {showHpVolumeSettings && ( + <> + + goSelect(dacText.hpMaxVolume?.label ?? "耳机最大音量", HP_MAX_VOLUME_OPTIONS, hpMaxVolumeIdx, "hpMaxVolume") + } + /> + + goSelect(dacText.hpStartupVolume?.label ?? "耳机启动音量", HP_STARTUP_VOLUME_OPTIONS, hpStartupVolumeIdx, "hpStartupVolume") + } + /> + + )} +
+ {/* ── 系统与接口 ── */}
diff --git a/client/src/pages/SelectPage.tsx b/client/src/pages/SelectPage.tsx index 6608a23..5446143 100644 --- a/client/src/pages/SelectPage.tsx +++ b/client/src/pages/SelectPage.tsx @@ -123,6 +123,10 @@ const KEY_TO_SETTING: Record = { dacImpedance: "dacImpedance", + hpMaxVolume: "hpMaxVolume", + + hpStartupVolume: "hpStartupVolume", + dacVolumeDirect: "dacVolumeDirect", dacArc: "dacArc",