improve config for cava and add base for equalizer. It works but needs some performance fixes

This commit is contained in:
Sem
2026-04-18 00:06:45 +02:00
parent 7bcd3220dd
commit 24b0c41ffb
7 changed files with 466 additions and 49 deletions

View File

@@ -11,21 +11,21 @@
; mode = normal
# Accepts only non-negative values.
; framerate = 60
framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
# new as of 0.6.0 autosens of low values (dynamic range)
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0
; autosens = 1
autosens = 1
; overshoot = 20
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
sensitivity = 40
# The number of bars (0-512). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
bars = 64
bars = 32
; bar_width = 2
; bar_spacing = 1
# bar_height is only used for output in "noritake" format
@@ -40,7 +40,7 @@ bars = 64
; bar_spacing = 0
# ceter bars in terminal, if there is space.
; center_align = 1
center_align = 0
# max height of bars in terminal, in percent of terminal height.
; max_height = 100
@@ -176,9 +176,9 @@ method = raw
# 'mono' outputs left to right lowest to highest frequencies.
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
# set 'reverse' to 1 to display frequencies the other way around.
; channels = stereo
; mono_option = average
; reverse = 0
channels = mono
mono_option = average
reverse = 0
# Only valid if orientation is set to 'horizontal'.
# Set 'horizontal_stereo' to 1 to have left channel bars at top and right channel at bottom.
@@ -202,8 +202,8 @@ ascii_max_range = 100
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
bar_delimiter = 59
frame_delimiter = 10
# sdl window size and position. -1,-1 is centered.
; sdl_width = 1024

332
cava/example_config Normal file
View File

@@ -0,0 +1,332 @@
## Configuration file for CAVA.
# Lines starting with ; show config parameters and default values.
# Remove the ; to change parameters.
[general]
# Auto reload config if the configuration file has changed. 1 = on, 0 = off.
; live-config = 0
# Accepts only non-negative values.
; framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak and increase slowly as
# long as the bars don't peak. 0 = off, 1 = normal, 2..n = more aggressive.
# increase to make sensitivity increase even faster.
; autosens = 1
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
# The number of bars (0-512). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
; bars = 0
; bar_width = 2
; bar_spacing = 1
# bar_height is only used for output in "noritake" format
; bar_height = 32
# For SDL width and space between bars is in pixels, defaults are:
; bar_width = 20
; bar_spacing = 5
# sdl_glsl have these default values, they are only used to calculate max number of bars.
; bar_width = 1
; bar_spacing = 0
# center bars in terminal, if there is space.
center_align = 0
# max height of bars in terminal, in percent of terminal height.
; max_height = 100
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff frequency if needed to satisfy the minimum bandwidth.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
; sleep_timer = 0
[input]
# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem'
# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.
# On Mac it defaults to 'portaudio' or 'fifo'
# On Windows this is automatic and no input settings are needed.
#
# Each input method uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For pipewire 'source' will be the object name or object.serial of the device to capture from.
# Both input and output devices are supported. To capture the monitor source of a sink node, append '.monitor' to the sink's object name.
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
#
# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.
# README.md contains further information on how to setup CAVA for sndio.
#
# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.
# README.md contains further information on how to setup CAVA for OSS on FreeBSD.
#
# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.
# README.md contains further information on how to setup CAVA for JACK.
#
; method = pulse
; source = auto
; method = pipewire
; source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
; method = shmem
; source = /squeezelite-AA:BB:CC:DD:EE:FF
; method = portaudio
; source = auto
; method = sndio
; source = default
; method = oss
; source = /dev/dsp
; method = jack
; source = default
# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods:
# sample_rate: fifo, pipewire, sndio, oss
# sample_bits: fifo, pipewire, sndio, oss
# channels: sndio, oss, jack
# autoconnect: jack
# Other methods ignore these settings.
# For pipewire, sample_rate will default to 48000, for all other input methods, sample_rate will default to 44100.
#
# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported
# by the chosen audio device, the device will use other supported values instead.
# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it
# will use 44100, 16 and 1.
#
#
# The 'pipewire' input method has three options to control linking and mixing:
# active: Force the node to always process. Useful for monitoring sources when no other application is active.
# remix: Allow pipewire to remix audio channels to match cava's channel count. Useful for surround sound.
# virtual: Set the node to virtual, to avoid recording notifications from the DE.
#
; sample_rate = 44100
; sample_bits = 16
; channels = 2
; autoconnect = 2
; active = 1
; remix = 1
; virtual = 1
[output]
# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl'
# or 'sdl_glsl'.
# 'noncurses' (default) uses a buffer and cursor movements to only print
# changes from frame to frame in the terminal. Uses less resources and is less
# prone to tearing (vsync issues) than 'ncurses'.
#
# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
# stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 1024 bars stereo (512 bars mono), which can be adjusted in the 'bars' option above.
#
# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display
# in graphic mode. It only support the 3000 series graphical VFDs for now.
#
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or
# use one of the predefined ones.
; method = noncurses
# Orientation of the visualization. Can be 'bottom', 'top', 'left', 'right' or
# 'horizontal'. Default is 'bottom'. 'left and 'right' are only supported on sdl
# and ncurses output. 'horizontal' (bars go up and down from center) is only supported
# on noncurses output.
# Note: many fonts have weird or missing glyphs for characters used in orientations
# other than 'bottom', which can make output not look right.
orientation = bottom
# Visual channels. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' outputs left to right lowest to highest frequencies.
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
# set 'reverse' to 1 to display frequencies the other way around.
channels = mono
mono_option = average
reverse = 0
# Only valid if orientation is set to 'horizontal'.
# Set 'horizontal_stereo' to 1 to have left channel bars at top and right channel at bottom.
# Set 'left_bottom' to 0 to have right channel at top and left channel at bottom.
; horizontal_stereo = 0
; left_bottom = 1
# Raw output target.
# On Linux, a fifo will be created if target does not exist.
# On Windows, a named pipe will be created if target does not exist.
; raw_target = /dev/stdout
# Raw data format. Can be 'binary' or 'ascii'.
; data_format = binary
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
; ascii_max_range = 1000
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiter.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
# sdl window size and position. -1,-1 is centered.
; sdl_width = 1024
; sdl_height = 512
; sdl_x = -1
; sdl_y= -1
; sdl_full_screen = 0
# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none'
# 'frequency' displays the lower cut off frequency of the bar above.
# Only supported on ncurses and noncurses output.
; xaxis = none
# enable synchronized sync. 1 = on, 0 = off
# removes flickering in alacritty terminal emulator.
# defaults to off since the behaviour in other terminal emulators is unknown
; synchronized_sync = 0
# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders
; vertex_shader = pass_through.vert
# Default spectrum shader
# default value: bar_spectrum.frag
; fragment_shader = bar_spectrum.frag
# other styles shaders
; fragment_shader = eye_of_phi.frag
; fragment_shader = northern_lights.frag
; fragment_shader = spectrogram.frag
; fragment_shader = winamp_line_style_spectrum.frag
# Orion shaders (use with: method = sdl_glsl)
# Static Orion
; fragment_shader = orion_circle.frag
# Rotating Orion
; fragment_shader = orion_circle_rotate.frag
# Orion saturn subring
; fragment_shader = orion_saturn_subring.frag
# Orion saturn core
; fragment_shader = orion_saturn_core.frag
# For glsl output mode, keep rendering even if no audio. 1 = on, 0 = off. Default: 0
# Enable for animated shaders so time-based effects keep updating.
; continuous_rendering = 0
# SDL_GLSL only: gain applied to bar amplitudes before sending to shaders, in percent. Default: 100
# 0 = mute, 100 = unchanged, >100 = amplify (shader input is clamped to the [0..1] range).
; sdl_glsl_gain = 100
# disable console blank (screen saver) in tty. 1 = on, 0 = off. Default: 0
# (Not supported on FreeBSD)
; disable_blanking = 0
# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off
; show_idle_bar_heads = 1
# show waveform instead of frequency spectrum, 1 = on, 0 = off
; waveform = 0
[color]
# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors require
# a terminal that can change color definitions such as Gnome-terminal or rxvt.
# default is to keep current terminal color
; background = default
; foreground = default
# SDL and sdl_glsl only support hex code colors, these are the default:
; background = '#111111'
; foreground = '#33ffff'
# Gradient mode, only hex defined colors are supported,
# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
# You can define as many as 8 different colors. They range from bottom to top of the screen
; gradient = 0
; gradient_color_1 = '#59cc33'
; gradient_color_2 = '#80cc33'
; gradient_color_3 = '#a6cc33'
; gradient_color_4 = '#cccc33'
; gradient_color_5 = '#cca633'
; gradient_color_6 = '#cc8033'
; gradient_color_7 = '#cc5933'
; gradient_color_8 = '#cc3333'
# Horizontal is only supported on noncurses output.
# Only one color will be calculated per bar.
; horizontal_gradient = 0
; horizontal_gradient_color_1 = '#c45161'
; horizontal_gradient_color_2 = '#e094a0'
; horizontal_gradient_color_3 = '#f2b6c0'
; horizontal_gradient_color_4 = '#f2dde1'
; horizontal_gradient_color_5 = '#cbc7d8'
; horizontal_gradient_color_6 = '#8db7d2'
; horizontal_gradient_color_7 = '#5e62a9'
; horizontal_gradient_color_8 = '#434279'
# If both vertical and horizontal gradients are enabled, the vertical one will be blended in this direction.
# Can be 'up', 'down', 'left' or 'right'. 'up' means the vertical gradient will be blended in from
# bottom to top. I.e. the bottom will only be the horizontal
# and top will only be the vertical color of the gradient.
; blend_direction = 'up'
# use theme file instead of defining colors in this file
# themes are located in $HOME/.config/cava/themes
; theme = 'none'
[smoothing]
# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
; monstercat = 0
; waves = 0
# Noise reduction, int 0 - 100. default 77
# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth
# 100 will be very slow and smooth, 0 will be fast but noisy.
; noise_reduction = 77
[eq]
# This one is tricky. You can have as many keys as you want.
# Remember to uncomment more than one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
; 1 = 1 # bass
; 2 = 1
; 3 = 1 # midtone
; 4 = 1
; 5 = 1 # treble

View File

@@ -4,4 +4,4 @@ exec-once = /usr/bin/qs & # quickshell
exec-once = awww-daemon # wallpaper
exec-once = hyprsunset # night light
exec-once = qs -c overview # workspace switcher https://github.com/Shanu-Kumawat/quickshell-overview
exec-once = cava -p ~/.config/cava/config
# exec-once = cava -p ~/.config/cava/config

View File

@@ -12,7 +12,7 @@ input {
follow_mouse = 1
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
sensitivity = -0.8 # -1.0 - 1.0, 0 means no modification.
touchpad {
natural_scroll = false

View File

@@ -7,20 +7,19 @@ Item {
signal cavaDataChanged(string data)
// Process {
// id: cavaProcess
// command: ["cat", "/tmp/cava.fifo"]
Process {
id: cavaProcess
command: ["cat", "/tmp/cava.fifo"]
// stdout: StdioCollector {
// waitForEnd: false
// onStreamFinished: {
// console.log("Cava data: " + this.text)
// root.cavaDataChanged(this.text)
// }
// }
// }
stdout: SplitParser {
splitMarker: "\n" // fires onRead() for each newline-delimited chunk
onRead: data => {
root.cavaDataChanged(data);
}
}
}
Component.onCompleted: {
cavaProcess.running = true
cavaProcess.running = true;
}
}

View File

@@ -1,9 +1,9 @@
import QtQuick
import QtQuick.Layouts
import "../constants"
import "../services"
Row {
id: root
@@ -12,10 +12,12 @@ Row {
property string artUrl: ""
property int maxTextLength: 50
property int numBands: 32
// if the artist - title text is too long, truncate it
readonly property string displayText: {
const fullText = artist !== "" ? (artist + " - " + title) : title
return fullText.length > maxTextLength ? fullText.substring(0, maxTextLength - 3) + "..." : fullText
const fullText = artist !== "" ? (artist + " - " + title) : title;
return fullText.length > maxTextLength ? fullText.substring(0, maxTextLength - 3) + "..." : fullText;
}
visible: title !== ""
@@ -27,20 +29,6 @@ Row {
// where each number represents the amplitude of a frequency band.
// this can be used to create a simple visualizer
// also add cava to autostart
Canvas {
// implicitWidth: parent.implicitWidth
// implicitHeight: parent.implicitHeight
// anchors.fill: parent
}
CavaService {
id: cavaService
onCavaDataChanged: {
// TODO update the canvas with the new data
// console.log("Cava data changed: " + data)
}
}
Image {
width: 18
height: 18
@@ -50,11 +38,107 @@ Row {
}
Text {
id: titleText
text: root.displayText
color: Colors.md3.primary
font.family: Constants.fontFamily
font.pixelSize: Constants.fontSize
anchors.verticalCenter: parent.verticalCenter
z: 1
// z: 1
}
Item {
id: titleArea
anchors.bottom: parent.bottom
width: titleText.implicitWidth
height: Math.max(titleText.implicitHeight, visualizer.height)
// Canvas {
// id: visualizer
// anchors.fill: parent
// property var cavaData: []
// property var smoothedData: []
// property real inputMax: 20
// property real attackAlpha: 1.0
// property real releaseAlpha: 0.9
// property real maxStepPerFrame: 50
// property bool needsInit: true
// Component.onCompleted: {
// for (let i = 0; i < root.numBands; i++) {
// cavaData[i] = 0;
// smoothedData[i] = 0;
// }
// needsInit = false;
// }
// function updateData(csvLine) {
// // Fast in-place parse: split once, parse directly into pre-allocated array
// let parts = csvLine.split(";");
// let idx = 0;
// for (let j = 0; j < parts.length && idx < root.numBands; j++) {
// let val = Number(parts[j]);
// if (!isNaN(val))
// cavaData[idx++] = Math.min(100, Math.max(0, val));
// }
// while (idx < root.numBands)
// cavaData[idx++] = 0;
// if (needsInit) {
// for (let i = 0; i < root.numBands; i++)
// smoothedData[i] = cavaData[i];
// needsInit = false;
// } else {
// // Two-speed smoothing in place with early exit if no significant change
// let changed = false;
// for (let i = 0; i < root.numBands; i++) {
// let prev = smoothedData[i];
// let next = cavaData[i];
// let alpha = next >= prev ? attackAlpha : releaseAlpha;
// let blended = prev + (next - prev) * alpha;
// let delta = blended - prev;
// if (Math.abs(delta) > 0.1)
// changed = true;
// if (delta > maxStepPerFrame)
// blended = prev + maxStepPerFrame;
// else if (delta < -maxStepPerFrame)
// blended = prev - maxStepPerFrame;
// smoothedData[i] = blended;
// }
// if (!changed)
// return;
// }
// visualizer.requestPaint();
// }
// onPaint: {
// var ctx = getContext("2d");
// ctx.clearRect(0, 0, width, height);
// if (smoothedData.length === 0) {
// return;
// }
// var barWidth = width / root.numBands;
// ctx.fillStyle = Colors.md3.on_primary;
// for (let i = 0; i < root.numBands; i++) {
// let normalized = (smoothedData[i] || 0) / inputMax;
// if (normalized > 1)
// normalized = 1;
// let barHeight = normalized * height;
// ctx.fillRect(Math.floor(i * barWidth), Math.floor(height - barHeight), Math.ceil(barWidth), Math.floor(barHeight));
// }
// }
// }
}
// CavaService {
// id: cavaService
// onCavaDataChanged: data => {
// visualizer.updateData(data);
// }
// }
}

View File

@@ -44,6 +44,8 @@ Item {
artist: root.nowPlayingArtist
title: root.nowPlayingTitle
artUrl: root.nowPlayingArtUrl
Layout.fillHeight: true
Layout.alignment: Qt.AlignBottom
}
// Spacer