Allow multichannel audio sources as direct CSS and value source input

Add resolve_audio_source() that accepts both MultichannelAudioSource
(defaults to mono mix) and MonoAudioSource. Update CSS and brightness
value source dropdowns to show all audio sources with type badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 20:41:42 +03:00
parent a5d855f469
commit f96cd5f367
6 changed files with 63 additions and 28 deletions

View File

@@ -210,25 +210,33 @@ class AudioSourceStore:
# ── Resolution ───────────────────────────────────────────────────
def resolve_mono_source(self, mono_id: str) -> Tuple[int, bool, str]:
"""Resolve a mono audio source to (device_index, is_loopback, channel).
def resolve_audio_source(self, source_id: str) -> Tuple[int, bool, str]:
"""Resolve any audio source to (device_index, is_loopback, channel).
Follows the reference chain: mono → multichannel.
Accepts both MultichannelAudioSource (defaults to "mono" channel)
and MonoAudioSource (follows reference chain to parent multichannel).
Raises:
ValueError: If source not found or chain is broken
"""
mono = self.get_source(mono_id)
if not isinstance(mono, MonoAudioSource):
raise ValueError(f"Audio source {mono_id} is not a mono source")
source = self.get_source(source_id)
parent = self.get_source(mono.audio_source_id)
if not isinstance(parent, MultichannelAudioSource):
raise ValueError(
f"Mono source {mono_id} references non-multichannel source {mono.audio_source_id}"
)
if isinstance(source, MultichannelAudioSource):
return source.device_index, source.is_loopback, "mono"
return parent.device_index, parent.is_loopback, mono.channel
if isinstance(source, MonoAudioSource):
parent = self.get_source(source.audio_source_id)
if not isinstance(parent, MultichannelAudioSource):
raise ValueError(
f"Mono source {source_id} references non-multichannel source {source.audio_source_id}"
)
return parent.device_index, parent.is_loopback, source.channel
raise ValueError(f"Audio source {source_id} is not a valid audio source")
def resolve_mono_source(self, mono_id: str) -> Tuple[int, bool, str]:
"""Backward-compatible wrapper for resolve_audio_source()."""
return self.resolve_audio_source(mono_id)
# ── Migration ────────────────────────────────────────────────────