EQ 预设加「电影院」「歌剧院」+ 预设按钮选中高亮
两个新预设按现实场所的声学设计, 不是随手画的微笑曲线: - 电影院: 高频按 X-curve(ISO 2969 国际版, 2 kHz 以上约 -1.5 dB/oct, 实测 2k->4k->8k->16k 逐段 -1.5)再叠银幕透声损失; 低频 25~60 Hz +2.5~3 dB(影院 sub / LFE 通道的体感) —— 厚, 暗, 有力 - 歌剧院: 中低频 150~400 Hz +2 dB(木质厅堂的温暖); 2~5 kHz +0.5~1 dB(没有扩声系统, 歌手靠 presence 区投射, 这里不能削); 极低频 20~40 Hz -1 dB; 高频只随大空间空气吸收 缓降 —— 暖, 亮, 有细节 两者实测差: 25~60 Hz 影院重 3.4 dB / 3.15~5 kHz 歌剧院足 3.0 dB / 8~16 kHz 歌剧院足 3.5 dB。 顺带修: `.presets button.on` 的样式一直定义了但没有任何代码加这个类 —— 点了预设没有选中 反馈。加 markPreset(): 点预设高亮对应按钮, 手动拖滑块 / 全部归零时同步更新。 验收(CDP 真实点击): 两个预设的 32 段值与设计逐位一致; 高亮 = 对应按钮名; 手动拖滑块后 高亮清空。README 加「EQ 预设的设计依据」节(含影院/歌剧院的混响湿量建议)。
This commit is contained in:
@@ -193,6 +193,51 @@ collaplex-audio stop # 连链路一起
|
||||
- 房间 IR 被压低频后峰值掉 3.7 dB, 湿路 `gain` 相应 **0.4 → 0.61** 补偿, 这样听感差异
|
||||
纯粹来自"低频变干净"而不是"混响变小"。
|
||||
|
||||
## EQ 预设的设计依据(2026-09-20)
|
||||
|
||||
前 10 个是常见调音口味; 后面两个「电影院」「歌剧院」是**按现实场所的声学特性**设计的,
|
||||
不是随手画的微笑曲线。
|
||||
|
||||
### 电影院
|
||||
|
||||
- **高频按 X-curve**(ISO 2969 国际版): 2 kHz 以上每倍频程约 **-1.5 dB**
|
||||
(北美 SMPTE 版是 -3 dB/oct, 听感更暗)。本预设实测 2k→4k→8k→16k = **-1.5 / -1.5 / -1.5 dB/oct**。
|
||||
再叠一层**银幕透声损失**(穿孔幕布在 4~10 kHz 的衰减), 所以中高频起点比纯 X-curve 再低一点。
|
||||
- **低频抬 +2.5~3 dB**: 影院有 **sub / LFE 通道**(标定电平比主声道高 10 dB)+ 厅内增益,
|
||||
25~60 Hz 是"体感"的来源。
|
||||
- **中低频 200~400 Hz 略降**: 银幕后扬声器 + 厅堂增益让这里容易浑, 让出一点。
|
||||
- 听感目标: **厚, 暗, 有力**。
|
||||
|
||||
### 歌剧院
|
||||
|
||||
- **中低频 150~400 Hz 抬 +2 dB**: 木质地板/墙面的厅堂温暖感(bloom), 也是大提琴/男中的厚度来源。
|
||||
- **2~5 kHz 抬 +0.5~1 dB**: 歌剧院**没有扩声系统**, 歌手和乐器的"投射"全靠这个 presence 区 ——
|
||||
这里**不能削**(削了就闷), 也正是和影院最大的分野。
|
||||
- **极低频 20~40 Hz 略降 -1 dB**: 没有电声强化, 自然厅堂里这一段本就不强。
|
||||
- **高频缓降**: 只有大空间的空气吸收, 10 kHz 以上 -0.5~-2 dB(**比影院缓得多**)。
|
||||
- 听感目标: **暖, 亮, 有细节**。
|
||||
|
||||
### 两者差异(实测平均)
|
||||
|
||||
| 频段 | 电影院 | 歌剧院 | 差 |
|
||||
|---|---|---|---|
|
||||
| 25~60 Hz | +2.75 | -0.62 | 影院重 **+3.4 dB** |
|
||||
| 150~400 Hz | -0.10 | +1.90 | 歌剧院足 **+2.0 dB** |
|
||||
| 1~2 kHz | -0.25 | +0.25 | 基本持平 |
|
||||
| 3.15~5 kHz | -2.00 | +1.00 | 歌剧院足 **+3.0 dB** |
|
||||
| 8~16 kHz | -4.25 | -0.75 | 歌剧院足 **+3.5 dB** |
|
||||
|
||||
### 配套的湿量建议
|
||||
|
||||
**混响时间**才是这两个场所最本质的差别, 影响比 EQ 更大:
|
||||
|
||||
| 场所 | 实际混响时间 | 建议湿量 |
|
||||
|---|---|---|
|
||||
| 电影院(带银幕的放映厅) | 0.4~0.8 s | **0.30~0.40** |
|
||||
| 歌剧院 | 1.4~1.8 s | **0.70~0.85** |
|
||||
|
||||
默认湿量 0.6 是居中的; 想更贴现实就按上表拖(面板上实时生效)。
|
||||
|
||||
## 参数持久化(2026-09-20)
|
||||
|
||||
面板上拖出来的 32 段 EQ / 总音量 / 湿量, 现在会**落盘**; 共享内存被清空后(开机、重启、
|
||||
|
||||
+19
-1
@@ -217,6 +217,7 @@ function buildEq(freqs) {
|
||||
v.textContent = val === 0 ? "" : (val > 0 ? "+" : "") + val.toFixed(1);
|
||||
gains[i] = val;
|
||||
commitEq();
|
||||
markPreset(null); // 手动改过就不是任何预设了
|
||||
});
|
||||
bindWheel(input, (val) => { input.value = val; input.dispatchEvent(new Event("input")); });
|
||||
input.addEventListener("dblclick", () => { input.value = 0; input.dispatchEvent(new Event("input")); });
|
||||
@@ -238,6 +239,14 @@ const PRESETS = {
|
||||
"高音": [[200, -1], [2000, 1], [6000, 4], [14000, 6]],
|
||||
"深夜": [[60, 4], [200, 3], [1000, 0], [4000, 1], [12000, 3]], // 小音量等响度补偿
|
||||
"柔化": [[3000, -2], [6000, -4], [12000, -5], [16000, -3]], // 削刺耳高频
|
||||
// 影院: 高频按 X-curve(ISO 2969 国际版, 2 kHz 以上约 -1.5 dB/oct; 北美 SMPTE 是 -3),
|
||||
// 再叠一层银幕透声损失(4~10 kHz); 低频是影院 sub / LFE 通道的体感 -- 厚, 暗, 有力.
|
||||
"电影院": [[25, 2.5], [60, 3], [150, 0.5], [400, -0.5], [1000, 0],
|
||||
[2000, -0.5], [4000, -2], [8000, -3.5], [16000, -5], [25000, -5.5]],
|
||||
// 歌剧院: 木质厅堂的温暖落在 150~400 Hz; 歌手不用麦, 全靠 2~5 kHz 的 presence 投射,
|
||||
// 所以这里要抬不能削; 大空间的空气吸收只削极高频 -- 暖, 亮, 有细节, 没有 sub 轰鸣.
|
||||
"歌剧院": [[30, -1], [80, 0.5], [160, 2], [300, 2], [700, 1], [1500, 0],
|
||||
[3000, 1], [5000, 1], [9000, 0], [16000, -1.5], [25000, -2]],
|
||||
};
|
||||
function curveTo(pts, freqs) {
|
||||
if (!pts.length) return freqs.map(() => 0);
|
||||
@@ -266,8 +275,17 @@ function applyPreset(name) {
|
||||
v.textContent = vals[i] === 0 ? "" : (vals[i] > 0 ? "+" : "") + vals[i].toFixed(1);
|
||||
});
|
||||
commitEq();
|
||||
markPreset(name);
|
||||
say("EQ 预设: " + name);
|
||||
}
|
||||
/* 点了哪个预设要看得见(不然选没选中没反馈); 手动改滑块即取消高亮。 */
|
||||
function markPreset(name) {
|
||||
const box = el("presets");
|
||||
if (!box) return;
|
||||
box.querySelectorAll("button").forEach((b) => {
|
||||
b.classList.toggle("on", name !== null && b.textContent === name);
|
||||
});
|
||||
}
|
||||
function buildPresets() {
|
||||
const box = el("presets");
|
||||
box.innerHTML = "";
|
||||
@@ -357,7 +375,7 @@ function applyState(d) {
|
||||
updateLoud(d.loudness_levels);
|
||||
state = d;
|
||||
}
|
||||
el("flat").addEventListener("click", () => { gains = new Array(32).fill(0); commitEq(); buildEq(state ? state.freqs : []); });
|
||||
el("flat").addEventListener("click", () => { gains = new Array(32).fill(0); commitEq(); markPreset("平直"); buildEq(state ? state.freqs : []); });
|
||||
el("reset").addEventListener("click", () => { state = null; fetch("/api/state").then(r => r.json()).then(applyState).catch(() => say("面板与 DSP 失联")); });
|
||||
fetch("/api/state").then(r => r.json()).then(applyState).catch(() => say("面板与 DSP 失联"));
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user