better structure
This commit is contained in:
146
config/quickshell/Services/AudioService.qml
Normal file
146
config/quickshell/Services/AudioService.qml
Normal file
@@ -0,0 +1,146 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Pipewire
|
||||
import qs.Utils
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => {
|
||||
if (!node.isStream) {
|
||||
if (node.isSink) {
|
||||
acc.sinks.push(node)
|
||||
} else if (node.audio) {
|
||||
acc.sources.push(node)
|
||||
}
|
||||
}
|
||||
return acc
|
||||
}, {
|
||||
"sources": [],
|
||||
"sinks": []
|
||||
})
|
||||
|
||||
readonly property PwNode sink: Pipewire.defaultAudioSink
|
||||
readonly property PwNode source: Pipewire.defaultAudioSource
|
||||
readonly property list<PwNode> sinks: nodes.sinks
|
||||
readonly property list<PwNode> sources: nodes.sources
|
||||
|
||||
// Volume [0..1] is readonly from outside
|
||||
readonly property alias volume: root._volume
|
||||
property real _volume: sink?.audio?.volume ?? 0
|
||||
|
||||
readonly property alias muted: root._muted
|
||||
property bool _muted: !!sink?.audio?.muted
|
||||
|
||||
// Input volume [0..1] is readonly from outside
|
||||
readonly property alias inputVolume: root._inputVolume
|
||||
property real _inputVolume: source?.audio?.volume ?? 0
|
||||
|
||||
readonly property alias inputMuted: root._inputMuted
|
||||
property bool _inputMuted: !!source?.audio?.muted
|
||||
|
||||
readonly property real stepVolume: 5 / 100.0
|
||||
|
||||
PwObjectTracker {
|
||||
objects: [...root.sinks, ...root.sources]
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: sink?.audio ? sink?.audio : null
|
||||
|
||||
function onVolumeChanged() {
|
||||
var vol = (sink?.audio.volume ?? 0)
|
||||
if (isNaN(vol)) {
|
||||
vol = 0
|
||||
}
|
||||
root._volume = vol
|
||||
}
|
||||
|
||||
function onMutedChanged() {
|
||||
root._muted = (sink?.audio.muted ?? true)
|
||||
Logger.log("AudioService", "OnMuteChanged:", root._muted)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: source?.audio ? source?.audio : null
|
||||
|
||||
function onVolumeChanged() {
|
||||
var vol = (source?.audio.volume ?? 0)
|
||||
if (isNaN(vol)) {
|
||||
vol = 0
|
||||
}
|
||||
root._inputVolume = vol
|
||||
}
|
||||
|
||||
function onMutedChanged() {
|
||||
root._inputMuted = (source?.audio.muted ?? true)
|
||||
Logger.log("AudioService", "OnInputMuteChanged:", root._inputMuted)
|
||||
}
|
||||
}
|
||||
|
||||
function increaseVolume() {
|
||||
setVolume(volume + stepVolume)
|
||||
}
|
||||
|
||||
function decreaseVolume() {
|
||||
setVolume(volume - stepVolume)
|
||||
}
|
||||
|
||||
function setVolume(newVolume: real) {
|
||||
if (sink?.ready && sink?.audio) {
|
||||
// Clamp it accordingly
|
||||
sink.audio.muted = false
|
||||
sink.audio.volume = Math.max(0, Math.min(1.0, newVolume))
|
||||
} else {
|
||||
Logger.warn("AudioService", "No sink available")
|
||||
}
|
||||
}
|
||||
|
||||
function setOutputMuted(muted: bool) {
|
||||
if (sink?.ready && sink?.audio) {
|
||||
sink.audio.muted = muted
|
||||
} else {
|
||||
Logger.warn("AudioService", "No sink available")
|
||||
}
|
||||
}
|
||||
|
||||
function setInputVolume(newVolume: real) {
|
||||
if (source?.ready && source?.audio) {
|
||||
// Clamp it accordingly
|
||||
source.audio.muted = false
|
||||
source.audio.volume = Math.max(0, Math.min(1.0, newVolume))
|
||||
} else {
|
||||
Logger.warn("AudioService", "No source available")
|
||||
}
|
||||
}
|
||||
|
||||
function setInputMuted(muted: bool) {
|
||||
if (source?.ready && source?.audio) {
|
||||
source.audio.muted = muted
|
||||
} else {
|
||||
Logger.warn("AudioService", "No source available")
|
||||
}
|
||||
}
|
||||
|
||||
function setAudioSink(newSink: PwNode): void {
|
||||
Pipewire.preferredDefaultAudioSink = newSink
|
||||
// Volume is changed by the sink change
|
||||
root._volume = newSink?.audio?.volume ?? 0
|
||||
root._muted = !!newSink?.audio?.muted
|
||||
}
|
||||
|
||||
function setAudioSource(newSource: PwNode): void {
|
||||
Pipewire.preferredDefaultAudioSource = newSource
|
||||
// Volume is changed by the source change
|
||||
root._inputVolume = newSource?.audio?.volume ?? 0
|
||||
root._inputMuted = !!newSource?.audio?.muted
|
||||
}
|
||||
|
||||
function toggleMute() {
|
||||
setOutputMuted(!muted)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user