Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SoCo method to determine HDMI/Optical input audio format #832

Merged
merged 8 commits into from
Oct 11, 2021
59 changes: 59 additions & 0 deletions soco/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from functools import wraps
from xml.sax.saxutils import escape
from xml.parsers.expat import ExpatError
from typing import Optional
import warnings
import xmltodict

Expand Down Expand Up @@ -198,6 +199,8 @@ class SoCo(_SocoSingletonBase):
dialog_mode
supports_fixed_volume
fixed_volume
soundbar_audio_input_format
soundbar_audio_input_format_code
trueplay
status_light
buttons_enabled
Expand Down Expand Up @@ -1072,6 +1075,62 @@ def trueplay(self, trueplay):
]
)

@property
def soundbar_audio_input_format_code(self) -> Optional[int]:
"""Return audio input format code as reported by the device.

Returns None when the device is not a soundbar.

While the variable is available on non-soundbar devices,
it is likely always 0 for devices without audio inputs.

See also :func:`soundbar_audio_input_format` for obtaining a
human-readable description of the format.
"""
if not self.is_soundbar:
return None

response = self.deviceProperties.GetZoneInfo()

return int(response["HTAudioIn"])

@property
def soundbar_audio_input_format(self) -> Optional[str]:
"""Return a string presentation of the audio input format.

Returns None when the device is not a soundbar.
Otherwise, this will return the string presentation of the currently
active sound format (e.g., "Dolby 5.1" or "No input")

See also :func:`soundbar_audio_input_format_code` for the raw value.
"""
if not self.is_soundbar:
return None

format_to_str = {
0: "No input connected",
2: "Stereo",
7: "Dolby 2.0",
18: "Dolby 5.1",
21: "No input",
22: "No audio",
33554434: "PCM 2.0",
33554454: "PCM 2.0 no audio",
33554488: "Dolby 2.0",
84934713: "Dolby 5.1",
}

format_code = self.soundbar_audio_input_format_code

if format_code not in format_to_str:
logging.warning("Unknown audio input format: %s", format_code)

format_str = format_to_str.get(
format_code, "Unknown audio input format: %s" % format_code
)

return format_str

@property
def supports_fixed_volume(self):
"""bool: Whether the device supports fixed volume output."""
Expand Down
14 changes: 14 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,20 @@ def test_soco_trueplay(self, moco):
with pytest.raises(SoCoNotVisibleException):
moco.trueplay = True

def test_soco_soundbar_audio_input_format(self, moco):
moco.deviceProperties.GetZoneInfo.return_value = {"HTAudioIn": "0"}
assert moco.soundbar_audio_input_format_code == 0
assert moco.soundbar_audio_input_format == "No input connected"

moco.deviceProperties.GetZoneInfo.assert_called_with()

moco.deviceProperties.GetZoneInfo.return_value = {"HTAudioIn": "12345"}
assert "Unknown audio input format: 12345" in moco.soundbar_audio_input_format

moco._is_soundbar = False
assert moco.soundbar_audio_input_format_code is None
assert moco.soundbar_audio_input_format is None

def test_soco_fixed_volume(self, moco):
moco.renderingControl.GetSupportsOutputFixed.return_value = {
"CurrentSupportsFixed": "1"
Expand Down