OVERVIEW
    A multi-threaded audio system built in Visual Studio using C++ and XAudio2 application interface (API). Microsoft XAudio2 is a low-level audio API that provides signal processing and mixing for games. This project aims to encapsulate the API into a more user-friendly library via the Actor Model.
Highlights
System Interface
    The XAudio2 API supports the ability to build complex soundscapes; supporting a wide range of functions for 3D effects and sound mixing. The comprehensive functionality provided by XAudio2 makes it difficult to use. This audio systems interface wraps the API and only exposes functional support for stereo  sound and basic audio controls.
    The User has access to the audio system through two classes: (1) Audio Engine, and (2) Sound. The Audio Engine class allows the User to initiate, destroy, update, and load audio assets. The Sound class provides the User audio controls such as play, pause, or changing volume.
The Actor Model
    The audio system implements the Actor Model to remove the need for lock-based synchronization between threads; each thread is considered an actor. An actor has the ability to (1) spawn more actors, (2) send or receive messages, and (3) make decisions that effect its own private state. The system transmits messages as a command that is passed through a mutex protected circular queue to each thread.
    The system uses five main threads; and their main roles are:
      • Game: runs game simulation and initiates sound
          requests
      • Audio: runs the bulk of audio functionality and
          coordinates message responses
      • File: used by Audio thread to offload audio file loading
      • Aux: used by Audio thread to offload system updates 
      • XAudio2: sends feedback to system about internal
         XAudio2 assets
Handle System
    A handle system was created as another layer of protection and validation for active resources. It was particularly important for resources that was accessible between multiple threads, such as sound objects.
Callback Support
    The user can define two types of callbacks for feedback: (1) File Callback for asynchronous audio loads, and (2) Sound Callback for sound status updates. The Sound Callback can notify a user if their sound has successfully played, paused, stopped, ended, or been forcibly stopped by the system. 
Sound Priorities
    The audio system has a priority table to track and limit the number of active sounds. An active sound is considered any audio that is actively playing or paused. Each sound is assigned a priority when created, the priority determines their table ranking. When the table is at capacity, sounds that have low priorities can be evicted. 
Post-Mortem
    This project was a result of a introductory multi-threaded architecture course at DePaul University. Thus the resulting system was restricted to using very minimal multi-threading tools such as mutexes and basic atomic types. The focus was really on learning how to properly launch and utilize threads, and create a relatively clean architecture. 
    If I was to continue this project, I would add support for other file types; the current system only loads wav files. I would also add the ability to  fast forward, rewind, and loop audio. Lastly, I would tighten up the interface. The user shouldn't really be able to touch anything else besides the Audio Engine and Sound class. The other classes that are completely driven by the audio thread should be further restricted. 
Back to Top