新增听力补偿,将有版本限制的功能,提取到配置文件,不再硬编码,优化部署文件参数
This commit is contained in:
@@ -120,6 +120,9 @@ export interface DeviceState {
|
||||
loudness_bass_gain: number;
|
||||
loudness_treble_gain: number;
|
||||
loudness_threshold_gain: number;
|
||||
hearing_enable: number;
|
||||
hearing_select: number;
|
||||
hearing_data: HearingProfile[] | string;
|
||||
bt_status: number;
|
||||
bt_srcname: string;
|
||||
bt_title: string;
|
||||
@@ -127,6 +130,37 @@ export interface DeviceState {
|
||||
msgCount: number;
|
||||
}
|
||||
|
||||
export interface HearingProfile {
|
||||
n: string;
|
||||
l: number[];
|
||||
r: number[];
|
||||
}
|
||||
|
||||
/** Parse `hearing_data` from syncData (array or JSON string). */
|
||||
export function parseHearingData(raw: unknown): HearingProfile[] {
|
||||
if (raw == null || raw === "") return [];
|
||||
let value: unknown = raw;
|
||||
if (typeof raw === "string") {
|
||||
try {
|
||||
value = JSON.parse(raw);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
if (!Array.isArray(value)) return [];
|
||||
return value
|
||||
.map((item) => {
|
||||
if (!item || typeof item !== "object") return null;
|
||||
const row = item as Record<string, unknown>;
|
||||
const n = typeof row.n === "string" ? row.n.trim() : String(row.n ?? "").trim();
|
||||
if (!n) return null;
|
||||
const l = Array.isArray(row.l) ? row.l.map((v) => Number(v)) : [];
|
||||
const r = Array.isArray(row.r) ? row.r.map((v) => Number(v)) : [];
|
||||
return { n, l, r };
|
||||
})
|
||||
.filter((item): item is HearingProfile => item !== null);
|
||||
}
|
||||
|
||||
export interface PeqFilter {
|
||||
fc: number;
|
||||
gain: number;
|
||||
@@ -375,7 +409,7 @@ export class LuxsinAPI {
|
||||
setCrossfeedEnable(enable: boolean) { return this.setSetting({ crossfeed_enable: enable ? 1 : 0 }); }
|
||||
setXlrPolarity(reverse: boolean) { return this.setSetting({ xlr: reverse ? 1 : 0 }); }
|
||||
setDacArc(earc: boolean) { return this.setSetting({ dacArc: earc ? 1 : 0 }); }
|
||||
/** Boot volume level: 0 = default, 1..6 = -5..-30 dB, 7..10 = -35..-50 dB (firmware >= 26). */
|
||||
/** Boot volume level: 0 = default, 1..6 = -5..-30 dB, 7..10 = -35..-50 dB (see firmwareFeatures.bootSoundExtendedSteps). */
|
||||
setBootSound(level: number) {
|
||||
return this.setSetting({ bootSound: Math.max(0, Math.min(10, Math.round(level))) });
|
||||
}
|
||||
@@ -383,7 +417,7 @@ export class LuxsinAPI {
|
||||
powerOff() { return this.setSetting({ power: 0 }); }
|
||||
}
|
||||
|
||||
/** Parse firmware `version` for feature gating (e.g. bootSound extended steps). */
|
||||
/** Parse firmware `version` for feature gating (see `config/firmwareFeatures.ts`). */
|
||||
export function parseFirmwareVersion(version: unknown): number {
|
||||
if (version === null || version === undefined) return 0;
|
||||
if (typeof version === "number" && Number.isFinite(version)) return version;
|
||||
@@ -423,10 +457,7 @@ export function isHomeVolumeLockedByPassthrough(
|
||||
return (output ?? -1) !== OUTPUT_HEADSET_INDEX;
|
||||
}
|
||||
|
||||
/** Max `bootSound` index available for the current firmware. */
|
||||
export function getBootSoundMaxIndex(firmwareVersion: number): number {
|
||||
return firmwareVersion >= 26 ? 10 : 6;
|
||||
}
|
||||
export { getBootSoundMaxIndex } from "@/config/firmwareFeatures";
|
||||
|
||||
/** Normalize `bootSound` from syncData (0 = default … 10 = -50 dB). */
|
||||
export function normalizeBootSound(value: unknown): number {
|
||||
@@ -502,6 +533,15 @@ export const MOCK_DEVICE_STATE: DeviceState = {
|
||||
loudness_bass_gain: 3,
|
||||
loudness_treble_gain: 2,
|
||||
loudness_threshold_gain: 60,
|
||||
hearing_enable: 0,
|
||||
hearing_select: 0,
|
||||
hearing_data: [
|
||||
{
|
||||
n: "testing",
|
||||
l: [1.7, 0.8, 0.5, 0.5, 0.5, 0.5, 0.4],
|
||||
r: [0.4, 0.4, 0.3, 0.3, 0.2, 0.4, 0.3],
|
||||
},
|
||||
],
|
||||
bt_status: 1,
|
||||
bt_srcname: "iPhone 15 Pro",
|
||||
bt_title: "Bohemian Rhapsody",
|
||||
|
||||
Reference in New Issue
Block a user