feat(audio): implement volume feedback sound

This commit is contained in:
kyle
2026-01-19 00:56:03 +11:00
parent c8f1cbb79e
commit 01c892df2e
7 changed files with 53 additions and 2 deletions
Binary file not shown.
+3 -1
View File
@@ -679,7 +679,9 @@
"volumes-step-size-description": "Adjust the step size for volume changes (scroll wheel, keyboard shortcuts).",
"volumes-step-size-label": "Volume step size",
"volumes-volume-overdrive-description": "Allow raising volume above 100%. May not be supported by all hardware.",
"volumes-volume-overdrive-label": "Allow volume overdrive"
"volumes-volume-overdrive-label": "Allow volume overdrive",
"volumes-volume-feedback-label": "Play volume feedback sound",
"volumes-volume-feedback-description": "Play a feedback sound when adjusting volume"
},
"bar": {
"appearance-background-opacity-description": "Set the background opacity specifically for the bar.",
+3 -1
View File
@@ -679,7 +679,9 @@
"volumes-step-size-description": "调整音量变化的步长(滚轮、键盘快捷键)。",
"volumes-step-size-label": "音量步长",
"volumes-volume-overdrive-description": "允许将音量提高到100%以上。可能不被所有硬件支持。",
"volumes-volume-overdrive-label": "允许音量过载"
"volumes-volume-overdrive-label": "允许音量过载",
"volumes-volume-feedback-label": "播放音量反馈",
"volumes-volume-feedback-description": "调整音量时播放反馈音效"
},
"bar": {
"appearance-background-opacity-description": "为状态栏设置背景不透明度。",
+1
View File
@@ -33,6 +33,7 @@ Noctalia Shell is made possible by the incredible work of many open-source proje
## Audio Assets
- **[Universfield on Pixabay](https://pixabay.com/users/universfield-28281460/)** - Notification sound effect
- **[DrNI on Freesound](https://freesound.org/people/DrNI/sounds/34562/)** - Timer's alarm sound effect
- **[Lucas McCallister on Freesound](http://www.freesound.org/samplesViewSingle.php?id=67091)** - Volume change feedback sound effect
## Special Thanks
+1
View File
@@ -586,6 +586,7 @@ Singleton {
property string visualizerType: "linear"
property list<string> mprisBlacklist: []
property string preferredPlayer: ""
property bool volumeFeedback: false
}
// brightness
@@ -61,6 +61,21 @@ ColumnLayout {
}
}
// Volume Feedback sound Toggle
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.audio.volumes-volume-feedback-label")
description: I18n.tr("panels.audio.volumes-volume-feedback-description")
checked: Settings.data.audio.volumeFeedback
defaultValue: Settings.getDefaultValue("audio.volumeFeedback")
onToggled: checked => Settings.data.audio.volumeFeedback = checked
}
}
// Mute Toggle
ColumnLayout {
spacing: Style.marginS
+30
View File
@@ -4,10 +4,15 @@ import QtQuick
import Quickshell
import Quickshell.Services.Pipewire
import qs.Commons
import qs.Services.System
Singleton {
id: root
// Rate limiting for volume feedback (minimum 100ms between sounds)
property var lastVolumeFeedbackTime: 0
readonly property int minVolumeFeedbackInterval: 100
// Devices
readonly property PwNode sink: Pipewire.ready ? Pipewire.defaultAudioSink : null
readonly property PwNode source: validatedSource
@@ -230,6 +235,8 @@ Singleton {
sink.audio.muted = false;
sink.audio.volume = clampedVolume;
playVolumeFeedback(clampedVolume);
// Clear flag after a short delay to allow external changes to be detected
Qt.callLater(() => {
isSettingOutputVolume = false;
@@ -305,6 +312,29 @@ Singleton {
});
}
function playVolumeFeedback(currentVolume: real) {
if (!SoundService.multimediaAvailable) {
return;
}
if (!Settings.data.audio.volumeFeedback) {
return;
}
const now = Date.now();
if (now - lastVolumeFeedbackTime < minVolumeFeedbackInterval) {
return;
}
lastVolumeFeedbackTime = now;
const feedbackVolume = currentVolume;
SoundService.playSound("volume-change.wav", {
volume: feedbackVolume,
fallback: false,
repeat: false
});
}
function setInputMuted(muted: bool) {
if (!Pipewire.ready || !source?.audio) {
Logger.w("AudioService", "No source available or Pipewire not ready");