Cava-Visualizer: optimizations on idle

This commit is contained in:
ItsLemmy
2025-11-09 09:35:27 -05:00
parent 3c07054ae8
commit 49c7c0cd72
5 changed files with 71 additions and 11 deletions
+1 -1
View File
@@ -366,7 +366,7 @@ Singleton {
property JsonObject audio: JsonObject {
property int volumeStep: 5
property bool volumeOverdrive: false
property int cavaFrameRate: 60
property int cavaFrameRate: 30
property string visualizerType: "linear"
property list<string> mprisBlacklist: []
property string preferredPlayer: ""
+34 -1
View File
@@ -20,6 +20,11 @@ Singleton {
property var values: Array(barsCount).fill(0)
property int barsCount: 48
// Idle detection to reduce GPU usage when there's no audio
property bool isIdle: true
property int idleFrameCount: 0
readonly property int idleThreshold: 30 // Frames of silence before considered idle (0.5s at 60fps)
property var config: ({
"general": {
"bars": barsCount,
@@ -74,7 +79,35 @@ Singleton {
}
stdout: SplitParser {
onRead: data => {
root.values = data.slice(0, -1).split(";").map(v => parseInt(v, 10) / 100)
const newValues = data.slice(0, -1).split(";").map(v => parseInt(v, 10) / 100)
// Check if all values are effectively zero (< 0.01)
const allZero = newValues.every(v => v < 0.01)
if (allZero) {
root.idleFrameCount++
if (root.idleFrameCount >= root.idleThreshold) {
// We're idle - stop updating values to save GPU
if (!root.isIdle) {
root.isIdle = true
// Set all values to 0 one final time
root.values = Array(root.barsCount).fill(0)
Logger.d("Cava", "Idle detected - stopped rendering")
}
// Don't update values while idle
return
}
} else {
// Audio detected - resume updates
root.idleFrameCount = 0
if (root.isIdle) {
root.isIdle = false
Logger.d("Cava", "Audio detected - resumed rendering")
}
}
// Update values (only when not idle)
root.values = newValues
}
}
stderr: StdioCollector {
@@ -35,10 +35,14 @@ Item {
border.width: root.strokeWidth
antialiasing: true
// Only update when value actually changes - reduces GPU load
width: vertical ? root.width * amp : root.barSlotSize * 0.5
height: vertical ? root.barSlotSize * 0.5 : root.height * amp
x: vertical ? root.width - width : index * root.barSlotSize + (root.barSlotSize * 0.25)
y: vertical ? index * root.barSlotSize + (root.barSlotSize * 0.25) : root.height - height
// Disable updates when invisible to save GPU
visible: root.visible
}
}
}
@@ -44,6 +44,9 @@ Item {
height: vertical ? root.barSlotSize * 0.8 : barSize
x: vertical ? root.centerX - (barSize / 2) : index * root.barSlotSize + (root.barSlotSize * 0.25)
y: vertical ? index * root.barSlotSize + (root.barSlotSize * 0.25) : root.centerY - (barSize / 2)
// Disable updates when invisible to save GPU
visible: root.visible
}
}
}
+29 -9
View File
@@ -13,15 +13,35 @@ Item {
property bool showMinimumSignal: false
property real minimumSignalValue: 0.05 // Default to 5% of height
// Redraw when necessary
onWidthChanged: canvas.requestPaint()
onHeightChanged: canvas.requestPaint()
onValuesChanged: canvas.requestPaint()
onFillColorChanged: canvas.requestPaint()
onStrokeColorChanged: canvas.requestPaint()
onShowMinimumSignalChanged: canvas.requestPaint()
onMinimumSignalValueChanged: canvas.requestPaint()
onVerticalChanged: canvas.requestPaint()
// Rendering active state - only redraw when visible and values are changing
property bool renderingActive: visible && values && values.length > 0
// Redraw when necessary - only if rendering is active
onWidthChanged: if (renderingActive)
canvas.requestPaint()
onHeightChanged: if (renderingActive)
canvas.requestPaint()
onValuesChanged: if (renderingActive)
canvas.requestPaint()
onFillColorChanged: if (renderingActive)
canvas.requestPaint()
onStrokeColorChanged: if (renderingActive)
canvas.requestPaint()
onShowMinimumSignalChanged: if (renderingActive)
canvas.requestPaint()
onMinimumSignalValueChanged: if (renderingActive)
canvas.requestPaint()
onVerticalChanged: if (renderingActive)
canvas.requestPaint()
// Clear canvas when not rendering
onRenderingActiveChanged: {
if (!renderingActive) {
var ctx = canvas.getContext("2d")
ctx.reset()
canvas.requestPaint()
}
}
Canvas {
id: canvas