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 ; Bars
[bar/floating] [bar/floating]
;modules-right = disk_short_pc checkupdates ovpn nvpn eth_pc
modules-left = sysinfo button_pavucontrol 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 modules-right = sensors_cpu_pc nvgpu memory
monitor = ${env:MONITOR:DP-4} monitor = ${env:MONITOR:DP-4}
width = 60% width = 60%
@@ -381,18 +381,9 @@ exec = ~/.config/polybar/scripts/polypopup.sh
click-left = ~/.config/polybar/scripts/polypopup.sh --toggle click-left = ~/.config/polybar/scripts/polypopup.sh --toggle
content = 󰋼 content = 󰋼
[module/cava]
type = custom/script
tail = true
interval = 0.1
format = <label>
exec = bash ~/.config/polybar/scripts/modules/cava_read.sh
[module/playerctl] [module/playerctl]
type = custom/script type = custom/script
tail = true tail = true
format-prefix = ""
format = <label>
exec = ~/.config/polybar/scripts/modules/playerctl.sh exec = ~/.config/polybar/scripts/modules/playerctl.sh
click-left = "playerctl play-pause" click-left = "playerctl play-pause"
click-right = "playerctl next" click-right = "playerctl next"
@@ -402,6 +393,11 @@ click-middle = "playerctl previous"
inherit="module/playerctl" inherit="module/playerctl"
exec = bash ~/.config/polybar/scripts/modules/playerctl.sh 30 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] [module/playerctl-buttons]
type = custom/menu type = custom/menu
expand-right = true expand-right = true
+32 -14
View File
@@ -1,31 +1,49 @@
#!/bin/bash #!/bin/bash
# Kill hideit instances ######################
# Kill programs used by modules
#
# hideit
ps -ef | grep hideIt | grep -v grep | awk '{print $2}' | xargs kill ps -ef | grep hideIt | grep -v grep | awk '{print $2}' | xargs kill
#
# cava
killall -q cava
######################
# Kill polybar instances # Kill polybar instances
#
killall -q polybar killall -q polybar
#
# Wait until the processes have been shut down # Wait until the processes have been shut down
while pgrep -x polybar >/dev/null; do sleep 1; done 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_wm -r -l warning &
polybar floating_sysinfo -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 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" STATUSFILE="$HOME/.config/polybar/scripts/.sysinfo.active"
rm "$STATUSFILE" rm -f "$STATUSFILE"
echo "Bar launched..."
######################
# Done!
#
echo "Bar launched!"
+33 -36
View File
@@ -15,6 +15,9 @@
###################### ######################
# Preferences # Preferences
# Print verbose logs
LOGS=0
# Set if opened popups should keep the bar shown # Set if opened popups should keep the bar shown
POPUPS_PIN=1 POPUPS_PIN=1
@@ -61,7 +64,6 @@ _HAS_REGION=1
_WAIT_PID="" _WAIT_PID=""
_PID_FILE="" _PID_FILE=""
usage() { usage() {
# Print usage # Print usage
printf "usage: $0 [options]\n" printf "usage: $0 [options]\n"
@@ -143,7 +145,6 @@ usage() {
printf " $ hideIt.sh --name '^dropdown-terminal$' --toggle\n" printf " $ hideIt.sh --name '^dropdown-terminal$' --toggle\n"
} }
argparse() { argparse() {
# Parse system args # Parse system args
@@ -181,7 +182,7 @@ argparse() {
;; ;;
"-r" | "--region") "-r" | "--region")
local posX posY offsetX offsetY local posX posY offsetX offsetY
read posX posY offsetX offsetY <<<$(echo "$2" | \ read posX posY offsetX offsetY <<<$(echo "$2" |
sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p') 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 # Test if we have proper values by trying
@@ -204,8 +205,8 @@ argparse() {
read MINY MAXY <<<"$MAXY $MINY" read MINY MAXY <<<"$MAXY $MINY"
fi fi
if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] \ if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] ||
|| [[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then [[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
printf "Missing or invalid region. See --help for usage.\n" 1>&2 printf "Missing or invalid region. See --help for usage.\n" 1>&2
exit 1 exit 1
fi fi
@@ -274,8 +275,8 @@ argparse() {
exit 1 exit 1
fi fi
if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] \ if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] &&
&& [ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then [ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
printf "At least one of --toggle, --signal, --hover or" 1>&2 printf "At least one of --toggle, --signal, --hover or" 1>&2
printf " --region is required!\n" 1>&2 printf " --region is required!\n" 1>&2
exit 1 exit 1
@@ -375,7 +376,6 @@ function fetch_screen_dimensions() {
SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p') SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
} }
function fetch_window_dimensions() { function fetch_window_dimensions() {
# Sets the values for the following globals unless no WIN_ID exists # Sets the values for the following globals unless no WIN_ID exists
# WIN_WIDTH, WIN_HEIGHT, WIN_POSX, WIN_POSY # 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') WIN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
if [ ! -z "$1" ] && [ $1 -eq 0 ]; then 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') 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') sed -rn 's/.*Absolute upper-left Y: +(-?[0-9]+)/\1/p')
fi fi
local win_info_MOVEALONG=$(xwininfo -id $WIN_ID_MOVEALONG_ONE) local win_info_MOVEALONG=$(xwininfo -id $WIN_ID_MOVEALONG_ONE)
WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" | \ WIN_POSX_MOVEALONG_ONE=$(echo "$win_info_MOVEALONG" |
sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p') sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
} }
function send_signal() { function send_signal() {
# Send a SIGUSR1 to an active hideIt.sh instance # Send a SIGUSR1 to an active hideIt.sh instance
# if a pid file was found. # if a pid file was found.
@@ -411,8 +410,8 @@ function send_signal() {
exit 1 exit 1
fi fi
local _pid=`cat $_PID_FILE` local _pid=$(cat $_PID_FILE)
printf "Sending ${signal} to instance...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Sending ${signal} to instance...\n"; fi
if [[ $_pid =~ [0-9]+ ]]; then if [[ $_pid =~ [0-9]+ ]]; then
kill -${signal} $_pid kill -${signal} $_pid
@@ -426,12 +425,12 @@ function send_signal() {
function winmove() { function winmove() {
#echo "WIN_ID $WIN_ID" #echo "WIN_ID $WIN_ID"
xdotool windowmove $WIN_ID $1 $2 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 # Tray
#echo "WIN_ID_MOVEALONG_ONE $WIN_ID_MOVEALONG_ONE" #echo "WIN_ID_MOVEALONG_ONE $WIN_ID_MOVEALONG_ONE"
#xdotool windowmove $WIN_ID_MOVEALONG_ONE $1 $2 #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))
} }
@@ -538,7 +537,6 @@ function hide_window() {
fi fi
} }
function toggle() { function toggle() {
# Toggle the hidden state of the window # Toggle the hidden state of the window
@@ -586,8 +584,8 @@ function serve_region() {
eval $(xdotool getmouselocation --shell) eval $(xdotool getmouselocation --shell)
# Test if the cursor is within the region # Test if the cursor is within the region
if [ $X -ge $MINX -a $X -le $MAXX ] \ if [ $X -ge $MINX -a $X -le $MAXX ] &&
&& [ $Y -ge $MINY -a $Y -le $MAXY ]; then [ $Y -ge $MINY -a $Y -le $MAXY ]; then
_hide=1 _hide=1
else else
@@ -600,9 +598,9 @@ function serve_region() {
fi fi
# Don't hide if the cursor is still above the window # Don't hide if the cursor is still above the window
if [ $_IS_HIDDEN -ne 0 ] \ if [ $_IS_HIDDEN -ne 0 ] &&
&& [ $_hide -eq 0 ] \ [ $_hide -eq 0 ] &&
&& [ $WINDOW -eq $WIN_ID ]; then [ $WINDOW -eq $WIN_ID ]; then
_hide=1 _hide=1
fi fi
@@ -618,7 +616,6 @@ function serve_region() {
done done
} }
function serve_xev() { function serve_xev() {
# Wait for cursor "Enter" and "Leave" events reported by # Wait for cursor "Enter" and "Leave" events reported by
# xev and act accordingly # xev and act accordingly
@@ -634,7 +631,6 @@ function serve_xev() {
done done
} }
function restore() { function restore() {
# Called by trap once we receive an EXIT # Called by trap once we receive an EXIT
@@ -647,39 +643,38 @@ function restore() {
fi fi
if [ $_IS_HIDDEN -eq 0 ]; then 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 hide_window 1
fi fi
exit 0 exit 0
} }
function main() { function main() {
# Entry point for hideIt # Entry point for hideIt
# Parse all the args! # Parse all the args!
argparse "$@" argparse "$@"
printf "Searching window...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Searching window...\n"; fi
fetch_window_id fetch_window_id
# If enabled, wait until a window was found. # If enabled, wait until a window was found.
if [ $WAIT -eq 0 ] && [[ ! $WIN_ID =~ [0-9]+ ]]; then 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 while [[ ! $WIN_ID =~ [0-9]+ ]]; do
printf "." printf "."
fetch_window_id fetch_window_id
sleep 1 sleep 1
done done
printf "\n" if [ ! "$LOGS" -eq 0 ]; then printf "\n"; fi
fi fi
if [[ ! $WIN_ID =~ [0-9]+ ]]; then if [[ ! $WIN_ID =~ [0-9]+ ]]; then
printf "No window found!\n" 1>&2 printf "No window found!\n" 1>&2
exit 1 exit 1
else else
printf "Found window with id: $WIN_ID\n" if [ ! "$LOGS" -eq 0 ]; then printf "Found window with id: $WIN_ID\n"; fi
fi fi
if [ $TOGGLE -eq 0 ]; then if [ $TOGGLE -eq 0 ]; then
@@ -692,15 +687,15 @@ function main() {
exit 0 exit 0
fi fi
printf "Fetching window dimensions...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Fetching window dimensions...\n"; fi
fetch_window_dimensions 0 fetch_window_dimensions 0
printf "Fetching screen dimensions...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Fetching screen dimensions...\n"; fi
fetch_screen_dimensions fetch_screen_dimensions
trap restore EXIT trap restore EXIT
printf "Initially hiding window...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Initially hiding window...\n"; fi
hide_window 0 hide_window 0
# Save our pid into a file # Save our pid into a file
@@ -709,20 +704,22 @@ function main() {
# Start observing # Start observing
if [ $_HAS_REGION -eq 0 ]; then if [ $_HAS_REGION -eq 0 ]; then
if [ ! "$LOGS" -eq 0 ]; then
printf "Defined region:\n" printf "Defined region:\n"
printf " X: $MINX $MAXX\n" printf " X: $MINX $MAXX\n"
printf " Y: $MINY $MAXY\n" printf " Y: $MINY $MAXY\n"
printf "\n" printf "\n"
printf "Waiting for region...\n" printf "Waiting for region...\n"
fi
serve_region & serve_region &
_WAIT_PID=$! _WAIT_PID=$!
elif [ $SIGNAL -eq 0 ]; then elif [ $SIGNAL -eq 0 ]; then
printf "Waiting for SIGUSR1...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for SIGUSR1...\n"; fi
trap toggle SIGUSR1 trap toggle SIGUSR1
sleep infinity & sleep infinity &
_WAIT_PID=$! _WAIT_PID=$!
elif [ $HOVER -eq 0 ]; then elif [ $HOVER -eq 0 ]; then
printf "Waiting for HOVER...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Waiting for HOVER...\n"; fi
serve_xev & serve_xev &
_WAIT_PID=$! _WAIT_PID=$!
fi fi
@@ -730,7 +727,7 @@ function main() {
if [ -n "$_WAIT_PID" ]; then if [ -n "$_WAIT_PID" ]; then
while true; do while true; do
wait "$_WAIT_PID" wait "$_WAIT_PID"
printf "Received signal...\n" if [ ! "$LOGS" -eq 0 ]; then printf "Received signal...\n"; fi
done done
fi fi
} }
+255 -129
View File
@@ -1,178 +1,304 @@
#!/usr/bin/python3 #!/usr/bin/python3
import sys import sys
import time import time
import struct import struct
import os.path import os.path
import subprocess import subprocess
import configparser import configparser
from collections import defaultdict
from collections import OrderedDict
################################################## ##################################################
# Config # Config
# Decide if the output should go to STDOUT or a fifo buffer # This script converts cava's data output into fancy little bars. These values can range from 0 to 100
PRINT_TO_STDOUT = False # 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.
HIDE_WHEN_EMPTY = True # 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
# Separator Character between bars (BAR_FACTOR * 1, ''),
# Examples: https://www.compart.com/en/unicode/category/Zs (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 = ' ' SEPARATOR = ' '
CONFIG_PATH = os.path.join(os.sep, "tmp","cava_polybar.config") # Display no output if all bars are at minimum level (no sound output)
RAW_PIPE_OUT = os.path.join(os.sep, "tmp","cava_polybar_output.fifo") #
# Default: False
#
HIDE_WHEN_EMPTY = True
# Data from the cava config # Specify how long this script should wait before printing another value
RAW_PIPE_IN = os.path.join(os.sep, "tmp","cava_polybar_input.fifo") #
OUTPUT_FILE = os.path.join(os.sep, "tmp","cava_polybar.out") # Default: 0.0005
BARS_NUMBER = 8 #
OUTPUT_BIT_FORMAT = "8bit" OUTPUT_DELAY = 0.0005
# Values range from 0 to 100 # Specify how many times cava can report "no sound" (all values are 0) before the script detects it
# Distribute 9 states over this value range #
# ▁▂▃▄▅▆▇█ # Default: 5
#
EMPTY_OUTPUT_THRESHOLD = 5
bar_factor = 100 / 10 # If the script output should be written to a named pipe, specify the path here.
bar_characters = dict([ # Set to 'None' to disable FIFO output and print to STDOUT
(0, ''), #
(bar_factor * 1, ''), # Default: None
(bar_factor * 2, ''), #
(bar_factor * 3, ''), # Examples:
(bar_factor * 4, ''), # "/tmp/cava_polybar_output.fifo"
(bar_factor * 5, ''), # os.path.join(os.sep, "tmp", "cava_polybar_output.fifo")
(bar_factor * 6, ''), #
(bar_factor * 7, ''), PIPE_OUT = None
(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 # 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): def output(string, file):
print(value, end="") """
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: else:
fifo.write(value) print(string, end="")
sys.stdout.flush()
time.sleep(OUTPUT_DELAY)
def valToBar(value): def valueToCharacter(value):
for bar_threshold in bar_characters: """
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): 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("")
print("Bar Characters:") print("Bar Characters:")
for bar_threshold in bar_characters: for bar_threshold in BAR_CHARACTERS:
print('{:02.2f}: {}'.format(bar_threshold,bar_characters[bar_threshold])) print('{:06.2f}: {}'.format(
bar_threshold, BAR_CHARACTERS[bar_threshold]))
print("") print("")
print("Value Test:") print("Value Test:")
for i in range(101): for i in range(101):
print('{:03d}: {}'.format(i,valToBar(i))) print('{:03d}: {}'.format(i, valueToCharacter(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)
if __name__ == "__main__": if __name__ == "__main__":
# Sort the dict to ensure correct character mapping
BAR_CHARACTERS = OrderedDict(sorted(BAR_CHARACTERS.items()))
for arg in sys.argv: for arg in sys.argv:
if (arg == "h" or arg == "help"): if (arg == "h" or arg == "help"):
print("") print("")
print("cava polybar parse script") 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("")
print("Adjust thresholds, characters and config directly in the script") 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("")
print("Arguments:") print("Arguments:")
print("<none> ... Execute normally") print("<none> ... Execute normally")
@@ -182,7 +308,7 @@ if __name__ == "__main__":
sys.exit() sys.exit()
if (arg == "t" or arg == "test"): if (arg == "t" or arg == "test"):
test() printTestData()
sys.exit() sys.exit()
run() 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"