Skip to content

Architecture

Matthew Stratford edited this page May 6, 2021 · 2 revisions

This is the high(er) level explanation what's present in BAPSicle, and how it all talks to each other.

BAPS3 Project Layout

"BAPSicle" is primarily used to refer to the audio server for BAPS3.

BAPSicle serves the "BAPS Presenter" User Interface via its web server module at /presenter, for packaging simplicity. The Presenter is based on a special build of URY's WebStudio project with most of the audio guts disabled and replaced with a WebSocket backend to BAPSicle. The Presenter is a git submodule in the <project>/presenter directory.

Server Layout

The BAPSicle server is made of multiple modules. Each module runs as its own MultiProcessing.Process joined together primarily with MultiProcessing.Queues in multiple directions. This was initially decided due to the implementation requirements of The Player and was continued across the rest of the project.

Main Modules

  • server.py - The main entry point (called from launch.py) that acts as the launcher and watchdog for the other module processes.
  • player.py - The code that actually manages a "channel" of the show plan, plays audio etc. Multiple instances of the Player class can be launched, each to handle a single "channel" of audio.
  • player_handler.py - Splits command responses from the player back to the module that sent the original command (or to all modules).
  • web_server.py - Provides the Sanic webserver used to serve the presenter UI, administer BAPSicle and act as an API proxy to (currently) MyRadio for UI track / show plan requests.
  • websocket_server.py - Provides a websocket server to allow the presenter UI instances to send / receive server state changes.
  • file_manager.py - The secret sauce that makes BAPSicle so responsive, handling pre-loading audio from the API to the local disk for quick loading.
  • controllers/*.py - Implementations of hardware controller interfaces for BAPSicle.

Module Communication

The main point of contact are the Player instances, since they handle playback and audio sequencing. Queues can be classed as multiple producers, single consumer. As an example, this means any module can send (produce) a command message to the player, but other modules cannot read (consume) from the same Queue. If they did, they would be stealing messages before reaching the player.

In a similar fashion, the player can therefor not directly respond to all modules with a response, each module would be stealing messages from the others. The PlayerHandler module therefore relays the response Queue from the player to separate Queue objects for the other modules.

Each command message sent to a Player must be prefixed by "SOURCE_NAME:". As of writing, these are defined in player.py as ["WEBSOCKET", "UI", "CONTROLLER", "TEST", "ALL"]. PlayerHandler will split the response back out to the module based on the Source Name given. "Test" refers to the test modules in <project>/tests/.

** Block Diagram To Follow **

Packaging

BAPSicle must primarily run on Windows in URY's use case. However, since it is Python based, with limited effort, it can run on multiple target platforms.

PyInstaller is used to "Freeze" the Python code into a self-contained target platform binary. Using the generosity of GitHub actions, builds for supported platforms (currently Windows, MacOS and Ubuntu) are build automatically. See the build / development instructions for more about doing this manually.

Clone this wiki locally