diff --git a/client/src/config/firmwareFeatures.ts b/client/src/config/firmwareFeatures.ts index 3e908e5..55874cd 100644 --- a/client/src/config/firmwareFeatures.ts +++ b/client/src/config/firmwareFeatures.ts @@ -13,6 +13,8 @@ export const FIRMWARE_FEATURE_MIN_VERSION = { peqPresetRenameAndSort: 29, /** Hearing compensation section on the Effects page. */ hearingCompensation: 30, + /** Headphone max/startup volume rows on the Audio page (hpMaxVolume/hpStartupVolume). */ + hpVolumeSettings: 31, } as const; export type FirmwareFeatureKey = keyof typeof FIRMWARE_FEATURE_MIN_VERSION; @@ -37,3 +39,7 @@ 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 4508650..63d0b5d 100644 --- a/client/src/lib/luxsinApi.ts +++ b/client/src/lib/luxsinApi.ts @@ -98,6 +98,10 @@ export interface DeviceState { dacGain: number; dacArc: number; dacImpedance: number; + /** Headphone max volume: 0 = 0dB, 1 = -5dB … 10 = -50dB (5dB steps). */ + hpMaxVolume: number; + /** Headphone startup volume: 0 = default, 1 = -20dB … 7 = -50dB (5dB steps). */ + hpStartupVolume: number; dreMode: number; dacVolumeDirect: number; analogGain: number; @@ -559,6 +563,8 @@ export const MOCK_DEVICE_STATE: DeviceState = { dacGain: 0, dacArc: 0, dacImpedance: 0, + hpMaxVolume: 0, + hpStartupVolume: 0, dreMode: 0, dacVolumeDirect: 0, analogGain: 0, diff --git a/client/src/locales/data-de.json b/client/src/locales/data-de.json index 5f3967a..3e59e46 100644 --- a/client/src/locales/data-de.json +++ b/client/src/locales/data-de.json @@ -435,6 +435,7 @@ "dac": { "sectionBalanceSensitivity": "Balance & Empfindlichkeit", "sectionOutput": "Ausgangsmerkmale", + "sectionHpSettings": "Kopfhörer-Einstellungen", "sectionIisSettings": "IIS-Einstellungen", "sectionSystemInterface": "System & Schnittstelle", "balance": "Links-Rechts-Balance", @@ -537,6 +538,92 @@ "cancel": "Abbrechen" }, "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 6f14830..cf2affe 100644 --- a/client/src/locales/data-en.json +++ b/client/src/locales/data-en.json @@ -435,6 +435,7 @@ "dac": { "sectionBalanceSensitivity": "Balance & sensitivity", "sectionOutput": "Output characteristics", + "sectionHpSettings": "Headphone settings", "sectionIisSettings": "IIS settings", "sectionSystemInterface": "System & interface", "balance": "Left-right balance", @@ -537,6 +538,92 @@ "cancel": "Cancel" }, "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 387fb52..7cfbac0 100644 --- a/client/src/locales/data-es.json +++ b/client/src/locales/data-es.json @@ -435,6 +435,7 @@ "dac": { "sectionBalanceSensitivity": "Balance y sensibilidad", "sectionOutput": "Características de salida", + "sectionHpSettings": "Ajustes de auriculares", "sectionIisSettings": "Ajustes IIS", "sectionSystemInterface": "Sistema e interfaz", "balance": "Balance izquierda-derecha", @@ -537,6 +538,92 @@ "cancel": "Cancelar" }, "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 arranque", "options": [ diff --git a/client/src/locales/data-fr.json b/client/src/locales/data-fr.json index 2d2d3b1..66c566e 100644 --- a/client/src/locales/data-fr.json +++ b/client/src/locales/data-fr.json @@ -435,6 +435,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", @@ -537,6 +538,92 @@ "cancel": "Annuler" }, "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 7a8222b..be47a5a 100644 --- a/client/src/locales/data-zh-HK.json +++ b/client/src/locales/data-zh-HK.json @@ -435,6 +435,7 @@ "dac": { "sectionBalanceSensitivity": "平衡與靈敏度", "sectionOutput": "輸出特性", + "sectionHpSettings": "耳機設定", "sectionIisSettings": "IIS設定", "sectionSystemInterface": "系統與介面", "balance": "左右平衡", @@ -537,6 +538,92 @@ "cancel": "取消" }, "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 4252614..6f6f591 100644 --- a/client/src/locales/data-zh.json +++ b/client/src/locales/data-zh.json @@ -435,6 +435,7 @@ "dac": { "sectionBalanceSensitivity": "平衡与灵敏度", "sectionOutput": "输出特性", + "sectionHpSettings": "耳机设定", "sectionIisSettings": "IIS设置", "sectionSystemInterface": "系统与接口", "balance": "左右平衡", @@ -537,6 +538,92 @@ "cancel": "取消" }, "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 774eae2..fbdbbf1 100644 --- a/client/src/pages/AudioPage.tsx +++ b/client/src/pages/AudioPage.tsx @@ -3,7 +3,8 @@ Design: Reference luxsin_x8_音频设置.png Sections: - 平衡与灵敏度: 左右平衡 slider, VU灵敏度 slider - - 输出特性: 滤波特性, 耳机增益, 音量幅度 + - 输出特性: 滤波特性, 动态范围增强, 音量幅度 + - 耳机设定: 耳机增益, 自动检测耳机阻抗, 耳机最大音量, 耳机启动音量(后两项 version >= 31 才显示) - IIS设置: IIS静音电平, IIS模式 - 系统与接口: 开机音量, XLR极性 All list rows → navigate to /select page @@ -14,7 +15,7 @@ import { useLocation } from "wouter"; import { useState, useEffect, useRef } from "react"; import BottomNav from "@/components/BottomNav"; import { navigateToSelect } from "./SelectPage"; -import { getBootSoundMaxIndex } from "@/config/firmwareFeatures"; +import { getBootSoundMaxIndex, supportsHpVolumeSettings } from "@/config/firmwareFeatures"; import { normalizeBootSound, parseFirmwareVersion, @@ -110,6 +111,7 @@ type LocaleDac = { dac?: { sectionBalanceSensitivity?: string; sectionOutput?: string; + sectionHpSettings?: string; sectionIisSettings?: string; sectionSystemInterface?: string; balance?: string; @@ -117,6 +119,8 @@ type LocaleDac = { filters?: { label?: string; options?: Array<{ index: number; label: string }> }; dacGain?: { label?: string; options?: Array<{ index: number; label: string }> }; autoImpedance?: { 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 }> }; dreMode?: { label?: string; options?: Array<{ index: number; label: string }> }; dacVolumeDirect?: { label?: string; options?: Array<{ index: number; label: string }> }; uacVer?: { label?: string; options?: Array<{ index: number; label: string }> }; @@ -216,6 +220,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 dreModeOn = (ds?.dreMode ?? 0) === 1; const dacVolumeDirectIdx = Math.min(Math.max(ds?.dacVolumeDirect ?? 0, 0), 2); const stepIdx = ds?.soundStep ?? 1; @@ -226,6 +232,7 @@ export default function AudioPage() { const uacVerIdx = Math.min(Math.max(ds?.uac_ver ?? 0, 0), 1); 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); @@ -241,6 +248,12 @@ export default function AudioPage() { "-12dB", ]); const UAC_VER_OPTIONS = optionLabels(dacText.uacVer?.options, ["UAC 2.0", "UAC 1.0"]); + 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"); @@ -322,16 +335,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") + } + /> + + )} +
+ {/* ── IIS 设置 ── */}
diff --git a/client/src/pages/SelectPage.tsx b/client/src/pages/SelectPage.tsx index ea70c37..894079e 100644 --- a/client/src/pages/SelectPage.tsx +++ b/client/src/pages/SelectPage.tsx @@ -52,6 +52,8 @@ const KEY_TO_SETTING: Record = { xlr: "xlr", dacGain: "dacGain", dacImpedance: "dacImpedance", + hpMaxVolume: "hpMaxVolume", + hpStartupVolume: "hpStartupVolume", dacVolumeDirect: "dacVolumeDirect", uacVer: "uac_ver", vu: "vu",