feat: Allow limiting max. volume

Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
This commit is contained in:
2025-12-23 13:56:07 +01:00
parent fe1c1eadf7
commit f46c045589
4 changed files with 20 additions and 6 deletions

View File

@@ -354,7 +354,8 @@
'root.BUTTON_MAP.PLAY_PAUSE': 'Play/Pause', 'root.BUTTON_MAP.PLAY_PAUSE': 'Play/Pause',
'root.TAG_TIMEOUT_SECS': 'Tag removal timeout (seconds)', 'root.TAG_TIMEOUT_SECS': 'Tag removal timeout (seconds)',
'root.TAGMODE': 'Tag mode', 'root.TAGMODE': 'Tag mode',
'root.LED_COUNT': 'Length of WS2182 (Neopixel) LED chain' 'root.LED_COUNT': 'Length of WS2182 (Neopixel) LED chain',
'root.VOLUME_MAX': 'Maximum volume (0-255)'
}; };
const config_input_override = { const config_input_override = {
'root.TAGMODE': { 'root.TAGMODE': {
@@ -393,6 +394,9 @@
}, },
'root.WLAN.PASSPHRASE': { 'root.WLAN.PASSPHRASE': {
'input-type': 'text' 'input-type': 'text'
},
'root.VOLUME_MAX': {
'input-type': 'number'
} }
}; };

View File

@@ -9,8 +9,8 @@ from utils import TimerManager
Dependencies = namedtuple('Dependencies', ('mp3player', 'nfcreader', 'buttons', 'playlistdb', 'hwconfig', 'leds', Dependencies = namedtuple('Dependencies', ('mp3player', 'nfcreader', 'buttons', 'playlistdb', 'hwconfig', 'leds',
'config')) 'config'))
# Should be ~ 6dB steps # Should be ~ 3dB steps
VOLUME_CURVE = [1, 2, 4, 8, 16, 32, 63, 126, 251] VOLUME_CURVE = [1, 2, 3, 4, 6, 8, 11, 16, 23, 32, 45, 64, 91, 128, 181, 255]
class PlayerApp: class PlayerApp:
@@ -52,6 +52,7 @@ class PlayerApp:
self.hwconfig = deps.hwconfig(self) self.hwconfig = deps.hwconfig(self)
self.leds = deps.leds(self) self.leds = deps.leds(self)
self.tag_mode = self.config.get_tagmode() self.tag_mode = self.config.get_tagmode()
self.volume_max = self.config.get_volume_max()
self.playing_tag = None self.playing_tag = None
self.playlist = None self.playlist = None
self.buttons = deps.buttons(self) if deps.buttons is not None else None self.buttons = deps.buttons(self) if deps.buttons is not None else None
@@ -91,8 +92,10 @@ class PlayerApp:
def onButtonPressed(self, what): def onButtonPressed(self, what):
assert self.buttons is not None assert self.buttons is not None
if what == self.buttons.VOLUP: if what == self.buttons.VOLUP:
self.volume_pos = min(self.volume_pos + 1, len(VOLUME_CURVE) - 1) new_volume = min(self.volume_pos + 1, len(VOLUME_CURVE) - 1)
self.player.set_volume(VOLUME_CURVE[self.volume_pos]) if VOLUME_CURVE[new_volume] <= self.volume_max:
self.volume_pos = new_volume
self.player.set_volume(VOLUME_CURVE[self.volume_pos])
elif what == self.buttons.VOLDOWN: elif what == self.buttons.VOLDOWN:
self.volume_pos = max(self.volume_pos - 1, 0) self.volume_pos = max(self.volume_pos - 1, 0)
self.player.set_volume(VOLUME_CURVE[self.volume_pos]) self.player.set_volume(VOLUME_CURVE[self.volume_pos])

View File

@@ -26,7 +26,8 @@ class Configuration:
'WIFI': { 'WIFI': {
'SSID': '', 'SSID': '',
'PASSPHRASE': '', 'PASSPHRASE': '',
} },
'VOLUME_MAX': 255
} }
def __init__(self, config_path='/config.json'): def __init__(self, config_path='/config.json'):
@@ -97,6 +98,9 @@ class Configuration:
def get_wifi_passphrase(self) -> str: def get_wifi_passphrase(self) -> str:
return self._get('WIFI')['PASSPHRASE'] return self._get('WIFI')['PASSPHRASE']
def get_volume_max(self) -> int:
return self._get('VOLUME_MAX')
# For the web API # For the web API
def get_config(self) -> Mapping[str, Any]: def get_config(self) -> Mapping[str, Any]:
return self.config return self.config

View File

@@ -139,6 +139,9 @@ class FakeConfig:
def get_tagmode(self): def get_tagmode(self):
return 'tagremains' return 'tagremains'
def get_volume_max(self):
return 255
def fake_open(filename, mode): def fake_open(filename, mode):
return FakeFile(filename, mode) return FakeFile(filename, mode)