mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(audio): implement volume feedback sound
This commit is contained in:
Binary file not shown.
@@ -679,7 +679,9 @@
|
|||||||
"volumes-step-size-description": "Adjust the step size for volume changes (scroll wheel, keyboard shortcuts).",
|
"volumes-step-size-description": "Adjust the step size for volume changes (scroll wheel, keyboard shortcuts).",
|
||||||
"volumes-step-size-label": "Volume step size",
|
"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-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": {
|
"bar": {
|
||||||
"appearance-background-opacity-description": "Set the background opacity specifically for the bar.",
|
"appearance-background-opacity-description": "Set the background opacity specifically for the bar.",
|
||||||
|
|||||||
@@ -679,7 +679,9 @@
|
|||||||
"volumes-step-size-description": "调整音量变化的步长(滚轮、键盘快捷键)。",
|
"volumes-step-size-description": "调整音量变化的步长(滚轮、键盘快捷键)。",
|
||||||
"volumes-step-size-label": "音量步长",
|
"volumes-step-size-label": "音量步长",
|
||||||
"volumes-volume-overdrive-description": "允许将音量提高到100%以上。可能不被所有硬件支持。",
|
"volumes-volume-overdrive-description": "允许将音量提高到100%以上。可能不被所有硬件支持。",
|
||||||
"volumes-volume-overdrive-label": "允许音量过载"
|
"volumes-volume-overdrive-label": "允许音量过载",
|
||||||
|
"volumes-volume-feedback-label": "播放音量反馈",
|
||||||
|
"volumes-volume-feedback-description": "调整音量时播放反馈音效"
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
"appearance-background-opacity-description": "为状态栏设置背景不透明度。",
|
"appearance-background-opacity-description": "为状态栏设置背景不透明度。",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Noctalia Shell is made possible by the incredible work of many open-source proje
|
|||||||
## Audio Assets
|
## Audio Assets
|
||||||
- **[Universfield on Pixabay](https://pixabay.com/users/universfield-28281460/)** - Notification sound effect
|
- **[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
|
- **[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
|
## Special Thanks
|
||||||
|
|||||||
@@ -586,6 +586,7 @@ Singleton {
|
|||||||
property string visualizerType: "linear"
|
property string visualizerType: "linear"
|
||||||
property list<string> mprisBlacklist: []
|
property list<string> mprisBlacklist: []
|
||||||
property string preferredPlayer: ""
|
property string preferredPlayer: ""
|
||||||
|
property bool volumeFeedback: false
|
||||||
}
|
}
|
||||||
|
|
||||||
// brightness
|
// 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
|
// Mute Toggle
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginS
|
spacing: Style.marginS
|
||||||
|
|||||||
@@ -4,10 +4,15 @@ import QtQuick
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.Pipewire
|
import Quickshell.Services.Pipewire
|
||||||
import qs.Commons
|
import qs.Commons
|
||||||
|
import qs.Services.System
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
// Rate limiting for volume feedback (minimum 100ms between sounds)
|
||||||
|
property var lastVolumeFeedbackTime: 0
|
||||||
|
readonly property int minVolumeFeedbackInterval: 100
|
||||||
|
|
||||||
// Devices
|
// Devices
|
||||||
readonly property PwNode sink: Pipewire.ready ? Pipewire.defaultAudioSink : null
|
readonly property PwNode sink: Pipewire.ready ? Pipewire.defaultAudioSink : null
|
||||||
readonly property PwNode source: validatedSource
|
readonly property PwNode source: validatedSource
|
||||||
@@ -230,6 +235,8 @@ Singleton {
|
|||||||
sink.audio.muted = false;
|
sink.audio.muted = false;
|
||||||
sink.audio.volume = clampedVolume;
|
sink.audio.volume = clampedVolume;
|
||||||
|
|
||||||
|
playVolumeFeedback(clampedVolume);
|
||||||
|
|
||||||
// Clear flag after a short delay to allow external changes to be detected
|
// Clear flag after a short delay to allow external changes to be detected
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
isSettingOutputVolume = false;
|
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) {
|
function setInputMuted(muted: bool) {
|
||||||
if (!Pipewire.ready || !source?.audio) {
|
if (!Pipewire.ready || !source?.audio) {
|
||||||
Logger.w("AudioService", "No source available or Pipewire not ready");
|
Logger.w("AudioService", "No source available or Pipewire not ready");
|
||||||
|
|||||||
Reference in New Issue
Block a user