1
0
mirror of https://gitlab.com/linuxstuff/dotfiles.git synced 2026-06-19 04:06:00 +02:00

Finalized cava module integration

This commit is contained in:
Simon
2021-01-16 15:07:23 +01:00
parent c5cd41b3fd
commit 7e2f21b27d
6 changed files with 454 additions and 329 deletions
+7 -11
View File
@@ -25,9 +25,9 @@ unfocused = ${xrdb:foreground}
; Bars
[bar/floating]
;modules-right = disk_short_pc checkupdates ovpn nvpn eth_pc
modules-left = sysinfo button_pavucontrol
modules-center = cava clock playerctl_long
modules-center = cava
;modules-center = cava clock playerctl_long
modules-right = sensors_cpu_pc nvgpu memory
monitor = ${env:MONITOR:DP-4}
width = 60%
@@ -381,18 +381,9 @@ exec = ~/.config/polybar/scripts/polypopup.sh
click-left = ~/.config/polybar/scripts/polypopup.sh --toggle
content = 󰋼
[module/cava]
type = custom/script
tail = true
interval = 0.1
format = <label>
exec = bash ~/.config/polybar/scripts/modules/cava_read.sh
[module/playerctl]
type = custom/script
tail = true
format-prefix = ""
format = <label>
exec = ~/.config/polybar/scripts/modules/playerctl.sh
click-left = "playerctl play-pause"
click-right = "playerctl next"
@@ -402,6 +393,11 @@ click-middle = "playerctl previous"
inherit="module/playerctl"
exec = bash ~/.config/polybar/scripts/modules/playerctl.sh 30
[module/cava]
type = custom/script
tail = true
exec = python /home/sim/.config/polybar/scripts/modules/cava.py
[module/playerctl-buttons]
type = custom/menu
expand-right = true
+32 -14
View File
@@ -1,31 +1,49 @@
#!/bin/bash
# Kill hideit instances
######################
# Kill programs used by modules
#
# hideit
ps -ef | grep hideIt | grep -v grep | awk '{print $2}' | xargs kill
#
# cava
killall -q cava
######################
# Kill polybar instances
#
killall -q polybar
#
# Wait until the processes have been shut down
while pgrep -x polybar >/dev/null; do sleep 1; done
# Launch
polybar floating -r -l warning &
#setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^Polybar tray window$' &
######################
# Launch polybar(s)
#
polybar floating -r -l warning &
polybar floating_wm -r -l warning &
polybar floating_sysinfo -r -l warning &
polybar pc_vnc_landscape -r -l warning &
#
#polybar pc_vnc_landscape -r -l warning &
#
# Wait a moment for the bar(s) to set up
sleep 1
setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^polybar-floating_DP-4$' &
# Toggle sysinfo polybar
(xdo id -m -N Polybar && polybar-msg -p $(ps -ef | grep floating_sysinfo | grep -v grep | awk '{print $2}') cmd hide)&
######################
# Launch programs used by modules
#
setsid ~/.config/polybar/scripts/hideIt.sh --wait --region 0x1080+1920+-10 --name '^polybar-floating_DP-4$' > /dev/null 2>&1 &
#
# Hide floating_sysinfo polybar and reset popup state
(xdo id -m -N Polybar && polybar-msg -p $(ps -ef | grep floating_sysinfo | grep -v grep | awk '{print $2}') cmd hide) > /dev/null 2>&1 &
STATUSFILE="$HOME/.config/polybar/scripts/.sysinfo.active"
rm "$STATUSFILE"
rm -f "$STATUSFILE"
echo "Bar launched..."
######################
# Done!
#
echo "Bar launched!"
+158 -161
View File
@@ -15,6 +15,9 @@
######################
# Preferences
# Print verbose logs
LOGS=0
# Set if opened popups should keep the bar shown
POPUPS_PIN=1
@@ -61,7 +64,6 @@ _HAS_REGION=1
_WAIT_PID=""
_PID_FILE=""
usage() {
# Print usage
printf "usage: $0 [options]\n"
@@ -143,125 +145,124 @@ usage() {
printf " $ hideIt.sh --name '^dropdown-terminal$' --toggle\n"
}
argparse() {
# Parse system args
while [ $# -gt 0 ]; do
case $1 in
"-N"|"--name")
WIN_NAME="$2"
shift
;;
"-C"|"--class")
WIN_CLASS="$2"
shift
;;
"-I"|"--instance")
WIN_INSTANCE="$2"
shift
;;
"--id")
if [[ ! $2 =~ [0-9]+ ]]; then
printf "Invalid window id. Should be a number.\n" 1>&2
exit 1
fi
WIN_ID="$2"
shift
;;
"-w"|"--wait")
WAIT=0
;;
"-H"|"--hover")
HOVER=0
;;
"-S"|"--signal")
SIGNAL=0
;;
"-r"|"--region")
local posX posY offsetX offsetY
read posX posY offsetX offsetY <<<$(echo "$2" | \
sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p')
# Test if we have proper values by trying
# to add them all together
expr $posX + $posY + $offsetX + $offsetY > /dev/null 2>&1
if [ $? -ne 0 ]; then
printf "Invalid region. See --help for usage.\n" 1>&2
exit 1
fi
MINX=$posX
MAXX=$((${MINX} + ${offsetX}))
if [ $MINX -gt $MAXX ]; then
read MINX MAXX <<< "$MAXX $MINX"
fi
MINY=$posY
MAXY=$((${MINY} + ${offsetY}))
if [ $MINY -gt $MAXY ]; then
read MINY MAXY <<< "$MAXY $MINY"
fi
if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] \
|| [[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
printf "Missing or invalid region. See --help for usage.\n" 1>&2
exit 1
fi
_HAS_REGION=0
shift
;;
"-i"|"--interval")
INTERVAL="$2"
if [[ ! $INTERVAL =~ [0-9]+ ]]; then
printf "Interval should be a number. " 1>&2
exit 1
fi
shift
;;
"-p"|"--peek")
PEEK="$2"
if [[ ! $PEEK =~ [0-9]+ ]]; then
printf "Peek should be a number. " 1>&2
exit 1
fi
shift
;;
"-d"|"--direction")
DIRECTION="$2"
if [[ ! "$DIRECTION" =~ ^(left|right|top|bottom)$ ]]; then
printf "Invalid direction. See --help for usage.\n" 1>&2
exit 1
fi
shift
;;
"-s"|"--steps")
STEPS="$2"
if [[ ! $STEPS =~ [0-9]+ ]]; then
printf "Steps should be a number. " 1>&2
exit 1
fi
shift
;;
"-T"|"--no-trans")
NO_TRANS=0
;;
"-t"|"--toggle")
TOGGLE=0
;;
"-P"|"--toggle-peek")
TOGGLE_PEEK=0
;;
"-h"|"--help")
usage
exit 0
;;
**)
printf "Didn't understand '$1'\n" 1>&2
printf "See --help for usage.\n"
"-N" | "--name")
WIN_NAME="$2"
shift
;;
"-C" | "--class")
WIN_CLASS="$2"
shift
;;
"-I" | "--instance")
WIN_INSTANCE="$2"
shift
;;
"--id")
if [[ ! $2 =~ [0-9]+ ]]; then
printf "Invalid window id. Should be a number.\n" 1>&2
exit 1
;;
fi
WIN_ID="$2"
shift
;;
"-w" | "--wait")
WAIT=0
;;
"-H" | "--hover")
HOVER=0
;;
"-S" | "--signal")
SIGNAL=0
;;
"-r" | "--region")
local posX posY offsetX offsetY
read posX posY offsetX offsetY <<<$(echo "$2" |
sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p')
# Test if we have proper values by trying
# to add them all together
expr $posX + $posY + $offsetX + $offsetY >/dev/null 2>&1
if [ $? -ne 0 ]; then
printf "Invalid region. See --help for usage.\n" 1>&2
exit 1
fi
MINX=$posX
MAXX=$((${MINX} + ${offsetX}))
if [ $MINX -gt $MAXX ]; then
read MINX MAXX <<<"$MAXX $MINX"
fi
MINY=$posY
MAXY=$((${MINY} + ${offsetY}))
if [ $MINY -gt $MAXY ]; then
read MINY MAXY <<<"$MAXY $MINY"
fi
if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] ||
[[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
printf "Missing or invalid region. See --help for usage.\n" 1>&2
exit 1
fi
_HAS_REGION=0
shift
;;
"-i" | "--interval")
INTERVAL="$2"
if [[ ! $INTERVAL =~ [0-9]+ ]]; then
printf "Interval should be a number. " 1>&2
exit 1
fi
shift
;;
"-p" | "--peek")
PEEK="$2"
if [[ ! $PEEK =~ [0-9]+ ]]; then
printf "Peek should be a number. " 1>&2
exit 1
fi
shift
;;
"-d" | "--direction")
DIRECTION="$2"
if [[ ! "$DIRECTION" =~ ^(left|right|top|bottom)$ ]]; then
printf "Invalid direction. See --help for usage.\n" 1>&2
exit 1
fi
shift
;;
"-s" | "--steps")
STEPS="$2"
if [[ ! $STEPS =~ [0-9]+ ]]; then
printf "Steps should be a number. " 1>&2
exit 1
fi
shift
;;
"-T" | "--no-trans")
NO_TRANS=0
;;
"-t" | "--toggle")
TOGGLE=0
;;
"-P" | "--toggle-peek")
TOGGLE_PEEK=0
;;
"-h" | "--help")
usage
exit 0
;;
**)
printf "Didn't understand '$1'\n" 1>&2
printf "See --help for usage.\n"
exit 1
;;
esac
shift
done
@@ -274,8 +275,8 @@ argparse() {
exit 1
fi
if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] \
&& [ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] &&
[ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
printf "At least one of --toggle, --signal, --hover or" 1>&2
printf " --region is required!\n" 1>&2
exit 1
@@ -375,7 +376,6 @@ function fetch_screen_dimensions() {
SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
}
function fetch_window_dimensions() {
# Sets the values for the following globals unless no WIN_ID exists
# WIN_WIDTH, WIN_HEIGHT, WIN_POSX, WIN_POSY
@@ -390,18 +390,17 @@ function fetch_window_dimensions() {
WIN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
if [ ! -z "$1" ] && [ $1 -eq 0 ]; then
WIN_POSX=$(echo "$win_info" | \
WIN_POSX=$(echo "$win_info" |
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
WIN_POSY=$(echo "$win_info" | \
WIN_POSY=$(echo "$win_info" |
sed -rn 's/.*Absolute upper-left Y: +(-?[0-9]+)/\1/p')
fi
local win_info_MOVEALONG=$(xwininfo -id $WIN_ID_MOVEALONG_ONE)
WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" | \
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" |
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
}
function send_signal() {
# Send a SIGUSR1 to an active hideIt.sh instance
# if a pid file was found.
@@ -411,8 +410,8 @@ function send_signal() {
exit 1
fi
local _pid=`cat $_PID_FILE`
printf "Sending ${signal} to instance...\n"
local _pid=$(cat $_PID_FILE)
if [ ! "$LOGS" -eq 0 ]; then printf "Sending ${signal} to instance...\n"; fi
if [[ $_pid =~ [0-9]+ ]]; then
kill -${signal} $_pid
@@ -426,13 +425,13 @@ function send_signal() {
function winmove() {
#echo "WIN_ID $WIN_ID"
xdotool windowmove $WIN_ID $1 $2
2>/dev/null 1>&2 xdotool windowmove $WIN_ID $1 $2
xdotool 2>/dev/null 1>&2 windowmove $WIN_ID $1 $2
# Tray
#echo "WIN_ID_MOVEALONG_ONE $WIN_ID_MOVEALONG_ONE"
#xdotool windowmove $WIN_ID_MOVEALONG_ONE $1 $2
2>/dev/null 1>&2 xdotool windowmove $WIN_ID_MOVEALONG_ONE $WIN_POSX_MOVEALONG_ONE $(($2 + 4))
xdotool 2>/dev/null 1>&2 windowmove $WIN_ID_MOVEALONG_ONE $WIN_POSX_MOVEALONG_ONE $(($2 + 4))
}
function hide_window() {
@@ -443,7 +442,7 @@ function hide_window() {
local hide=$1
# Make sure window still exists and exit if not.
xwininfo -id $WIN_ID &> /dev/null
xwininfo -id $WIN_ID &>/dev/null
if [ $? -ne 0 ]; then
printf "Window doesn't exist anymore, exiting!\n"
exit 0
@@ -458,11 +457,11 @@ function hide_window() {
# Should bring it to the front, change workspace etc.
if [ $hide -ne 0 ]; then
# Unhide
xdotool windowactivate $WIN_ID > /dev/null 2>&1
else
xdotool windowactivate $WIN_ID >/dev/null 2>&1
else
# Hide
#while [ -f "$STATUSFILE" ]; do
# File exists
# File exists
# sleep 0.2
#done
bash ~/.config/polybar/scripts/polypopup.sh --hide
@@ -534,11 +533,10 @@ function hide_window() {
# underneath the cursor.
if [ $hide -eq 0 ]; then
eval $(xdotool getmouselocation --shell)
xdotool windowactivate $WINDOW > /dev/null 2>&1
xdotool windowactivate $WINDOW >/dev/null 2>&1
fi
}
function toggle() {
# Toggle the hidden state of the window
@@ -586,8 +584,8 @@ function serve_region() {
eval $(xdotool getmouselocation --shell)
# Test if the cursor is within the region
if [ $X -ge $MINX -a $X -le $MAXX ] \
&& [ $Y -ge $MINY -a $Y -le $MAXY ]; then
if [ $X -ge $MINX -a $X -le $MAXX ] &&
[ $Y -ge $MINY -a $Y -le $MAXY ]; then
_hide=1
else
@@ -596,19 +594,19 @@ function serve_region() {
else
_hide=0
fi
fi
# Don't hide if the cursor is still above the window
if [ $_IS_HIDDEN -ne 0 ] \
&& [ $_hide -eq 0 ] \
&& [ $WINDOW -eq $WIN_ID ]; then
if [ $_IS_HIDDEN -ne 0 ] &&
[ $_hide -eq 0 ] &&
[ $WINDOW -eq $WIN_ID ]; then
_hide=1
fi
# Only do something if necessary
if [ $_IS_HIDDEN -ne $_hide ]; then
hide_window $_hide
fi
fi
@@ -618,7 +616,6 @@ function serve_region() {
done
}
function serve_xev() {
# Wait for cursor "Enter" and "Leave" events reported by
# xev and act accordingly
@@ -634,7 +631,6 @@ function serve_xev() {
done
}
function restore() {
# Called by trap once we receive an EXIT
@@ -647,39 +643,38 @@ function restore() {
fi
if [ $_IS_HIDDEN -eq 0 ]; then
printf "Restoring original window position...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Restoring original window position...\n"; fi
hide_window 1
fi
exit 0
}
function main() {
# Entry point for hideIt
# Parse all the args!
argparse "$@"
printf "Searching window...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Searching window...\n"; fi
fetch_window_id
# If enabled, wait until a window was found.
if [ $WAIT -eq 0 ] && [[ ! $WIN_ID =~ [0-9]+ ]]; then
printf "Waiting for window"
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for window"; fi
while [[ ! $WIN_ID =~ [0-9]+ ]]; do
printf "."
fetch_window_id
sleep 1
done
printf "\n"
if [ ! "$LOGS" -eq 0 ]; then printf "\n"; fi
fi
if [[ ! $WIN_ID =~ [0-9]+ ]]; then
printf "No window found!\n" 1>&2
exit 1
else
printf "Found window with id: $WIN_ID\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Found window with id: $WIN_ID\n"; fi
fi
if [ $TOGGLE -eq 0 ]; then
@@ -692,37 +687,39 @@ function main() {
exit 0
fi
printf "Fetching window dimensions...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Fetching window dimensions...\n"; fi
fetch_window_dimensions 0
printf "Fetching screen dimensions...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Fetching screen dimensions...\n"; fi
fetch_screen_dimensions
trap restore EXIT
printf "Initially hiding window...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Initially hiding window...\n"; fi
hide_window 0
# Save our pid into a file
echo "$$" > /tmp/hideIt-${WIN_ID}.pid
echo "$$" >/tmp/hideIt-${WIN_ID}.pid
trap toggle_peek SIGUSR2
# Start observing
if [ $_HAS_REGION -eq 0 ]; then
printf "Defined region:\n"
printf " X: $MINX $MAXX\n"
printf " Y: $MINY $MAXY\n"
printf "\n"
printf "Waiting for region...\n"
if [ ! "$LOGS" -eq 0 ]; then
printf "Defined region:\n"
printf " X: $MINX $MAXX\n"
printf " Y: $MINY $MAXY\n"
printf "\n"
printf "Waiting for region...\n"
fi
serve_region &
_WAIT_PID=$!
elif [ $SIGNAL -eq 0 ]; then
printf "Waiting for SIGUSR1...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for SIGUSR1...\n"; fi
trap toggle SIGUSR1
sleep infinity &
_WAIT_PID=$!
elif [ $HOVER -eq 0 ]; then
printf "Waiting for HOVER...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for HOVER...\n"; fi
serve_xev &
_WAIT_PID=$!
fi
@@ -730,7 +727,7 @@ function main() {
if [ -n "$_WAIT_PID" ]; then
while true; do
wait "$_WAIT_PID"
printf "Received signal...\n"
if [ ! "$LOGS" -eq 0 ]; then printf "Received signal...\n"; fi
done
fi
}
+257 -131
View File
@@ -1,188 +1,314 @@
#!/usr/bin/python3
import sys
import time
import struct
import os.path
import subprocess
import configparser
from collections import defaultdict
from collections import OrderedDict
##################################################
# Config
# Decide if the output should go to STDOUT or a fifo buffer
PRINT_TO_STDOUT = False
# This script converts cava's data output into fancy little bars. These values can range from 0 to 100
# We need to distribute 9 characters ('Zero output' and all bar heights: '▁▂▃▄▅▆▇█') over this value range.
# The 'BAR_FACTOR' is used to calculator all those states and keep the code readable
# (See 'BAR_CHARACTERS')
#
BAR_FACTOR = 100 / 7
# Display no output if all bars are at level 0
# Configure resolution and style of the output here.
# The script fetches the cava output value and searches for the biggest matching key to get the character from
# (See 'BAR_FACTOR')
#
BAR_CHARACTERS = dict([
(000, ''), # Zero output
(BAR_FACTOR * 1, ''),
(BAR_FACTOR * 2, ''),
(BAR_FACTOR * 3, ''),
(BAR_FACTOR * 4, ''),
(BAR_FACTOR * 5, ''),
(BAR_FACTOR * 6, ''),
(BAR_FACTOR * 7, ''),
(100, ''), # Highest output
])
# Separator Character between bars. Can be anything
#
# Default: ' '
#
SEPARATOR = ' '
# Display no output if all bars are at minimum level (no sound output)
#
# Default: False
#
HIDE_WHEN_EMPTY = True
# Separator Character between bars
# Examples: https://www.compart.com/en/unicode/category/Zs
SEPARATOR = ''
# Specify how long this script should wait before printing another value
#
# Default: 0.0005
#
OUTPUT_DELAY = 0.0005
CONFIG_PATH = os.path.join(os.sep, "tmp","cava_polybar.config")
RAW_PIPE_OUT = os.path.join(os.sep, "tmp","cava_polybar_output.fifo")
# Specify how many times cava can report "no sound" (all values are 0) before the script detects it
#
# Default: 5
#
EMPTY_OUTPUT_THRESHOLD = 5
# Data from the cava config
RAW_PIPE_IN = os.path.join(os.sep, "tmp","cava_polybar_input.fifo")
OUTPUT_FILE = os.path.join(os.sep, "tmp","cava_polybar.out")
BARS_NUMBER = 8
OUTPUT_BIT_FORMAT = "8bit"
# If the script output should be written to a named pipe, specify the path here.
# Set to 'None' to disable FIFO output and print to STDOUT
#
# Default: None
#
# Examples:
# "/tmp/cava_polybar_output.fifo"
# os.path.join(os.sep, "tmp", "cava_polybar_output.fifo")
#
PIPE_OUT = None
# Values range from 0 to 100
# Distribute 9 states over this value range
# ▁▂▃▄▅▆▇█
bar_factor = 100 / 10
bar_characters = dict([
(0, ''),
(bar_factor * 1, ''),
(bar_factor * 2, ''),
(bar_factor * 3, ''),
(bar_factor * 4, ''),
(bar_factor * 5, ''),
(bar_factor * 6, ''),
(bar_factor * 7, ''),
(bar_factor * 8, '')
])
# Path of the temporary cava configuration used to run the cava subprocess
#
# Default: os.path.join(os.sep, "tmp", "cava_polybar.config")
#
# Examples:
# "/tmp/cava_polybar.config"
# os.path.join(os.sep, "tmp", "cava_polybar.config")
#
CAVA_CONFIG_PATH = os.path.join(os.sep, "tmp", "cava_polybar.config")
# The following data will be used in the temporary cava config
#
# FIFO input pipe for raw cava data
#
PIPE_IN = os.path.join(os.sep, "tmp", "cava_polybar_input.fifo")
# Number of bars in cava
#
# Default: 8
#
CAVA_BARS_NUMBER = 16
# Output bit format for cava.
# Can be 16bit ot 8bit, but 8 should be plenty of resolution for the default of 8 bars...
#
# Default: "8bit"
#
CAVA_BIT_FORMAT = "8bit"
##################################################
# Code begins here
bytetype, bytesize, bytenorm = ("H", 2, 65535) if (OUTPUT_BIT_FORMAT == "16bit") else ("B", 1, 255)
bytetype, bytesize, bytenorm = ("H", 2, 65535) if (
CAVA_BIT_FORMAT == "16bit") else ("B", 1, 255)
def output(value, fifo):
if (PRINT_TO_STDOUT):
print(value, end="")
def output(string, file):
"""
Print/Write the given value either to STDOUT ot the specified output pipe
Args:
string ([string]): String to print
file ([file]): [description]
"""
if (PIPE_OUT):
file.write(string)
else:
fifo.write(value)
print(string, end="")
sys.stdout.flush()
time.sleep(OUTPUT_DELAY)
def valToBar(value):
for bar_threshold in bar_characters:
def valueToCharacter(value):
"""
Returns the respective character for a value. Returns 'highest' character if no match is found
Args:
value ([int]): Value that should be mapped to a character
Returns:
[char]: Respective character for the given value
"""
for bar_threshold in BAR_CHARACTERS:
if(value < bar_threshold):
return bar_characters[bar_threshold]
return BAR_CHARACTERS[bar_threshold]
return BAR_CHARACTERS[100]
return bar_characters[bar_factor * 8]
def test():
def run():
"""
Prepare variables and run the conversion process
"""
createCavaConfig()
# Create cava subprocess
FNULL = open(os.devnull, 'w')
cavaProcess = subprocess.Popen(
["cava", "-p", CAVA_CONFIG_PATH],
stdout=FNULL,
stderr=subprocess.STDOUT
)
# Open output pipe if specified
outputPipe = None
if (PIPE_OUT):
print("The converted output can be found in " + PIPE_OUT)
if os.path.exists(PIPE_OUT):
os.remove(PIPE_OUT)
os.mkfifo(PIPE_OUT)
outputPipe = open(PIPE_OUT, "w")
# Open input pipe (raw cava data)
inputPipe = open(PIPE_IN, "rb")
exitCode = 0
try:
# Run the conversion process
convert(inputPipe, outputPipe)
except KeyboardInterrupt:
exitCode = 1
# Close output pipe if needed
if (PIPE_OUT):
outputPipe.close()
os.remove(PIPE_OUT)
# Close input pipe and kill the subprocess
inputPipe.close()
cavaProcess.kill()
sys.exit(exitCode)
def convert(inputPipe, outputPipe=None):
"""
Converts values taken from the input pipe to printable characters.
The result is either printed to STDOUT or written to the output pipe
Args:
inputPipe ([file]): Input file containing raw cava data
outputPipe ([file]): Output file (if specified)
"""
# Initialize variables
chunk = bytesize * CAVA_BARS_NUMBER
fmt = bytetype * CAVA_BARS_NUMBER
emptyOutputs = 0
# Convert
while True:
rawData = inputPipe.read(chunk)
if len(rawData) < chunk:
break
tstring = ""
emptyOutput = True
for i in struct.unpack(fmt, rawData):
value = int(i / bytenorm * 100)
if (len(tstring) > 0):
tstring += SEPARATOR
tstring += valueToCharacter(value)
if (value != 0):
emptyOutput = False
if (emptyOutput and HIDE_WHEN_EMPTY):
emptyOutputs += 1
if (emptyOutputs > EMPTY_OUTPUT_THRESHOLD):
output(" " + os.linesep, outputPipe)
else:
emptyOutputs = 0
output(tstring + os.linesep, outputPipe)
def createCavaConfig():
"""
Create the temporary configuration file used by the cava subprocess
"""
config = configparser.ConfigParser()
config.add_section('general')
config.set('general', 'bars', str(CAVA_BARS_NUMBER))
config.set('general', 'overshoot', str(0))
config.add_section('output')
config.set('output', 'method', 'raw')
config.set('output', 'channels', 'mono')
config.set('output', 'mono_option', 'average')
config.set('output', 'raw_target', PIPE_IN)
config.set('output', 'bit_format', CAVA_BIT_FORMAT)
config.add_section('smoothing')
config.set('smoothing', 'integral', '0')
with open(CAVA_CONFIG_PATH, 'w') as configfile:
config.write(configfile)
def printTestData():
"""
Prints test data to stdout. Useful for checking resolution and customisation configuration
"""
print("")
print("Bar Characters:")
for bar_threshold in bar_characters:
print('{:02.2f}: {}'.format(bar_threshold,bar_characters[bar_threshold]))
for bar_threshold in BAR_CHARACTERS:
print('{:06.2f}: {}'.format(
bar_threshold, BAR_CHARACTERS[bar_threshold]))
print("")
print("Value Test:")
for i in range(101):
print('{:03d}: {}'.format(i,valToBar(i)))
def createCavaConfig():
# Exit if file is already there
#if (os.path.isfile(CONFIG_PATH)):
# return
config = configparser.ConfigParser()
config.add_section('general')
config.set('general', 'bars', str(BARS_NUMBER))
#config.set('general', 'overshoot', str(0))
config.add_section('output')
config.set('output', 'method', 'raw')
#config.set('output', 'channels', 'mono')
#config.set('output', 'mono_option', 'average')
config.set('output', 'raw_target', RAW_PIPE_IN)
config.set('output', 'bit_format', OUTPUT_BIT_FORMAT)
#config.add_section('smoothing')
#config.set('smoothing', 'integral', '0')
with open(CONFIG_PATH, 'w') as configfile:
config.write(configfile)
def run():
createCavaConfig()
process = subprocess.Popen(["cava", "-p", CONFIG_PATH])
exit_code = 0
fifo_out = None
if (not PRINT_TO_STDOUT):
if os.path.exists(RAW_PIPE_OUT):
os.remove(RAW_PIPE_OUT)
os.mkfifo(RAW_PIPE_OUT)
print("Output can be found in " + RAW_PIPE_OUT)
fifo_out = open(RAW_PIPE_OUT, "w")
fifo_in = open(RAW_PIPE_IN, "rb")
try:
convert(fifo_in, fifo_out)
except KeyboardInterrupt:
exit_code = 1
finally:
if (not PRINT_TO_STDOUT):
fifo_out.close()
os.remove(RAW_PIPE_OUT)
fifo_in.close()
sys.exit(exit_code)
def convert(fifo_in, fifo_out):
chunk = bytesize * BARS_NUMBER
fmt = bytetype * BARS_NUMBER
emptyOutputs = 0
tstring = ""
while True:
rawData = fifo_in.read(chunk)
if len(rawData) < chunk:
break
empty = True
tstring = ""
for i in struct.unpack(fmt, rawData):
value = int(i / bytenorm * 100)
tstring += valToBar(value) + SEPARATOR
if (value != 0):
empty = False
if (empty and HIDE_WHEN_EMPTY):
emptyOutputs += 1
if (emptyOutputs > 5):
output(" " + '\n', fifo_out)
else:
emptyOutputs = 0
output(tstring + '\n', fifo_out)
print('{:03d}: {}'.format(i, valueToCharacter(i)))
if __name__ == "__main__":
# Sort the dict to ensure correct character mapping
BAR_CHARACTERS = OrderedDict(sorted(BAR_CHARACTERS.items()))
for arg in sys.argv:
if (arg == "h" or arg == "help"):
print("")
print("cava polybar parse script")
print("Converts cava raw values into characters and outputs to STDOUT or a fifo buffer")
print(
"Converts cava raw values into characters and outputs to STDOUT or a fifo buffer")
print("")
print("Adjust thresholds, characters and config directly in the script")
print("If the config file at 'CONFIG_PATH' (/tmp/cava_polybar.config) is messed up, simply delet it")
print(
"If the config file at 'CONFIG_PATH' (/tmp/cava_polybar.config) is messed up, simply delet it")
print("")
print("Arguments:")
print("<none> ... Execute normally")
print("t, test ... Run test mode (stdout only)")
print("h, help ... Show this help message and exit (stdout only)")
print("")
sys.exit()
sys.exit()
if (arg == "t" or arg == "test"):
test()
sys.exit()
printTestData()
sys.exit()
run()
@@ -1,12 +0,0 @@
#!/bin/bash
python "$HOME/.config/polybar/scripts/modules/cava.py" &
sleep 1
fifo_name="/tmp/cava_polybar_output.fifo"
while true
do
echo "$line"
done <"$fifo_name"