2026-09-19 18:06:23 +08:00
|
|
|
# Collaplex HRTF(双耳虚拟环绕)+ 房间混响 —— 本文件由 脚本/安装.sh 生成
|
|
|
|
|
# 占位符: __HRIR__ 脉冲响应目录 / __REVERB__ 房间 IR / __TARGET__ 数字输出 / __WET__ 湿量
|
|
|
|
|
# 链路: 全局音频 -> 虚拟声卡 -> 响度归一化 -> [本图] 双耳 HRTF -> 房间混响(湿量 __WET__) -> 数字输出
|
|
|
|
|
#
|
|
|
|
|
# HRTF: 左耳 = L·h(FL→L) + R·h(FR→L), 右耳 = L·h(FL→R) + R·h(FR→R)
|
|
|
|
|
# 混响: 干路直通(Gain 1 = 1.0) + 湿路经房间 IR(Gain 2 = 湿量) —— 按能量归一, 湿量 G 时湿路电平 = 干路 + 20log10(G)
|
|
|
|
|
context.modules = [
|
|
|
|
|
{ name = libpipewire-module-filter-chain
|
|
|
|
|
flags = [ nofail ]
|
|
|
|
|
args = {
|
|
|
|
|
node.description = "Collaplex HRTF (双耳虚拟环绕)"
|
|
|
|
|
media.name = "Collaplex HRTF"
|
|
|
|
|
filter.graph = {
|
|
|
|
|
nodes = [
|
|
|
|
|
{ type = builtin label = copy name = iL }
|
|
|
|
|
{ type = builtin label = copy name = iR }
|
|
|
|
|
{ type = builtin label = convolver name = cFLL config = { filename = "__HRIR__/FL_L.wav" } }
|
|
|
|
|
{ type = builtin label = convolver name = cFLR config = { filename = "__HRIR__/FL_R.wav" } }
|
|
|
|
|
{ type = builtin label = convolver name = cFRL config = { filename = "__HRIR__/FR_L.wav" } }
|
|
|
|
|
{ type = builtin label = convolver name = cFRR config = { filename = "__HRIR__/FR_R.wav" } }
|
|
|
|
|
{ type = builtin label = mixer name = hL control = { "Gain 1" = 1.0 "Gain 2" = 1.0 } }
|
|
|
|
|
{ type = builtin label = mixer name = hR control = { "Gain 1" = 1.0 "Gain 2" = 1.0 } }
|
2026-09-20 13:05:10 +08:00
|
|
|
{ type = builtin label = convolver name = revL config = { filename = "__REVERB__" channel = 0 gain = 0.61 } }
|
|
|
|
|
{ type = builtin label = convolver name = revR config = { filename = "__REVERB__" channel = 1 gain = 0.61 } }
|
2026-09-19 19:37:54 +08:00
|
|
|
{ type = builtin label = pipe name = wetgL config = { command = "__WET_WRAPPER__" } }
|
|
|
|
|
{ type = builtin label = pipe name = wetgR config = { command = "__WET_WRAPPER__" } }
|
|
|
|
|
{ type = builtin label = mixer name = wetL control = { "Gain 1" = 1.0 "Gain 2" = 1.0 } }
|
|
|
|
|
{ type = builtin label = mixer name = wetR control = { "Gain 1" = 1.0 "Gain 2" = 1.0 } }
|
2026-09-19 18:06:23 +08:00
|
|
|
]
|
|
|
|
|
links = [
|
|
|
|
|
{ output = "iL:Out" input = "cFLL:In" }
|
|
|
|
|
{ output = "iL:Out" input = "cFLR:In" }
|
|
|
|
|
{ output = "iR:Out" input = "cFRL:In" }
|
|
|
|
|
{ output = "iR:Out" input = "cFRR:In" }
|
|
|
|
|
{ output = "cFLL:Out" input = "hL:In 1" }
|
|
|
|
|
{ output = "cFRL:Out" input = "hL:In 2" }
|
|
|
|
|
{ output = "cFLR:Out" input = "hR:In 1" }
|
|
|
|
|
{ output = "cFRR:Out" input = "hR:In 2" }
|
|
|
|
|
{ output = "hL:Out" input = "wetL:In 1" }
|
|
|
|
|
{ output = "hL:Out" input = "revL:In" }
|
2026-09-19 19:37:54 +08:00
|
|
|
{ output = "revL:Out" input = "wetgL:In" }
|
|
|
|
|
{ output = "wetgL:Out" input = "wetL:In 2" }
|
2026-09-19 18:06:23 +08:00
|
|
|
{ output = "hR:Out" input = "wetR:In 1" }
|
|
|
|
|
{ output = "hR:Out" input = "revR:In" }
|
2026-09-19 19:37:54 +08:00
|
|
|
{ output = "revR:Out" input = "wetgR:In" }
|
|
|
|
|
{ output = "wetgR:Out" input = "wetR:In 2" }
|
2026-09-19 18:06:23 +08:00
|
|
|
]
|
|
|
|
|
inputs = [ "iL:In" "iR:In" ]
|
2026-09-19 18:53:18 +08:00
|
|
|
outputs = [ "wetL:Out" "wetR:Out" ]
|
2026-09-19 18:06:23 +08:00
|
|
|
}
|
|
|
|
|
capture.props = {
|
|
|
|
|
media.class = Audio/Sink
|
|
|
|
|
node.name = collaplex_hrtf_in
|
|
|
|
|
node.description = "Collaplex HRTF 接入"
|
|
|
|
|
audio.channels = 2
|
|
|
|
|
audio.position = [ FL FR ]
|
2026-09-20 12:55:51 +08:00
|
|
|
# 同 10-: 整条链都不能空闲休眠, 否则客户端会停推
|
|
|
|
|
node.always-process = true
|
|
|
|
|
node.pause-on-idle = false
|
2026-09-19 18:06:23 +08:00
|
|
|
}
|
|
|
|
|
playback.props = {
|
|
|
|
|
node.name = collaplex_hrtf_out
|
|
|
|
|
audio.channels = 2
|
|
|
|
|
audio.position = [ FL FR ]
|
2026-09-19 18:34:56 +08:00
|
|
|
node.target = "__EQ_IN__"
|
2026-09-20 12:55:51 +08:00
|
|
|
node.always-process = true
|
|
|
|
|
node.pause-on-idle = false
|
2026-09-19 18:06:23 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|