-
-
Save git58/a679486ca253b0032025cc8c74770e9f to your computer and use it in GitHub Desktop.
| #!/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 |
В версии 1.1 баг (хотя и не критичный): похоже, что при попытке запуска Youtube видео в плеере Haruna нужно перезагружать вкладку Youtube в Edge, чтобы в браузере появился звук. Также в это время происходила установка софта через pacman (gtk-youtube-viewer)
Changelog for v1.2
Viper4Linux Auto‑Routing Supervisor Script — Документация
Общее описание
Этот скрипт является автоматическим надзорным механизмом для аудиопайплайна Viper4Linux, работающего поверх PipeWire. Его задача — обеспечить стабильную работу цепочки:
Приложения → viper (null-sink) → viper.monitor → gst-launch → viperfx → ALSA
PipeWire иногда нарушает маршрутизацию, пересоздаёт узлы или сбрасывает соединения. Скрипт предотвращает такие сбои, автоматически восстанавливая корректные связи и перезапуская аудиопроцессинг при необходимости.
Скрипт предназначен для автозапуска в KDE Plasma и работает полностью в фоне, без открытия терминала.
Основные функции скрипта
1. Создание и инициализация виртуального sink viper
Скрипт проверяет, существует ли виртуальный sink с именем viper.
Если нет — создаёт его через module-null-sink.
Этот sink служит входной точкой для ViperFX.
Также скрипт устанавливает:
viperкак default sinkviper.monitorкак default source
Это уменьшает вероятность того, что PipeWire переназначит маршруты.
2. Ожидание появления viper.monitor
PipeWire может задерживать регистрацию монитор‑источника.
Скрипт ждёт, пока viper.monitor не появится, прежде чем запускать обработку звука.
3. Удаление старых процессов gst-launch
Перед запуском новой цепочки скрипт убивает все старые экземпляры gst-launch-1.0, чтобы избежать дублирования потоков.
4. Загрузка параметров ViperFX
Скрипт читает конфигурационный файл:
~/.config/viper4linux/audio.conf
и преобразует строки вида:
vb-gain = 800
в формат:
vb-gain=800
Если конфиг отсутствует — используются параметры по умолчанию.
5. Запуск аудиопайплайна через gst-launch
Скрипт запускает следующую цепочку:
pulsesrc (viper.monitor)
→ viperfx (с параметрами из конфига)
→ pulsesink (физическое ALSA‑устройство)
Запуск выполняется в фоне.
6. Восстановление PipeWire‑соединений
Функция restore_links() создаёт необходимые соединения:
viper.monitor→viperfxviperfx→ ALSA‑sink
PipeWire игнорирует дубликаты, поэтому функция безопасна при повторных вызовах.
7. Запуск графического интерфейса Viper4Linux
GUI запускается в фоне и не влияет на работу пайплайна.
Фоновый мониторинг (основная логика скрипта)
Скрипт запускает бесконечный цикл, который каждые 3 секунды проверяет:
1. Жив ли процесс gst-launch
Если он упал:
- запускается новый экземпляр
- восстанавливаются PipeWire‑линки
2. Изменился ли конфигурационный файл
Скрипт вычисляет MD5‑хеш файла.
Если конфиг изменился:
gst-launchперезапускается- параметры обновляются
- связи восстанавливаются
3. На месте ли PipeWire‑соединения
Если хотя бы одно соединение отсутствует — вызывается restore_links().
4. Существует ли viper.monitor
Если PipeWire удалил виртуальный sink:
- создаётся новый
viper - назначается default sink/source
- восстанавливаются связи
Поведение при сбоях
Скрипт автоматически:
- перезапускает аудиопайплайн
- восстанавливает соединения
- пересоздаёт виртуальный sink
- обновляет параметры ViperFX
- предотвращает неправильную маршрутизацию PipeWire
Он работает как самовосстанавливающийся сервис, но без systemd.
Преимущества данного решения
✔ Полностью автономен
Не требует systemd, работает из автозагрузки KDE.
✔ Самовосстанавливающийся
Любой сбой в пайплайне автоматически исправляется.
✔ Устойчив к изменениям PipeWire
PipeWire может пересоздавать узлы — скрипт это компенсирует.
✔ Минимальная задержка реакции
Проверка каждые 3 секунды.
✔ Безопасен
Не ломает существующие соединения, только восстанавливает нужные.
Когда использовать этот скрипт
Он идеально подходит для систем, где:
- PipeWire часто сбрасывает соединения
- ViperFX используется как постоянный аудиофильтр
- требуется стабильная работа null‑sink → ViperFX → ALSA
- пользователь не хочет вручную чинить граф в qpwgraph/helvum




Changelog for v1.1
Changelog — Viper4Linux Autostart Script (Enhanced Edition v1.1, относительно предыдущего и первого релиза v1.0)
[Added] Безопасный парсер конфигурации
audio.conf, который:key=value;viperfx.conv_ir_path="conv-cc-level=0") могли полностью ломать DSP‑цепочку.[Added] Проверка IR‑файла перед запуском
conv_ir_pathиз конфига.conv_enableпринудительно отключается;[Added] Watchdog для GStreamer‑пайплайна
gst-launch-1.0.Restart=always.[Improved] Управление пайплайном
start_pipeline()для чистого и повторяемого запуска.[Improved] Надёжность и отказоустойчивость
[Misc] Чистка и структурирование
[INFO],[WARN],[ERROR].