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

Audio Service Menu and FAST Audio Board Support #1743

Merged
merged 8 commits into from
Jan 22, 2024

Conversation

avanwinkle
Copy link
Collaborator

This PR implements a new Service Menu for Audio Controls, including both software and hardware volume controls, and refactors the FAST Audio Board code.

Audio Service Menu -> Software Levels

The Audio Menu is added to the default service menu and populates a "Software Levels" submenu. The submenu parses the machine's sound_system: configuration to identify each of the tracks and offers volume control for each track. To support this functionality, the Tracks class is updated to use a machine variable for its volume level, similar to how the main volume control does. The Tracks also support the label config option for displaying a human-friendly name in the service menu.

The menu is currently hard-coded to offer volume levels from 0-100% at 5% increments. A future update could make this customizable, if desired.

The various menu and submenus use the same formatting and kwargs as the other service menu, so no new slides are needed if a user has already established (or is using the default) service slides.

Audio Service Menu -> Hardware Levels

The Audio Menu can detect the presence of a hardware sound device (currently, only the FAST Audio Board is supported) and provide level-setting for the hardware using its serial API. Each hardware platform defines its level options (e.g. speakers, subwoofer, headphones) and exposes a method to change their level.

When the Audio Service menu is loaded, it checks whether a hardware device is attached and if so, automatically adds the Hardware Levels submenu next to the Software Levels. If no hardware device is detected, the submenu is not added.

There is also an option in the submenu to write the current level settings to the hardware device, which is automatically added if the device supports a write_to_firmware() method.

FAST Audio Board

This PR refactors much of the initial implementation of the FAST Audio Board by @toomanybrians based on my testing and usage. The main changes are:

  • Rename variables to use amp_name for string-type refs to amp types, and reserve amp variables for objects containing properties about the amp.
  • Pass, store, and load volume levels as decimal integers, and only convert to hexadecimal when writing over serial
  • Track volume levels based on the absolute units, rather than steps. This prevents accidental blowout if the number of steps changes.
  • Make the audio board connection "optional", so it can be defined in the configs but isn't required to run the game. For users with limited USB ports or looking to scrape every possible CPU resource, disconnecting the audio board during normal play can be advantageous.
  • Eliminate a redundant initialization call prior to opening the hardware connection
  • Don't link the main speaker volume to itself by default (saves code paths)

Other FAST Changes

This PR also improves the port auto-detection logic to prevent hangs when a certain device is not attached. Previously, MPF would identify the ports it needs to auto-detect and wait until each one reported in. If one is not connected, the startup flow will hang. This PR changes that logic with a few tweaks:

  • Any port that has a pid and vid of a FAST device but doesn't respond to an ID: command will give up after 5 attempts, instead of probing indefinitely.
  • Any port that didn't successfully find an auto-detect port won't attempt to connect, instead of trying to open port "auto".
  • Any device tagged as "optional" in the configs won't block startup if it's not found (see optional audio board above).

Future Improvements

The FAST Audio Board and its amps do not use a base class or interface, so this implementation currently cannot scale to other platforms. Abstracting the properties and methods would allow other devices to be controlled.

The FAST Audio currently has two classes, an Interface for exposing volume levels and a Connector for communicating over serial. Each of these classes has a collection of amp objects (basic Dict instances) with different properties and uses. It would simplify understanding to build an Amp class that could be shared/passed between these two consumers.

Testing

All tests have been updated and pass. I've verified the functionality manually on my Mass Effect 2 machine, with both software and hardware volume controls, saved variables, and service menu interactions. However this is a big set of changes so any feedback and testers are appreciated!

can you hear me

Copy link

Quality Gate Passed Quality Gate passed

Kudos, no new issues were introduced!

0 New issues
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant