AudioVisualizer: Low vs High Quality via setting.

This commit is contained in:
ItsLemmy
2025-11-09 10:06:50 -05:00
parent 49c7c0cd72
commit 2cea2d12de
15 changed files with 135 additions and 14 deletions
+9
View File
@@ -503,6 +503,10 @@
"top_left": "Oben links",
"top_right": "Oben rechts"
},
"visualizer-quality": {
"high": "Hoch",
"low": "Niedrig"
},
"visualizer-types": {
"linear": "Linear",
"mirrored": "Gespiegelt",
@@ -693,6 +697,10 @@
"description": "Bevorzugte und ignorierte Medienanwendungen festlegen.",
"label": "Medienplayer"
},
"visualizer-quality": {
"description": "Hohe Qualität verbraucht mehr GPU-Ressourcen.",
"label": "Visualisierungsqualität"
},
"visualizer-type": {
"description": "Visualisierungstyp für Medienwiedergabe wählen.",
"label": "Visualisierungstyp"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Hintergrundbild-Farben deaktiviert",
"enabled": "Hintergrundbild-Farben aktiviert",
"label": "Hintergrundfarbengenerierung",
"not-installed": "Matugen nicht installiert - erforderlich für Hintergrundbild-Farbextraktion"
},
"wifi": {
+12 -4
View File
@@ -503,6 +503,10 @@
"top_left": "Top left",
"top_right": "Top right"
},
"visualizer-quality": {
"high": "High",
"low": "Low"
},
"visualizer-types": {
"linear": "Linear",
"mirrored": "Mirrored",
@@ -682,19 +686,23 @@
"placeholder": "e.g. spotify, vlc, mpv"
},
"scrolling-speed": {
"description": "Time in seconds for the title to scroll from start to end",
"description": "Time in seconds for the title to scroll from start to end.",
"label": "Scrolling speed"
},
"scrolling-title": {
"description": "Enable continuous scrolling for long media titles",
"description": "Enable continuous scrolling for long media titles.",
"label": "Scrolling title"
},
"section": {
"description": "Set your preferred and ignored media applications.",
"label": "Media players"
},
"visualizer-quality": {
"description": "High quality use more GPU ressources.",
"label": "Visualization quality"
},
"visualizer-type": {
"description": "Choose a visualization type for media playback",
"description": "Choose a visualization type for media playback.",
"label": "Visualization type"
}
},
@@ -1757,9 +1765,9 @@
"title-predefined": "Predefined color cheme processing failed"
},
"wallpaper-colors": {
"label": "Wallpaper colors generation",
"disabled": "Wallpaper colors disabled",
"enabled": "Wallpaper colors enabled",
"label": "Wallpaper colors generation",
"not-installed": "Matugen not installed - required for wallpaper color extraction"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "Superior izquierda",
"top_right": "Superior derecha"
},
"visualizer-quality": {
"high": "Alto/Alta",
"low": "Bajo"
},
"visualizer-types": {
"linear": "Lineal",
"mirrored": "Espejado",
@@ -693,6 +697,10 @@
"description": "Establece tus aplicaciones multimedia preferidas e ignoradas.",
"label": "Reproductores multimedia"
},
"visualizer-quality": {
"description": "Alta calidad usa más recursos de la GPU.",
"label": "Calidad de visualización"
},
"visualizer-type": {
"description": "Elige un tipo de visualización para la reproducción de medios.",
"label": "Tipo de visualización"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Colores del fondo de pantalla desactivados",
"enabled": "Colores del fondo de pantalla activados",
"label": "Generación de colores para fondos de pantalla",
"not-installed": "Matugen no instalado - requerido para extraer colores del fondo de pantalla"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "En haut à gauche",
"top_right": "En haut à droite"
},
"visualizer-quality": {
"high": "Haut/Haute",
"low": "Bas"
},
"visualizer-types": {
"linear": "Linéaire",
"mirrored": "Miroir",
@@ -693,6 +697,10 @@
"description": "Définissez vos applications multimédias préférées et ignorées.",
"label": "Lecteurs multimédias"
},
"visualizer-quality": {
"description": "L'utilisation de haute qualité nécessite plus de ressources GPU.",
"label": "Qualité de la visualisation"
},
"visualizer-type": {
"description": "Choisissez un type de visualisation pour la lecture multimédia.",
"label": "Type de visualisation"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Couleurs du fond d'écran désactivées",
"enabled": "Couleurs du fond d'écran activées",
"label": "Génération de couleurs pour fonds d'écran",
"not-installed": "Matugen non installé - requis pour l'extraction des couleurs du fond d'écran"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "Superior esquerda",
"top_right": "Superior direita"
},
"visualizer-quality": {
"high": "Alto(a)",
"low": "Baixo(a)"
},
"visualizer-types": {
"linear": "Linear",
"mirrored": "Espelhado",
@@ -693,6 +697,10 @@
"description": "Defina seus aplicativos de mídia preferidos e ignorados.",
"label": "Reprodutores de mídia"
},
"visualizer-quality": {
"description": "Alta qualidade usa mais recursos da GPU.",
"label": "Qualidade da visualização"
},
"visualizer-type": {
"description": "Escolha um tipo de visualização para a reprodução de mídia",
"label": "Tipo de visualização"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Cores do papel de parede desativadas",
"enabled": "Cores do papel de parede ativadas",
"label": "Geração de cores para papel de parede",
"not-installed": "Matugen não instalado - necessário para extração de cores do papel de parede"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "Sol üst",
"top_right": "Sağ üst"
},
"visualizer-quality": {
"high": "Yüksek",
"low": "Düşük"
},
"visualizer-types": {
"linear": "Doğrusal",
"mirrored": "Yansıtılmış",
@@ -693,6 +697,10 @@
"description": "Tercih ettiğiniz ve yoksayacağınız medya uygulamalarını ayarlayın.",
"label": "Medya oynatıcılar"
},
"visualizer-quality": {
"description": "Yüksek kalite daha fazla GPU kaynağı kullanır.",
"label": "Görselleştirme kalitesi"
},
"visualizer-type": {
"description": "Medya oynatımı için bir görselleştirme türü seçin",
"label": "Görselleştirme türü"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Duvar kağıdı renkleri devre dışı",
"enabled": "Duvar kağıdı renkleri etkin",
"label": "Duvar kağıdı renkleri oluşturma",
"not-installed": "Matugen kurulu değil - duvar kağıdı renk çıkarmak için gerekli"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "Згори ліворуч",
"top_right": "Згори праворуч"
},
"visualizer-quality": {
"high": "Високий",
"low": "Низький"
},
"visualizer-types": {
"linear": "Лінійний",
"mirrored": "Дзеркальний",
@@ -693,6 +697,10 @@
"description": "Встановіть бажані та ігноровані медіапрограми.",
"label": "Медіаплеєри"
},
"visualizer-quality": {
"description": "Висока якість використовує більше ресурсів GPU.",
"label": "Якість візуалізації"
},
"visualizer-type": {
"description": "Виберіть тип візуалізації для відтворення медіа",
"label": "Тип візуалізації"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "Кольори шпалер вимкнено",
"enabled": "Кольори шпалер увімкнено",
"label": "Генерація кольорів шпалер",
"not-installed": "Matugen не встановлено - потрібний для витягу кольорів зі шпалер"
},
"wifi": {
+9
View File
@@ -503,6 +503,10 @@
"top_left": "左上",
"top_right": "右上"
},
"visualizer-quality": {
"high": "高",
"low": "低"
},
"visualizer-types": {
"linear": "线性",
"mirrored": "镜像",
@@ -693,6 +697,10 @@
"description": "设置您首选和要忽略的媒体应用程序。",
"label": "媒体播放器"
},
"visualizer-quality": {
"description": "高质量使用更多 GPU 资源。",
"label": "可视化质量"
},
"visualizer-type": {
"description": "选择媒体播放的可视化类型",
"label": "可视化类型"
@@ -1759,6 +1767,7 @@
"wallpaper-colors": {
"disabled": "壁纸颜色已禁用",
"enabled": "壁纸颜色已启用",
"label": "壁纸颜色生成",
"not-installed": "Matugen 未安装 - 壁纸颜色提取所需"
},
"wifi": {
+1
View File
@@ -228,6 +228,7 @@
"volumeOverdrive": false,
"cavaFrameRate": 60,
"visualizerType": "linear",
"visualizerQuality": "high",
"mprisBlacklist": [],
"preferredPlayer": ""
},
+1
View File
@@ -368,6 +368,7 @@ Singleton {
property bool volumeOverdrive: false
property int cavaFrameRate: 30
property string visualizerType: "linear"
property string visualizerQuality: "high"
property list<string> mprisBlacklist: []
property string preferredPlayer: ""
}
+14 -1
View File
@@ -331,7 +331,6 @@ ColumnLayout {
}
// AudioService Visualizer section
NComboBox {
id: audioVisualizerCombo
label: I18n.tr("settings.audio.media.visualizer-type.label")
description: I18n.tr("settings.audio.media.visualizer-type.description")
model: [{
@@ -351,6 +350,20 @@ ColumnLayout {
onSelected: key => Settings.data.audio.visualizerType = key
}
NComboBox {
label: I18n.tr("settings.audio.media.visualizer-quality.label")
description: I18n.tr("settings.audio.media.visualizer-quality.description")
model: [{
"key": "low",
"name": I18n.tr("options.visualizer-quality.low")
}, {
"key": "high",
"name": I18n.tr("options.visualizer-quality.high")
}]
currentKey: Settings.data.audio.visualizerQuality
onSelected: key => Settings.data.audio.visualizerQuality = key
}
NComboBox {
label: I18n.tr("settings.audio.media.frame-rate.label")
description: I18n.tr("settings.audio.media.frame-rate.description")
+35 -5
View File
@@ -19,12 +19,20 @@ Singleton {
property bool shouldRun: BarService.hasAudioVisualizer || PanelService.lockScreen?.active || (PanelService.openedPanel && PanelService.openedPanel.objectName.startsWith("controlCenterPanel"))
property var values: Array(barsCount).fill(0)
property int barsCount: 48
property int barsCount: 32
// 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)
// Frame skipping for GPU optimization - skip every Nth frame when playing
property int frameCounter: 0
readonly property int frameSkip: 1 // Update every N frames (1 = no skip, 2 = every other frame, etc)
// Change detection - only update if values changed significantly
property var lastValues: Array(barsCount).fill(0)
readonly property real changeThreshold: 0.005 // Minimum change (1%) to trigger update
property var config: ({
"general": {
"bars": barsCount,
@@ -35,8 +43,9 @@ Singleton {
"higher_cutoff_freq": 12000
},
"smoothing": {
"monstercat": 0,
"noise_reduction": 77
"monstercat": 1,
"noise_reduction"// Enable monstercat smoothing for less jittery animation
: 77
},
"output": {
"method": "raw",
@@ -92,6 +101,7 @@ Singleton {
root.isIdle = true
// Set all values to 0 one final time
root.values = Array(root.barsCount).fill(0)
root.lastValues = Array(root.barsCount).fill(0)
Logger.d("Cava", "Idle detected - stopped rendering")
}
// Don't update values while idle
@@ -106,8 +116,28 @@ Singleton {
}
}
// Update values (only when not idle)
root.values = newValues
// Frame skipping optimization - skip frames to reduce GPU load
root.frameCounter++
if (root.frameSkip > 1 && root.frameCounter % root.frameSkip !== 0) {
// Skip this frame
return
}
// Change detection - only update if values changed significantly
let hasSignificantChange = false
for (var i = 0; i < newValues.length; i++) {
const delta = Math.abs(newValues[i] - root.lastValues[i])
if (delta > root.changeThreshold) {
hasSignificantChange = true
break
}
}
// Update values only if there's a significant change
if (hasSignificantChange) {
root.lastValues = newValues.slice() // Copy array
root.values = newValues
}
}
}
stderr: StdioCollector {
+3 -1
View File
@@ -17,6 +17,7 @@ Item {
readonly property int valuesCount: (values && Array.isArray(values)) ? values.length : 0
readonly property int totalBars: valuesCount * 2
readonly property real barSlotSize: totalBars > 0 ? (vertical ? height : width) / totalBars : 0
readonly property bool highQuality: (Settings.data.audio.visualizerType === "low") ? false : true
Repeater {
model: root.totalBars
@@ -33,7 +34,8 @@ Item {
color: root.fillColor
border.color: root.strokeColor
border.width: root.strokeWidth
antialiasing: true
antialiasing: root.highQuality
smooth: root.highQuality
// Only update when value actually changes - reduces GPU load
width: vertical ? root.width * amp : root.barSlotSize * 0.5
+3 -2
View File
@@ -17,7 +17,7 @@ Item {
readonly property int valuesCount: (values && Array.isArray(values)) ? values.length : 0
readonly property int totalBars: valuesCount * 2
readonly property real barSlotSize: totalBars > 0 ? (vertical ? height : width) / totalBars : 0
readonly property bool highQuality: (Settings.data.audio.visualizerType === "low") ? false : true
readonly property real centerY: height / 2
readonly property real centerX: width / 2
@@ -38,7 +38,8 @@ Item {
color: root.fillColor
border.color: root.strokeColor
border.width: root.strokeWidth
antialiasing: true
antialiasing: root.highQuality
smooth: root.highQuality
width: vertical ? barSize : root.barSlotSize * 0.8
height: vertical ? root.barSlotSize * 0.8 : barSize
+3 -1
View File
@@ -46,7 +46,9 @@ Item {
Canvas {
id: canvas
anchors.fill: parent
antialiasing: true
antialiasing: false // Disable for better performance - shape is smooth enough without it
renderStrategy: Canvas.Threaded // Render in separate thread to reduce main thread load
renderTarget: Canvas.FramebufferObject // Use FBO for better performance
onPaint: {
var ctx = getContext("2d")