Skip to content

Commit aab9a31

Browse files
authored
new self.pa_channels attribute
a new self.pa_channels attribute (from max_output_channels — for example 8 for the X-Fi 7.1 master, 6 for HD Audio 5.1, 2 for remap sinks) is now passed to every set_sink_volume() call, so pa_cvolume.channels always matches the target sink's actual channel map. This should make volume control responsive on the multi-channel masters too.
1 parent f24589f commit aab9a31

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

music_assistant/providers/local_audio/sendspin_bridge.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ def __init__(
120120
self.pa_sink_name: str | None = device_info.get("pa_sink_name")
121121
self.sample_rate: int = device_info.get("sample_rate", BRIDGE_SAMPLE_RATE)
122122
self.bit_depth: int = device_info.get("bit_depth", BRIDGE_BIT_DEPTH)
123+
# The PA sink's actual channel count (e.g. 8 for a 7.1 master, 2 for a
124+
# remap sink). Used for pa_cvolume_set in PAVolumeController calls —
125+
# a mismatch against the sink's real channel_map can leave the
126+
# displayed reference_volume updated while soft_volume (real gain)
127+
# doesn't change. This is independent of BRIDGE_CHANNELS, which is
128+
# the audio *stream's* channel count (always 2).
129+
self.pa_channels: int = device_info.get("max_output_channels", BRIDGE_CHANNELS)
123130
self.device_index: int | None = device_info.get("index")
124131
self.backend: str = backend
125132
self.logger = provider.logger.getChild(f"bridge.{self.display_name}")
@@ -344,7 +351,7 @@ async def _reset_sink_volume(self) -> None:
344351
controller = self._shared_volume_controller
345352
try:
346353
ok = await self.mass.loop.run_in_executor(
347-
None, controller.set_sink_volume, pa_sink_name, 100
354+
None, controller.set_sink_volume, pa_sink_name, 100, self.pa_channels
348355
)
349356
if not ok:
350357
self.logger.warning("Failed to pin PA sink volume to 100%% for %s", pa_sink_name)
@@ -379,7 +386,7 @@ async def _apply_hardware_volume(self) -> None:
379386
controller = self._volume_controller
380387
try:
381388
ok = await self.mass.loop.run_in_executor(
382-
None, controller.set_sink_volume, pa_sink_name, target_pct
389+
None, controller.set_sink_volume, pa_sink_name, target_pct, self.pa_channels
383390
)
384391
if not ok:
385392
self.logger.warning(
@@ -847,4 +854,4 @@ async def stop_all(self) -> None:
847854
with suppress(Exception):
848855
await self.mass.loop.run_in_executor(None, self._volume_controller.close)
849856
self._volume_controller = None
850-
self.logger.debug("All local audio bridges stopped")
857+
self.logger.debug("All local audio bridges stopped")

0 commit comments

Comments
 (0)