Skip to content

Commit 8bb26ba

Browse files
committed
Improved handling of FAST Audio board
1 parent 34e6480 commit 8bb26ba

File tree

5 files changed

+64
-40
lines changed

5 files changed

+64
-40
lines changed

mpf/modes/high_score/code/high_score.py

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ async def _ask_player_for_initials(self, player: Player, award_label: str, value
271271
input_initials = choice(unused_initials)
272272
return input_initials
273273

274+
# pylint: disable-msg=too-many-arguments
274275
async def _show_award_slide(self, player_num, player_name: str, category_name: str, award: str, value: int) -> None:
275276
if not self.high_score_config['award_slide_display_time']:
276277
return

mpf/platforms/fast/fast_audio.py

+40-31
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
from math import ceil
44
from mpf.core.logging import LogMixin
5+
from mpf.core.settings_controller import SettingEntry
6+
7+
VARIABLE_NAME = "fast_audio_%s_volume"
8+
SETTING_TYPE = "hw_volume"
59

610

711
class FASTAudioInterface(LogMixin):
@@ -17,9 +21,9 @@ def __init__(self, platform, communicator):
1721
self.machine = platform.machine
1822
self.communicator = communicator
1923
self.amps = {
20-
'main': {'name': 'fast_audio_main', 'label': "Speakers"},
21-
'sub': {'name': 'fast_audio_sub', 'label': "Subwoofer"},
22-
'headphones': {'name': 'fast_audio_headphones', 'label': "Headphones"}
24+
'main': {'name': 'fast_audio_main', 'label': "Speakers", 'sort': 0},
25+
'sub': {'name': 'fast_audio_sub', 'label': "Subwoofer", 'sort': 1},
26+
'headphones': {'name': 'fast_audio_headphones', 'label': "Headphones", 'sort': 2}
2327
}
2428
self.control_pin_pulse_times = list()
2529

@@ -35,30 +39,41 @@ def _initialize(self, **kwargs):
3539
self._register_event_handlers()
3640

3741
def _configure_machine_vars(self):
38-
for amp_name in self.amps:
39-
var_name = f'fast_audio_{amp_name}_volume'
40-
41-
# Is there a race condition on first boot if the linked amp
42-
# comes in the iteration before 'main' is written?
43-
if amp_name != 'main' and self.communicator.config[f'link_{amp_name}_to_main']:
44-
self.machine.variables.set_machine_var(
45-
name=var_name,
46-
value=self.machine.variables.get_machine_var('fast_audio_main_volume'),
47-
persist=self.communicator.config['persist_volume_settings']
48-
)
49-
elif not self.machine.variables.is_machine_var(var_name):
50-
self.machine.variables.set_machine_var(
51-
name=var_name,
52-
value=self.communicator.config[f'default_{amp_name}_volume'],
53-
persist=self.communicator.config['persist_volume_settings']
54-
)
42+
# See if main volume has been defined yet, otherwise use default
43+
main_volume = self.machine.variables.get_machine_var('fast_audio_main_volume')
44+
if main_volume is None:
45+
main_volume = self.communicator.config['default_main_volume']
46+
47+
for amp_name, settings in self.amps.items():
48+
49+
default_value = self.communicator.config[f'default_{amp_name}_volume']
50+
if self.communicator.config.get(f'link_{amp_name}_to_main', False):
51+
machine_var_name = VARIABLE_NAME % "main"
52+
else:
53+
machine_var_name = VARIABLE_NAME % amp_name
54+
55+
# Create a machine variable if one doesn't exist
56+
if not self.machine.variables.is_machine_var(machine_var_name):
57+
self.machine.variables.set_machine_var(machine_var_name, default_value,
58+
self.communicator.config['persist_volume_settings'])
59+
60+
# Identify the machine var for this amp
61+
settings["machine_var"] = machine_var_name
62+
self.machine.settings.add_setting(SettingEntry(
63+
settings['name'],
64+
settings['label'],
65+
settings['sort'],
66+
machine_var_name,
67+
default_value,
68+
None,
69+
SETTING_TYPE
70+
))
5571

5672
def _init_amps(self):
5773
for amp_name, amp in self.amps.items():
5874
amp['steps'] = self.communicator.config[f'{amp_name}_steps']
5975
amp['max_volume'] = self.communicator.config[f'max_hw_volume_{amp_name}']
6076
amp['levels_list'] = self.communicator.config[f'{amp_name}_levels_list']
61-
amp['link_to_main'] = self.communicator.config[f'link_{amp_name}_to_main']
6277

6378
# Just set everything here. The communicator will send the
6479
# config as part of its init process later
@@ -71,7 +86,8 @@ def _init_amps(self):
7186
# if we have a levels list in the config, make sure the steps num is right
7287
amp['steps'] = len(amp['levels_list']) - 1
7388

74-
if amp['link_to_main'] and len(amp['levels_list']) != len(self.amps['main']['levels_list']):
89+
if self.communicator.config[f'link_{amp_name}_to_main'] and \
90+
len(amp['levels_list']) != len(self.amps['main']['levels_list']):
7591
raise AssertionError(f"Cannot link {amp_name} to main. The number of volume steps must be the same. "
7692
f"Main has {len(self.amps['main']['levels_list'])} steps, "
7793
f"but {amp_name} has {len(amp['levels_list'])} steps.")
@@ -135,7 +151,6 @@ def send_volume_to_hw(self, amp_name=None, send_now=True):
135151
for each_amp_name in self.amps:
136152
self.send_volume_to_hw(each_amp_name, send_now)
137153
return
138-
139154
self.communicator.set_volume(amp_name, self.get_volume(amp_name), send_now)
140155

141156
def _set_volume(self, amp_name, value=0, **kwargs):
@@ -155,19 +170,13 @@ def _set_volume(self, amp_name, value=0, **kwargs):
155170
#self.platform.debug_log("Writing FAST amp volume %s to %s (decimal)", amp_name, value)
156171
self.send_volume_to_hw(amp_name)
157172

158-
if amp_name == 'main':
159-
for other_amp_name, other_amp in self.amps.items():
160-
if other_amp_name != amp_name and other_amp['link_to_main']:
161-
# Update the machine var, which will be caught and handled
162-
self._set_machine_var_volume(other_amp_name, value)
163-
164173
def get_volume(self, amp_name, **kwargs):
165174
"""Return the current volume of the specified amp."""
166175
del kwargs
167-
return self.machine.variables.get_machine_var(f'fast_audio_{amp_name}_volume')
176+
return self.machine.variables.get_machine_var(self.amps[amp_name]["machine_var"]) or 0
168177

169178
def _set_machine_var_volume(self, amp_name, value):
170-
self.machine.variables.set_machine_var(f'fast_audio_{amp_name}_volume', value)
179+
self.machine.variables.set_machine_var(self.amps[amp_name]["machine_var"], value)
171180

172181
def temp_volume(self, amp_name, change=1, **kwargs):
173182
"""Temporarily change the volume by the specified number of units, up or down.

mpf/tests/machine_files/fast/config/audio.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ fast:
2222
power_pulse_time: 98
2323
reset_pulse_time: 97
2424

25+
machine_vars:
26+
fast_audio_sub_volume:
27+
initial_value: 9
28+
fast_audio_main_volume:
29+
initial_value: 8
30+
fast_audio_headphones_volume:
31+
initial_value: 10
32+
2533
variable_player:
2634
increase_main_volume:
2735
fast_audio_main_volume:

mpf/tests/machine_files/fast/config/audio2.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ fast:
2727
- 14
2828
- 15
2929
headphones_level: line
30+
link_sub_to_main: true
3031

3132
machine_vars:
3233
fast_audio_main_volume:

mpf/tests/test_Fast_Audio.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ def create_expected_commands(self):
2525
self.serial_connections['aud'].autorespond_commands['WD:3E8'] = 'WD:3E8,03'
2626

2727
else:
28-
self.serial_connections['aud'].expected_commands = {'AM:0B':'AM:0B',
29-
'AV:08':'AV:08',
30-
'AS:09':'AS:09',
31-
'AH:0A':'AH:0A',}
28+
self.serial_connections['aud'].expected_commands = {
29+
# 'AV:00':'AV:00',
30+
# 'AS:00':'AS:00',
31+
# 'AH:00':'AH:00',
32+
'AM:0B':'AM:0B',
33+
'AV:08':'AV:08',
34+
'AS:09':'AS:09',
35+
'AH:0A':'AH:0A',
36+
}
3237

3338
def test_audio_basics(self):
3439

@@ -69,10 +74,6 @@ def test_audio_basics(self):
6974
self.assertTrue(fast_audio.communicator.amps['sub']['enabled'])
7075
self.assertTrue(fast_audio.communicator.amps['headphones']['enabled'])
7176

72-
self.assertFalse(fast_audio.amps['main']['link_to_main'])
73-
self.assertFalse(fast_audio.amps['sub']['link_to_main'])
74-
self.assertFalse(fast_audio.amps['headphones']['link_to_main'])
75-
7677
# Change the volume var and make sure it's reflected in the hardware
7778
self.aud_cpu.expected_commands['AV:0D'] = 'AV:0D'
7879
self.machine.variables.set_machine_var('fast_audio_main_volume', 13)
@@ -113,9 +114,13 @@ def test_control_pins(self):
113114
@test_config('audio2.yaml')
114115
def test_machine_var_loading(self):
115116
fast_audio = self.machine.default_platform.audio_interface
117+
self.advance_time_and_run()
116118
self.assertEqual(15, self.machine.variables.get_machine_var('fast_audio_main_volume'))
119+
self.assertEqual(15, fast_audio.get_volume('main'))
117120
self.assertEqual(15, fast_audio.communicator.amps['main']['volume'])
121+
# sub has a machine value set in the configs, which is persisted
122+
self.assertEqual(2, self.machine.variables.get_machine_var('fast_audio_sub_volume'))
118123
# sub is linked to main, so it will be 15 even though the config value is 2
119-
self.assertEqual(15, self.machine.variables.get_machine_var('fast_audio_sub_volume'))
124+
self.assertEqual(15, fast_audio.get_volume('main'))
120125
self.assertEqual(15, fast_audio.communicator.amps['sub']['volume'])
121126
self.assertEqual(17, self.machine.variables.get_machine_var('fast_audio_headphones_volume'))

0 commit comments

Comments
 (0)