mirror of
https://github.com/ublue-os/bazzite.git
synced 2025-01-30 12:32:37 +00:00
feat(just): Update surround to use spatializer (#1838)
* feat(just): Update surround to use spatializer - Also adds instructions to identify and get a .sofa HRTF which best matches user anatomy. * chore(just): Add housekeeping steps
This commit is contained in:
parent
7f5992e3ea
commit
39fdca7bbe
@ -94,12 +94,12 @@ setup-virtual-channels ACTION="":
|
|||||||
echo "Virtual audio channels config removed, the channels will be removed next time you login."
|
echo "Virtual audio channels config removed, the channels will be removed next time you login."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Setup a simple Virtual Surround 7.1 sink using the ASH Control Room 1 convolver file (you can change this yourself after setup)
|
# Setup a virtual 7.1 surround sink for headphones using the PipeWire Spatializer module
|
||||||
setup-virtual-surround ACTION="":
|
setup-virtual-surround ACTION="":
|
||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
source /usr/lib/ujust/ujust.sh
|
source /usr/lib/ujust/ujust.sh
|
||||||
mkdir -p ~/.config/pipewire/pipewire.conf.d
|
mkdir -p ~/.config/pipewire/pipewire.conf.d
|
||||||
mkdir -p ~/.config/pipewire/hrir_hesuvi
|
mkdir -p ~/.config/pipewire/hrtf-sofa
|
||||||
OPTION={{ ACTION }}
|
OPTION={{ ACTION }}
|
||||||
if [ "$OPTION" == "help" ]; then
|
if [ "$OPTION" == "help" ]; then
|
||||||
echo "Usage: ujust setup-virtual-surround <option>"
|
echo "Usage: ujust setup-virtual-surround <option>"
|
||||||
@ -112,115 +112,185 @@ setup-virtual-surround ACTION="":
|
|||||||
OPTION=$(Choose "Enable Virtual Surround" "Disable Virtual Surround")
|
OPTION=$(Choose "Enable Virtual Surround" "Disable Virtual Surround")
|
||||||
fi
|
fi
|
||||||
if [[ "${OPTION,,}" =~ ^enable ]]; then
|
if [[ "${OPTION,,}" =~ ^enable ]]; then
|
||||||
echo "Downloading HeSuVi convolver profile Control Room 1 from https://github.com/ShanonPearce/ASH-Listening-Set"
|
echo "Downloading a sample HRTF .sofa from the Sofacoustics database..."
|
||||||
wget -O ~/.config/pipewire/hrir_hesuvi/Control_Room_1.wav https://github.com/ShanonPearce/ASH-Listening-Set/raw/main/HeSuVi/hrir/_Control_Room_1.wav
|
wget -O ~/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa https://sofacoustics.org/data/database_sofa_0.6/mit/mit_kemar_normal_pinna.sofa
|
||||||
bash -c 'cat << HESUVI > ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf
|
if [ -f ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf ]; then
|
||||||
|
mv ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf ~/.config/pipewire/virtual-surround-71.conf.bak
|
||||||
|
fi
|
||||||
|
bash -c 'cat << SPATIALIZER > ~/.config/pipewire/pipewire.conf.d/spatializer-7.1.conf
|
||||||
|
# Headphone surround sink
|
||||||
|
#
|
||||||
|
# Adjust the paths to the sofa file to match your system.
|
||||||
|
# Preferably, use absolute paths.
|
||||||
|
#
|
||||||
context.modules = [
|
context.modules = [
|
||||||
{ name = libpipewire-module-filter-chain
|
{ name = libpipewire-module-filter-chain
|
||||||
flags = [ nofail ]
|
flags = [ nofail ]
|
||||||
args = {
|
args = {
|
||||||
node.description = "Virtual Surround 7.1"
|
node.description = "Spatial Sink"
|
||||||
media.name = "Virtual Surround 7.1"
|
media.name = "Spatial Sink"
|
||||||
filter.graph = {
|
filter.graph = {
|
||||||
nodes = [
|
nodes = [
|
||||||
# Duplicate inputs
|
{
|
||||||
{ type = builtin label = copy name = copyFL }
|
type = sofa
|
||||||
{ type = builtin label = copy name = copyFR }
|
label = spatializer
|
||||||
{ type = builtin label = copy name = copyFC }
|
name = spFL
|
||||||
{ type = builtin label = copy name = copyRL }
|
config = {
|
||||||
{ type = builtin label = copy name = copyRR }
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
{ type = builtin label = copy name = copySL }
|
}
|
||||||
{ type = builtin label = copy name = copySR }
|
control = {
|
||||||
{ type = builtin label = copy name = copyLFE }
|
"Azimuth" = 30.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spFR
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 330.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spFC
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 0.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spRL
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 150.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spRR
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 210.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spSL
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 90.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spSR
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 270.0
|
||||||
|
"Elevation" = 0.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = sofa
|
||||||
|
label = spatializer
|
||||||
|
name = spLFE
|
||||||
|
config = {
|
||||||
|
filename = "$HOME/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa"
|
||||||
|
}
|
||||||
|
control = {
|
||||||
|
"Azimuth" = 0.0
|
||||||
|
"Elevation" = -60.0
|
||||||
|
"Radius" = 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Apply hrir - HeSuVi 14-channel WAV (not the *-.wav variants) (note: */44/* in HeSuVi are the same, but resampled to 44100)
|
{ type = builtin label = mixer name = mixL }
|
||||||
# The file paths HAS to be absolute paths
|
{ type = builtin label = mixer name = mixR }
|
||||||
{ type = builtin label = convolver name = convFL_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 0 } }
|
]
|
||||||
{ type = builtin label = convolver name = convFL_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 1 } }
|
links = [
|
||||||
{ type = builtin label = convolver name = convSL_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 2 } }
|
# output
|
||||||
{ type = builtin label = convolver name = convSL_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 3 } }
|
{ output = "spFL:Out L" input="mixL:In 1" }
|
||||||
{ type = builtin label = convolver name = convRL_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 4 } }
|
{ output = "spFL:Out R" input="mixR:In 1" }
|
||||||
{ type = builtin label = convolver name = convRL_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 5 } }
|
{ output = "spFR:Out L" input="mixL:In 2" }
|
||||||
{ type = builtin label = convolver name = convFC_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 6 } }
|
{ output = "spFR:Out R" input="mixR:In 2" }
|
||||||
{ type = builtin label = convolver name = convFR_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 7 } }
|
{ output = "spFC:Out L" input="mixL:In 3" }
|
||||||
{ type = builtin label = convolver name = convFR_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 8 } }
|
{ output = "spFC:Out R" input="mixR:In 3" }
|
||||||
{ type = builtin label = convolver name = convSR_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 9 } }
|
{ output = "spRL:Out L" input="mixL:In 4" }
|
||||||
{ type = builtin label = convolver name = convSR_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 10 } }
|
{ output = "spRL:Out R" input="mixR:In 4" }
|
||||||
{ type = builtin label = convolver name = convRR_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 11 } }
|
{ output = "spRR:Out L" input="mixL:In 5" }
|
||||||
{ type = builtin label = convolver name = convRR_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 12 } }
|
{ output = "spRR:Out R" input="mixR:In 5" }
|
||||||
{ type = builtin label = convolver name = convFC_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 13 } }
|
{ output = "spSL:Out L" input="mixL:In 6" }
|
||||||
|
{ output = "spSL:Out R" input="mixR:In 6" }
|
||||||
# Treat LFE as FC
|
{ output = "spSR:Out L" input="mixL:In 7" }
|
||||||
{ type = builtin label = convolver name = convLFE_L config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 6 } }
|
{ output = "spSR:Out R" input="mixR:In 7" }
|
||||||
{ type = builtin label = convolver name = convLFE_R config = { filename = "$HOME/.config/pipewire/hrir_hesuvi/Control_Room_1.wav" channel = 13 } }
|
{ output = "spLFE:Out L" input="mixL:In 8" }
|
||||||
|
{ output = "spLFE:Out R" input="mixR:In 8" }
|
||||||
# Stereo output
|
]
|
||||||
{ type = builtin label = mixer name = mixL }
|
inputs = [ "spFL:In" "spFR:In" "spFC:In" "spLFE:In" "spRL:In" "spRR:In", "spSL:In", "spSR:In" ]
|
||||||
{ type = builtin label = mixer name = mixR }
|
outputs = [ "mixL:Out" "mixR:Out" ]
|
||||||
]
|
}
|
||||||
links = [
|
capture.props = {
|
||||||
# Input
|
node.name = "effect_input.spatializer"
|
||||||
{ output = "copyFL:Out" input="convFL_L:In" }
|
media.class = Audio/Sink
|
||||||
{ output = "copyFL:Out" input="convFL_R:In" }
|
audio.channels = 8
|
||||||
{ output = "copySL:Out" input="convSL_L:In" }
|
audio.position = [ FL FR FC LFE RL RR SL SR ]
|
||||||
{ output = "copySL:Out" input="convSL_R:In" }
|
}
|
||||||
{ output = "copyRL:Out" input="convRL_L:In" }
|
playback.props = {
|
||||||
{ output = "copyRL:Out" input="convRL_R:In" }
|
node.name = "effect_output.spatializer"
|
||||||
{ output = "copyFC:Out" input="convFC_L:In" }
|
node.passive = true
|
||||||
{ output = "copyFR:Out" input="convFR_R:In" }
|
audio.channels = 2
|
||||||
{ output = "copyFR:Out" input="convFR_L:In" }
|
audio.position = [ SL SR ]
|
||||||
{ output = "copySR:Out" input="convSR_R:In" }
|
}
|
||||||
{ output = "copySR:Out" input="convSR_L:In" }
|
}
|
||||||
{ output = "copyRR:Out" input="convRR_R:In" }
|
}
|
||||||
{ output = "copyRR:Out" input="convRR_L:In" }
|
|
||||||
{ output = "copyFC:Out" input="convFC_R:In" }
|
|
||||||
{ output = "copyLFE:Out" input="convLFE_L:In" }
|
|
||||||
{ output = "copyLFE:Out" input="convLFE_R:In" }
|
|
||||||
|
|
||||||
# Output
|
|
||||||
{ output = "convFL_L:Out" input="mixL:In 1" }
|
|
||||||
{ output = "convFL_R:Out" input="mixR:In 1" }
|
|
||||||
{ output = "convSL_L:Out" input="mixL:In 2" }
|
|
||||||
{ output = "convSL_R:Out" input="mixR:In 2" }
|
|
||||||
{ output = "convRL_L:Out" input="mixL:In 3" }
|
|
||||||
{ output = "convRL_R:Out" input="mixR:In 3" }
|
|
||||||
{ output = "convFC_L:Out" input="mixL:In 4" }
|
|
||||||
{ output = "convFC_R:Out" input="mixR:In 4" }
|
|
||||||
{ output = "convFR_R:Out" input="mixR:In 5" }
|
|
||||||
{ output = "convFR_L:Out" input="mixL:In 5" }
|
|
||||||
{ output = "convSR_R:Out" input="mixR:In 6" }
|
|
||||||
{ output = "convSR_L:Out" input="mixL:In 6" }
|
|
||||||
{ output = "convRR_R:Out" input="mixR:In 7" }
|
|
||||||
{ output = "convRR_L:Out" input="mixL:In 7" }
|
|
||||||
{ output = "convLFE_R:Out" input="mixR:In 8" }
|
|
||||||
{ output = "convLFE_L:Out" input="mixL:In 8" }
|
|
||||||
]
|
|
||||||
inputs = [ "copyFL:In" "copyFR:In" "copyFC:In" "copyLFE:In" "copyRL:In" "copyRR:In", "copySL:In", "copySR:In" ]
|
|
||||||
outputs = [ "mixL:Out" "mixR:Out" ]
|
|
||||||
}
|
|
||||||
capture.props = {
|
|
||||||
node.name = "effect_input.virtual-surround-7.1-hesuvi"
|
|
||||||
media.class = Audio/Sink
|
|
||||||
audio.channels = 8
|
|
||||||
audio.position = [ FL FR FC LFE RL RR SL SR ]
|
|
||||||
}
|
|
||||||
playback.props = {
|
|
||||||
node.name = "effect_output.virtual-surround-7.1-hesuvi"
|
|
||||||
node.passive = true
|
|
||||||
audio.channels = 2
|
|
||||||
audio.position = [ FL FR ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
HESUVI'
|
SPATIALIZER'
|
||||||
echo "Virtual Surround 7.1 has now been set up with a basic convolver file, either restart pipewire or reboot for it to take effect."
|
echo ""
|
||||||
echo "Then select the Virtual Surround 7.1 audio output as your default audio output."
|
echo "Virtual surround has now been set up with a sample HRTF file; either restart PipeWire or reboot for it to take effect. If not using EasyEffects, you'll need to select Spatial Sink as your default audio output for it to work."
|
||||||
echo "If you want something like DTS, Atmos or OpenAL, you will have to acquire those convolver wav files yourself and edit ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf to point to the one you want to use."
|
echo ""
|
||||||
|
echo "${bold}IMPORTANT:${normal}"
|
||||||
|
echo "${bold}1.${normal} See https://youtu.be/VCXQp7swp5k for a demonstration of various HRTFs to find one that best matches your anatomy. Do note that correcting your headphones' response curve beforehand with something like https://autoeq.app/ is also recommended;"
|
||||||
|
echo "${bold}2.${normal} Once you find an HRTF that suits you, you may download it from https://sofacoustics.org/data/database_sofa_0.6/;"
|
||||||
|
echo "${bold}3.${normal} Then, open ~/.config/pipewire/pipewire.conf.d/spatializer-7.1.conf with a text editor, and replace the paths to the sample file with the path to yours."
|
||||||
elif [[ "${OPTION,,}" =~ ^disable ]]; then
|
elif [[ "${OPTION,,}" =~ ^disable ]]; then
|
||||||
rm ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf
|
if [ -f ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf ]; then
|
||||||
rm ~/.config/pipewire/hrir_hesuvi/Control_Room_1.wav
|
rm ~/.config/pipewire/pipewire.conf.d/virtual-surround-71.conf
|
||||||
echo "Virtual Surround 7.1 removed, please reboot or restart pipewire for it to take effect."
|
fi
|
||||||
|
rm ~/.config/pipewire/pipewire.conf.d/spatializer-7.1.conf
|
||||||
|
rm ~/.config/pipewire/hrtf-sofa/mit_kemar_normal_pinna.sofa
|
||||||
|
echo "Surround configuration file and sample .sofa removed, please reboot or restart PipeWire for changes to take effect."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Restart pipewire
|
# Restart pipewire
|
||||||
|
Loading…
x
Reference in New Issue
Block a user