samsung_multiroom/equalizer/equalizer.py
"""
Control speaker's sound adjustments.
"""
import abc
class EqualizerBase(metaclass=abc.ABCMeta):
"""
Abstract base class for equalizers.
"""
@abc.abstractmethod
def get_presets_names(self):
"""
:returns: List of preset names
"""
raise NotImplementedError()
@abc.abstractmethod
def set(self, *args):
"""
Set equalizer values by preset name or list of band values
:param: Name of the preset to set or list of 7 band values to set
"""
raise NotImplementedError()
@abc.abstractmethod
def save(self, name=None):
"""
Create a new or overwrite existing preset.
:param name: If empty, current preset will be saved, if provided name exist, that preset will overwrite existing
one, otherwise a new preset is created with that name. In either case band values used will be ones
currently set on a speaker e.g. via set() method.
"""
raise NotImplementedError()
@abc.abstractmethod
def delete(self, name):
"""
Delete preset.
:param name: Name of a preset to delete
"""
raise NotImplementedError()
class Equalizer(EqualizerBase):
"""
Control speaker's sound adjustments.
Allows adjustments for bands 150, 300, 600, 1.2k, 2.5k, 5.0k, 10.0k, each value must be integer between -6 and 6.
"""
def __init__(self, api):
self._api = api
def get_presets_names(self):
"""
:returns: List of preset names
"""
presets = self._api.get_7band_eq_list()
return [p['presetname'] for p in presets]
def set(self, *args):
"""
Set equalizer values by preset name or list of band values
:param: Name of the preset to set or list of 7 band values to set
"""
# set by preset name
if isinstance(args[0], str):
preset_index = self._get_preset_index_by_name(args[0])
if not preset_index:
raise ValueError('Preset {0} does not exists'.format(args[0]))
self._api.set_7band_eq_mode(preset_index)
# set band values
else:
if not isinstance(args[0], list) or len(args[0]) != 7:
raise ValueError('Pass all 7 band values as a list')
if [value for value in args[0] if not isinstance(value, int) or abs(value) > 6]:
raise ValueError('Band values must be integers between -6 and 6')
preset_index = self._get_current_preset()['id']
self._api.set_7band_eq_value(preset_index, args[0])
def save(self, name=None):
"""
Create a new or overwrite existing preset.
:param name: If empty, current preset will be saved, if provided name exist, that preset will overwrite existing
one, otherwise a new preset is created with that name. In either case band values used will be ones
currently set on a speaker e.g. via set() method.
"""
current_preset = self._get_current_preset()
# overwrite current one
if name is None:
self._api.reset_7band_eq_value(current_preset['id'], current_preset['band_values'])
else:
preset_index = self._get_preset_index_by_name(name)
# overwrite preset with the same name
if preset_index:
self._api.reset_7band_eq_value(preset_index, current_preset['band_values'])
# create a new preset
else:
presets = self._api.get_7band_eq_list()
presets_ids = [int(p['presetindex']) for p in presets]
self._api.add_custom_eq_mode(max(presets_ids) + 1, name)
def delete(self, name):
"""
Delete preset.
:param name: Name of a preset to delete
"""
preset_index = self._get_preset_index_by_name(name)
if not preset_index:
raise ValueError('Preset {0} does not exists'.format(name))
self._api.del_custom_eq_mode(preset_index)
def _get_preset_index_by_name(self, name):
presets = self._api.get_7band_eq_list()
matching_presets = [int(p['presetindex']) for p in presets if p['presetname'] == name]
if matching_presets:
return matching_presets[0]
return None
def _get_current_preset(self):
preset = self._api.get_current_eq_mode()
return {
'id': int(preset['presetindex']),
'name': preset['presetname'],
'band_values': [int(preset['eqvalue' + str(i)]) for i in range(1, 8)]
}