Skip to content

Instantly share code, notes, and snippets.

@git58
Last active February 2, 2026 12:46
Show Gist options
  • Select an option

  • Save git58/a679486ca253b0032025cc8c74770e9f to your computer and use it in GitHub Desktop.

Select an option

Save git58/a679486ca253b0032025cc8c74770e9f to your computer and use it in GitHub Desktop.
Fix viper4android on Manjaro KDE Plasma 6 (PipeWire)
#!/bin/bash
###############################################################################
# Viper4Linux Auto-Routing Supervisor Script
# ------------------------------------------
# This script performs three major tasks:
# 1. Creates and initializes the Viper4Linux audio processing pipeline.
# 2. Periodically monitors PipeWire routing and configuration changes.
# 3. Automatically restores correct audio links if PipeWire breaks them.
#
# The script is intended to run from KDE autostart without opening a terminal.
###############################################################################
# Short initial delay to allow PipeWire and PulseAudio compatibility layer to start.
sleep 2
###############################################################################
# 1. Ensure the virtual sink "viper" exists
###############################################################################
# Check if a sink named "viper" already exists.
# If not, create a null-sink that will act as the input for ViperFX.
if ! pactl list short sinks | grep -q "viper"; then
pactl load-module module-null-sink \
sink_name=viper \
sink_properties=device.description="Viper4Linux"
fi
# Set the newly created sink as the default sink and source.
# This reduces the chance of PipeWire auto-routing audio elsewhere.
pactl set-default-sink viper
pactl set-default-source viper.monitor
###############################################################################
# 2. Wait until the monitor source appears
###############################################################################
# PipeWire may take some time to register "viper.monitor".
# We wait until it becomes available before launching the processing pipeline.
while ! pactl list short sources | grep -q "viper.monitor"; do
sleep 0.2
done
###############################################################################
# 3. Kill any old gst-launch processes to avoid duplicates
###############################################################################
killall -9 gst-launch-1.0 2>/dev/null
###############################################################################
# 4. Load ViperFX parameters from config file
###############################################################################
CONFIG_FILE="$HOME/.config/viper4linux/audio.conf"
# If the config file exists, normalize whitespace and convert it into a single line.
# Example: "vb-gain = 800" → "vb-gain=800"
if [ -f "$CONFIG_FILE" ]; then
VIPER_PARAMS=$(sed -e 's/[[:space:]]*=[[:space:]]*/=/g' "$CONFIG_FILE" | tr '\n' ' ')
else
# Fallback parameters if no config file is found.
VIPER_PARAMS="fx-enable=true vb-enable=true vb-gain=800"
fi
###############################################################################
# 5. Start the audio processing pipeline
###############################################################################
# Launch gst-launch in the background:
# - pulsesrc reads from viper.monitor
# - viperfx applies audio effects
# - pulsesink outputs to the real hardware device
gst-launch-1.0 \
pulsesrc device=viper.monitor ! \
viperfx $VIPER_PARAMS ! \
pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" &
# Give gst-launch time to initialize its node in PipeWire.
sleep 1
###############################################################################
# 6. Function to restore correct PipeWire links
###############################################################################
restore_links() {
# This function re-establishes the correct audio routing.
# It is safe to call repeatedly; PipeWire will ignore duplicate links.
pw-link viper.monitor:monitor_FL viperfx:input_FL
pw-link viper.monitor:monitor_FR viperfx:input_FR
pw-link viperfx:output_FL alsa_output.pci-0000_00_1f.3.analog-stereo:playback_FL
pw-link viperfx:output_FR alsa_output.pci-0000_00_1f.3.analog-stereo:playback_FR
}
# Initial link restoration
restore_links
###############################################################################
# 7. Start the GUI
###############################################################################
# Launch the Viper4Linux GUI in the background.
viper4linux-gui &
###############################################################################
# 8. Background monitoring loop
###############################################################################
# This loop runs forever in the background and periodically checks:
# - Whether gst-launch is still running.
# - Whether the config file has changed.
# - Whether PipeWire links are still correct.
# - Whether viper.monitor still exists.
#
# If anything is wrong, the script automatically repairs it.
###############################################################################
# Save initial config checksum to detect changes.
LAST_CONF_HASH=$(md5sum "$CONFIG_FILE" 2>/dev/null | awk '{print $1}')
(
while true; do
###########################################################################
# Check if gst-launch is still running
###########################################################################
if ! pgrep -x "gst-launch-1.0" >/dev/null; then
# Restart the pipeline if it crashed or was killed.
gst-launch-1.0 \
pulsesrc device=viper.monitor ! \
viperfx $VIPER_PARAMS ! \
pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" &
sleep 1
restore_links
fi
###########################################################################
# Check if the config file has changed
###########################################################################
CURRENT_HASH=$(md5sum "$CONFIG_FILE" 2>/dev/null | awk '{print $1}')
if [ "$CURRENT_HASH" != "$LAST_CONF_HASH" ]; then
# Reload parameters and restart gst-launch with new settings.
LAST_CONF_HASH="$CURRENT_HASH"
killall -9 gst-launch-1.0 2>/dev/null
VIPER_PARAMS=$(sed -e 's/[[:space:]]*=[[:space:]]*/=/g' "$CONFIG_FILE" | tr '\n' ' ')
gst-launch-1.0 \
pulsesrc device=viper.monitor ! \
viperfx $VIPER_PARAMS ! \
pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" &
sleep 1
restore_links
fi
###########################################################################
# Check if PipeWire links are still correct
###########################################################################
# If any link is missing, restore all links.
if ! pw-link -l | grep -q "viper.monitor:monitor_FL.*viperfx:input_FL"; then restore_links; fi
if ! pw-link -l | grep -q "viperfx:output_FL.*analog-stereo:playback_FL"; then restore_links; fi
###########################################################################
# Check if viper.monitor still exists
###########################################################################
if ! pactl list short sources | grep -q "viper.monitor"; then
# Recreate the sink if PipeWire removed it.
pactl load-module module-null-sink \
sink_name=viper \
sink_properties=device.description="Viper4Linux"
pactl set-default-sink viper
pactl set-default-source viper.monitor
sleep 1
restore_links
fi
###########################################################################
# Sleep before next check
###########################################################################
sleep 3
done
) &
# End of script
@git58
Copy link
Author

git58 commented Feb 2, 2026

Фото схем со сломанным и рабочим соединением аудио

↓↓↓ Анализатор звукового тракта Helvum - звука нет ↓↓↓
helvum_bad

↓↓↓ Анализатор звукового тракта Helvum - звук есть ↓↓↓
helvum_good

↓↓↓ Анализатор звукового тракта qpwgraph - звука нет ↓↓↓
qpwgraph_bad

↓↓↓ Анализатор звукового тракта qpwgraph - звук есть ↓↓↓
qpwgraph_good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment