Balance/bass/treble controls for MediaPlayer entities

This originally came up as a request by a few people to add balance/bass/treble controls to the Xantech/Dayton Audio/Monoprice/etc integrations but it is equally applicable to other receivers/pre-amps as it is is a very common feature among media devices/streamers/etc.

Rather than post a reply in that thread, I figured I’d put this in the main features forum in case anyone is interested in contributing this to Home Assistant. I don’t have the time right now to do the proper amount of testing, but the following lays out the rough set of changes needed.

The bass/treble/balance controls would best be implemented on media_player base classes/services built-into Home Assistant itself.

The rough steps someone would need to contribute to Home Assistant for this to work:

  1. Add to MediaPlayerEntityFeature in const.py
BALANCE_STEP = 4194304
BASE_STEP = 8388608
TREBLE_STEP = 16777216

As well as the service constants:

SERVICE_BALANCE_LEFT = ‘balance_left’
SERVICE_BALANCE_RIGHT = ‘balance_right’
SERVICE_BASS_UP = ‘bass_up’
SERVICE_BASS_DOWN = ‘bass_down’
SERVICE_TREBLE_UP = ‘treble_up’
SERVICE_TREBLE_DOWN = ‘treble_down’
  1. Add to services.yaml:
balance_left:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.BALANCE_STEP

balance_right:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.BALANCE_STEP

bass_up:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.BASS_STEP

bass_down:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.BASS_STEP

treble_up:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.TREBLE_STEP

treble_down:
  target:
    entity:
      domain: media_player
      supported_features:
        - media_player.MediaPlayerEntityFeature.TREBLE_STEP
  1. Add the new services registered in init.py Will need to add some imports as well from const.py.
    component.async_register_entity_service(
        SERVICE_BALANCE_LEFT,
        {},
        "async_balance_left",
        [MediaPlayerEntityFeature.BALANCE_STEP,
    )

    component.async_register_entity_service(
        SERVICE_BALANCE_RIGHT,
        {},
        "async_balance_right",
        [MediaPlayerEntityFeature.BALANCE_STEP,
    )

    component.async_register_entity_service(
        SERVICE_BASS_UP,
        {},
        "async_bass_up”,
        [MediaPlayerEntityFeature.BASS_STEP,
    )

    component.async_register_entity_service(
        SERVICE_BASS_DOWN,
        {},
        "async_bass_down”,
        [MediaPlayerEntityFeature.BASS_STEP,
    )

    component.async_register_entity_service(
        SERVICE_TREBLE__UP,
        {},
        "async_treble_up”,
        [MediaPlayerEntityFeature.TREBLE_STEP,
    )

    component.async_register_entity_service(
        SERVICE_TREBLE_DOWN,
        {},
        "async_treble-down”,
        [MediaPlayerEntityFeature.TREBLE_STEP,
    )

And then add for all of the above the async methods that are registered, like the following:

    async def async_balance_left(self) -> None:
        “””Adjust the balance left for media player.

        This method is a coroutine.
        """
        if hasattr(self, “balance_left”):
            await self.hass.async_add_executor_job(self.balance_left)
            return


    async def async_bass_up(self) -> None:
        “””Adjust the bass up for media player.

        This method is a coroutine.
        """
        if hasattr(self, “bass_up”):
            await self.hass.async_add_executor_job(self.bass_up)
            return

That’s the rough changes needed for a really great addition to MediaPlayer for Home Assistant. Then individual integrations can start adding actual implementations of this to support it for a specific device.

Ideally, the above change would also include service APIs to directly set bass/balance/treble by adding set of MediaPlayerEntityFeature support flags (BASS_SET, BALANCE_SET, TREBLE_SET).

This needs to be different support flags than the _STEP features since it seems more common for devices to support step but not the direct setting of the value for tone controls.

Very nice start. However, it depends on the depth/target of the integration in core. The pseudo code above combines somewhat surround sound concepts and stereo concepts.

Stereo is basically Balance, Treble, Bass (which is what I put into the Stereo multiplexer integration for my own code) because that is all I needed. You can move sound to left/right and increase/decrease bass and treble delivered to the speakers.

Surround Sound = much more complex. Balance left/right on rear, balance left/right on front, balance front/back, throw on center, and I am sure many more (like controlling subwoofer, etc.). I am by no means a surround sound expert and I really do not have a need, I play music in Stereo and that is all I need.

Just my opinion but trying to replicate a complete controller for sound equalization and tuning for surround sound systems is 10x the complexity for stereo.

This enhancement should be targeting stereo-based media players and not full blown surround sound unit media_players.

Would very much appreciate this too!

Agreed, my suggestion above was for typical stereo controls on most receivers/pre-amps/matrix devices. More complex multi-channel controls/room correction is another whole topic and design.

Many of the existing built-in integrations to Home Assistant (for example, Monoprice, Anthem, etc) would all benefit from having balance/tone controls.

1 Like

As some integrations (at least) have already done it would not be part of the media player entity itself but as a number entity.